From 52f2c1386139d067b682d3c1c17a76abcf237e90 Mon Sep 17 00:00:00 2001 From: chenrl Date: Sun, 21 Mar 2021 16:46:15 +0800 Subject: [PATCH 001/735] check file with realPath is existing --- .../web/context/support/ServletContextResource.java | 9 +++++++-- .../web/context/support/ResourceTests.java | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java index 9f19b76d9971..ad236509d88d 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java @@ -139,10 +139,15 @@ public boolean isFile() { return true; } else { - return (this.servletContext.getRealPath(this.path) != null); + String realPath = this.servletContext.getRealPath(this.path); + if (realPath == null) { + return false; + } + File file = new File(realPath); + return (file.exists() && file.isFile()); } } - catch (MalformedURLException ex) { + catch (IOException ex) { return false; } } diff --git a/spring-web/src/test/java/org/springframework/web/context/support/ResourceTests.java b/spring-web/src/test/java/org/springframework/web/context/support/ResourceTests.java index 340838871814..937885e107f7 100644 --- a/spring-web/src/test/java/org/springframework/web/context/support/ResourceTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/support/ResourceTests.java @@ -36,6 +36,8 @@ public void testServletContextResource() throws IOException { MockServletContext sc = new MockServletContext(); Resource resource = new ServletContextResource(sc, "org/springframework/core/io/Resource.class"); doTestResource(resource); + Resource resourceNotExists = new ServletContextResource(sc, "org/springframework/core/io/ResourceNotExists.class"); + doTestNotExistsResource(resourceNotExists); assertThat(new ServletContextResource(sc, "org/springframework/core/../core/io/./Resource.class")).isEqualTo(resource); } @@ -48,6 +50,9 @@ public void testServletContextResourceWithRelativePath() throws IOException { } private void doTestResource(Resource resource) throws IOException { + assertThat(resource.getFile()).isNotNull(); + assertThat(resource.exists()).isTrue(); + assertThat(resource.isFile()).isTrue(); assertThat(resource.getFilename()).isEqualTo("Resource.class"); assertThat(resource.getURL().getFile().endsWith("Resource.class")).isTrue(); @@ -61,4 +66,9 @@ private void doTestResource(Resource resource) throws IOException { assertThat(relative2.getURL().getFile().endsWith("ResourcePatternResolver.class")).isTrue(); assertThat(relative2.exists()).isTrue(); } + + private void doTestNotExistsResource(Resource resource) throws IOException { + assertThat(resource.exists()).isFalse(); + assertThat(resource.isFile()).isFalse(); + } } From 462e19d417dc1e3513211ef5d5a3ea4c351f1c14 Mon Sep 17 00:00:00 2001 From: Erik van Paassen Date: Sun, 22 Aug 2021 14:10:25 +0200 Subject: [PATCH 002/735] Fix UrlPathHelper#shouldRemoveSemicolonContent() (#27303) The checkReadOnly() method should only be called from methods that modify properties to prevent modification of read-only instances. Fixes #27256 --- .../java/org/springframework/web/util/UrlPathHelper.java | 1 - .../org/springframework/web/util/UrlPathHelperTests.java | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java index 575f822f957f..663dbb7566c4 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java +++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java @@ -147,7 +147,6 @@ public void setRemoveSemicolonContent(boolean removeSemicolonContent) { * Whether configured to remove ";" (semicolon) content from the request URI. */ public boolean shouldRemoveSemicolonContent() { - checkReadOnly(); return this.removeSemicolonContent; } diff --git a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java index 0aea5a0b51d9..1b2921205f51 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java @@ -22,6 +22,7 @@ import org.springframework.web.testfixture.servlet.MockHttpServletRequest; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; /** * Unit tests for {@link UrlPathHelper}. @@ -165,6 +166,11 @@ public void getLookupPathWithSemicolonContentAndNullPathInfo() { assertThat(helper.getLookupPathForRequest(request)).isEqualTo("/welcome.html;c=d"); } + @Test // gh-27303 + public void shouldRemoveSemicolonContentWithReadOnlyInstance() { + assertThatCode(UrlPathHelper.defaultInstance::shouldRemoveSemicolonContent).doesNotThrowAnyException(); + } + // // suite of tests root requests for default servlets (SRV 11.2) on Websphere vs Tomcat and other containers From 99970a5ddc063b6747970973c3bfdf803e21b1b3 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 22 Aug 2021 14:22:51 +0200 Subject: [PATCH 003/735] Polish contribution See gh-27303 --- .../web/util/UrlPathHelperTests.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java index 1b2921205f51..3c1bbd282015 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ import org.springframework.web.testfixture.servlet.MockHttpServletRequest; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** * Unit tests for {@link UrlPathHelper}. @@ -167,8 +167,24 @@ public void getLookupPathWithSemicolonContentAndNullPathInfo() { } @Test // gh-27303 - public void shouldRemoveSemicolonContentWithReadOnlyInstance() { - assertThatCode(UrlPathHelper.defaultInstance::shouldRemoveSemicolonContent).doesNotThrowAnyException(); + public void defaultInstanceReadOnlyBehavior() { + UrlPathHelper helper = UrlPathHelper.defaultInstance; + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> helper.setAlwaysUseFullPath(true)) + .withMessage("This instance cannot be modified"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> helper.setUrlDecode(true)) + .withMessage("This instance cannot be modified"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> helper.setRemoveSemicolonContent(true)) + .withMessage("This instance cannot be modified"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> helper.setDefaultEncoding("UTF-8")) + .withMessage("This instance cannot be modified"); + + assertThat(helper.isUrlDecode()).isTrue(); + assertThat(helper.shouldRemoveSemicolonContent()).isTrue(); } From 6c71cf2f96d8ccb46965753d5a47847b2adfdcdf Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 22 Aug 2021 14:27:47 +0200 Subject: [PATCH 004/735] Polishing --- .../web/util/UrlPathHelperTests.java | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java index 3c1bbd282015..094e33d419fd 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java @@ -31,7 +31,7 @@ * @author Juergen Hoeller * @author Costin Leau */ -public class UrlPathHelperTests { +class UrlPathHelperTests { private static final String WEBSPHERE_URI_ATTRIBUTE = "com.ibm.websphere.servlet.uri_non_decoded"; @@ -41,7 +41,7 @@ public class UrlPathHelperTests { @Test - public void getPathWithinApplication() { + void getPathWithinApplication() { request.setContextPath("/petclinic"); request.setRequestURI("/petclinic/welcome.html"); @@ -49,7 +49,7 @@ public void getPathWithinApplication() { } @Test - public void getPathWithinApplicationForRootWithNoLeadingSlash() { + void getPathWithinApplicationForRootWithNoLeadingSlash() { request.setContextPath("/petclinic"); request.setRequestURI("/petclinic"); @@ -57,7 +57,7 @@ public void getPathWithinApplicationForRootWithNoLeadingSlash() { } @Test - public void getPathWithinApplicationForSlashContextPath() { + void getPathWithinApplicationForSlashContextPath() { request.setContextPath("/"); request.setRequestURI("/welcome.html"); @@ -65,7 +65,7 @@ public void getPathWithinApplicationForSlashContextPath() { } @Test - public void getPathWithinServlet() { + void getPathWithinServlet() { request.setContextPath("/petclinic"); request.setServletPath("/main"); request.setRequestURI("/petclinic/main/welcome.html"); @@ -74,7 +74,7 @@ public void getPathWithinServlet() { } @Test - public void alwaysUseFullPath() { + void alwaysUseFullPath() { helper.setAlwaysUseFullPath(true); request.setContextPath("/petclinic"); request.setServletPath("/main"); @@ -84,7 +84,7 @@ public void alwaysUseFullPath() { } @Test // SPR-11101 - public void getPathWithinServletWithoutUrlDecoding() { + void getPathWithinServletWithoutUrlDecoding() { request.setContextPath("/SPR-11101"); request.setServletPath("/test_url_decoding/a/b"); request.setRequestURI("/test_url_decoding/a%2Fb"); @@ -96,7 +96,7 @@ public void getPathWithinServletWithoutUrlDecoding() { } @Test - public void getRequestUri() { + void getRequestUri() { request.setRequestURI("/welcome.html"); assertThat(helper.getRequestUri(request)).isEqualTo("/welcome.html"); @@ -111,7 +111,7 @@ public void getRequestUri() { } @Test - public void getRequestRemoveSemicolonContent() { + void getRequestRemoveSemicolonContent() { helper.setRemoveSemicolonContent(true); request.setRequestURI("/foo;f=F;o=O;o=O/bar;b=B;a=A;r=R"); assertThat(helper.getRequestUri(request)).isEqualTo("/foo/bar"); @@ -126,7 +126,7 @@ public void getRequestRemoveSemicolonContent() { } @Test - public void getRequestKeepSemicolonContent() { + void getRequestKeepSemicolonContent() { helper.setRemoveSemicolonContent(false); testKeepSemicolonContent("/foo;a=b;c=d", "/foo;a=b;c=d"); @@ -145,7 +145,7 @@ private void testKeepSemicolonContent(String requestUri, String expectedPath) { } @Test - public void getLookupPathWithSemicolonContent() { + void getLookupPathWithSemicolonContent() { helper.setRemoveSemicolonContent(false); request.setContextPath("/petclinic"); @@ -156,7 +156,7 @@ public void getLookupPathWithSemicolonContent() { } @Test - public void getLookupPathWithSemicolonContentAndNullPathInfo() { + void getLookupPathWithSemicolonContentAndNullPathInfo() { helper.setRemoveSemicolonContent(false); request.setContextPath("/petclinic"); @@ -167,7 +167,7 @@ public void getLookupPathWithSemicolonContentAndNullPathInfo() { } @Test // gh-27303 - public void defaultInstanceReadOnlyBehavior() { + void defaultInstanceReadOnlyBehavior() { UrlPathHelper helper = UrlPathHelper.defaultInstance; assertThatExceptionOfType(IllegalArgumentException.class) @@ -199,7 +199,7 @@ public void defaultInstanceReadOnlyBehavior() { // @Test - public void tomcatDefaultServletRoot() { + void tomcatDefaultServletRoot() { request.setContextPath("/test"); request.setServletPath("/"); request.setPathInfo(null); @@ -208,7 +208,7 @@ public void tomcatDefaultServletRoot() { } @Test - public void tomcatDefaultServletFile() { + void tomcatDefaultServletFile() { request.setContextPath("/test"); request.setServletPath("/foo"); request.setPathInfo(null); @@ -218,7 +218,7 @@ public void tomcatDefaultServletFile() { } @Test - public void tomcatDefaultServletFolder() { + void tomcatDefaultServletFolder() { request.setContextPath("/test"); request.setServletPath("/foo/"); request.setPathInfo(null); @@ -228,7 +228,7 @@ public void tomcatDefaultServletFolder() { } @Test //SPR-12372, SPR-13455 - public void removeDuplicateSlashesInPath() { + void removeDuplicateSlashesInPath() { request.setContextPath("/SPR-12372"); request.setPathInfo(null); request.setServletPath("/foo/bar/"); @@ -249,7 +249,7 @@ public void removeDuplicateSlashesInPath() { } @Test - public void wasDefaultServletRoot() { + void wasDefaultServletRoot() { request.setContextPath("/test"); request.setPathInfo("/"); request.setServletPath(""); @@ -260,13 +260,13 @@ public void wasDefaultServletRoot() { } @Test - public void wasDefaultServletRootWithCompliantSetting() { + void wasDefaultServletRootWithCompliantSetting() { request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/"); tomcatDefaultServletRoot(); } @Test - public void wasDefaultServletFile() { + void wasDefaultServletFile() { request.setContextPath("/test"); request.setPathInfo("/foo"); request.setServletPath(""); @@ -277,13 +277,13 @@ public void wasDefaultServletFile() { } @Test - public void wasDefaultServletFileWithCompliantSetting() { + void wasDefaultServletFileWithCompliantSetting() { request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo"); tomcatDefaultServletFile(); } @Test - public void wasDefaultServletFolder() { + void wasDefaultServletFolder() { request.setContextPath("/test"); request.setPathInfo("/foo/"); request.setServletPath(""); @@ -294,7 +294,7 @@ public void wasDefaultServletFolder() { } @Test - public void wasDefaultServletFolderWithCompliantSetting() { + void wasDefaultServletFolderWithCompliantSetting() { UrlPathHelper.websphereComplianceFlag = true; try { request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo/"); @@ -311,7 +311,7 @@ public void wasDefaultServletFolderWithCompliantSetting() { // @Test - public void tomcatCasualServletRoot() { + void tomcatCasualServletRoot() { request.setContextPath("/test"); request.setPathInfo("/"); request.setServletPath("/foo"); @@ -321,9 +321,9 @@ public void tomcatCasualServletRoot() { } @Disabled - // test the root mapping for /foo/* w/o a trailing slash - //foo @Test - public void tomcatCasualServletRootWithMissingSlash() { + // test the root mapping for /foo/* w/o a trailing slash - //foo + void tomcatCasualServletRootWithMissingSlash() { request.setContextPath("/test"); request.setPathInfo(null); request.setServletPath("/foo"); @@ -333,7 +333,7 @@ public void tomcatCasualServletRootWithMissingSlash() { } @Test - public void tomcatCasualServletFile() { + void tomcatCasualServletFile() { request.setContextPath("/test"); request.setPathInfo("/foo"); request.setServletPath("/foo"); @@ -343,7 +343,7 @@ public void tomcatCasualServletFile() { } @Test - public void tomcatCasualServletFolder() { + void tomcatCasualServletFolder() { request.setContextPath("/test"); request.setPathInfo("/foo/"); request.setServletPath("/foo"); @@ -353,7 +353,7 @@ public void tomcatCasualServletFolder() { } @Test - public void wasCasualServletRoot() { + void wasCasualServletRoot() { request.setContextPath("/test"); request.setPathInfo(null); request.setServletPath("/foo/"); @@ -364,15 +364,15 @@ public void wasCasualServletRoot() { } @Test - public void wasCasualServletRootWithCompliantSetting() { + void wasCasualServletRootWithCompliantSetting() { request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo/"); tomcatCasualServletRoot(); } @Disabled - // test the root mapping for /foo/* w/o a trailing slash - //foo @Test - public void wasCasualServletRootWithMissingSlash() { + // test the root mapping for /foo/* w/o a trailing slash - //foo + void wasCasualServletRootWithMissingSlash() { request.setContextPath("/test"); request.setPathInfo(null); request.setServletPath("/foo"); @@ -384,13 +384,13 @@ public void wasCasualServletRootWithMissingSlash() { @Disabled @Test - public void wasCasualServletRootWithMissingSlashWithCompliantSetting() { + void wasCasualServletRootWithMissingSlashWithCompliantSetting() { request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo"); tomcatCasualServletRootWithMissingSlash(); } @Test - public void wasCasualServletFile() { + void wasCasualServletFile() { request.setContextPath("/test"); request.setPathInfo("/foo"); request.setServletPath("/foo"); @@ -401,13 +401,13 @@ public void wasCasualServletFile() { } @Test - public void wasCasualServletFileWithCompliantSetting() { + void wasCasualServletFileWithCompliantSetting() { request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo/foo"); tomcatCasualServletFile(); } @Test - public void wasCasualServletFolder() { + void wasCasualServletFolder() { request.setContextPath("/test"); request.setPathInfo("/foo/"); request.setServletPath("/foo"); @@ -418,33 +418,33 @@ public void wasCasualServletFolder() { } @Test - public void wasCasualServletFolderWithCompliantSetting() { + void wasCasualServletFolderWithCompliantSetting() { request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo/foo/"); tomcatCasualServletFolder(); } @Test - public void getOriginatingRequestUri() { + void getOriginatingRequestUri() { request.setAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE, "/path"); request.setRequestURI("/forwarded"); assertThat(helper.getOriginatingRequestUri(request)).isEqualTo("/path"); } @Test - public void getOriginatingRequestUriWebsphere() { + void getOriginatingRequestUriWebsphere() { request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/path"); request.setRequestURI("/forwarded"); assertThat(helper.getOriginatingRequestUri(request)).isEqualTo("/path"); } @Test - public void getOriginatingRequestUriDefault() { + void getOriginatingRequestUriDefault() { request.setRequestURI("/forwarded"); assertThat(helper.getOriginatingRequestUri(request)).isEqualTo("/forwarded"); } @Test - public void getOriginatingQueryString() { + void getOriginatingQueryString() { request.setQueryString("forward=on"); request.setAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE, "/path"); request.setAttribute(WebUtils.FORWARD_QUERY_STRING_ATTRIBUTE, "original=on"); @@ -452,13 +452,13 @@ public void getOriginatingQueryString() { } @Test - public void getOriginatingQueryStringNotPresent() { + void getOriginatingQueryStringNotPresent() { request.setQueryString("forward=true"); assertThat(this.helper.getOriginatingQueryString(request)).isEqualTo("forward=true"); } @Test - public void getOriginatingQueryStringIsNull() { + void getOriginatingQueryStringIsNull() { request.setQueryString("forward=true"); request.setAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE, "/path"); assertThat(this.helper.getOriginatingQueryString(request)).isNull(); From b28f403bf8314d27704b789a0eeda11f74aaf886 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 22 Aug 2021 14:45:55 +0200 Subject: [PATCH 005/735] Fix Checkstyle violation See gh-27303 --- .../springframework/web/util/UrlPathHelperTests.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java index 094e33d419fd..e3281e55273f 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java @@ -22,7 +22,7 @@ import org.springframework.web.testfixture.servlet.MockHttpServletRequest; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; /** * Unit tests for {@link UrlPathHelper}. @@ -170,16 +170,16 @@ void getLookupPathWithSemicolonContentAndNullPathInfo() { void defaultInstanceReadOnlyBehavior() { UrlPathHelper helper = UrlPathHelper.defaultInstance; - assertThatExceptionOfType(IllegalArgumentException.class) + assertThatIllegalArgumentException() .isThrownBy(() -> helper.setAlwaysUseFullPath(true)) .withMessage("This instance cannot be modified"); - assertThatExceptionOfType(IllegalArgumentException.class) + assertThatIllegalArgumentException() .isThrownBy(() -> helper.setUrlDecode(true)) .withMessage("This instance cannot be modified"); - assertThatExceptionOfType(IllegalArgumentException.class) + assertThatIllegalArgumentException() .isThrownBy(() -> helper.setRemoveSemicolonContent(true)) .withMessage("This instance cannot be modified"); - assertThatExceptionOfType(IllegalArgumentException.class) + assertThatIllegalArgumentException() .isThrownBy(() -> helper.setDefaultEncoding("UTF-8")) .withMessage("This instance cannot be modified"); From 7da7a976e67fad30b2e5e5caaf9bf2fa8045d5d1 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 22 Aug 2021 15:54:35 +0200 Subject: [PATCH 006/735] Document when prepareTestInstance() is invoked by the SpringMethodRule Closes gh-27305 --- .../test/annotation/Repeat.java | 8 ++++++-- .../test/context/TestContextManager.java | 10 +++++++--- .../test/context/TestExecutionListener.java | 20 +++++++++++-------- .../junit4/rules/SpringMethodRule.java | 6 +++++- src/docs/asciidoc/testing.adoc | 6 ++++-- 5 files changed, 34 insertions(+), 16 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/annotation/Repeat.java b/spring-test/src/main/java/org/springframework/test/annotation/Repeat.java index e81bb9c85690..dfa062ceb2ba 100644 --- a/spring-test/src/main/java/org/springframework/test/annotation/Repeat.java +++ b/spring-test/src/main/java/org/springframework/test/annotation/Repeat.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,11 @@ * *

Note that the scope of execution to be repeated includes execution of the * test method itself as well as any set up or tear down of - * the test fixture. + * the test fixture. When used with the + * {@link org.springframework.test.context.junit4.rules.SpringMethodRule + * SpringMethodRule}, the scope additionally includes + * {@linkplain org.springframework.test.context.TestExecutionListener#prepareTestInstance + * preparation of the test instance}. * *

This annotation may be used as a meta-annotation to create custom * composed annotations. diff --git a/spring-test/src/main/java/org/springframework/test/context/TestContextManager.java b/spring-test/src/main/java/org/springframework/test/context/TestContextManager.java index 30d67923e4fb..d93b78d88d56 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestContextManager.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestContextManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -221,8 +221,12 @@ public void beforeTestClass() throws Exception { /** * Hook for preparing a test instance prior to execution of any individual - * test methods, for example for injecting dependencies, etc. Should be - * called immediately after instantiation of the test instance. + * test methods — for example, to inject dependencies. + *

This method should be called immediately after instantiation of the test + * class or as soon after instantiation as possible (as is the case with the + * {@link org.springframework.test.context.junit4.rules.SpringMethodRule + * SpringMethodRule}). In any case, this method must be called prior to any + * framework-specific lifecycle callbacks. *

The managed {@link TestContext} will be updated with the supplied * {@code testInstance}. *

An attempt will be made to give each registered diff --git a/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java index a9b188e6e92d..e10d2422bdcc 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86,10 +86,14 @@ default void beforeTestClass(TestContext testContext) throws Exception { } /** - * Prepares the {@link Object test instance} of the supplied - * {@link TestContext test context}, for example by injecting dependencies. + * Prepares the {@linkplain Object test instance} of the supplied + * {@linkplain TestContext test context} — for example, to inject + * dependencies. *

This method should be called immediately after instantiation of the test - * instance but prior to any framework-specific lifecycle callbacks. + * class or as soon after instantiation as possible (as is the case with the + * {@link org.springframework.test.context.junit4.rules.SpringMethodRule + * SpringMethodRule}). In any case, this method must be called prior to any + * framework-specific lifecycle callbacks. *

The default implementation is empty. Can be overridden by * concrete classes as necessary. * @param testContext the test context for the test; never {@code null} @@ -123,8 +127,8 @@ default void beforeTestMethod(TestContext testContext) throws Exception { /** * Pre-processes a test immediately before execution of the - * {@link java.lang.reflect.Method test method} in the supplied - * {@link TestContext test context} — for example, for timing + * {@linkplain java.lang.reflect.Method test method} in the supplied + * {@linkplain TestContext test context} — for example, for timing * or logging purposes. *

This method must be called after framework-specific * before lifecycle callbacks. @@ -143,8 +147,8 @@ default void beforeTestExecution(TestContext testContext) throws Exception { /** * Post-processes a test immediately after execution of the - * {@link java.lang.reflect.Method test method} in the supplied - * {@link TestContext test context} — for example, for timing + * {@linkplain java.lang.reflect.Method test method} in the supplied + * {@linkplain TestContext test context} — for example, for timing * or logging purposes. *

This method must be called before framework-specific * after lifecycle callbacks. diff --git a/spring-test/src/main/java/org/springframework/test/context/junit4/rules/SpringMethodRule.java b/spring-test/src/main/java/org/springframework/test/context/junit4/rules/SpringMethodRule.java index 639ee9d6f623..57478d4bd8a6 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit4/rules/SpringMethodRule.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit4/rules/SpringMethodRule.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,6 +79,10 @@ *

NOTE: As of Spring Framework 4.3, this class requires JUnit 4.12 or higher. * *

WARNING: Due to the shortcomings of JUnit rules, the + * {@code SpringMethodRule} + * {@linkplain org.springframework.test.context.TestExecutionListener#prepareTestInstance + * prepares the test instance} before {@code @Before} lifecycle methods instead of + * immediately after instantiation of the test class. In addition, the * {@code SpringMethodRule} does not support the * {@code beforeTestExecution()} and {@code afterTestExecution()} callbacks of the * {@link org.springframework.test.context.TestExecutionListener TestExecutionListener} diff --git a/src/docs/asciidoc/testing.adoc b/src/docs/asciidoc/testing.adoc index 81455ea5ac12..90c463fbe6fa 100644 --- a/src/docs/asciidoc/testing.adoc +++ b/src/docs/asciidoc/testing.adoc @@ -1657,8 +1657,10 @@ before failing. times that the test method is to be run is specified in the annotation. The scope of execution to be repeated includes execution of the test method itself as -well as any setting up or tearing down of the test fixture. The following example shows -how to use the `@Repeat` annotation: +well as any setting up or tearing down of the test fixture. When used with the +<>, the scope additionally includes +preparation of the test instance by `TestExecutionListener` implementations. The +following example shows how to use the `@Repeat` annotation: [source,java,indent=0,subs="verbatim,quotes",role="primary"] .Java From 8a7c4fc10d60168ebded312e2b02b3a052c46d33 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 22 Aug 2021 17:44:14 +0200 Subject: [PATCH 007/735] Support HtmlFileInput.setData() with HtmlUnit and MockMvc Prior to this commit, if the user tested file upload support with HtmlUnit and MockMvc by invoking HtmlFileInput.setData() instead of HtmlFileInput.setFiles(), the in-memory file data was simply ignored. This commit addresses this issue by creating a MockPart from the in-memory data in HtmlUnitRequestBuilder. Closes gh-27199 --- .../htmlunit/HtmlUnitRequestBuilder.java | 14 +++++--- .../htmlunit/HtmlUnitRequestBuilderTests.java | 32 +++++++++++++++++-- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java index fa52c987c667..7d76e63e7511 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java @@ -377,12 +377,18 @@ private void params(MockHttpServletRequest request, UriComponents uriComponents) MockPart part; if (file != null) { part = new MockPart(pair.getName(), file.getName(), readAllBytes(file)); - part.getHeaders().setContentType(MediaType.valueOf(pair.getMimeType())); } - else { // mimic empty file upload - part = new MockPart(pair.getName(), "", null); - part.getHeaders().setContentType(MediaType.APPLICATION_OCTET_STREAM); + else { + // Support empty file upload OR file upload via setData(). + // For an empty file upload, getValue() returns an empty string, and + // getData() returns null. + // For a file upload via setData(), getData() returns the file data, and + // getValue() returns the file name (if set) or an empty string. + part = new MockPart(pair.getName(), pair.getValue(), pair.getData()); } + MediaType mediaType = (pair.getMimeType() != null ? MediaType.valueOf(pair.getMimeType()) : + MediaType.APPLICATION_OCTET_STREAM); + part.getHeaders().setContentType(mediaType); request.addPart(part); } else { 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 b1f73b4741f9..96ebbb4ed529 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 @@ -16,6 +16,7 @@ package org.springframework.test.web.servlet.htmlunit; +import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; @@ -443,6 +444,33 @@ public void buildRequestParameterMapViaWebRequestDotSetRequestParametersWithFile assertThat(part.getContentType()).isEqualTo(MimeType.TEXT_PLAIN); } + @Test // gh-27199 + public void buildRequestParameterMapViaWebRequestDotSetRequestParametersWithFileDataAsParameter() throws Exception { + String data = "{}"; + KeyDataPair keyDataPair = new KeyDataPair("key", new File("test.json"), null, MimeType.APPLICATION_JSON, StandardCharsets.UTF_8); + keyDataPair.setData(data.getBytes()); + + webRequest.setRequestParameters(Collections.singletonList(keyDataPair)); + + MockHttpServletRequest actualRequest = requestBuilder.buildRequest(servletContext); + + assertThat(actualRequest.getParts()).hasSize(1); + Part part = actualRequest.getPart("key"); + + assertSoftly(softly -> { + softly.assertThat(part).as("part").isNotNull(); + softly.assertThat(part.getName()).as("name").isEqualTo("key"); + softly.assertThat(part.getSubmittedFileName()).as("file name").isEqualTo("test.json"); + softly.assertThat(part.getContentType()).as("content type").isEqualTo(MimeType.APPLICATION_JSON); + try { + softly.assertThat(IOUtils.toString(part.getInputStream(), StandardCharsets.UTF_8)).as("content").isEqualTo(data); + } + catch (IOException ex) { + softly.fail("failed to get InputStream", ex); + } + }); + } + @Test // gh-26799 public void buildRequestParameterMapViaWebRequestDotSetRequestParametersWithNullFileToUploadAsParameter() throws Exception { webRequest.setRequestParameters(Collections.singletonList(new KeyDataPair("key", null, null, null, (Charset) null))); @@ -453,11 +481,11 @@ public void buildRequestParameterMapViaWebRequestDotSetRequestParametersWithNull Part part = actualRequest.getPart("key"); assertSoftly(softly -> { - softly.assertThat(part).isNotNull(); + softly.assertThat(part).as("part").isNotNull(); softly.assertThat(part.getName()).as("name").isEqualTo("key"); softly.assertThat(part.getSize()).as("size").isEqualTo(0); try { - softly.assertThat(part.getInputStream()).isEmpty(); + softly.assertThat(part.getInputStream()).as("input stream").isEmpty(); } catch (IOException ex) { softly.fail("failed to get InputStream", ex); From 81a6ba42a36230ad7cdbf1d4e699e09dad012ad1 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 23 Aug 2021 11:37:22 +0200 Subject: [PATCH 008/735] Introduce ExceptionCollector testing utility This commit introduces a new ExceptionCollector testing utility in order to support "soft assertion" use cases. Closes gh-27316 --- .../test/util/ExceptionCollector.java | 127 +++++++++++++++ .../test/util/ExceptionCollectorTests.java | 151 ++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 spring-test/src/main/java/org/springframework/test/util/ExceptionCollector.java create mode 100644 spring-test/src/test/java/org/springframework/test/util/ExceptionCollectorTests.java diff --git a/spring-test/src/main/java/org/springframework/test/util/ExceptionCollector.java b/spring-test/src/main/java/org/springframework/test/util/ExceptionCollector.java new file mode 100644 index 000000000000..1c5ffaa33236 --- /dev/null +++ b/spring-test/src/main/java/org/springframework/test/util/ExceptionCollector.java @@ -0,0 +1,127 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * {@code ExceptionCollector} is a test utility for executing code blocks, + * collecting exceptions, and generating a single {@link AssertionError} + * containing any exceptions encountered as {@linkplain Throwable#getSuppressed() + * suppressed exceptions}. + * + *

This utility is intended to support soft assertion use cases + * similar to the {@code SoftAssertions} support in AssertJ and the + * {@code assertAll()} support in JUnit Jupiter. + * + * @author Sam Brannen + * @since 5.3.10 + */ +public class ExceptionCollector { + + private final List exceptions = new ArrayList<>(); + + + /** + * Execute the supplied {@link Executable} and track any exception thrown. + * @param executable the {@code Executable} to execute + * @see #getExceptions() + * @see #assertEmpty() + */ + public void execute(Executable executable) { + try { + executable.execute(); + } + catch (Throwable ex) { + this.exceptions.add(ex); + } + } + + /** + * Get the list of exceptions encountered in {@link #execute(Executable)}. + * @return an unmodifiable copy of the list of exceptions, potentially empty + * @see #assertEmpty() + */ + public List getExceptions() { + return Collections.unmodifiableList(this.exceptions); + } + + /** + * Assert that this {@code ExceptionCollector} does not contain any + * {@linkplain #getExceptions() exceptions}. + *

If this collector is empty, this method is effectively a no-op. + *

If this collector contains a single {@link Error} or {@link Exception}, + * this method rethrows the error or exception. + *

If this collector contains a single {@link Throwable}, this method throws + * an {@link AssertionError} with the error message of the {@code Throwable} + * and with the {@code Throwable} as the {@linkplain Throwable#getCause() cause}. + *

If this collector contains multiple exceptions, this method throws an + * {@code AssertionError} whose message is "Multiple Exceptions (#):" + * followed by a new line with the error message of each exception separated + * by a new line, with {@code #} replaced with the number of exceptions present. + * In addition, each exception will be added to the {@code AssertionError} as + * a {@link Throwable#addSuppressed(Throwable) suppressed exception}. + * @see #execute(Executable) + * @see #getExceptions() + */ + public void assertEmpty() throws Exception { + if (this.exceptions.isEmpty()) { + return; + } + + if (this.exceptions.size() == 1) { + Throwable exception = this.exceptions.get(0); + if (exception instanceof Error) { + throw (Error) exception; + } + if (exception instanceof Exception) { + throw (Exception) exception; + } + AssertionError assertionError = new AssertionError(exception.getMessage()); + assertionError.initCause(exception); + throw assertionError; + } + + StringBuilder message = new StringBuilder(); + message.append("Multiple Exceptions (").append(this.exceptions.size()).append("):"); + for (Throwable exception : this.exceptions) { + message.append('\n'); + message.append(exception.getMessage()); + } + AssertionError assertionError = new AssertionError(message); + this.exceptions.forEach(assertionError::addSuppressed); + throw assertionError; + } + + + /** + * {@code Executable} is a functional interface that can be used to implement + * any generic block of code that potentially throws a {@link Throwable}. + * + *

The {@code Executable} interface is similar to {@link java.lang.Runnable}, + * except that an {@code Executable} can throw any kind of exception. + */ + @FunctionalInterface + interface Executable { + + void execute() throws Throwable; + + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/util/ExceptionCollectorTests.java b/spring-test/src/test/java/org/springframework/test/util/ExceptionCollectorTests.java new file mode 100644 index 000000000000..6bb39d407b01 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/util/ExceptionCollectorTests.java @@ -0,0 +1,151 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.util; + +import org.junit.jupiter.api.Test; + +import org.springframework.test.util.ExceptionCollector.Executable; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; + +/** + * Unit tests for {@link ExceptionCollector}. + * + * @author Sam Brannen + * @since 5.3.10 + */ +public class ExceptionCollectorTests { + + private static final char EOL = '\n'; + + private final ExceptionCollector collector = new ExceptionCollector(); + + + @Test + void noExceptions() { + this.collector.execute(() -> {}); + + assertThat(this.collector.getExceptions()).isEmpty(); + assertThatNoException().isThrownBy(this.collector::assertEmpty); + } + + @Test + void oneError() { + this.collector.execute(error()); + + assertOneFailure(Error.class, "error"); + } + + @Test + void oneAssertionError() { + this.collector.execute(assertionError()); + + assertOneFailure(AssertionError.class, "assertion"); + } + + @Test + void oneCheckedException() { + this.collector.execute(checkedException()); + + assertOneFailure(Exception.class, "checked"); + } + + @Test + void oneUncheckedException() { + this.collector.execute(uncheckedException()); + + assertOneFailure(RuntimeException.class, "unchecked"); + } + + @Test + void oneThrowable() { + this.collector.execute(throwable()); + + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(this.collector::assertEmpty) + .withMessage("throwable") + .withCauseExactlyInstanceOf(Throwable.class) + .satisfies(error -> assertThat(error.getCause()).hasMessage("throwable")) + .satisfies(error -> assertThat(error).hasNoSuppressedExceptions()); + } + + private void assertOneFailure(Class expectedType, String failureMessage) { + assertThatExceptionOfType(expectedType) + .isThrownBy(this.collector::assertEmpty) + .satisfies(exception -> + assertThat(exception) + .isExactlyInstanceOf(expectedType) + .hasNoSuppressedExceptions() + .hasNoCause() + .hasMessage(failureMessage)); + } + + @Test + void multipleFailures() { + this.collector.execute(assertionError()); + this.collector.execute(checkedException()); + this.collector.execute(uncheckedException()); + this.collector.execute(error()); + this.collector.execute(throwable()); + + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(this.collector::assertEmpty) + .withMessage("Multiple Exceptions (5):" + EOL + // + "assertion" + EOL + // + "checked" + EOL + // + "unchecked" + EOL + // + "error" + EOL + // + "throwable"// + ) + .satisfies(exception -> + assertThat(exception.getSuppressed()).extracting(Object::getClass).map(Class::getSimpleName) + .containsExactly("AssertionError", "Exception", "RuntimeException", "Error", "Throwable")); + } + + private Executable throwable() { + return () -> { + throw new Throwable("throwable"); + }; + } + + private Executable error() { + return () -> { + throw new Error("error"); + }; + } + + private Executable assertionError() { + return () -> { + throw new AssertionError("assertion"); + }; + } + + private Executable checkedException() { + return () -> { + throw new Exception("checked"); + }; + } + + private Executable uncheckedException() { + return () -> { + throw new RuntimeException("unchecked"); + }; + } + +} From 4c153b80eef662af0d5ae3b316aa4f9f3d874e8a Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 23 Aug 2021 11:57:54 +0200 Subject: [PATCH 009/735] Make ExceptionCollector.Executable public See gh-27316 --- .../java/org/springframework/test/util/ExceptionCollector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-test/src/main/java/org/springframework/test/util/ExceptionCollector.java b/spring-test/src/main/java/org/springframework/test/util/ExceptionCollector.java index 1c5ffaa33236..f53190b7aff7 100644 --- a/spring-test/src/main/java/org/springframework/test/util/ExceptionCollector.java +++ b/spring-test/src/main/java/org/springframework/test/util/ExceptionCollector.java @@ -118,7 +118,7 @@ public void assertEmpty() throws Exception { * except that an {@code Executable} can throw any kind of exception. */ @FunctionalInterface - interface Executable { + public interface Executable { void execute() throws Throwable; From 35bec8102b014feac18c5b096b39c3592c27b76e Mon Sep 17 00:00:00 2001 From: Michal Rowicki Date: Sun, 9 May 2021 23:57:41 +0200 Subject: [PATCH 010/735] Introduce soft assertions for MockMvc It happens very often that MockMvc is used in heavyweight integration tests. It's no use to waste time to check if another condition has been fixed or not. Soft assertions help a lot by checking all conditions at once even if one of them fails. See gh-26917 Co-authored-by: Sach Nguyen --- .../test/web/servlet/ResultActions.java | 12 +++- .../test/web/servlet/ResultMatcher.java | 29 ++++++++ .../test/web/servlet/ResultMatcherTests.java | 66 +++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java index d63a5dd4884e..bbcb0a2e127d 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java @@ -42,7 +42,7 @@ public interface ResultActions { * .andExpect(jsonPath("$.person.name").value("Jason")); * * - *

Or alternatively provide all matchers as a vararg: + *

Either provide all matchers as a vararg: *

 	 * static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*, ResultMatcher.matchAll
 	 *
@@ -56,6 +56,16 @@ public interface ResultActions {
 	 *       flash().attribute("message", "success!"))
 	 *   );
 	 * 
+ * + *

Or provide all matchers to be evaluated no matter if one of them fail: + *

+	 * static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*, ResultMatcher.matchAllSoftly
+	 * mockMvc.perform(post("/form"))
+	 *   .andExpect(matchAllSoftly(
+	 *       status().isOk(),
+	 *       redirectedUrl("/person/1")
+	 *   );
+	 * 
*/ ResultActions andExpect(ResultMatcher matcher) throws Exception; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java index 1b6b409806d4..6c4d054d2359 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java @@ -16,6 +16,9 @@ package org.springframework.test.web.servlet; +import java.util.ArrayList; +import java.util.List; + /** * A {@code ResultMatcher} matches the result of an executed request against * some expectation. @@ -70,4 +73,30 @@ static ResultMatcher matchAll(ResultMatcher... matchers) { }; } + /** + * Static method for matching with an array of result matchers whose assertion failures are caught and stored. + * Only when all of them would be called a {@link AssertionError} be thrown containing the error messages of those + * previously caught assertion failures. + * @param matchers the matchers + * @author Michał Rowicki + * @since 5.2 + */ + static ResultMatcher matchAllSoftly(ResultMatcher... matchers) { + return result -> { + List failedMessages = new ArrayList<>(); + for (int i = 0; i < matchers.length; i++) { + ResultMatcher matcher = matchers[i]; + try { + matcher.match(result); + } + catch (AssertionError assertionException) { + failedMessages.add("[" + i + "] " + assertionException.getMessage()); + } + } + if (!failedMessages.isEmpty()) { + throw new AssertionError(String.join("\n", failedMessages)); + } + }; + } + } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java new file mode 100644 index 000000000000..40cbb56063f9 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java @@ -0,0 +1,66 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.web.servlet; + +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; + +class ResultMatcherTests { + + @Test + void whenProvidedMatcherPassesThenSoftAssertionsAlsoPasses() { + ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(this::doNothing); + StubMvcResult stubMvcResult = new StubMvcResult(null, null, null, null, null, null, null); + + assertThatNoException().isThrownBy(() -> resultMatcher.match(stubMvcResult)); + } + + @Test + void whenOneOfMatcherFailsThenSoftAssertionFailsWithTheVerySameMessage() { + String failMessage = "fail message"; + StubMvcResult stubMvcResult = new StubMvcResult(null, null, null, null, null, null, null); + ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(failMatcher(failMessage)); + + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(() -> resultMatcher.match(stubMvcResult)) + .withMessage("[0] " + failMessage); + } + + @Test + void whenMultipleMatchersFailsThenSoftAssertionFailsWithOneErrorWithMessageContainingAllErrorMessagesWithTheSameOrder() { + String firstFail = "firstFail"; + String secondFail = "secondFail"; + StubMvcResult stubMvcResult = new StubMvcResult(null, null, null, null, null, null, null); + ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(failMatcher(firstFail), failMatcher(secondFail)); + + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(() -> resultMatcher.match(stubMvcResult)) + .withMessage("[0] " + firstFail + "\n[1] " + secondFail); + } + + @NotNull + private ResultMatcher failMatcher(String failMessage) { + return result -> { + throw new AssertionError(failMessage); + }; + } + + void doNothing(MvcResult mvcResult) {} +} From 5f47d3be227e115c57b03e73f5df97993c44fdd8 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 22 Aug 2021 18:32:05 +0200 Subject: [PATCH 011/735] Polish soft assertions for MockMvc See gh-26917 --- .../test/web/servlet/ResultActions.java | 19 ++++---- .../test/web/servlet/ResultMatcher.java | 32 ++++++------- .../test/web/servlet/ResultMatcherTests.java | 45 ++++++++++++------- 3 files changed, 55 insertions(+), 41 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java index bbcb0a2e127d..8259a19508b7 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,9 +32,11 @@ public interface ResultActions { /** * Perform an expectation. * - *

Example

+ *

Examples

+ * + *

You can invoke {@code andExpect()} multiple times. *

-	 * static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*
+	 * // static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*
 	 *
 	 * mockMvc.perform(get("/person/1"))
 	 *   .andExpect(status().isOk())
@@ -42,9 +44,9 @@ public interface ResultActions {
 	 *   .andExpect(jsonPath("$.person.name").value("Jason"));
 	 * 
* - *

Either provide all matchers as a vararg: + *

You can provide all matchers as a var-arg list with {@code matchAll()}. *

-	 * static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*, ResultMatcher.matchAll
+	 * // static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*, ResultMatcher.matchAll
 	 *
 	 * mockMvc.perform(post("/form"))
 	 *   .andExpect(matchAll(
@@ -57,13 +59,14 @@ public interface ResultActions {
 	 *   );
 	 * 
* - *

Or provide all matchers to be evaluated no matter if one of them fail: + *

Alternatively, you can provide all matchers to be evaluated using + * soft assertions with {@code matchAllSoftly()}. *

-	 * static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*, ResultMatcher.matchAllSoftly
+	 * // static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*, ResultMatcher.matchAllSoftly
 	 * mockMvc.perform(post("/form"))
 	 *   .andExpect(matchAllSoftly(
 	 *       status().isOk(),
-	 *       redirectedUrl("/person/1")
+	 *       redirectedUrl("/person/1"))
 	 *   );
 	 * 
*/ diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java index 6c4d054d2359..13624102988f 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,6 @@ package org.springframework.test.web.servlet; -import java.util.ArrayList; -import java.util.List; - /** * A {@code ResultMatcher} matches the result of an executed request against * some expectation. @@ -47,6 +44,7 @@ * * @author Rossen Stoyanchev * @author Sam Brannen + * @author Michał Rowicki * @since 3.2 */ @FunctionalInterface @@ -74,27 +72,29 @@ static ResultMatcher matchAll(ResultMatcher... matchers) { } /** - * Static method for matching with an array of result matchers whose assertion failures are caught and stored. - * Only when all of them would be called a {@link AssertionError} be thrown containing the error messages of those - * previously caught assertion failures. + * Static method for matching with an array of result matchers whose assertion + * failures are caught and stored. Once all matchers have been called, if any + * failures occurred, an {@link AssertionError} will be thrown containing the + * error messages of all assertion failures. * @param matchers the matchers - * @author Michał Rowicki - * @since 5.2 + * @since 5.3.10 */ static ResultMatcher matchAllSoftly(ResultMatcher... matchers) { return result -> { - List failedMessages = new ArrayList<>(); - for (int i = 0; i < matchers.length; i++) { - ResultMatcher matcher = matchers[i]; + String message = ""; + for (ResultMatcher matcher : matchers) { try { matcher.match(result); } - catch (AssertionError assertionException) { - failedMessages.add("[" + i + "] " + assertionException.getMessage()); + catch (Error | Exception ex) { + if (!message.isEmpty()) { + message += System.lineSeparator(); + } + message += ex.getMessage(); } } - if (!failedMessages.isEmpty()) { - throw new AssertionError(String.join("\n", failedMessages)); + if (!message.isEmpty()) { + throw new AssertionError(message); } }; } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java index 40cbb56063f9..17ff0588269f 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java @@ -16,51 +16,62 @@ package org.springframework.test.web.servlet; -import org.jetbrains.annotations.NotNull; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatNoException; +/** + * Unit tests for {@link ResultMatcher}. + * + * @author Michał Rowicki + * @author Sam Brannen + * @since 5.3.10 + */ class ResultMatcherTests { + private final StubMvcResult stubMvcResult = new StubMvcResult(null, null, null, null, null, null, null); + + @Test - void whenProvidedMatcherPassesThenSoftAssertionsAlsoPasses() { + void softAssertionsWithNoFailures() { ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(this::doNothing); - StubMvcResult stubMvcResult = new StubMvcResult(null, null, null, null, null, null, null); assertThatNoException().isThrownBy(() -> resultMatcher.match(stubMvcResult)); } @Test - void whenOneOfMatcherFailsThenSoftAssertionFailsWithTheVerySameMessage() { - String failMessage = "fail message"; - StubMvcResult stubMvcResult = new StubMvcResult(null, null, null, null, null, null, null); - ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(failMatcher(failMessage)); + void softAssertionsWithOneFailure() { + String failureMessage = "failure message"; + ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(failingMatcher(failureMessage)); assertThatExceptionOfType(AssertionError.class) .isThrownBy(() -> resultMatcher.match(stubMvcResult)) - .withMessage("[0] " + failMessage); + .withMessage(failureMessage); } @Test - void whenMultipleMatchersFailsThenSoftAssertionFailsWithOneErrorWithMessageContainingAllErrorMessagesWithTheSameOrder() { - String firstFail = "firstFail"; - String secondFail = "secondFail"; - StubMvcResult stubMvcResult = new StubMvcResult(null, null, null, null, null, null, null); - ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(failMatcher(firstFail), failMatcher(secondFail)); + void softAssertionsWithTwoFailures() { + String firstFailure = "firstFailure"; + String secondFailure = "secondFailure"; + ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(failingMatcher(firstFailure), exceptionalMatcher(secondFailure)); assertThatExceptionOfType(AssertionError.class) .isThrownBy(() -> resultMatcher.match(stubMvcResult)) - .withMessage("[0] " + firstFail + "\n[1] " + secondFail); + .withMessage(firstFailure + System.lineSeparator() + secondFailure); } - @NotNull - private ResultMatcher failMatcher(String failMessage) { + private ResultMatcher failingMatcher(String failureMessage) { + return result -> Assertions.fail(failureMessage); + } + + private ResultMatcher exceptionalMatcher(String failureMessage) { return result -> { - throw new AssertionError(failMessage); + throw new RuntimeException(failureMessage); }; } void doNothing(MvcResult mvcResult) {} + } From cd078eaad83e2c6cb441719086b460e665c20f35 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 22 Aug 2021 19:03:32 +0200 Subject: [PATCH 012/735] Use ExceptionCollector for soft assertions in MockMvc See gh-26917 --- .../test/web/servlet/ResultMatcher.java | 18 ++---- .../test/web/servlet/ResultMatcherTests.java | 62 +++++++++++++++---- 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java index 13624102988f..ac40b9d71619 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java @@ -16,6 +16,8 @@ package org.springframework.test.web.servlet; +import org.springframework.test.util.ExceptionCollector; + /** * A {@code ResultMatcher} matches the result of an executed request against * some expectation. @@ -81,21 +83,11 @@ static ResultMatcher matchAll(ResultMatcher... matchers) { */ static ResultMatcher matchAllSoftly(ResultMatcher... matchers) { return result -> { - String message = ""; + ExceptionCollector exceptionCollector = new ExceptionCollector(); for (ResultMatcher matcher : matchers) { - try { - matcher.match(result); - } - catch (Error | Exception ex) { - if (!message.isEmpty()) { - message += System.lineSeparator(); - } - message += ex.getMessage(); - } - } - if (!message.isEmpty()) { - throw new AssertionError(message); + exceptionCollector.execute(() -> matcher.match(result)); } + exceptionCollector.assertEmpty(); }; } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java index 17ff0588269f..dd7cd3527cd5 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java @@ -16,9 +16,9 @@ package org.springframework.test.web.servlet; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatNoException; @@ -31,6 +31,8 @@ */ class ResultMatcherTests { + private static final String EOL = "\n"; + private final StubMvcResult stubMvcResult = new StubMvcResult(null, null, null, null, null, null, null); @@ -42,36 +44,74 @@ void softAssertionsWithNoFailures() { } @Test - void softAssertionsWithOneFailure() { - String failureMessage = "failure message"; - ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(failingMatcher(failureMessage)); + void softAssertionsWithOneAssertionError() { + String failureMessage = "error"; + ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(assertionErrorMatcher(failureMessage)); assertThatExceptionOfType(AssertionError.class) .isThrownBy(() -> resultMatcher.match(stubMvcResult)) - .withMessage(failureMessage); + .withMessage(failureMessage) + .withNoCause() + .satisfies(error -> assertThat(error).hasNoSuppressedExceptions()); + } + + @Test + void softAssertionsWithOneRuntimeException() { + String failureMessage = "exception"; + ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(uncheckedExceptionMatcher(failureMessage)); + + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> resultMatcher.match(stubMvcResult)) + .withMessage(failureMessage) + .withNoCause() + .satisfies(error -> assertThat(error).hasNoSuppressedExceptions()); + } + + @Test + void softAssertionsWithOneCheckedException() { + String failureMessage = "exception"; + ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(checkedExceptionMatcher(failureMessage)); + + assertThatExceptionOfType(Exception.class) + .isThrownBy(() -> resultMatcher.match(stubMvcResult)) + .withMessage(failureMessage) + .withNoCause() + .satisfies(exception -> assertThat(exception).hasNoSuppressedExceptions()); } @Test void softAssertionsWithTwoFailures() { String firstFailure = "firstFailure"; String secondFailure = "secondFailure"; - ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(failingMatcher(firstFailure), exceptionalMatcher(secondFailure)); + String thirdFailure = "thirdFailure"; + ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(assertionErrorMatcher(firstFailure), + checkedExceptionMatcher(secondFailure), uncheckedExceptionMatcher(thirdFailure)); assertThatExceptionOfType(AssertionError.class) .isThrownBy(() -> resultMatcher.match(stubMvcResult)) - .withMessage(firstFailure + System.lineSeparator() + secondFailure); + .withMessage("Multiple Exceptions (3):" + EOL + firstFailure + EOL + secondFailure + EOL + thirdFailure) + .satisfies(error -> assertThat(error.getSuppressed()).hasSize(3)); } - private ResultMatcher failingMatcher(String failureMessage) { - return result -> Assertions.fail(failureMessage); + private ResultMatcher assertionErrorMatcher(String failureMessage) { + return result -> { + throw new AssertionError(failureMessage); + }; } - private ResultMatcher exceptionalMatcher(String failureMessage) { + private ResultMatcher uncheckedExceptionMatcher(String failureMessage) { return result -> { throw new RuntimeException(failureMessage); }; } - void doNothing(MvcResult mvcResult) {} + private ResultMatcher checkedExceptionMatcher(String failureMessage) { + return result -> { + throw new Exception(failureMessage); + }; + } + + void doNothing(MvcResult mvcResult) { + } } From dd9b99e13d6b30462fb168799e6bbca1456123da Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 23 Aug 2021 13:05:50 +0200 Subject: [PATCH 013/735] Introduce ResultActions.andExpectAll() for soft assertions in MockMvc Closes gh-26917 --- .../test/web/servlet/ResultActions.java | 65 ++++++---- .../test/web/servlet/ResultMatcher.java | 29 +---- .../test/web/servlet/ResultMatcherTests.java | 117 ------------------ .../samples/context/JavaConfigTests.java | 40 +++++- src/docs/asciidoc/testing.adoc | 20 ++- 5 files changed, 102 insertions(+), 169 deletions(-) delete mode 100644 spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java index 8259a19508b7..f4fd6da14b58 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java @@ -16,6 +16,8 @@ package org.springframework.test.web.servlet; +import org.springframework.test.util.ExceptionCollector; + /** * Allows applying actions, such as expectations, on the result of an executed * request. @@ -25,6 +27,8 @@ * {@link org.springframework.test.web.servlet.result.MockMvcResultHandlers}. * * @author Rossen Stoyanchev + * @author Sam Brannen + * @author Michał Rowicki * @since 3.2 */ public interface ResultActions { @@ -32,9 +36,9 @@ public interface ResultActions { /** * Perform an expectation. * - *

Examples

- * - *

You can invoke {@code andExpect()} multiple times. + *

Example

+ *

You can invoke {@code andExpect()} multiple times as in the following + * example. *

 	 * // static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*
 	 *
@@ -44,33 +48,48 @@ public interface ResultActions {
 	 *   .andExpect(jsonPath("$.person.name").value("Jason"));
 	 * 
* - *

You can provide all matchers as a var-arg list with {@code matchAll()}. + * @see #andExpectAll(ResultMatcher...) + */ + ResultActions andExpect(ResultMatcher matcher) throws Exception; + + /** + * Perform multiple expectations, with the guarantee that all expectations + * will be asserted even if one or more expectations fail with an exception. + *

If a single {@link Error} or {@link Exception} is thrown, it will + * be rethrown. + *

If multiple exceptions are thrown, this method will throw an + * {@link AssertionError} whose error message is a summary of all of the + * exceptions. In addition, each exception will be added as a + * {@linkplain Throwable#addSuppressed(Throwable) suppressed exception} to + * the {@code AssertionError}. + *

This feature is similar to the {@code SoftAssertions} support in AssertJ + * and the {@code assertAll()} support in JUnit Jupiter. + * + *

Example

+ *

Instead of invoking {@code andExpect()} multiple times, you can invoke + * {@code andExpectAll()} as in the following example. *

-	 * // static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*, ResultMatcher.matchAll
+	 * // static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*
 	 *
-	 * mockMvc.perform(post("/form"))
-	 *   .andExpect(matchAll(
+	 * mockMvc.perform(get("/person/1"))
+	 *   .andExpectAll(
 	 *       status().isOk(),
-	 *       redirectedUrl("/person/1"),
-	 *   	 model().size(1),
-	 *       model().attributeExists("person"),
-	 *       flash().attributeCount(1),
-	 *       flash().attribute("message", "success!"))
+	 *       content().contentType(MediaType.APPLICATION_JSON),
+	 *       jsonPath("$.person.name").value("Jason")
 	 *   );
 	 * 
* - *

Alternatively, you can provide all matchers to be evaluated using - * soft assertions with {@code matchAllSoftly()}. - *

-	 * // static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*, ResultMatcher.matchAllSoftly
-	 * mockMvc.perform(post("/form"))
-	 *   .andExpect(matchAllSoftly(
-	 *       status().isOk(),
-	 *       redirectedUrl("/person/1"))
-	 *   );
-	 * 
+ * @since 5.3.10 + * @see #andExpect(ResultMatcher) */ - ResultActions andExpect(ResultMatcher matcher) throws Exception; + default ResultActions andExpectAll(ResultMatcher... matchers) throws Exception { + ExceptionCollector exceptionCollector = new ExceptionCollector(); + for (ResultMatcher matcher : matchers) { + exceptionCollector.execute(() -> this.andExpect(matcher)); + } + exceptionCollector.assertEmpty(); + return this; + } /** * Perform a general action. diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java index ac40b9d71619..44aae68e150c 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java @@ -16,8 +16,6 @@ package org.springframework.test.web.servlet; -import org.springframework.test.util.ExceptionCollector; - /** * A {@code ResultMatcher} matches the result of an executed request against * some expectation. @@ -40,13 +38,13 @@ * MockMvc mockMvc = webAppContextSetup(wac).build(); * * mockMvc.perform(get("/form")) - * .andExpect(status().isOk()) - * .andExpect(content().mimeType(MediaType.APPLICATION_JSON)); + * .andExpectAll( + * status().isOk(), + * content().mimeType(MediaType.APPLICATION_JSON)); * * * @author Rossen Stoyanchev * @author Sam Brannen - * @author Michał Rowicki * @since 3.2 */ @FunctionalInterface @@ -64,7 +62,10 @@ public interface ResultMatcher { * Static method for matching with an array of result matchers. * @param matchers the matchers * @since 5.1 + * @deprecated as of Spring Framework 5.3.10, in favor of + * {@link ResultActions#andExpectAll(ResultMatcher...)} */ + @Deprecated static ResultMatcher matchAll(ResultMatcher... matchers) { return result -> { for (ResultMatcher matcher : matchers) { @@ -73,22 +74,4 @@ static ResultMatcher matchAll(ResultMatcher... matchers) { }; } - /** - * Static method for matching with an array of result matchers whose assertion - * failures are caught and stored. Once all matchers have been called, if any - * failures occurred, an {@link AssertionError} will be thrown containing the - * error messages of all assertion failures. - * @param matchers the matchers - * @since 5.3.10 - */ - static ResultMatcher matchAllSoftly(ResultMatcher... matchers) { - return result -> { - ExceptionCollector exceptionCollector = new ExceptionCollector(); - for (ResultMatcher matcher : matchers) { - exceptionCollector.execute(() -> matcher.match(result)); - } - exceptionCollector.assertEmpty(); - }; - } - } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java deleted file mode 100644 index dd7cd3527cd5..000000000000 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.test.web.servlet; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatNoException; - -/** - * Unit tests for {@link ResultMatcher}. - * - * @author Michał Rowicki - * @author Sam Brannen - * @since 5.3.10 - */ -class ResultMatcherTests { - - private static final String EOL = "\n"; - - private final StubMvcResult stubMvcResult = new StubMvcResult(null, null, null, null, null, null, null); - - - @Test - void softAssertionsWithNoFailures() { - ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(this::doNothing); - - assertThatNoException().isThrownBy(() -> resultMatcher.match(stubMvcResult)); - } - - @Test - void softAssertionsWithOneAssertionError() { - String failureMessage = "error"; - ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(assertionErrorMatcher(failureMessage)); - - assertThatExceptionOfType(AssertionError.class) - .isThrownBy(() -> resultMatcher.match(stubMvcResult)) - .withMessage(failureMessage) - .withNoCause() - .satisfies(error -> assertThat(error).hasNoSuppressedExceptions()); - } - - @Test - void softAssertionsWithOneRuntimeException() { - String failureMessage = "exception"; - ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(uncheckedExceptionMatcher(failureMessage)); - - assertThatExceptionOfType(RuntimeException.class) - .isThrownBy(() -> resultMatcher.match(stubMvcResult)) - .withMessage(failureMessage) - .withNoCause() - .satisfies(error -> assertThat(error).hasNoSuppressedExceptions()); - } - - @Test - void softAssertionsWithOneCheckedException() { - String failureMessage = "exception"; - ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(checkedExceptionMatcher(failureMessage)); - - assertThatExceptionOfType(Exception.class) - .isThrownBy(() -> resultMatcher.match(stubMvcResult)) - .withMessage(failureMessage) - .withNoCause() - .satisfies(exception -> assertThat(exception).hasNoSuppressedExceptions()); - } - - @Test - void softAssertionsWithTwoFailures() { - String firstFailure = "firstFailure"; - String secondFailure = "secondFailure"; - String thirdFailure = "thirdFailure"; - ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(assertionErrorMatcher(firstFailure), - checkedExceptionMatcher(secondFailure), uncheckedExceptionMatcher(thirdFailure)); - - assertThatExceptionOfType(AssertionError.class) - .isThrownBy(() -> resultMatcher.match(stubMvcResult)) - .withMessage("Multiple Exceptions (3):" + EOL + firstFailure + EOL + secondFailure + EOL + thirdFailure) - .satisfies(error -> assertThat(error.getSuppressed()).hasSize(3)); - } - - private ResultMatcher assertionErrorMatcher(String failureMessage) { - return result -> { - throw new AssertionError(failureMessage); - }; - } - - private ResultMatcher uncheckedExceptionMatcher(String failureMessage) { - return result -> { - throw new RuntimeException(failureMessage); - }; - } - - private ResultMatcher checkedExceptionMatcher(String failureMessage) { - return result -> { - throw new Exception(failureMessage); - }; - } - - void doNothing(MvcResult mvcResult) { - } - -} diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java index e96c0c1f6cbe..9cde95fe2ce3 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,11 +47,13 @@ import org.springframework.web.servlet.view.tiles3.TilesConfigurer; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.BDDMockito.given; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -61,6 +63,7 @@ * @author Rossen Stoyanchev * @author Sam Brannen * @author Sebastien Deleuze + * @author Michał Rowicki */ @ExtendWith(SpringExtension.class) @WebAppConfiguration("classpath:META-INF/web-resources") @@ -93,9 +96,38 @@ public void setup() { public void person() throws Exception { this.mockMvc.perform(get("/person/5").accept(MediaType.APPLICATION_JSON)) .andDo(print()) - .andExpect(status().isOk()) - .andExpect(request().asyncNotStarted()) - .andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); + .andExpectAll( + status().isOk(), + request().asyncNotStarted(), + content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"), + jsonPath("$.name").value("Joe") + ); + } + + @Test + public void andExpectAllWithOneFailure() { + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(() -> this.mockMvc.perform(get("/person/5").accept(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isBadGateway(), + request().asyncNotStarted(), + jsonPath("$.name").value("Joe"))) + .withMessage("Status expected:<502> but was:<200>") + .satisfies(error -> assertThat(error).hasNoSuppressedExceptions()); + } + + @Test + public void andExpectAllWithMultipleFailures() { + assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> + this.mockMvc.perform(get("/person/5").accept(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isBadGateway(), + request().asyncNotStarted(), + jsonPath("$.name").value("Joe"), + jsonPath("$.name").value("Jane") + )) + .withMessage("Multiple Exceptions (2):\nStatus expected:<502> but was:<200>\nJSON path \"$.name\" expected: but was:") + .satisfies(error -> assertThat(error.getSuppressed()).hasSize(2)); } @Test diff --git a/src/docs/asciidoc/testing.adoc b/src/docs/asciidoc/testing.adoc index 90c463fbe6fa..bc3af10d0891 100644 --- a/src/docs/asciidoc/testing.adoc +++ b/src/docs/asciidoc/testing.adoc @@ -7219,8 +7219,9 @@ they must be specified on every request. [[spring-mvc-test-server-defining-expectations]] ===== Defining Expectations -You can define expectations by appending one or more `.andExpect(..)` calls after -performing a request, as the following example shows: +You can define expectations by appending one or more `andExpect(..)` calls after +performing a request, as the following example shows. As soon as one expectation fails, +no other expectations will be asserted. [source,java,indent=0,subs="verbatim,quotes",role="primary"] .Java @@ -7240,6 +7241,21 @@ performing a request, as the following example shows: } ---- +You can define multiple expectations by appending `andExpectAll(..)` after performing a +request, as the following example shows. In contrast to `andExpect(..)`, +`andExpectAll(..)` guarantees that all supplied expectations will be asserted and that +all failures will be tracked and reported. + +[source,java,indent=0,subs="verbatim,quotes",role="primary"] +.Java +---- + // static import of MockMvcRequestBuilders.* and MockMvcResultMatchers.* + + mockMvc.perform(get("/accounts/1")).andExpectAll( + status().isOk(), + content().contentType("application/json;charset=UTF-8")); +---- + `MockMvcResultMatchers.*` provides a number of expectations, some of which are further nested with more detailed expectations. From 25dca404138e85e8864e4bfa4b37c88f236a559e Mon Sep 17 00:00:00 2001 From: Michal Rowicki Date: Sun, 23 May 2021 13:21:31 +0200 Subject: [PATCH 014/735] Introduce soft assertions for WebTestClient It happens very often that WebTestClient is used in heavyweight integration tests, and it's a hindrance to developer productivity to fix one failed assertion after another. Soft assertions help a lot by checking all conditions at once even if one of them fails. This commit introduces a new expectAllSoftly(..) method in WebTestClient to address this issue. client.get().uri("/hello") .exchange() .expectAllSoftly( spec -> spec.expectStatus().isOk(), spec -> spec.expectBody(String.class).isEqualTo("Hello, World") ); Closes gh-26969 --- .../reactive/server/DefaultWebTestClient.java | 19 +++++ .../web/reactive/server/WebTestClient.java | 6 ++ .../server/samples/SoftAssertionTests.java | 75 +++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/SoftAssertionTests.java diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java index 8d0ec7de0c5d..06dab2ea38a6 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java @@ -21,6 +21,7 @@ import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.ZonedDateTime; +import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; @@ -507,6 +508,24 @@ public FluxExchangeResult returnResult(ParameterizedTypeReference elem Flux body = this.response.bodyToFlux(elementTypeRef); return new FluxExchangeResult<>(this.exchangeResult, body); } + + @Override + public ResponseSpec expectAllSoftly(ResponseSpecMatcher... asserts) { + List failedMessages = new ArrayList<>(); + for (int i = 0; i < asserts.length; i++) { + ResponseSpecMatcher anAssert = asserts[i]; + try { + anAssert.accept(this); + } + catch (AssertionError assertionException) { + failedMessages.add("[" + i + "] " + assertionException.getMessage()); + } + } + if (!failedMessages.isEmpty()) { + throw new AssertionError(String.join("\n", failedMessages)); + } + return this; + } } diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java index 6d2fcefebd70..8f0159aa70ad 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java @@ -845,6 +845,11 @@ interface ResponseSpec { * about a target type with generics. */ FluxExchangeResult returnResult(ParameterizedTypeReference elementTypeRef); + + /** + * Array of assertions to test together a.k.a. soft assertions. + */ + ResponseSpec expectAllSoftly(ResponseSpecMatcher... asserts); } @@ -1006,4 +1011,5 @@ default XpathAssertions xpath(String expression, Object... args) { EntityExchangeResult returnResult(); } + interface ResponseSpecMatcher extends Consumer {} } diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/SoftAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/SoftAssertionTests.java new file mode 100644 index 000000000000..17d5cc1a3d34 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/SoftAssertionTests.java @@ -0,0 +1,75 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.test.web.reactive.server.samples; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +/** + * Samples of tests using {@link WebTestClient} with soft assertions. + * + * @author Michał Rowicki + * @since 5.3 + */ +public class SoftAssertionTests { + + private WebTestClient client; + + + @BeforeEach + public void setUp() throws Exception { + this.client = WebTestClient.bindToController(new TestController()).build(); + } + + + @Test + public void test() throws Exception { + this.client.get().uri("/test") + .exchange() + .expectAllSoftly( + exchange -> exchange.expectStatus().isOk(), + exchange -> exchange.expectBody(String.class).isEqualTo("It works!") + ); + } + + @Test + public void testAllFails() throws Exception { + assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> + this.client.get().uri("/test") + .exchange() + .expectAllSoftly( + exchange -> exchange.expectStatus().isBadRequest(), + exchange -> exchange.expectBody(String.class).isEqualTo("It won't work :(") + ) + ).withMessage("[0] Status expected:<400 BAD_REQUEST> but was:<200 OK>\n[1] Response body expected: but was:"); + } + + + @RestController + static class TestController { + + @GetMapping("/test") + public String handle() { + return "It works!"; + } + } +} From 3c2dfebf4ec5e9d791c1f3c9fa0ad35a5a9fcd6b Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 23 Aug 2021 18:59:41 +0200 Subject: [PATCH 015/735] Polish soft assertion support for WebTestClient See gh-26969 --- .../reactive/server/DefaultWebTestClient.java | 34 ++++++++----- .../web/reactive/server/WebTestClient.java | 40 +++++++++++++-- .../server/samples/SoftAssertionTests.java | 51 +++++++++---------- .../testing/testing-webtestclient.adoc | 33 +++++++++--- 4 files changed, 106 insertions(+), 52 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java index 06dab2ea38a6..8628ef262261 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java @@ -21,7 +21,6 @@ import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.ZonedDateTime; -import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; @@ -45,6 +44,7 @@ import org.springframework.http.client.reactive.ClientHttpRequest; import org.springframework.lang.Nullable; import org.springframework.test.util.AssertionErrors; +import org.springframework.test.util.ExceptionCollector; import org.springframework.test.util.JsonExpectationsHelper; import org.springframework.test.util.XmlExpectationsHelper; import org.springframework.util.Assert; @@ -64,6 +64,8 @@ * Default implementation of {@link WebTestClient}. * * @author Rossen Stoyanchev + * @author Sam Brannen + * @author Michał Rowicki * @since 5.0 */ class DefaultWebTestClient implements WebTestClient { @@ -510,19 +512,25 @@ public FluxExchangeResult returnResult(ParameterizedTypeReference elem } @Override - public ResponseSpec expectAllSoftly(ResponseSpecMatcher... asserts) { - List failedMessages = new ArrayList<>(); - for (int i = 0; i < asserts.length; i++) { - ResponseSpecMatcher anAssert = asserts[i]; - try { - anAssert.accept(this); - } - catch (AssertionError assertionException) { - failedMessages.add("[" + i + "] " + assertionException.getMessage()); - } + public ResponseSpec expectAll(ResponseSpecConsumer... consumers) { + ExceptionCollector exceptionCollector = new ExceptionCollector(); + for (ResponseSpecConsumer consumer : consumers) { + exceptionCollector.execute(() -> consumer.accept(this)); + } + try { + exceptionCollector.assertEmpty(); + } + catch (RuntimeException ex) { + throw ex; } - if (!failedMessages.isEmpty()) { - throw new AssertionError(String.join("\n", failedMessages)); + catch (Exception ex) { + // In theory, a ResponseSpecConsumer should never throw an Exception + // that is not a RuntimeException, but since ExceptionCollector may + // throw a checked Exception, we handle this to appease the compiler + // and in case someone uses a "sneaky throws" technique. + AssertionError assertionError = new AssertionError(ex.getMessage()); + assertionError.initCause(ex); + throw assertionError; } return this; } diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java index 8f0159aa70ad..84adf85013c5 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java @@ -86,6 +86,8 @@ * * @author Rossen Stoyanchev * @author Brian Clozel + * @author Sam Brannen + * @author Michał Rowicki * @since 5.0 * @see StatusAssertions * @see HeaderAssertions @@ -781,6 +783,34 @@ interface RequestBodyUriSpec extends RequestBodySpec, RequestHeadersUriSpecIf a single {@link Error} or {@link RuntimeException} is thrown, + * it will be rethrown. + *

If multiple exceptions are thrown, this method will throw an + * {@link AssertionError} whose error message is a summary of all of the + * exceptions. In addition, each exception will be added as a + * {@linkplain Throwable#addSuppressed(Throwable) suppressed exception} to + * the {@code AssertionError}. + *

This feature is similar to the {@code SoftAssertions} support in + * AssertJ and the {@code assertAll()} support in JUnit Jupiter. + * + *

Example

+ *
+		 * webTestClient.get().uri("/hello").exchange()
+		 *     .expectAll(
+		 *         responseSpec -> responseSpec.expectStatus().isOk(),
+		 *         responseSpec -> responseSpec.expectBody(String.class).isEqualTo("Hello, World!")
+		 *     );
+		 * 
+ * @param consumers the list of {@code ResponseSpec} consumers + * @since 5.3.10 + */ + ResponseSpec expectAll(ResponseSpecConsumer... consumers); + /** * Assertions on the response status. */ @@ -847,9 +877,14 @@ interface ResponseSpec { FluxExchangeResult returnResult(ParameterizedTypeReference elementTypeRef); /** - * Array of assertions to test together a.k.a. soft assertions. + * {@link Consumer} of a {@link ResponseSpec}. + * @since 5.3.10 + * @see ResponseSpec#expectAll(ResponseSpecConsumer...) */ - ResponseSpec expectAllSoftly(ResponseSpecMatcher... asserts); + @FunctionalInterface + interface ResponseSpecConsumer extends Consumer { + } + } @@ -1011,5 +1046,4 @@ default XpathAssertions xpath(String expression, Object... args) { EntityExchangeResult returnResult(); } - interface ResponseSpecMatcher extends Consumer {} } diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/SoftAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/SoftAssertionTests.java index 17d5cc1a3d34..a4d4bb8c72fe 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/SoftAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/SoftAssertionTests.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.reactive.server.samples; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.test.web.reactive.server.WebTestClient; @@ -25,42 +25,36 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** - * Samples of tests using {@link WebTestClient} with soft assertions. + * Integration tests for {@link WebTestClient} with soft assertions. * * @author Michał Rowicki - * @since 5.3 + * @author Sam Brannen + * @since 5.3.10 */ -public class SoftAssertionTests { - - private WebTestClient client; +class SoftAssertionTests { - - @BeforeEach - public void setUp() throws Exception { - this.client = WebTestClient.bindToController(new TestController()).build(); - } + private final WebTestClient webTestClient = WebTestClient.bindToController(new TestController()).build(); @Test - public void test() throws Exception { - this.client.get().uri("/test") - .exchange() - .expectAllSoftly( - exchange -> exchange.expectStatus().isOk(), - exchange -> exchange.expectBody(String.class).isEqualTo("It works!") - ); + void expectAll() { + this.webTestClient.get().uri("/test").exchange() + .expectAll( + responseSpec -> responseSpec.expectStatus().isOk(), + responseSpec -> responseSpec.expectBody(String.class).isEqualTo("hello") + ); } @Test - public void testAllFails() throws Exception { + void expectAllWithMultipleFailures() throws Exception { assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> - this.client.get().uri("/test") - .exchange() - .expectAllSoftly( - exchange -> exchange.expectStatus().isBadRequest(), - exchange -> exchange.expectBody(String.class).isEqualTo("It won't work :(") - ) - ).withMessage("[0] Status expected:<400 BAD_REQUEST> but was:<200 OK>\n[1] Response body expected: but was:"); + this.webTestClient.get().uri("/test").exchange() + .expectAll( + responseSpec -> responseSpec.expectStatus().isBadRequest(), + responseSpec -> responseSpec.expectStatus().isOk(), + responseSpec -> responseSpec.expectBody(String.class).isEqualTo("bogus") + ) + ).withMessage("Multiple Exceptions (2):\nStatus expected:<400 BAD_REQUEST> but was:<200 OK>\nResponse body expected: but was:"); } @@ -68,8 +62,9 @@ public void testAllFails() throws Exception { static class TestController { @GetMapping("/test") - public String handle() { - return "It works!"; + String handle() { + return "hello"; } } + } diff --git a/src/docs/asciidoc/testing/testing-webtestclient.adoc b/src/docs/asciidoc/testing/testing-webtestclient.adoc index 6c5dfb80da51..4335760e1048 100644 --- a/src/docs/asciidoc/testing/testing-webtestclient.adoc +++ b/src/docs/asciidoc/testing/testing-webtestclient.adoc @@ -262,19 +262,36 @@ To assert the response status and headers, use the following: .Java ---- client.get().uri("/persons/1") - .accept(MediaType.APPLICATION_JSON) - .exchange() - .expectStatus().isOk() - .expectHeader().contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus().isOk() + .expectHeader().contentType(MediaType.APPLICATION_JSON); ---- [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] .Kotlin ---- client.get().uri("/persons/1") - .accept(MediaType.APPLICATION_JSON) - .exchange() - .expectStatus().isOk() - .expectHeader().contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus().isOk() + .expectHeader().contentType(MediaType.APPLICATION_JSON) +---- + +If you would like for all expectations to be asserted even if one of them fails, you can +use `expectAll(..)` instead of multiple chained `expect*(..)` calls. This feature is +similar to the _soft assertions_ support in AssertJ and the `assertAll()` support in +JUnit Jupiter. + +[source,java,indent=0,subs="verbatim,quotes",role="primary"] +.Java +---- + client.get().uri("/persons/1") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectAll( + spec -> spec.expectStatus().isOk(), + spec -> spec.expectHeader().contentType(MediaType.APPLICATION_JSON) + ); ---- You can then choose to decode the response body through one of the following: From e99b43b91e2a02b1cf18261ee85dccae5e6494e7 Mon Sep 17 00:00:00 2001 From: Axzial Date: Sat, 21 Aug 2021 18:00:26 +0200 Subject: [PATCH 016/735] Support TimeUnit in the @Scheduled annotation This commit introduces a new `timeUnit` attribute in the @Scheduled annotation to allow the user to specify a time unit other than milliseconds. Closes gh-27309 --- .../scheduling/annotation/Scheduled.java | 36 ++- .../ScheduledAnnotationBeanPostProcessor.java | 15 +- ...duledAnnotationBeanPostProcessorTests.java | 216 +++++++++++++++++- 3 files changed, 249 insertions(+), 18 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java index 415c72381792..de7866073931 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java @@ -22,6 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.concurrent.TimeUnit; import org.springframework.scheduling.config.ScheduledTaskRegistrar; @@ -46,6 +47,7 @@ * @author Juergen Hoeller * @author Dave Syer * @author Chris Beams + * @author Victor Brown * @since 3.0 * @see EnableScheduling * @see ScheduledAnnotationBeanPostProcessor @@ -101,52 +103,64 @@ String zone() default ""; /** - * Execute the annotated method with a fixed period in milliseconds between the + * Execute the annotated method with a fixed period between the * end of the last invocation and the start of the next. - * @return the delay in milliseconds + * Using milliseconds by default with timeUnit(). + * @return the delay */ long fixedDelay() default -1; /** - * Execute the annotated method with a fixed period in milliseconds between the + * Execute the annotated method with a fixed period between the * end of the last invocation and the start of the next. - * @return the delay in milliseconds as a String value, e.g. a placeholder + * Using milliseconds by default with fixedDelayTimeUnit(). + * @return the delay as a String value, e.g. a placeholder * or a {@link java.time.Duration#parse java.time.Duration} compliant value * @since 3.2.2 */ String fixedDelayString() default ""; /** - * Execute the annotated method with a fixed period in milliseconds between + * Execute the annotated method with a fixed period between * invocations. - * @return the period in milliseconds + * Using milliseconds by default with timeUnit(). + * @return the period */ long fixedRate() default -1; /** - * Execute the annotated method with a fixed period in milliseconds between + * Execute the annotated method with a fixed period between * invocations. - * @return the period in milliseconds as a String value, e.g. a placeholder + * Using milliseconds by default with fixedRateTimeUnit(). + * @return the period as a String value, e.g. a placeholder * or a {@link java.time.Duration#parse java.time.Duration} compliant value * @since 3.2.2 */ String fixedRateString() default ""; /** - * Number of milliseconds to delay before the first execution of a + * Number to delay before the first execution of a * {@link #fixedRate} or {@link #fixedDelay} task. - * @return the initial delay in milliseconds + * Using milliseconds by default with timeUnit(). + * @return the initial * @since 3.2 */ long initialDelay() default -1; /** - * Number of milliseconds to delay before the first execution of a + * Number to delay before the first execution of a * {@link #fixedRate} or {@link #fixedDelay} task. + * Using milliseconds by default with initialDelayTimeUnit(). * @return the initial delay in milliseconds as a String value, e.g. a placeholder * or a {@link java.time.Duration#parse java.time.Duration} compliant value * @since 3.2.2 */ String initialDelayString() default ""; + /** + * Specify the {@link TimeUnit} to use for initialDelay, fixedRate and fixedDelay values. + * @return the {@link TimeUnit}, by default milliseconds will be used. + */ + TimeUnit timeUnit() default TimeUnit.MILLISECONDS; + } diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java index 14b73d6d7f7c..52fae5dbab98 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java @@ -30,6 +30,7 @@ import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -94,6 +95,7 @@ * @author Juergen Hoeller * @author Chris Beams * @author Elizabeth Chatman + * @author Victor Brown * @since 3.0 * @see Scheduled * @see EnableScheduling @@ -398,7 +400,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean) Set tasks = new LinkedHashSet<>(4); // Determine initial delay - long initialDelay = scheduled.initialDelay(); + long initialDelay = TimeUnit.MILLISECONDS.convert(scheduled.initialDelay(), scheduled.timeUnit()); String initialDelayString = scheduled.initialDelayString(); if (StringUtils.hasText(initialDelayString)) { Assert.isTrue(initialDelay < 0, "Specify 'initialDelay' or 'initialDelayString', not both"); @@ -407,7 +409,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean) } if (StringUtils.hasLength(initialDelayString)) { try { - initialDelay = parseDelayAsLong(initialDelayString); + initialDelay = TimeUnit.MILLISECONDS.convert(parseDelayAsLong(initialDelayString), scheduled.timeUnit()); } catch (RuntimeException ex) { throw new IllegalArgumentException( @@ -446,12 +448,13 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean) } // Check fixed delay - long fixedDelay = scheduled.fixedDelay(); + long fixedDelay = TimeUnit.MILLISECONDS.convert(scheduled.fixedDelay(), scheduled.timeUnit()); if (fixedDelay >= 0) { Assert.isTrue(!processedSchedule, errorMessage); processedSchedule = true; tasks.add(this.registrar.scheduleFixedDelayTask(new FixedDelayTask(runnable, fixedDelay, initialDelay))); } + String fixedDelayString = scheduled.fixedDelayString(); if (StringUtils.hasText(fixedDelayString)) { if (this.embeddedValueResolver != null) { @@ -461,7 +464,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean) Assert.isTrue(!processedSchedule, errorMessage); processedSchedule = true; try { - fixedDelay = parseDelayAsLong(fixedDelayString); + fixedDelay = TimeUnit.MILLISECONDS.convert(parseDelayAsLong(fixedDelayString), scheduled.timeUnit()); } catch (RuntimeException ex) { throw new IllegalArgumentException( @@ -472,7 +475,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean) } // Check fixed rate - long fixedRate = scheduled.fixedRate(); + long fixedRate = TimeUnit.MILLISECONDS.convert(scheduled.fixedRate(), scheduled.timeUnit()); if (fixedRate >= 0) { Assert.isTrue(!processedSchedule, errorMessage); processedSchedule = true; @@ -487,7 +490,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean) Assert.isTrue(!processedSchedule, errorMessage); processedSchedule = true; try { - fixedRate = parseDelayAsLong(fixedRateString); + fixedRate = TimeUnit.MILLISECONDS.convert(parseDelayAsLong(fixedRateString), scheduled.timeUnit()); } catch (RuntimeException ex) { throw new IllegalArgumentException( diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java index 842910070227..494bf075c6df 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ import java.util.Map; import java.util.Properties; import java.util.TimeZone; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -67,6 +68,7 @@ * @author Chris Beams * @author Sam Brannen * @author Stevo Slavić + * @author Victor Brown */ public class ScheduledAnnotationBeanPostProcessorTests { @@ -107,6 +109,62 @@ public void fixedDelayTask() { assertThat(task.getInterval()).isEqualTo(5000L); } + @Test + public void fixedDelayWithSecondsTimeUnitTask() { + BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); + BeanDefinition targetDefinition = new RootBeanDefinition(FixedDelayWithSecondsTimeUnitTestBean.class); + context.registerBeanDefinition("postProcessor", processorDefinition); + context.registerBeanDefinition("target", targetDefinition); + context.refresh(); + + ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class); + assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1); + + Object target = context.getBean("target"); + ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) + new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); + @SuppressWarnings("unchecked") + List fixedDelayTasks = (List) + new DirectFieldAccessor(registrar).getPropertyValue("fixedDelayTasks"); + assertThat(fixedDelayTasks.size()).isEqualTo(1); + IntervalTask task = fixedDelayTasks.get(0); + ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); + Object targetObject = runnable.getTarget(); + Method targetMethod = runnable.getMethod(); + assertThat(targetObject).isEqualTo(target); + assertThat(targetMethod.getName()).isEqualTo("fixedDelay"); + assertThat(task.getInitialDelay()).isEqualTo(0L); + assertThat(task.getInterval()).isEqualTo(5000L); + } + + @Test + public void fixedDelayWithMinutesTimeUnitTask() { + BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); + BeanDefinition targetDefinition = new RootBeanDefinition(FixedDelayWithMinutesTimeUnitTestBean.class); + context.registerBeanDefinition("postProcessor", processorDefinition); + context.registerBeanDefinition("target", targetDefinition); + context.refresh(); + + ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class); + assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1); + + Object target = context.getBean("target"); + ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) + new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); + @SuppressWarnings("unchecked") + List fixedDelayTasks = (List) + new DirectFieldAccessor(registrar).getPropertyValue("fixedDelayTasks"); + assertThat(fixedDelayTasks.size()).isEqualTo(1); + IntervalTask task = fixedDelayTasks.get(0); + ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); + Object targetObject = runnable.getTarget(); + Method targetMethod = runnable.getMethod(); + assertThat(targetObject).isEqualTo(target); + assertThat(targetMethod.getName()).isEqualTo("fixedDelay"); + assertThat(task.getInitialDelay()).isEqualTo(0L); + assertThat(task.getInterval()).isEqualTo(180000L); + } + @Test public void fixedRateTask() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); @@ -135,6 +193,62 @@ public void fixedRateTask() { assertThat(task.getInterval()).isEqualTo(3000L); } + @Test + public void fixedRateWithSecondsTimeUnitTask() { + BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); + BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithSecondsTimeUnitTestBean.class); + context.registerBeanDefinition("postProcessor", processorDefinition); + context.registerBeanDefinition("target", targetDefinition); + context.refresh(); + + ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class); + assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1); + + Object target = context.getBean("target"); + ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) + new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); + @SuppressWarnings("unchecked") + List fixedRateTasks = (List) + new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks"); + assertThat(fixedRateTasks.size()).isEqualTo(1); + IntervalTask task = fixedRateTasks.get(0); + ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); + Object targetObject = runnable.getTarget(); + Method targetMethod = runnable.getMethod(); + assertThat(targetObject).isEqualTo(target); + assertThat(targetMethod.getName()).isEqualTo("fixedRate"); + assertThat(task.getInitialDelay()).isEqualTo(0L); + assertThat(task.getInterval()).isEqualTo(5000L); + } + + @Test + public void fixedRateWithMinutesTimeUnitTask() { + BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); + BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithMinutesTimeUnitTestBean.class); + context.registerBeanDefinition("postProcessor", processorDefinition); + context.registerBeanDefinition("target", targetDefinition); + context.refresh(); + + ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class); + assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1); + + Object target = context.getBean("target"); + ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) + new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); + @SuppressWarnings("unchecked") + List fixedRateTasks = (List) + new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks"); + assertThat(fixedRateTasks.size()).isEqualTo(1); + IntervalTask task = fixedRateTasks.get(0); + ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); + Object targetObject = runnable.getTarget(); + Method targetMethod = runnable.getMethod(); + assertThat(targetObject).isEqualTo(target); + assertThat(targetMethod.getName()).isEqualTo("fixedRate"); + assertThat(task.getInitialDelay()).isEqualTo(0L); + assertThat(task.getInterval()).isEqualTo(180000L); + } + @Test public void fixedRateTaskWithInitialDelay() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); @@ -163,6 +277,62 @@ public void fixedRateTaskWithInitialDelay() { assertThat(task.getInterval()).isEqualTo(3000L); } + @Test + public void fixedRateTaskWithSecondsTimeUnitWithInitialDelay() { + BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); + BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithSecondsTimeUnitInitialDelayTestBean.class); + context.registerBeanDefinition("postProcessor", processorDefinition); + context.registerBeanDefinition("target", targetDefinition); + context.refresh(); + + ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class); + assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1); + + Object target = context.getBean("target"); + ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) + new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); + @SuppressWarnings("unchecked") + List fixedRateTasks = (List) + new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks"); + assertThat(fixedRateTasks.size()).isEqualTo(1); + IntervalTask task = fixedRateTasks.get(0); + ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); + Object targetObject = runnable.getTarget(); + Method targetMethod = runnable.getMethod(); + assertThat(targetObject).isEqualTo(target); + assertThat(targetMethod.getName()).isEqualTo("fixedRate"); + assertThat(task.getInitialDelay()).isEqualTo(5000L); + assertThat(task.getInterval()).isEqualTo(3000L); + } + + @Test + public void fixedRateTaskWithMinutesTimeUnitWithInitialDelay() { + BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); + BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithMinutesTimeUnitInitialDelayTestBean.class); + context.registerBeanDefinition("postProcessor", processorDefinition); + context.registerBeanDefinition("target", targetDefinition); + context.refresh(); + + ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class); + assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1); + + Object target = context.getBean("target"); + ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) + new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); + @SuppressWarnings("unchecked") + List fixedRateTasks = (List) + new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks"); + assertThat(fixedRateTasks.size()).isEqualTo(1); + IntervalTask task = fixedRateTasks.get(0); + ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); + Object targetObject = runnable.getTarget(); + Method targetMethod = runnable.getMethod(); + assertThat(targetObject).isEqualTo(target); + assertThat(targetMethod.getName()).isEqualTo("fixedRate"); + assertThat(task.getInitialDelay()).isEqualTo(60000L); + assertThat(task.getInterval()).isEqualTo(180000L); + } + @Test public void severalFixedRatesWithRepeatedScheduledAnnotation() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); @@ -702,6 +872,22 @@ public void fixedDelay() { } } + static class FixedDelayWithSecondsTimeUnitTestBean { + + @Scheduled(fixedDelay = 5, timeUnit = TimeUnit.SECONDS) + public void fixedDelay() { + } + + } + + static class FixedDelayWithMinutesTimeUnitTestBean { + + @Scheduled(fixedDelay = 3, timeUnit = TimeUnit.MINUTES) + public void fixedDelay() { + } + + } + static class FixedRateTestBean { @@ -709,6 +895,20 @@ static class FixedRateTestBean { public void fixedRate() { } } + static class FixedRateWithSecondsTimeUnitTestBean { + + @Scheduled(fixedRate = 5, timeUnit = TimeUnit.SECONDS) + public void fixedRate() { + } + } + + + static class FixedRateWithMinutesTimeUnitTestBean { + + @Scheduled(fixedRate = 3, timeUnit = TimeUnit.MINUTES) + public void fixedRate() { + } + } static class FixedRateWithInitialDelayTestBean { @@ -718,6 +918,20 @@ public void fixedRate() { } } + static class FixedRateWithSecondsTimeUnitInitialDelayTestBean { + + @Scheduled(fixedRate = 3, initialDelay = 5, timeUnit = TimeUnit.SECONDS) + public void fixedRate() { + } + } + + static class FixedRateWithMinutesTimeUnitInitialDelayTestBean { + + @Scheduled(fixedRate = 3, initialDelay = 1, timeUnit = TimeUnit.MINUTES) + public void fixedRate() { + } + } + static class SeveralFixedRatesWithSchedulesContainerAnnotationTestBean { From bd72e4498b9d1824646c88fa6fa08c1780484d2f Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 25 Aug 2021 20:46:51 +0200 Subject: [PATCH 017/735] Revise and document TimeUnit support in @Scheduled This commit also fixes a bug introduced in commit e99b43b91e, where java.time.Duration strings were converted to milliseconds and then converted again using the configured TimeUnit. See gh-27309 --- .../scheduling/annotation/Scheduled.java | 54 ++- .../ScheduledAnnotationBeanPostProcessor.java | 29 +- ...duledAnnotationBeanPostProcessorTests.java | 454 +++++++----------- src/docs/asciidoc/integration.adoc | 41 +- 4 files changed, 253 insertions(+), 325 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java index de7866073931..ce55aeb82cbd 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java @@ -48,6 +48,7 @@ * @author Dave Syer * @author Chris Beams * @author Victor Brown + * @author Sam Brannen * @since 3.0 * @see EnableScheduling * @see ScheduledAnnotationBeanPostProcessor @@ -103,63 +104,74 @@ String zone() default ""; /** - * Execute the annotated method with a fixed period between the - * end of the last invocation and the start of the next. - * Using milliseconds by default with timeUnit(). + * Execute the annotated method with a fixed period between the end of the + * last invocation and the start of the next. + *

The time unit is milliseconds by default but can be overridden via + * {@link #timeUnit}. * @return the delay */ long fixedDelay() default -1; /** - * Execute the annotated method with a fixed period between the - * end of the last invocation and the start of the next. - * Using milliseconds by default with fixedDelayTimeUnit(). - * @return the delay as a String value, e.g. a placeholder + * Execute the annotated method with a fixed period between the end of the + * last invocation and the start of the next. + *

The time unit is milliseconds by default but can be overridden via + * {@link #timeUnit}. + * @return the delay as a String value — for example, a placeholder * or a {@link java.time.Duration#parse java.time.Duration} compliant value * @since 3.2.2 */ String fixedDelayString() default ""; /** - * Execute the annotated method with a fixed period between - * invocations. - * Using milliseconds by default with timeUnit(). + * Execute the annotated method with a fixed period between invocations. + *

The time unit is milliseconds by default but can be overridden via + * {@link #timeUnit}. * @return the period */ long fixedRate() default -1; /** - * Execute the annotated method with a fixed period between - * invocations. - * Using milliseconds by default with fixedRateTimeUnit(). - * @return the period as a String value, e.g. a placeholder + * Execute the annotated method with a fixed period between invocations. + *

The time unit is milliseconds by default but can be overridden via + * {@link #timeUnit}. + * @return the period as a String value — for example, a placeholder * or a {@link java.time.Duration#parse java.time.Duration} compliant value * @since 3.2.2 */ String fixedRateString() default ""; /** - * Number to delay before the first execution of a + * Number of units of time to delay before the first execution of a * {@link #fixedRate} or {@link #fixedDelay} task. - * Using milliseconds by default with timeUnit(). + *

The time unit is milliseconds by default but can be overridden via + * {@link #timeUnit}. * @return the initial * @since 3.2 */ long initialDelay() default -1; /** - * Number to delay before the first execution of a + * Number of units of time to delay before the first execution of a * {@link #fixedRate} or {@link #fixedDelay} task. - * Using milliseconds by default with initialDelayTimeUnit(). - * @return the initial delay in milliseconds as a String value, e.g. a placeholder + *

The time unit is milliseconds by default but can be overridden via + * {@link #timeUnit}. + * @return the initial delay as a String value — for example, a placeholder * or a {@link java.time.Duration#parse java.time.Duration} compliant value * @since 3.2.2 */ String initialDelayString() default ""; /** - * Specify the {@link TimeUnit} to use for initialDelay, fixedRate and fixedDelay values. - * @return the {@link TimeUnit}, by default milliseconds will be used. + * The {@link TimeUnit} to use for {@link #fixedDelay}, {@link #fixedDelayString}, + * {@link #fixedRate}, {@link #fixedRateString}, {@link #initialDelay}, and + * {@link #initialDelayString}. + *

Defaults to {@link TimeUnit#MICROSECONDS}. + *

This attribute is ignored for {@linkplain #cron() cron expressions} + * and for {@link java.time.Duration} values supplied via {@link #fixedDelayString}, + * {@link #fixedRateString}, or {@link #initialDelayString}. + * @return the {@code TimeUnit} to use + * @since 5.3.10 */ TimeUnit timeUnit() default TimeUnit.MILLISECONDS; diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java index 52fae5dbab98..5e47ccda548f 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java @@ -96,6 +96,7 @@ * @author Chris Beams * @author Elizabeth Chatman * @author Victor Brown + * @author Sam Brannen * @since 3.0 * @see Scheduled * @see EnableScheduling @@ -385,7 +386,7 @@ public Object postProcessAfterInitialization(Object bean, String beanName) { /** * Process the given {@code @Scheduled} method declaration on the given bean. - * @param scheduled the @Scheduled annotation + * @param scheduled the {@code @Scheduled} annotation * @param method the method that the annotation has been declared on * @param bean the target bean instance * @see #createRunnable(Object, Method) @@ -400,7 +401,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean) Set tasks = new LinkedHashSet<>(4); // Determine initial delay - long initialDelay = TimeUnit.MILLISECONDS.convert(scheduled.initialDelay(), scheduled.timeUnit()); + long initialDelay = convertToMillis(scheduled.initialDelay(), scheduled.timeUnit()); String initialDelayString = scheduled.initialDelayString(); if (StringUtils.hasText(initialDelayString)) { Assert.isTrue(initialDelay < 0, "Specify 'initialDelay' or 'initialDelayString', not both"); @@ -409,7 +410,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean) } if (StringUtils.hasLength(initialDelayString)) { try { - initialDelay = TimeUnit.MILLISECONDS.convert(parseDelayAsLong(initialDelayString), scheduled.timeUnit()); + initialDelay = convertToMillis(initialDelayString, scheduled.timeUnit()); } catch (RuntimeException ex) { throw new IllegalArgumentException( @@ -448,7 +449,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean) } // Check fixed delay - long fixedDelay = TimeUnit.MILLISECONDS.convert(scheduled.fixedDelay(), scheduled.timeUnit()); + long fixedDelay = convertToMillis(scheduled.fixedDelay(), scheduled.timeUnit()); if (fixedDelay >= 0) { Assert.isTrue(!processedSchedule, errorMessage); processedSchedule = true; @@ -464,7 +465,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean) Assert.isTrue(!processedSchedule, errorMessage); processedSchedule = true; try { - fixedDelay = TimeUnit.MILLISECONDS.convert(parseDelayAsLong(fixedDelayString), scheduled.timeUnit()); + fixedDelay = convertToMillis(fixedDelayString, scheduled.timeUnit()); } catch (RuntimeException ex) { throw new IllegalArgumentException( @@ -475,7 +476,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean) } // Check fixed rate - long fixedRate = TimeUnit.MILLISECONDS.convert(scheduled.fixedRate(), scheduled.timeUnit()); + long fixedRate = convertToMillis(scheduled.fixedRate(), scheduled.timeUnit()); if (fixedRate >= 0) { Assert.isTrue(!processedSchedule, errorMessage); processedSchedule = true; @@ -490,7 +491,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean) Assert.isTrue(!processedSchedule, errorMessage); processedSchedule = true; try { - fixedRate = TimeUnit.MILLISECONDS.convert(parseDelayAsLong(fixedRateString), scheduled.timeUnit()); + fixedRate = convertToMillis(fixedRateString, scheduled.timeUnit()); } catch (RuntimeException ex) { throw new IllegalArgumentException( @@ -530,11 +531,19 @@ protected Runnable createRunnable(Object target, Method method) { return new ScheduledMethodRunnable(target, invocableMethod); } - private static long parseDelayAsLong(String value) throws RuntimeException { - if (value.length() > 1 && (isP(value.charAt(0)) || isP(value.charAt(1)))) { + private static long convertToMillis(long value, TimeUnit timeUnit) { + return TimeUnit.MILLISECONDS.convert(value, timeUnit); + } + + private static long convertToMillis(String value, TimeUnit timeUnit) { + if (isDurationString(value)) { return Duration.parse(value).toMillis(); } - return Long.parseLong(value); + return convertToMillis(Long.parseLong(value), timeUnit); + } + + private static boolean isDurationString(String value) { + return (value.length() > 1 && (isP(value.charAt(0)) || isP(value.charAt(1)))); } private static boolean isP(char ch) { diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java index 494bf075c6df..04a08b00e64c 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java @@ -33,6 +33,12 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.converter.ArgumentConversionException; +import org.junit.jupiter.params.converter.ArgumentConverter; +import org.junit.jupiter.params.converter.ConvertWith; +import org.junit.jupiter.params.provider.CsvSource; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.scope.ScopedProxyUtils; @@ -61,8 +67,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.SoftAssertions.assertSoftly; /** + * Tests for {@link ScheduledAnnotationBeanPostProcessor}. + * * @author Mark Fisher * @author Juergen Hoeller * @author Chris Beams @@ -70,77 +79,25 @@ * @author Stevo Slavić * @author Victor Brown */ -public class ScheduledAnnotationBeanPostProcessorTests { +class ScheduledAnnotationBeanPostProcessorTests { private final StaticApplicationContext context = new StaticApplicationContext(); @AfterEach - public void closeContextAfterTest() { + void closeContextAfterTest() { context.close(); } - - @Test - public void fixedDelayTask() { - BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); - BeanDefinition targetDefinition = new RootBeanDefinition(FixedDelayTestBean.class); - context.registerBeanDefinition("postProcessor", processorDefinition); - context.registerBeanDefinition("target", targetDefinition); - context.refresh(); - - ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class); - assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1); - - Object target = context.getBean("target"); - ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) - new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); - @SuppressWarnings("unchecked") - List fixedDelayTasks = (List) - new DirectFieldAccessor(registrar).getPropertyValue("fixedDelayTasks"); - assertThat(fixedDelayTasks.size()).isEqualTo(1); - IntervalTask task = fixedDelayTasks.get(0); - ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); - Object targetObject = runnable.getTarget(); - Method targetMethod = runnable.getMethod(); - assertThat(targetObject).isEqualTo(target); - assertThat(targetMethod.getName()).isEqualTo("fixedDelay"); - assertThat(task.getInitialDelay()).isEqualTo(0L); - assertThat(task.getInterval()).isEqualTo(5000L); - } - - @Test - public void fixedDelayWithSecondsTimeUnitTask() { - BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); - BeanDefinition targetDefinition = new RootBeanDefinition(FixedDelayWithSecondsTimeUnitTestBean.class); - context.registerBeanDefinition("postProcessor", processorDefinition); - context.registerBeanDefinition("target", targetDefinition); - context.refresh(); - - ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class); - assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1); - - Object target = context.getBean("target"); - ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) - new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); - @SuppressWarnings("unchecked") - List fixedDelayTasks = (List) - new DirectFieldAccessor(registrar).getPropertyValue("fixedDelayTasks"); - assertThat(fixedDelayTasks.size()).isEqualTo(1); - IntervalTask task = fixedDelayTasks.get(0); - ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); - Object targetObject = runnable.getTarget(); - Method targetMethod = runnable.getMethod(); - assertThat(targetObject).isEqualTo(target); - assertThat(targetMethod.getName()).isEqualTo("fixedDelay"); - assertThat(task.getInitialDelay()).isEqualTo(0L); - assertThat(task.getInterval()).isEqualTo(5000L); - } - - @Test - public void fixedDelayWithMinutesTimeUnitTask() { + @ParameterizedTest + @CsvSource({ + "FixedDelay, 5000", + "FixedDelayInSeconds, 5000", + "FixedDelayInMinutes, 180000" + }) + void fixedDelayTask(@NameToClass Class beanClass, long expectedInterval) { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); - BeanDefinition targetDefinition = new RootBeanDefinition(FixedDelayWithMinutesTimeUnitTestBean.class); + BeanDefinition targetDefinition = new RootBeanDefinition(beanClass); context.registerBeanDefinition("postProcessor", processorDefinition); context.registerBeanDefinition("target", targetDefinition); context.refresh(); @@ -154,7 +111,7 @@ public void fixedDelayWithMinutesTimeUnitTask() { @SuppressWarnings("unchecked") List fixedDelayTasks = (List) new DirectFieldAccessor(registrar).getPropertyValue("fixedDelayTasks"); - assertThat(fixedDelayTasks.size()).isEqualTo(1); + assertThat(fixedDelayTasks).hasSize(1); IntervalTask task = fixedDelayTasks.get(0); ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); Object targetObject = runnable.getTarget(); @@ -162,125 +119,18 @@ public void fixedDelayWithMinutesTimeUnitTask() { assertThat(targetObject).isEqualTo(target); assertThat(targetMethod.getName()).isEqualTo("fixedDelay"); assertThat(task.getInitialDelay()).isEqualTo(0L); - assertThat(task.getInterval()).isEqualTo(180000L); - } - - @Test - public void fixedRateTask() { - BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); - BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateTestBean.class); - context.registerBeanDefinition("postProcessor", processorDefinition); - context.registerBeanDefinition("target", targetDefinition); - context.refresh(); - - ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class); - assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1); - - Object target = context.getBean("target"); - ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) - new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); - @SuppressWarnings("unchecked") - List fixedRateTasks = (List) - new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks"); - assertThat(fixedRateTasks.size()).isEqualTo(1); - IntervalTask task = fixedRateTasks.get(0); - ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); - Object targetObject = runnable.getTarget(); - Method targetMethod = runnable.getMethod(); - assertThat(targetObject).isEqualTo(target); - assertThat(targetMethod.getName()).isEqualTo("fixedRate"); - assertThat(task.getInitialDelay()).isEqualTo(0L); - assertThat(task.getInterval()).isEqualTo(3000L); - } - - @Test - public void fixedRateWithSecondsTimeUnitTask() { - BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); - BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithSecondsTimeUnitTestBean.class); - context.registerBeanDefinition("postProcessor", processorDefinition); - context.registerBeanDefinition("target", targetDefinition); - context.refresh(); - - ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class); - assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1); - - Object target = context.getBean("target"); - ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) - new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); - @SuppressWarnings("unchecked") - List fixedRateTasks = (List) - new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks"); - assertThat(fixedRateTasks.size()).isEqualTo(1); - IntervalTask task = fixedRateTasks.get(0); - ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); - Object targetObject = runnable.getTarget(); - Method targetMethod = runnable.getMethod(); - assertThat(targetObject).isEqualTo(target); - assertThat(targetMethod.getName()).isEqualTo("fixedRate"); - assertThat(task.getInitialDelay()).isEqualTo(0L); - assertThat(task.getInterval()).isEqualTo(5000L); - } - - @Test - public void fixedRateWithMinutesTimeUnitTask() { - BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); - BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithMinutesTimeUnitTestBean.class); - context.registerBeanDefinition("postProcessor", processorDefinition); - context.registerBeanDefinition("target", targetDefinition); - context.refresh(); - - ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class); - assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1); - - Object target = context.getBean("target"); - ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) - new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); - @SuppressWarnings("unchecked") - List fixedRateTasks = (List) - new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks"); - assertThat(fixedRateTasks.size()).isEqualTo(1); - IntervalTask task = fixedRateTasks.get(0); - ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); - Object targetObject = runnable.getTarget(); - Method targetMethod = runnable.getMethod(); - assertThat(targetObject).isEqualTo(target); - assertThat(targetMethod.getName()).isEqualTo("fixedRate"); - assertThat(task.getInitialDelay()).isEqualTo(0L); - assertThat(task.getInterval()).isEqualTo(180000L); - } - - @Test - public void fixedRateTaskWithInitialDelay() { - BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); - BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithInitialDelayTestBean.class); - context.registerBeanDefinition("postProcessor", processorDefinition); - context.registerBeanDefinition("target", targetDefinition); - context.refresh(); - - ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class); - assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1); - - Object target = context.getBean("target"); - ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) - new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); - @SuppressWarnings("unchecked") - List fixedRateTasks = (List) - new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks"); - assertThat(fixedRateTasks.size()).isEqualTo(1); - IntervalTask task = fixedRateTasks.get(0); - ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable(); - Object targetObject = runnable.getTarget(); - Method targetMethod = runnable.getMethod(); - assertThat(targetObject).isEqualTo(target); - assertThat(targetMethod.getName()).isEqualTo("fixedRate"); - assertThat(task.getInitialDelay()).isEqualTo(1000L); - assertThat(task.getInterval()).isEqualTo(3000L); + assertThat(task.getInterval()).isEqualTo(expectedInterval); } - @Test - public void fixedRateTaskWithSecondsTimeUnitWithInitialDelay() { + @ParameterizedTest + @CsvSource({ + "FixedRate, 3000", + "FixedRateInSeconds, 5000", + "FixedRateInMinutes, 180000" + }) + void fixedRateTask(@NameToClass Class beanClass, long expectedInterval) { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); - BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithSecondsTimeUnitInitialDelayTestBean.class); + BeanDefinition targetDefinition = new RootBeanDefinition(beanClass); context.registerBeanDefinition("postProcessor", processorDefinition); context.registerBeanDefinition("target", targetDefinition); context.refresh(); @@ -301,14 +151,21 @@ public void fixedRateTaskWithSecondsTimeUnitWithInitialDelay() { Method targetMethod = runnable.getMethod(); assertThat(targetObject).isEqualTo(target); assertThat(targetMethod.getName()).isEqualTo("fixedRate"); - assertThat(task.getInitialDelay()).isEqualTo(5000L); - assertThat(task.getInterval()).isEqualTo(3000L); - } - - @Test - public void fixedRateTaskWithMinutesTimeUnitWithInitialDelay() { + assertSoftly(softly -> { + softly.assertThat(task.getInitialDelay()).as("initial delay").isEqualTo(0); + softly.assertThat(task.getInterval()).as("interval").isEqualTo(expectedInterval); + }); + } + + @ParameterizedTest + @CsvSource({ + "FixedRateWithInitialDelay, 1000, 3000", + "FixedRateWithInitialDelayInSeconds, 5000, 3000", + "FixedRateWithInitialDelayInMinutes, 60000, 180000" + }) + void fixedRateTaskWithInitialDelay(@NameToClass Class beanClass, long expectedInitialDelay, long expectedInterval) { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); - BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithMinutesTimeUnitInitialDelayTestBean.class); + BeanDefinition targetDefinition = new RootBeanDefinition(beanClass); context.registerBeanDefinition("postProcessor", processorDefinition); context.registerBeanDefinition("target", targetDefinition); context.refresh(); @@ -329,40 +186,42 @@ public void fixedRateTaskWithMinutesTimeUnitWithInitialDelay() { Method targetMethod = runnable.getMethod(); assertThat(targetObject).isEqualTo(target); assertThat(targetMethod.getName()).isEqualTo("fixedRate"); - assertThat(task.getInitialDelay()).isEqualTo(60000L); - assertThat(task.getInterval()).isEqualTo(180000L); + assertSoftly(softly -> { + softly.assertThat(task.getInitialDelay()).as("initial delay").isEqualTo(expectedInitialDelay); + softly.assertThat(task.getInterval()).as("interval").isEqualTo(expectedInterval); + }); } @Test - public void severalFixedRatesWithRepeatedScheduledAnnotation() { + void severalFixedRatesWithRepeatedScheduledAnnotation() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean.class); severalFixedRates(context, processorDefinition, targetDefinition); } @Test - public void severalFixedRatesWithSchedulesContainerAnnotation() { + void severalFixedRatesWithSchedulesContainerAnnotation() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(SeveralFixedRatesWithSchedulesContainerAnnotationTestBean.class); severalFixedRates(context, processorDefinition, targetDefinition); } @Test - public void severalFixedRatesOnBaseClass() { + void severalFixedRatesOnBaseClass() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(FixedRatesSubBean.class); severalFixedRates(context, processorDefinition, targetDefinition); } @Test - public void severalFixedRatesOnDefaultMethod() { + void severalFixedRatesOnDefaultMethod() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(FixedRatesDefaultBean.class); severalFixedRates(context, processorDefinition, targetDefinition); } @Test - public void severalFixedRatesAgainstNestedCglibProxy() { + void severalFixedRatesAgainstNestedCglibProxy() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean.class); targetDefinition.setFactoryMethodName("nestedProxy"); @@ -405,7 +264,7 @@ private void severalFixedRates(StaticApplicationContext context, } @Test - public void cronTask() { + void cronTask() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(CronTestBean.class); context.registerBeanDefinition("postProcessor", processorDefinition); @@ -432,7 +291,7 @@ public void cronTask() { } @Test - public void cronTaskWithZone() { + void cronTaskWithZone() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(CronWithTimezoneTestBean.class); context.registerBeanDefinition("postProcessor", processorDefinition); @@ -478,7 +337,7 @@ public void cronTaskWithZone() { } @Test - public void cronTaskWithInvalidZone() { + void cronTaskWithInvalidZone() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(CronWithInvalidTimezoneTestBean.class); context.registerBeanDefinition("postProcessor", processorDefinition); @@ -488,7 +347,7 @@ public void cronTaskWithInvalidZone() { } @Test - public void cronTaskWithMethodValidation() { + void cronTaskWithMethodValidation() { BeanDefinition validationDefinition = new RootBeanDefinition(MethodValidationPostProcessor.class); BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(CronTestBean.class); @@ -500,7 +359,7 @@ public void cronTaskWithMethodValidation() { } @Test - public void cronTaskWithScopedProxy() { + void cronTaskWithScopedProxy() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); context.registerBeanDefinition("postProcessor", processorDefinition); new AnnotatedBeanDefinitionReader(context).register(ProxiedCronTestBean.class, ProxiedCronTestBeanDependent.class); @@ -525,7 +384,7 @@ public void cronTaskWithScopedProxy() { } @Test - public void metaAnnotationWithFixedRate() { + void metaAnnotationWithFixedRate() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(MetaAnnotationFixedRateTestBean.class); context.registerBeanDefinition("postProcessor", processorDefinition); @@ -552,7 +411,7 @@ public void metaAnnotationWithFixedRate() { } @Test - public void composedAnnotationWithInitialDelayAndFixedRate() { + void composedAnnotationWithInitialDelayAndFixedRate() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(ComposedAnnotationFixedRateTestBean.class); context.registerBeanDefinition("postProcessor", processorDefinition); @@ -580,7 +439,7 @@ public void composedAnnotationWithInitialDelayAndFixedRate() { } @Test - public void metaAnnotationWithCronExpression() { + void metaAnnotationWithCronExpression() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(MetaAnnotationCronTestBean.class); context.registerBeanDefinition("postProcessor", processorDefinition); @@ -607,7 +466,7 @@ public void metaAnnotationWithCronExpression() { } @Test - public void propertyPlaceholderWithCron() { + void propertyPlaceholderWithCron() { String businessHoursCronExpression = "0 0 9-17 * * MON-FRI"; BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition placeholderDefinition = new RootBeanDefinition(PropertySourcesPlaceholderConfigurer.class); @@ -640,7 +499,7 @@ public void propertyPlaceholderWithCron() { } @Test - public void propertyPlaceholderWithInactiveCron() { + void propertyPlaceholderWithInactiveCron() { String businessHoursCronExpression = "-"; BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition placeholderDefinition = new RootBeanDefinition(PropertySourcesPlaceholderConfigurer.class); @@ -657,24 +516,23 @@ public void propertyPlaceholderWithInactiveCron() { assertThat(postProcessor.getScheduledTasks().isEmpty()).isTrue(); } - @Test - public void propertyPlaceholderWithFixedDelayInMillis() { - propertyPlaceholderWithFixedDelay(false); - } - - @Test - public void propertyPlaceholderWithFixedDelayInDuration() { - propertyPlaceholderWithFixedDelay(true); - } + @ParameterizedTest + @CsvSource({ + "PropertyPlaceholderWithFixedDelay, 5000, 1000, 5000, 1000", + "PropertyPlaceholderWithFixedDelay, PT5S, PT1S, 5000, 1000", + "PropertyPlaceholderWithFixedDelayInSeconds, 5000, 1000, 5000000, 1000000", + "PropertyPlaceholderWithFixedDelayInSeconds, PT5S, PT1S, 5000, 1000" + }) + void propertyPlaceholderWithFixedDelay(@NameToClass Class beanClass, String fixedDelay, String initialDelay, + long expectedInterval, long expectedInitialDelay) { - private void propertyPlaceholderWithFixedDelay(boolean durationFormat) { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition placeholderDefinition = new RootBeanDefinition(PropertySourcesPlaceholderConfigurer.class); Properties properties = new Properties(); - properties.setProperty("fixedDelay", (durationFormat ? "PT5S" : "5000")); - properties.setProperty("initialDelay", (durationFormat ? "PT1S" : "1000")); + properties.setProperty("fixedDelay", fixedDelay); + properties.setProperty("initialDelay", initialDelay); placeholderDefinition.getPropertyValues().addPropertyValue("properties", properties); - BeanDefinition targetDefinition = new RootBeanDefinition(PropertyPlaceholderWithFixedDelayTestBean.class); + BeanDefinition targetDefinition = new RootBeanDefinition(beanClass); context.registerBeanDefinition("postProcessor", processorDefinition); context.registerBeanDefinition("placeholder", placeholderDefinition); context.registerBeanDefinition("target", targetDefinition); @@ -696,28 +554,29 @@ private void propertyPlaceholderWithFixedDelay(boolean durationFormat) { Method targetMethod = runnable.getMethod(); assertThat(targetObject).isEqualTo(target); assertThat(targetMethod.getName()).isEqualTo("fixedDelay"); - assertThat(task.getInitialDelay()).isEqualTo(1000L); - assertThat(task.getInterval()).isEqualTo(5000L); - } - - @Test - public void propertyPlaceholderWithFixedRateInMillis() { - propertyPlaceholderWithFixedRate(false); - } - - @Test - public void propertyPlaceholderWithFixedRateInDuration() { - propertyPlaceholderWithFixedRate(true); - } + assertSoftly(softly -> { + softly.assertThat(task.getInitialDelay()).as("initial delay").isEqualTo(expectedInitialDelay); + softly.assertThat(task.getInterval()).as("interval").isEqualTo(expectedInterval); + }); + } + + @ParameterizedTest + @CsvSource({ + "PropertyPlaceholderWithFixedRate, 3000, 1000, 3000, 1000", + "PropertyPlaceholderWithFixedRate, PT3S, PT1S, 3000, 1000", + "PropertyPlaceholderWithFixedRateInSeconds, 3000, 1000, 3000000, 1000000", + "PropertyPlaceholderWithFixedRateInSeconds, PT3S, PT1S, 3000, 1000" + }) + void propertyPlaceholderWithFixedRate(@NameToClass Class beanClass, String fixedRate, String initialDelay, + long expectedInterval, long expectedInitialDelay) { - private void propertyPlaceholderWithFixedRate(boolean durationFormat) { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition placeholderDefinition = new RootBeanDefinition(PropertySourcesPlaceholderConfigurer.class); Properties properties = new Properties(); - properties.setProperty("fixedRate", (durationFormat ? "PT3S" : "3000")); - properties.setProperty("initialDelay", (durationFormat ? "PT1S" : "1000")); + properties.setProperty("fixedRate", fixedRate); + properties.setProperty("initialDelay", initialDelay); placeholderDefinition.getPropertyValues().addPropertyValue("properties", properties); - BeanDefinition targetDefinition = new RootBeanDefinition(PropertyPlaceholderWithFixedRateTestBean.class); + BeanDefinition targetDefinition = new RootBeanDefinition(beanClass); context.registerBeanDefinition("postProcessor", processorDefinition); context.registerBeanDefinition("placeholder", placeholderDefinition); context.registerBeanDefinition("target", targetDefinition); @@ -739,12 +598,14 @@ private void propertyPlaceholderWithFixedRate(boolean durationFormat) { Method targetMethod = runnable.getMethod(); assertThat(targetObject).isEqualTo(target); assertThat(targetMethod.getName()).isEqualTo("fixedRate"); - assertThat(task.getInitialDelay()).isEqualTo(1000L); - assertThat(task.getInterval()).isEqualTo(3000L); + assertSoftly(softly -> { + softly.assertThat(task.getInitialDelay()).as("initial delay").isEqualTo(expectedInitialDelay); + softly.assertThat(task.getInterval()).as("interval").isEqualTo(expectedInterval); + }); } @Test - public void expressionWithCron() { + void expressionWithCron() { String businessHoursCronExpression = "0 0 9-17 * * MON-FRI"; BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(ExpressionWithCronTestBean.class); @@ -775,7 +636,7 @@ public void expressionWithCron() { } @Test - public void propertyPlaceholderForMetaAnnotation() { + void propertyPlaceholderForMetaAnnotation() { String businessHoursCronExpression = "0 0 9-17 * * MON-FRI"; BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition placeholderDefinition = new RootBeanDefinition(PropertySourcesPlaceholderConfigurer.class); @@ -808,7 +669,7 @@ public void propertyPlaceholderForMetaAnnotation() { } @Test - public void nonVoidReturnType() { + void nonVoidReturnType() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(NonVoidReturnTypeTestBean.class); context.registerBeanDefinition("postProcessor", processorDefinition); @@ -835,7 +696,7 @@ public void nonVoidReturnType() { } @Test - public void emptyAnnotation() { + void emptyAnnotation() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(EmptyAnnotationTestBean.class); context.registerBeanDefinition("postProcessor", processorDefinition); @@ -845,7 +706,7 @@ public void emptyAnnotation() { } @Test - public void invalidCron() throws Throwable { + void invalidCron() throws Throwable { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(InvalidCronTestBean.class); context.registerBeanDefinition("postProcessor", processorDefinition); @@ -855,7 +716,7 @@ public void invalidCron() throws Throwable { } @Test - public void nonEmptyParamList() { + void nonEmptyParamList() { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(NonEmptyParamListTestBean.class); context.registerBeanDefinition("postProcessor", processorDefinition); @@ -865,70 +726,68 @@ public void nonEmptyParamList() { } - static class FixedDelayTestBean { + static class FixedDelay { @Scheduled(fixedDelay = 5000) - public void fixedDelay() { + void fixedDelay() { } } - static class FixedDelayWithSecondsTimeUnitTestBean { + static class FixedDelayInSeconds { @Scheduled(fixedDelay = 5, timeUnit = TimeUnit.SECONDS) - public void fixedDelay() { + void fixedDelay() { } - } - static class FixedDelayWithMinutesTimeUnitTestBean { + static class FixedDelayInMinutes { @Scheduled(fixedDelay = 3, timeUnit = TimeUnit.MINUTES) - public void fixedDelay() { + void fixedDelay() { } - } - static class FixedRateTestBean { + static class FixedRate { @Scheduled(fixedRate = 3000) - public void fixedRate() { + void fixedRate() { } } - static class FixedRateWithSecondsTimeUnitTestBean { + + static class FixedRateInSeconds { @Scheduled(fixedRate = 5, timeUnit = TimeUnit.SECONDS) - public void fixedRate() { + void fixedRate() { } } - - static class FixedRateWithMinutesTimeUnitTestBean { + static class FixedRateInMinutes { @Scheduled(fixedRate = 3, timeUnit = TimeUnit.MINUTES) - public void fixedRate() { + void fixedRate() { } } - static class FixedRateWithInitialDelayTestBean { + static class FixedRateWithInitialDelay { @Scheduled(fixedRate = 3000, initialDelay = 1000) - public void fixedRate() { + void fixedRate() { } } - static class FixedRateWithSecondsTimeUnitInitialDelayTestBean { + static class FixedRateWithInitialDelayInSeconds { @Scheduled(fixedRate = 3, initialDelay = 5, timeUnit = TimeUnit.SECONDS) - public void fixedRate() { + void fixedRate() { } } - static class FixedRateWithMinutesTimeUnitInitialDelayTestBean { + static class FixedRateWithInitialDelayInMinutes { @Scheduled(fixedRate = 3, initialDelay = 1, timeUnit = TimeUnit.MINUTES) - public void fixedRate() { + void fixedRate() { } } @@ -936,7 +795,7 @@ public void fixedRate() { static class SeveralFixedRatesWithSchedulesContainerAnnotationTestBean { @Schedules({@Scheduled(fixedRate = 4000), @Scheduled(fixedRate = 4000, initialDelay = 2000)}) - public void fixedRate() { + void fixedRate() { } } @@ -945,7 +804,7 @@ static class SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean { @Scheduled(fixedRate = 4000) @Scheduled(fixedRate = 4000, initialDelay = 2000) - public void fixedRate() { + void fixedRate() { } static SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean nestedProxy() { @@ -962,7 +821,7 @@ static class FixedRatesBaseBean { @Scheduled(fixedRate = 4000) @Scheduled(fixedRate = 4000, initialDelay = 2000) - public void fixedRate() { + void fixedRate() { } } @@ -1006,7 +865,7 @@ protected void cron() throws IOException { static class CronWithInvalidTimezoneTestBean { @Scheduled(cron = "0 0 0-4,6-23 * * ?", zone = "FOO") - public void cron() throws IOException { + void cron() throws IOException { throw new IOException("no no no"); } } @@ -1017,7 +876,7 @@ public void cron() throws IOException { static class ProxiedCronTestBean { @Scheduled(cron = "*/7 * * * * ?") - public void cron() throws IOException { + void cron() throws IOException { throw new IOException("no no no"); } } @@ -1025,7 +884,7 @@ public void cron() throws IOException { static class ProxiedCronTestBeanDependent { - public ProxiedCronTestBeanDependent(ProxiedCronTestBean testBean) { + ProxiedCronTestBeanDependent(ProxiedCronTestBean testBean) { } } @@ -1033,7 +892,7 @@ public ProxiedCronTestBeanDependent(ProxiedCronTestBean testBean) { static class NonVoidReturnTypeTestBean { @Scheduled(cron = "0 0 9-17 * * MON-FRI") - public String cron() { + String cron() { return "oops"; } } @@ -1042,7 +901,7 @@ public String cron() { static class EmptyAnnotationTestBean { @Scheduled - public void invalid() { + void invalid() { } } @@ -1050,7 +909,7 @@ public void invalid() { static class InvalidCronTestBean { @Scheduled(cron = "abc") - public void invalid() { + void invalid() { } } @@ -1058,7 +917,7 @@ public void invalid() { static class NonEmptyParamListTestBean { @Scheduled(fixedRate = 3000) - public void invalid(String oops) { + void invalid(String oops) { } } @@ -1090,7 +949,7 @@ public void invalid(String oops) { static class MetaAnnotationFixedRateTestBean { @EveryFiveSeconds - public void checkForUpdates() { + void checkForUpdates() { } } @@ -1098,7 +957,7 @@ public void checkForUpdates() { static class ComposedAnnotationFixedRateTestBean { @WaitASec(fixedRate = 5000) - public void checkForUpdates() { + void checkForUpdates() { } } @@ -1106,7 +965,7 @@ public void checkForUpdates() { static class MetaAnnotationCronTestBean { @Hourly - public void generateReport() { + void generateReport() { } } @@ -1114,23 +973,37 @@ public void generateReport() { static class PropertyPlaceholderWithCronTestBean { @Scheduled(cron = "${schedules.businessHours}") - public void x() { + void x() { } } - static class PropertyPlaceholderWithFixedDelayTestBean { + static class PropertyPlaceholderWithFixedDelay { @Scheduled(fixedDelayString = "${fixedDelay}", initialDelayString = "${initialDelay}") - public void fixedDelay() { + void fixedDelay() { } } + static class PropertyPlaceholderWithFixedDelayInSeconds { + + @Scheduled(fixedDelayString = "${fixedDelay}", initialDelayString = "${initialDelay}", timeUnit = TimeUnit.SECONDS) + void fixedDelay() { + } + } - static class PropertyPlaceholderWithFixedRateTestBean { + + static class PropertyPlaceholderWithFixedRate { @Scheduled(fixedRateString = "${fixedRate}", initialDelayString = "${initialDelay}") - public void fixedRate() { + void fixedRate() { + } + } + + static class PropertyPlaceholderWithFixedRateInSeconds { + + @Scheduled(fixedRateString = "${fixedRate}", initialDelayString = "${initialDelay}", timeUnit = TimeUnit.SECONDS) + void fixedRate() { } } @@ -1138,7 +1011,7 @@ public void fixedRate() { static class ExpressionWithCronTestBean { @Scheduled(cron = "#{schedules.businessHours}") - public void x() { + void x() { } } @@ -1153,7 +1026,24 @@ public void x() { static class PropertyPlaceholderMetaAnnotationTestBean { @BusinessHours - public void y() { + void y() { + } + } + + @Retention(RetentionPolicy.RUNTIME) + @ConvertWith(NameToClass.Converter.class) + private @interface NameToClass { + class Converter implements ArgumentConverter { + @Override + public Class convert(Object beanClassName, ParameterContext context) throws ArgumentConversionException { + try { + String name = getClass().getEnclosingClass().getEnclosingClass().getName() + "$" + beanClassName; + return getClass().getClassLoader().loadClass(name); + } + catch (Exception ex) { + throw new ArgumentConversionException("Failed to convert class name to Class", ex); + } + } } } diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index 15e49e487d23..dae0ac82ac01 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -4923,37 +4923,54 @@ switching to `aspectj` mode in combination with compile-time or load-time weavin ==== The `@Scheduled` annotation You can add the `@Scheduled` annotation to a method, along with trigger metadata. For -example, the following method is invoked every five seconds with a fixed delay, -meaning that the period is measured from the completion time of each preceding -invocation: +example, the following method is invoked every five seconds (5000 milliseconds) with a +fixed delay, meaning that the period is measured from the completion time of each +preceding invocation. [source,java,indent=0,subs="verbatim,quotes"] ---- - @Scheduled(fixedDelay=5000) + @Scheduled(fixedDelay = 5000) public void doSomething() { // something that should run periodically } ---- -If you need a fixed-rate execution, you can change the property name specified within -the annotation. The following method is invoked every five seconds (measured between the -successive start times of each invocation): +[NOTE] +==== +By default, milliseconds will be used as the time unit for fixed delay, fixed rate, and +initial delay values. If you would like to use a different time unit such as seconds or +minutes, you can configure this via the `timeUnit` attribute in `@Scheduled`. + +For example, the previous example can also be written as follows. + +[source,java,indent=0,subs="verbatim,quotes"] +---- + @Scheduled(fixedDelay = 5, timeUnit = TimeUnit.SECONDS) + public void doSomething() { + // something that should run periodically + } +---- +==== + +If you need a fixed-rate execution, you can use the `fixedRate` attribute within the +annotation. The following method is invoked every five seconds (measured between the +successive start times of each invocation). [source,java,indent=0,subs="verbatim,quotes"] ---- - @Scheduled(fixedRate=5000) + @Scheduled(fixedRate = 5, timeUnit = TimeUnit.SECONDS) public void doSomething() { // something that should run periodically } ---- For fixed-delay and fixed-rate tasks, you can specify an initial delay by indicating the -number of milliseconds to wait before the first execution of the method, as the following -`fixedRate` example shows: +amount of time to wait before the first execution of the method, as the following +`fixedRate` example shows. [source,java,indent=0,subs="verbatim,quotes"] ---- - @Scheduled(initialDelay=1000, fixedRate=5000) + @Scheduled(initialDelay = 1000, fixedRate = 5000) public void doSomething() { // something that should run periodically } @@ -4975,7 +4992,7 @@ The following example runs only on weekdays: TIP: You can also use the `zone` attribute to specify the time zone in which the cron expression is resolved. -Notice that the methods to be scheduled must have void returns and must not expect any +Notice that the methods to be scheduled must have void returns and must not accept any arguments. If the method needs to interact with other objects from the application context, those would typically have been provided through dependency injection. From 9a7fb7022dd5b7d2d8d5514ab2fb827b3e32854a Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 26 Aug 2021 13:43:48 +0200 Subject: [PATCH 018/735] Fix typo in @Scheduled See gh-27309 --- .../org/springframework/scheduling/annotation/Scheduled.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java index ce55aeb82cbd..468906a61445 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java @@ -166,7 +166,7 @@ * The {@link TimeUnit} to use for {@link #fixedDelay}, {@link #fixedDelayString}, * {@link #fixedRate}, {@link #fixedRateString}, {@link #initialDelay}, and * {@link #initialDelayString}. - *

Defaults to {@link TimeUnit#MICROSECONDS}. + *

Defaults to {@link TimeUnit#MILLISECONDS}. *

This attribute is ignored for {@linkplain #cron() cron expressions} * and for {@link java.time.Duration} values supplied via {@link #fixedDelayString}, * {@link #fixedRateString}, or {@link #initialDelayString}. From c27ec00ae94bb3a2555c7762264ff009fa57ee0c Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 26 Aug 2021 14:09:23 +0200 Subject: [PATCH 019/735] Polish scheduling Javadoc --- .../annotation/EnableScheduling.java | 30 ++++++++----------- .../scheduling/annotation/Scheduled.java | 2 +- .../ScheduledAnnotationBeanPostProcessor.java | 15 ++++++---- .../annotation/SchedulingConfigurer.java | 18 +++++------ 4 files changed, 32 insertions(+), 33 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/EnableScheduling.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/EnableScheduling.java index d94b5f5e9c79..e35b0a799291 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/EnableScheduling.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/EnableScheduling.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ /** * Enables Spring's scheduled task execution capability, similar to * functionality found in Spring's {@code } XML namespace. To be used - * on @{@link Configuration} classes as follows: + * on {@link Configuration @Configuration} classes as follows: * *

  * @Configuration
@@ -41,8 +41,8 @@
  *     // various @Bean definitions
  * }
* - * This enables detection of @{@link Scheduled} annotations on any Spring-managed - * bean in the container. For example, given a class {@code MyTask} + *

This enables detection of {@link Scheduled @Scheduled} annotations on any + * Spring-managed bean in the container. For example, given a class {@code MyTask}: * *

  * package com.myco.tasks;
@@ -55,7 +55,7 @@
  *     }
  * }
* - * the following configuration would ensure that {@code MyTask.work()} is called + *

the following configuration would ensure that {@code MyTask.work()} is called * once every 1000 ms: * *

@@ -69,7 +69,7 @@
  *     }
  * }
* - * Alternatively, if {@code MyTask} were annotated with {@code @Component}, the + *

Alternatively, if {@code MyTask} were annotated with {@code @Component}, the * following configuration would ensure that its {@code @Scheduled} method is * invoked at the desired interval: * @@ -80,7 +80,7 @@ * public class AppConfig { * } * - * Methods annotated with {@code @Scheduled} may even be declared directly within + *

Methods annotated with {@code @Scheduled} may even be declared directly within * {@code @Configuration} classes: * *

@@ -94,7 +94,7 @@
  *     }
  * }
* - *

By default, will be searching for an associated scheduler definition: either + *

By default, Spring will search for an associated scheduler definition: either * a unique {@link org.springframework.scheduling.TaskScheduler} bean in the context, * or a {@code TaskScheduler} bean named "taskScheduler" otherwise; the same lookup * will also be performed for a {@link java.util.concurrent.ScheduledExecutorService} @@ -141,11 +141,7 @@ * public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { * taskRegistrar.setScheduler(taskScheduler()); * taskRegistrar.addTriggerTask( - * new Runnable() { - * public void run() { - * myTask().work(); - * } - * }, + * () -> myTask().work(), * new CustomTrigger() * ); * } @@ -165,7 +161,7 @@ * configuration: * *

- * <beans>
+ * <beans>
  *
  *     <task:annotation-driven scheduler="taskScheduler"/>
  *
@@ -180,13 +176,13 @@
  * </beans>
  * 
* - * The examples are equivalent save that in XML a fixed-rate period is used + *

The examples are equivalent save that in XML a fixed-rate period is used * instead of a custom {@code Trigger} implementation; this is because the * {@code task:} namespace {@code scheduled} cannot easily expose such support. This is * but one demonstration how the code-based approach allows for maximum configurability - * through direct access to actual componentry.

+ * through direct access to actual componentry. * - * Note: {@code @EnableScheduling} applies to its local application context only, + *

Note: {@code @EnableScheduling} applies to its local application context only, * allowing for selective scheduling of beans at different levels. Please redeclare * {@code @EnableScheduling} in each individual context, e.g. the common root web * application context and any separate {@code DispatcherServlet} application contexts, diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java index 468906a61445..f3aa81296a23 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java @@ -38,7 +38,7 @@ *

Processing of {@code @Scheduled} annotations is performed by * registering a {@link ScheduledAnnotationBeanPostProcessor}. This can be * done manually or, more conveniently, through the {@code } - * element or @{@link EnableScheduling} annotation. + * XML element or {@link EnableScheduling @EnableScheduling} annotation. * *

This annotation may be used as a meta-annotation to create custom * composed annotations with attribute overrides. diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java index 5e47ccda548f..f0aae203468a 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java @@ -78,9 +78,10 @@ import org.springframework.util.StringValueResolver; /** - * Bean post-processor that registers methods annotated with @{@link Scheduled} - * to be invoked by a {@link org.springframework.scheduling.TaskScheduler} according - * to the "fixedRate", "fixedDelay", or "cron" expression provided via the annotation. + * Bean post-processor that registers methods annotated with + * {@link Scheduled @Scheduled} to be invoked by a + * {@link org.springframework.scheduling.TaskScheduler} according to the + * "fixedRate", "fixedDelay", or "cron" expression provided via the annotation. * *

This post-processor is automatically registered by Spring's * {@code } XML element, and also by the @@ -88,8 +89,9 @@ * *

Autodetects any {@link SchedulingConfigurer} instances in the container, * allowing for customization of the scheduler to be used or for fine-grained - * control over task registration (e.g. registration of {@link Trigger} tasks. - * See the @{@link EnableScheduling} javadocs for complete usage details. + * control over task registration (e.g. registration of {@link Trigger} tasks). + * See the {@link EnableScheduling @EnableScheduling} javadocs for complete usage + * details. * * @author Mark Fisher * @author Juergen Hoeller @@ -153,7 +155,8 @@ public ScheduledAnnotationBeanPostProcessor() { /** * Create a {@code ScheduledAnnotationBeanPostProcessor} delegating to the * specified {@link ScheduledTaskRegistrar}. - * @param registrar the ScheduledTaskRegistrar to register @Scheduled tasks on + * @param registrar the ScheduledTaskRegistrar to register {@code @Scheduled} + * tasks on * @since 5.1 */ public ScheduledAnnotationBeanPostProcessor(ScheduledTaskRegistrar registrar) { diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/SchedulingConfigurer.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/SchedulingConfigurer.java index 05283e3fd503..26f0076077f7 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/SchedulingConfigurer.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/SchedulingConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,17 +19,17 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar; /** - * Optional interface to be implemented by @{@link - * org.springframework.context.annotation.Configuration Configuration} classes annotated - * with @{@link EnableScheduling}. Typically used for setting a specific + * Optional interface to be implemented by {@link + * org.springframework.context.annotation.Configuration @Configuration} classes annotated + * with {@link EnableScheduling @EnableScheduling}. Typically used for setting a specific * {@link org.springframework.scheduling.TaskScheduler TaskScheduler} bean to be used when * executing scheduled tasks or for registering scheduled tasks in a programmatic - * fashion as opposed to the declarative approach of using the @{@link Scheduled} - * annotation. For example, this may be necessary when implementing {@link - * org.springframework.scheduling.Trigger Trigger}-based tasks, which are not supported by - * the {@code @Scheduled} annotation. + * fashion as opposed to the declarative approach of using the + * {@link Scheduled @Scheduled} annotation. For example, this may be necessary + * when implementing {@link org.springframework.scheduling.Trigger Trigger}-based + * tasks, which are not supported by the {@code @Scheduled} annotation. * - *

See @{@link EnableScheduling} for detailed usage examples. + *

See {@link EnableScheduling @EnableScheduling} for detailed usage examples. * * @author Chris Beams * @since 3.1 From b120e0b8f4e48b44ffba59b0002d6d04883dc4a4 Mon Sep 17 00:00:00 2001 From: Steve Wei Date: Mon, 30 Aug 2021 23:47:31 +0900 Subject: [PATCH 020/735] Fix Kotlin example for filtering handler functions Closes gh-#27337 --- src/docs/asciidoc/web/webmvc-functional.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/docs/asciidoc/web/webmvc-functional.adoc b/src/docs/asciidoc/web/webmvc-functional.adoc index 368654f02c8d..1dd3779e1ed4 100644 --- a/src/docs/asciidoc/web/webmvc-functional.adoc +++ b/src/docs/asciidoc/web/webmvc-functional.adoc @@ -799,10 +799,10 @@ For instance, consider the following example: ServerRequest.from(it) .header("X-RequestHeader", "Value").build() } - POST("/person", handler::createPerson) - after { _, response -> // <2> - logResponse(response) - } + } + POST("/person", handler::createPerson) + after { _, response -> // <2> + logResponse(response) } } ---- From debf61b948fd44a8757c4a8c286202ca3b6762b5 Mon Sep 17 00:00:00 2001 From: Philippe Marschall Date: Mon, 30 Aug 2021 16:51:59 +0200 Subject: [PATCH 021/735] Remove unused private loggers Closes gh-27336 --- .../aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java | 5 ----- .../expression/ApplicationContextExpressionTests.java | 6 ------ .../support/TransactionSynchronizationManager.java | 5 ----- .../http/converter/json/Jackson2ObjectMapperBuilder.java | 4 ---- 4 files changed, 20 deletions(-) diff --git a/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java b/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java index 0b6d3394ffba..0ea96012223e 100644 --- a/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java +++ b/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java @@ -20,8 +20,6 @@ import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; @@ -40,7 +38,6 @@ import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.config.MethodInvokingFactoryBean; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.testfixture.beans.ITestBean; import org.springframework.beans.testfixture.beans.TestBean; @@ -66,8 +63,6 @@ */ public class AspectJAutoProxyCreatorTests { - private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class); - @Test public void testAspectsAreApplied() { diff --git a/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java b/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java index e3c9921a504c..c2dfc35dce8d 100644 --- a/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java +++ b/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java @@ -28,8 +28,6 @@ import java.util.Optional; import java.util.Properties; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.ObjectFactory; @@ -40,7 +38,6 @@ import org.springframework.beans.factory.config.Scope; import org.springframework.beans.factory.config.TypedStringValue; import org.springframework.beans.factory.support.AutowireCandidateQualifier; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.testfixture.beans.TestBean; @@ -64,9 +61,6 @@ */ class ApplicationContextExpressionTests { - private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class); - - @Test @SuppressWarnings("deprecation") void genericApplicationContext() throws Exception { diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java b/spring-tx/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java index 3b6e1558acfc..55b3b8c788c6 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java @@ -24,9 +24,6 @@ import java.util.Map; import java.util.Set; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import org.springframework.core.NamedThreadLocal; import org.springframework.core.OrderComparator; import org.springframework.lang.Nullable; @@ -76,8 +73,6 @@ */ public abstract class TransactionSynchronizationManager { - private static final Log logger = LogFactory.getLog(TransactionSynchronizationManager.class); - private static final ThreadLocal> resources = new NamedThreadLocal<>("Transactional resources"); diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java index 0157d4efb61d..415113ff0596 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java @@ -55,13 +55,11 @@ import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule; import com.fasterxml.jackson.dataformat.xml.XmlFactory; import com.fasterxml.jackson.dataformat.xml.XmlMapper; -import org.apache.commons.logging.Log; import org.springframework.beans.BeanUtils; import org.springframework.beans.FatalBeanException; import org.springframework.context.ApplicationContext; import org.springframework.core.KotlinDetector; -import org.springframework.http.HttpLogging; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -105,8 +103,6 @@ */ public class Jackson2ObjectMapperBuilder { - private final Log logger = HttpLogging.forLogName(getClass()); - private final Map, Class> mixIns = new LinkedHashMap<>(); private final Map, JsonSerializer> serializers = new LinkedHashMap<>(); From ae56f2ac09248c3d97288acb044ff30c5ea16897 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 30 Aug 2021 16:54:16 +0200 Subject: [PATCH 022/735] Polish contribution See gh-27336 --- .../aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java | 3 +-- .../context/expression/ApplicationContextExpressionTests.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java b/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java index 0ea96012223e..279e600ec9e8 100644 --- a/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java +++ b/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +63,6 @@ */ public class AspectJAutoProxyCreatorTests { - @Test public void testAspectsAreApplied() { ClassPathXmlApplicationContext bf = newContext("aspects.xml"); diff --git a/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java b/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java index c2dfc35dce8d..657597bc23f9 100644 --- a/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java +++ b/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 8d3e8ca3a2d534f6ee872bb6a65a89c44e987cf6 Mon Sep 17 00:00:00 2001 From: Daniel Knittl-Frank Date: Wed, 23 Dec 2020 21:53:08 +0100 Subject: [PATCH 023/735] Optimize allocation in StringUtils#cleanPath This commit applies several optimizations to StringUtils#cleanPath and related methods: * pre-size pathElements deque in StringUtils#cleanPath with pathElements.length elements, since this this is the maximum size and the most likely case. * optimize StringUtils#collectionToDelimitedString to calculate the size of the resulting String and avoid array auto-resizing in the StringBuilder. * If the path did not contain any components that required cleaning, return the (normalized) path as-is. No need to concatenate the prefix and the trailing path. See gh-26316 --- .../org/springframework/util/StringUtils.java | 44 +++++++++++++++++-- .../util/StringUtilsTests.java | 2 + 2 files changed, 42 insertions(+), 4 deletions(-) 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 edbbaea91d45..e320e9bd4c5a 100644 --- a/spring-core/src/main/java/org/springframework/util/StringUtils.java +++ b/spring-core/src/main/java/org/springframework/util/StringUtils.java @@ -667,7 +667,9 @@ public static String cleanPath(String path) { if (!hasLength(path)) { return path; } - String pathToUse = replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR); + + String normalizedPath = replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR); + String pathToUse = normalizedPath; // Shortcut if there is no work to do if (pathToUse.indexOf('.') == -1) { @@ -695,7 +697,8 @@ public static String cleanPath(String path) { } String[] pathArray = delimitedListToStringArray(pathToUse, FOLDER_SEPARATOR); - Deque pathElements = new ArrayDeque<>(); + // we never require more elements than pathArray and in the common case the same number + Deque pathElements = new ArrayDeque<>(pathArray.length); int tops = 0; for (int i = pathArray.length - 1; i >= 0; i--) { @@ -721,7 +724,7 @@ else if (TOP_PATH.equals(element)) { // All path elements stayed the same - shortcut if (pathArray.length == pathElements.size()) { - return prefix + pathToUse; + return normalizedPath; } // Remaining top paths need to be retained. for (int i = 0; i < tops; i++) { @@ -732,7 +735,40 @@ else if (TOP_PATH.equals(element)) { pathElements.addFirst(CURRENT_PATH); } - return prefix + collectionToDelimitedString(pathElements, FOLDER_SEPARATOR); + final String joined = joinStrings(pathElements, FOLDER_SEPARATOR); + // avoid string concatenation with empty prefix + return prefix.isEmpty() ? joined : prefix + joined; + } + + /** + * Convert a {@link Collection Collection<String>} to a delimited {@code String} (e.g. CSV). + *

This is an optimized variant of {@link #collectionToDelimitedString(Collection, String)}, which does not + * require dynamic resizing of the StringBuilder's backing array. + * @param coll the {@code Collection Collection<String>} to convert (potentially {@code null} or empty) + * @param delim the delimiter to use (typically a ",") + * @return the delimited {@code String} + */ + private static String joinStrings(@Nullable Collection coll, String delim) { + + if (CollectionUtils.isEmpty(coll)) { + return ""; + } + + // precompute total length of resulting string + int totalLength = (coll.size() - 1) * delim.length(); + for (String str : coll) { + totalLength += str.length(); + } + + StringBuilder sb = new StringBuilder(totalLength); + Iterator it = coll.iterator(); + while (it.hasNext()) { + sb.append(it.next()); + if (it.hasNext()) { + sb.append(delim); + } + } + return sb.toString(); } /** diff --git a/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java b/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java index 9d81c82d5f1c..2aae6260dd0e 100644 --- a/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java @@ -402,6 +402,8 @@ void cleanPath() { assertThat(StringUtils.cleanPath("file:.././")).isEqualTo("file:../"); assertThat(StringUtils.cleanPath("file:/mypath/spring.factories")).isEqualTo("file:/mypath/spring.factories"); assertThat(StringUtils.cleanPath("file:///c:/some/../path/the%20file.txt")).isEqualTo("file:///c:/path/the%20file.txt"); + assertThat(StringUtils.cleanPath("jar:file:///c:\\some\\..\\path\\.\\the%20file.txt")).isEqualTo("jar:file:///c:/path/the%20file.txt"); + assertThat(StringUtils.cleanPath("jar:file:///c:/some/../path/./the%20file.txt")).isEqualTo("jar:file:///c:/path/the%20file.txt"); } @Test From cc026fcb8ae51172f3d063e7ed07a32927e23d8e Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 30 Aug 2021 17:58:12 +0200 Subject: [PATCH 024/735] Polish "Optimize allocation in StringUtils#cleanPath" This commit also introduces JMH benchmarks related to the code optimizations. Closes gh-2631 --- .../util/StringUtilsBenchmark.java | 116 ++++++++++++++++++ .../org/springframework/util/StringUtils.java | 40 ++---- 2 files changed, 123 insertions(+), 33 deletions(-) create mode 100644 spring-core/src/jmh/java/org/springframework/util/StringUtilsBenchmark.java diff --git a/spring-core/src/jmh/java/org/springframework/util/StringUtilsBenchmark.java b/spring-core/src/jmh/java/org/springframework/util/StringUtilsBenchmark.java new file mode 100644 index 000000000000..1fc7753b2218 --- /dev/null +++ b/spring-core/src/jmh/java/org/springframework/util/StringUtilsBenchmark.java @@ -0,0 +1,116 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Random; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.infra.Blackhole; + +/** + * Benchmarks for {@link StringUtils}. + * + * @author Brian Clozel + */ +@BenchmarkMode(Mode.Throughput) +public class StringUtilsBenchmark { + + @Benchmark + public void collectionToDelimitedString(DelimitedStringState state, Blackhole bh) { + bh.consume(StringUtils.collectionToCommaDelimitedString(state.elements)); + } + + @State(Scope.Benchmark) + public static class DelimitedStringState { + + @Param("10") + int elementMinSize; + + @Param("20") + int elementMaxSize; + + @Param("10") + int elementCount; + + Collection elements; + + @Setup(Level.Iteration) + public void setup() { + Random random = new Random(); + this.elements = new ArrayList<>(this.elementCount); + int bound = this.elementMaxSize - this.elementMinSize; + for (int i = 0; i < this.elementCount; i++) { + this.elements.add(String.format("%0" + (random.nextInt(bound) + this.elementMinSize) + "d", 1)); + } + } + } + + @Benchmark + public void cleanPath(CleanPathState state, Blackhole bh) { + for (String path : state.paths) { + bh.consume(StringUtils.cleanPath(path)); + } + } + + @State(Scope.Benchmark) + public static class CleanPathState { + + private static final List SEGMENTS = Arrays.asList("some", "path", ".", "..", "springspring"); + + @Param("10") + int segmentCount; + + @Param("20") + int pathsCount; + + Collection paths; + + @Setup(Level.Iteration) + public void setup() { + this.paths = new ArrayList<>(this.pathsCount); + Random random = new Random(); + for (int i = 0; i < this.pathsCount; i++) { + this.paths.add(createSamplePath(random)); + } + } + + private String createSamplePath(Random random) { + String separator = random.nextBoolean() ? "/" : "\\"; + StringBuilder sb = new StringBuilder(); + sb.append("jar:file:///c:"); + for (int i = 0; i < this.segmentCount; i++) { + sb.append(separator); + sb.append(SEGMENTS.get(random.nextInt(SEGMENTS.size()))); + } + sb.append(separator); + sb.append("the%20file.txt"); + return sb.toString(); + } + + } +} 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 e320e9bd4c5a..80a996d481fb 100644 --- a/spring-core/src/main/java/org/springframework/util/StringUtils.java +++ b/spring-core/src/main/java/org/springframework/util/StringUtils.java @@ -735,42 +735,11 @@ else if (TOP_PATH.equals(element)) { pathElements.addFirst(CURRENT_PATH); } - final String joined = joinStrings(pathElements, FOLDER_SEPARATOR); + final String joined = collectionToDelimitedString(pathElements, FOLDER_SEPARATOR); // avoid string concatenation with empty prefix return prefix.isEmpty() ? joined : prefix + joined; } - /** - * Convert a {@link Collection Collection<String>} to a delimited {@code String} (e.g. CSV). - *

This is an optimized variant of {@link #collectionToDelimitedString(Collection, String)}, which does not - * require dynamic resizing of the StringBuilder's backing array. - * @param coll the {@code Collection Collection<String>} to convert (potentially {@code null} or empty) - * @param delim the delimiter to use (typically a ",") - * @return the delimited {@code String} - */ - private static String joinStrings(@Nullable Collection coll, String delim) { - - if (CollectionUtils.isEmpty(coll)) { - return ""; - } - - // precompute total length of resulting string - int totalLength = (coll.size() - 1) * delim.length(); - for (String str : coll) { - totalLength += str.length(); - } - - StringBuilder sb = new StringBuilder(totalLength); - Iterator it = coll.iterator(); - while (it.hasNext()) { - sb.append(it.next()); - if (it.hasNext()) { - sb.append(delim); - } - } - return sb.toString(); - } - /** * Compare two paths after normalization of them. * @param path1 first path for comparison @@ -1330,7 +1299,12 @@ public static String collectionToDelimitedString( return ""; } - StringBuilder sb = new StringBuilder(); + int totalLength = coll.size() * (prefix.length() + suffix.length()) + (coll.size() - 1) * delim.length(); + for (Object element : coll) { + totalLength += element.toString().length(); + } + + StringBuilder sb = new StringBuilder(totalLength); Iterator it = coll.iterator(); while (it.hasNext()) { sb.append(prefix).append(it.next()).append(suffix); From e5a5f8b20b00a896bb1edad5fbc13f982cd0e6ca Mon Sep 17 00:00:00 2001 From: Georgi Ushev Date: Tue, 31 Aug 2021 10:37:29 +0300 Subject: [PATCH 025/735] Remove unnecessary brace in websocket documenation Closes gh-#27339 --- src/docs/asciidoc/web/websocket.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/asciidoc/web/websocket.adoc b/src/docs/asciidoc/web/websocket.adoc index 272e4669cc07..080a75e0ab3f 100644 --- a/src/docs/asciidoc/web/websocket.adoc +++ b/src/docs/asciidoc/web/websocket.adoc @@ -1177,7 +1177,7 @@ We can trace the flow through a simple example. Consider the following example, @Controller public class GreetingController { - @MessageMapping("/greeting") { + @MessageMapping("/greeting") public String handle(String greeting) { return "[" + getTimestamp() + ": " + greeting; } From 871e378ed054d95f19bcb75fa0f01e202e83f367 Mon Sep 17 00:00:00 2001 From: Inmord <53592130+Inmord@users.noreply.github.com> Date: Tue, 31 Aug 2021 15:40:28 +0800 Subject: [PATCH 026/735] Polish AbstractAspectJAdvisorFactory Closes gh-27340 --- .../aspectj/annotation/AbstractAspectJAdvisorFactory.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java index e76156bf8265..78573e429d9a 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java @@ -103,10 +103,11 @@ private boolean compiledByAjc(Class clazz) { @Override public void validate(Class aspectClass) throws AopConfigException { // If the parent has the annotation and isn't abstract it's an error - if (aspectClass.getSuperclass().getAnnotation(Aspect.class) != null && - !Modifier.isAbstract(aspectClass.getSuperclass().getModifiers())) { + Class superclass = aspectClass.getSuperclass(); + if (superclass.getAnnotation(Aspect.class) != null && + !Modifier.isAbstract(superclass.getModifiers())) { throw new AopConfigException("[" + aspectClass.getName() + "] cannot extend concrete aspect [" + - aspectClass.getSuperclass().getName() + "]"); + superclass.getName() + "]"); } AjType ajType = AjTypeSystem.getAjType(aspectClass); From 88af24c1cb5cb0325c2322e0efdc109e4eceb487 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 31 Aug 2021 09:46:10 +0200 Subject: [PATCH 027/735] Update copyright date --- .../aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java index 78573e429d9a..58f3c23b459f 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 310bdbb1b204bcb1e4b241d73b81df9bc153e9ac Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 1 Sep 2021 10:34:16 +0200 Subject: [PATCH 028/735] Fix error in ApplicationEvents example --- src/docs/asciidoc/testing.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/asciidoc/testing.adoc b/src/docs/asciidoc/testing.adoc index bc3af10d0891..64f07918d46e 100644 --- a/src/docs/asciidoc/testing.adoc +++ b/src/docs/asciidoc/testing.adoc @@ -2613,7 +2613,7 @@ published while invoking a method in a Spring-managed component: // Invoke method in OrderService that publishes an event orderService.submitOrder(new Order(/* ... */)); // Verify that an OrderSubmitted event was published - int numEvents = events.stream(OrderSubmitted.class).count(); // <3> + long numEvents = events.stream(OrderSubmitted.class).count(); // <3> assertThat(numEvents).isEqualTo(1); } } From 164dcef6ae3ca05e03c828cbdc0bfd97b8043bd0 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 2 Sep 2021 22:19:57 +0200 Subject: [PATCH 029/735] Tracking ASM master See gh-27069 --- .../springframework/asm/AnnotationVisitor.java | 12 ++++++------ .../java/org/springframework/asm/ByteVector.java | 3 +++ .../org/springframework/asm/ClassVisitor.java | 13 ++++++------- .../org/springframework/asm/FieldVisitor.java | 15 ++++++--------- .../org/springframework/asm/MethodVisitor.java | 12 ++++++------ 5 files changed, 27 insertions(+), 28 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java b/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java index 51357068800b..c3c236aefabb 100644 --- a/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java @@ -38,8 +38,8 @@ public abstract class AnnotationVisitor { /** - * The ASM API version implemented by this visitor. The value of this field must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. + * The ASM API version implemented by this visitor. The value of this field must be one of the + * {@code ASM}x values in {@link Opcodes}. */ protected final int api; @@ -52,8 +52,8 @@ public abstract class AnnotationVisitor { /** * Constructs a new {@link AnnotationVisitor}. * - * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. + * @param api the ASM API version implemented by this visitor. Must be one of the {@code + * ASM}x values in {@link Opcodes}. */ public AnnotationVisitor(final int api) { this(api, null); @@ -62,8 +62,8 @@ public AnnotationVisitor(final int api) { /** * Constructs a new {@link AnnotationVisitor}. * - * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. + * @param api the ASM API version implemented by this visitor. Must be one of the {@code + * ASM}x values in {@link Opcodes}. * @param annotationVisitor the annotation visitor to which this visitor must delegate method * calls. May be {@literal null}. */ diff --git a/spring-core/src/main/java/org/springframework/asm/ByteVector.java b/spring-core/src/main/java/org/springframework/asm/ByteVector.java index 3789eec3fd6d..6187c1e22c7d 100644 --- a/spring-core/src/main/java/org/springframework/asm/ByteVector.java +++ b/spring-core/src/main/java/org/springframework/asm/ByteVector.java @@ -352,6 +352,9 @@ public ByteVector putByteArray( * @param size number of additional bytes that this byte vector should be able to receive. */ private void enlarge(final int size) { + if (length > data.length) { + throw new AssertionError("Internal error"); + } int doubleCapacity = 2 * data.length; int minimalCapacity = length + size; byte[] newData = new byte[doubleCapacity > minimalCapacity ? doubleCapacity : minimalCapacity]; diff --git a/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java b/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java index b49c3eebce5e..05b448321afc 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java @@ -40,8 +40,8 @@ public abstract class ClassVisitor { /** - * The ASM API version implemented by this visitor. The value of this field must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. + * The ASM API version implemented by this visitor. The value of this field must be one of the + * {@code ASM}x values in {@link Opcodes}. */ protected final int api; @@ -51,8 +51,8 @@ public abstract class ClassVisitor { /** * Constructs a new {@link ClassVisitor}. * - * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. + * @param api the ASM API version implemented by this visitor. Must be one of the {@code + * ASM}x values in {@link Opcodes}. */ public ClassVisitor(final int api) { this(api, null); @@ -61,9 +61,8 @@ public ClassVisitor(final int api) { /** * Constructs a new {@link ClassVisitor}. * - * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link - * Opcodes#ASM8} or {@link Opcodes#ASM9}. + * @param api the ASM API version implemented by this visitor. Must be one of the {@code + * ASM}x values in {@link Opcodes}. * @param classVisitor the class visitor to which this visitor must delegate method calls. May be * null. */ diff --git a/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java b/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java index 841b4a3cb78f..727417045faa 100644 --- a/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java @@ -37,9 +37,8 @@ public abstract class FieldVisitor { /** - * The ASM API version implemented by this visitor. The value of this field must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link - * Opcodes#ASM8} or {@link Opcodes#ASM9}. + * The ASM API version implemented by this visitor. The value of this field must be one of the + * {@code ASM}x values in {@link Opcodes}. */ protected final int api; @@ -49,9 +48,8 @@ public abstract class FieldVisitor { /** * Constructs a new {@link FieldVisitor}. * - * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link - * Opcodes#ASM8} or {@link Opcodes#ASM9}. + * @param api the ASM API version implemented by this visitor. Must be one of the {@code + * ASM}x values in {@link Opcodes}. */ public FieldVisitor(final int api) { this(api, null); @@ -60,9 +58,8 @@ public FieldVisitor(final int api) { /** * Constructs a new {@link FieldVisitor}. * - * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link - * Opcodes#ASM8}. + * @param api the ASM API version implemented by this visitor. Must be one of the {@code + * ASM}x values in {@link Opcodes}. * @param fieldVisitor the field visitor to which this visitor must delegate method calls. May be * null. */ 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 ff5ce1056d27..15ca4a5e4eb3 100644 --- a/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java @@ -51,8 +51,8 @@ public abstract class MethodVisitor { private static final String REQUIRES_ASM5 = "This feature requires ASM5"; /** - * The ASM API version implemented by this visitor. The value of this field must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. + * The ASM API version implemented by this visitor. The value of this field must be one of the + * {@code ASM}x values in {@link Opcodes}. */ protected final int api; @@ -64,8 +64,8 @@ public abstract class MethodVisitor { /** * Constructs a new {@link MethodVisitor}. * - * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. + * @param api the ASM API version implemented by this visitor. Must be one of the {@code + * ASM}x values in {@link Opcodes}. */ public MethodVisitor(final int api) { this(api, null); @@ -74,8 +74,8 @@ public MethodVisitor(final int api) { /** * Constructs a new {@link MethodVisitor}. * - * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. + * @param api the ASM API version implemented by this visitor. Must be one of the {@code + * ASM}x values in {@link Opcodes}. * @param methodVisitor the method visitor to which this visitor must delegate method calls. May * be null. */ From 837301fdb3a92b1e40535a404dbdbf57b01c3816 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 2 Sep 2021 22:20:52 +0200 Subject: [PATCH 030/735] Convenient configuration of type permissions for XStream 1.4.18 Closes gh-27343 --- .../oxm/xstream/XStreamMarshaller.java | 33 ++++++++++++++++--- .../oxm/xstream/XStreamMarshallerTests.java | 12 ++++--- .../oxm/xstream/XStreamUnmarshallerTests.java | 28 ++++++++++------ 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java index a992ab814188..ccb10d27c172 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,6 +63,8 @@ import com.thoughtworks.xstream.mapper.CannotResolveClassException; import com.thoughtworks.xstream.mapper.Mapper; import com.thoughtworks.xstream.mapper.MapperWrapper; +import com.thoughtworks.xstream.security.ForbiddenClassException; +import com.thoughtworks.xstream.security.TypePermission; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -106,7 +108,7 @@ * Therefore, it has limited namespace support. As such, it is rather unsuitable for * usage within Web Services. * - *

This marshaller requires XStream 1.4.5 or higher, as of Spring 4.3. + *

This marshaller requires XStream 1.4.7 or higher, as of Spring 5.2.17. * Note that {@link XStream} construction has been reworked in 4.0, with the * stream driver and the class loader getting passed into XStream itself now. * @@ -146,6 +148,9 @@ public class XStreamMarshaller extends AbstractMarshaller implements BeanClassLo @Nullable private ConverterMatcher[] converters; + @Nullable + private TypePermission[] typePermissions; + @Nullable private MarshallingStrategy marshallingStrategy; @@ -268,6 +273,20 @@ public void setConverters(ConverterMatcher... converters) { this.converters = converters; } + /** + * Set XStream type permissions such as + * {@link com.thoughtworks.xstream.security.AnyTypePermission}, + * {@link com.thoughtworks.xstream.security.ExplicitTypePermission} etc, + * as an alternative to overriding the {@link #customizeXStream} method. + *

Note: As of XStream 1.4.18, the default type permissions are + * restricted to well-known core JDK types. For any custom types, + * explicit type permissions need to be registered. + * @since 5.2.17 + */ + public void setTypePermissions(TypePermission... typePermissions) { + this.typePermissions = typePermissions; + } + /** * Set a custom XStream {@link MarshallingStrategy} to use. * @since 4.0 @@ -407,7 +426,7 @@ public void setBeanClassLoader(ClassLoader classLoader) { @Override public void afterPropertiesSet() { - // no-op due to use of SingletonSupplier for the XStream field. + // no-op due to use of SingletonSupplier for the XStream field } /** @@ -479,6 +498,12 @@ else if (this.converters[i] instanceof SingleValueConverter) { } } + if (this.typePermissions != null) { + for (TypePermission permission : this.typePermissions) { + xstream.addPermission(permission); + } + } + if (this.marshallingStrategy != null) { xstream.setMarshallingStrategy(this.marshallingStrategy); } @@ -844,7 +869,7 @@ private Object doUnmarshal(HierarchicalStreamReader streamReader, @Nullable Data */ protected XmlMappingException convertXStreamException(Exception ex, boolean marshalling) { if (ex instanceof StreamException || ex instanceof CannotResolveClassException || - ex instanceof ConversionException) { + ex instanceof ForbiddenClassException || ex instanceof ConversionException) { if (marshalling) { return new MarshallingFailureException("XStream marshalling exception", ex); } diff --git a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java index 5f05936d751a..304d3fcc771b 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,6 +43,7 @@ import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver; import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver; import com.thoughtworks.xstream.io.json.JsonWriter; +import com.thoughtworks.xstream.security.AnyTypePermission; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InOrder; @@ -67,18 +68,21 @@ /** * @author Arjen Poutsma * @author Sam Brannen + * @author Juergen Hoeller */ class XStreamMarshallerTests { private static final String EXPECTED_STRING = "42"; - private final XStreamMarshaller marshaller = new XStreamMarshaller(); - private final Flight flight = new Flight(); + private XStreamMarshaller marshaller; + @BeforeEach void createMarshaller() { + marshaller = new XStreamMarshaller(); + marshaller.setTypePermissions(AnyTypePermission.ANY); marshaller.setAliases(Collections.singletonMap("flight", Flight.class.getName())); flight.setFlightNumber(42L); } @@ -143,7 +147,7 @@ void marshalStreamResultOutputStream() throws Exception { ByteArrayOutputStream os = new ByteArrayOutputStream(); StreamResult result = new StreamResult(os); marshaller.marshal(flight, result); - String s = new String(os.toByteArray(), "UTF-8"); + String s = os.toString("UTF-8"); assertThat(XmlContent.of(s)).isSimilarTo(EXPECTED_STRING); } diff --git a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamUnmarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamUnmarshallerTests.java index 1c864545aa68..7c87eda2253b 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamUnmarshallerTests.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamUnmarshallerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.io.ByteArrayInputStream; import java.io.StringReader; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; @@ -29,6 +30,7 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamSource; +import com.thoughtworks.xstream.security.AnyTypePermission; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.w3c.dom.Document; @@ -40,6 +42,7 @@ /** * @author Arjen Poutsma + * @author Juergen Hoeller */ public class XStreamUnmarshallerTests { @@ -47,21 +50,16 @@ public class XStreamUnmarshallerTests { private XStreamMarshaller unmarshaller; + @BeforeEach - public void createUnmarshaller() throws Exception { + public void createUnmarshaller() { unmarshaller = new XStreamMarshaller(); + unmarshaller.setTypePermissions(AnyTypePermission.ANY); Map> aliases = new HashMap<>(); aliases.put("flight", Flight.class); unmarshaller.setAliases(aliases); } - private void testFlight(Object o) { - boolean condition = o instanceof Flight; - assertThat(condition).as("Unmarshalled object is not Flights").isTrue(); - Flight flight = (Flight) o; - assertThat(flight).as("Flight is null").isNotNull(); - assertThat(flight.getFlightNumber()).as("Number is invalid").isEqualTo(42L); - } @Test public void unmarshalDomSource() throws Exception { @@ -83,7 +81,7 @@ public void unmarshalStaxSourceXmlStreamReader() throws Exception { @Test public void unmarshalStreamSourceInputStream() throws Exception { - StreamSource source = new StreamSource(new ByteArrayInputStream(INPUT_STRING.getBytes("UTF-8"))); + StreamSource source = new StreamSource(new ByteArrayInputStream(INPUT_STRING.getBytes(StandardCharsets.UTF_8))); Object flights = unmarshaller.unmarshal(source); testFlight(flights); } @@ -94,5 +92,15 @@ public void unmarshalStreamSourceReader() throws Exception { Object flights = unmarshaller.unmarshal(source); testFlight(flights); } + + + private void testFlight(Object o) { + boolean condition = o instanceof Flight; + assertThat(condition).as("Unmarshalled object is not Flights").isTrue(); + Flight flight = (Flight) o; + assertThat(flight).as("Flight is null").isNotNull(); + assertThat(flight.getFlightNumber()).as("Number is invalid").isEqualTo(42L); + } + } From b6c2c11805993a7d0b6e2520ee205fbb54ad215f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 2 Sep 2021 22:21:27 +0200 Subject: [PATCH 031/735] Polishing --- .../beans/factory/config/ConstructorArgumentValues.java | 6 ++++-- .../org/springframework/web/servlet/FrameworkServlet.java | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java index 4fbfb435875d..c4d779e697b8 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -351,7 +351,9 @@ public ValueHolder getArgumentValue(int index, Class requiredType, String req * @return the ValueHolder for the argument, or {@code null} if none set */ @Nullable - public ValueHolder getArgumentValue(int index, @Nullable Class requiredType, @Nullable String requiredName, @Nullable Set usedValueHolders) { + public ValueHolder getArgumentValue(int index, @Nullable Class requiredType, + @Nullable String requiredName, @Nullable Set usedValueHolders) { + Assert.isTrue(index >= 0, "Index must not be negative"); ValueHolder valueHolder = getIndexedArgumentValue(index, requiredType, requiredName); if (valueHolder == null) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java index 6d3e8d3d2b45..40e1d1030e91 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java @@ -1085,7 +1085,7 @@ private void logResult(HttpServletRequest request, HttpServletResponse response, } DispatcherType dispatchType = request.getDispatcherType(); - boolean initialDispatch = DispatcherType.REQUEST == dispatchType; + boolean initialDispatch = (dispatchType == DispatcherType.REQUEST); if (failureCause != null) { if (!initialDispatch) { @@ -1109,7 +1109,7 @@ else if (logger.isTraceEnabled()) { } int status = response.getStatus(); - String headers = ""; // nothing below trace + String headers = ""; // nothing below trace if (logger.isTraceEnabled()) { Collection names = response.getHeaderNames(); From 2f60392fe347066b6bacab00b4ff0437a00203b4 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 2 Sep 2021 22:22:37 +0200 Subject: [PATCH 032/735] Upgrade to Netty 4.1.67, RxJava 3.1.1, Gson 2.8.8, XStream 1.4.18 --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 7f41d37257b9..69b6cf85bb30 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ configure(allprojects) { project -> dependencyManagement { imports { mavenBom "com.fasterxml.jackson:jackson-bom:2.12.4" - mavenBom "io.netty:netty-bom:4.1.66.Final" + mavenBom "io.netty:netty-bom:4.1.67.Final" mavenBom "io.projectreactor:reactor-bom:2020.0.10" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" mavenBom "io.rsocket:rsocket-bom:1.1.1" @@ -67,7 +67,7 @@ configure(allprojects) { project -> dependency "io.reactivex:rxjava:1.3.8" dependency "io.reactivex:rxjava-reactive-streams:1.2.1" dependency "io.reactivex.rxjava2:rxjava:2.2.21" - dependency "io.reactivex.rxjava3:rxjava:3.1.0" + dependency "io.reactivex.rxjava3:rxjava:3.1.1" dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE" dependency "com.caucho:hessian:4.0.63" @@ -75,10 +75,10 @@ configure(allprojects) { project -> dependency("com.fasterxml.woodstox:woodstox-core:6.2.6") { exclude group: "stax", name: "stax-api" } - dependency "com.google.code.gson:gson:2.8.7" + dependency "com.google.code.gson:gson:2.8.8" dependency "com.google.protobuf:protobuf-java-util:3.17.3" dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4" - dependency("com.thoughtworks.xstream:xstream:1.4.17") { + dependency("com.thoughtworks.xstream:xstream:1.4.18") { exclude group: "xpp3", name: "xpp3_min" exclude group: "xmlpull", name: "xmlpull" } From b2eaa7c1c3025dddd197df62a46d80ee2a84b8dd Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 2 Sep 2021 22:59:33 +0200 Subject: [PATCH 033/735] Polishing --- .../beans/BeanWrapperAutoGrowingTests.java | 2 +- .../beans/BeanWrapperGenericsTests.java | 52 ++++++++----------- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/spring-beans/src/test/java/org/springframework/beans/BeanWrapperAutoGrowingTests.java b/spring-beans/src/test/java/org/springframework/beans/BeanWrapperAutoGrowingTests.java index 2dddf884e319..78524e632b0c 100644 --- a/spring-beans/src/test/java/org/springframework/beans/BeanWrapperAutoGrowingTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/BeanWrapperAutoGrowingTests.java @@ -38,7 +38,7 @@ public class BeanWrapperAutoGrowingTests { @BeforeEach - public void setUp() { + public void setup() { wrapper.setAutoGrowNestedPaths(true); } diff --git a/spring-beans/src/test/java/org/springframework/beans/BeanWrapperGenericsTests.java b/spring-beans/src/test/java/org/springframework/beans/BeanWrapperGenericsTests.java index f5fef0b04a84..760e98cf9351 100644 --- a/spring-beans/src/test/java/org/springframework/beans/BeanWrapperGenericsTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/BeanWrapperGenericsTests.java @@ -16,7 +16,6 @@ package org.springframework.beans; -import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -85,7 +84,7 @@ void testGenericSetWithConversionFailure() { } @Test - void testGenericList() throws MalformedURLException { + void testGenericList() throws Exception { GenericBean gb = new GenericBean<>(); BeanWrapper bw = new BeanWrapperImpl(gb); List input = new ArrayList<>(); @@ -97,7 +96,7 @@ void testGenericList() throws MalformedURLException { } @Test - void testGenericListElement() throws MalformedURLException { + void testGenericListElement() throws Exception { GenericBean gb = new GenericBean<>(); gb.setResourceList(new ArrayList<>()); BeanWrapper bw = new BeanWrapperImpl(gb); @@ -162,10 +161,8 @@ void testGenericMapWithCollectionValue() { value2.add(Boolean.TRUE); input.put("2", value2); bw.setPropertyValue("collectionMap", input); - boolean condition1 = gb.getCollectionMap().get(1) instanceof HashSet; - assertThat(condition1).isTrue(); - boolean condition = gb.getCollectionMap().get(2) instanceof ArrayList; - assertThat(condition).isTrue(); + assertThat(gb.getCollectionMap().get(1) instanceof HashSet).isTrue(); + assertThat(gb.getCollectionMap().get(2) instanceof ArrayList).isTrue(); } @Test @@ -177,8 +174,7 @@ void testGenericMapElementWithCollectionValue() { HashSet value1 = new HashSet<>(); value1.add(1); bw.setPropertyValue("collectionMap[1]", value1); - boolean condition = gb.getCollectionMap().get(1) instanceof HashSet; - assertThat(condition).isTrue(); + assertThat(gb.getCollectionMap().get(1) instanceof HashSet).isTrue(); } @Test @@ -194,7 +190,7 @@ void testGenericMapFromProperties() { } @Test - void testGenericListOfLists() throws MalformedURLException { + void testGenericListOfLists() { GenericBean gb = new GenericBean<>(); List> list = new ArrayList<>(); list.add(new ArrayList<>()); @@ -206,7 +202,7 @@ void testGenericListOfLists() throws MalformedURLException { } @Test - void testGenericListOfListsWithElementConversion() throws MalformedURLException { + void testGenericListOfListsWithElementConversion() { GenericBean gb = new GenericBean<>(); List> list = new ArrayList<>(); list.add(new ArrayList<>()); @@ -218,7 +214,7 @@ void testGenericListOfListsWithElementConversion() throws MalformedURLException } @Test - void testGenericListOfArrays() throws MalformedURLException { + void testGenericListOfArrays() { GenericBean gb = new GenericBean<>(); ArrayList list = new ArrayList<>(); list.add(new String[] {"str1", "str2"}); @@ -230,7 +226,7 @@ void testGenericListOfArrays() throws MalformedURLException { } @Test - void testGenericListOfArraysWithElementConversion() throws MalformedURLException { + void testGenericListOfArraysWithElementConversion() { GenericBean gb = new GenericBean<>(); ArrayList list = new ArrayList<>(); list.add(new String[] {"str1", "str2"}); @@ -243,7 +239,7 @@ void testGenericListOfArraysWithElementConversion() throws MalformedURLException } @Test - void testGenericListOfMaps() throws MalformedURLException { + void testGenericListOfMaps() { GenericBean gb = new GenericBean<>(); List> list = new ArrayList<>(); list.add(new HashMap<>()); @@ -267,7 +263,7 @@ void testGenericListOfMapsWithElementConversion() { } @Test - void testGenericMapOfMaps() throws MalformedURLException { + void testGenericMapOfMaps() { GenericBean gb = new GenericBean<>(); Map> map = new HashMap<>(); map.put("mykey", new HashMap<>()); @@ -279,7 +275,7 @@ void testGenericMapOfMaps() throws MalformedURLException { } @Test - void testGenericMapOfMapsWithElementConversion() throws MalformedURLException { + void testGenericMapOfMapsWithElementConversion() { GenericBean gb = new GenericBean<>(); Map> map = new HashMap<>(); map.put("mykey", new HashMap<>()); @@ -291,7 +287,7 @@ void testGenericMapOfMapsWithElementConversion() throws MalformedURLException { } @Test - void testGenericMapOfLists() throws MalformedURLException { + void testGenericMapOfLists() { GenericBean gb = new GenericBean<>(); Map> map = new HashMap<>(); map.put(1, new ArrayList<>()); @@ -303,7 +299,7 @@ void testGenericMapOfLists() throws MalformedURLException { } @Test - void testGenericMapOfListsWithElementConversion() throws MalformedURLException { + void testGenericMapOfListsWithElementConversion() { GenericBean gb = new GenericBean<>(); Map> map = new HashMap<>(); map.put(1, new ArrayList<>()); @@ -315,7 +311,7 @@ void testGenericMapOfListsWithElementConversion() throws MalformedURLException { } @Test - void testGenericTypeNestingMapOfInteger() throws Exception { + void testGenericTypeNestingMapOfInteger() { Map map = new HashMap<>(); map.put("testKey", "100"); @@ -324,12 +320,11 @@ void testGenericTypeNestingMapOfInteger() throws Exception { bw.setPropertyValue("mapOfInteger", map); Object obj = gb.getMapOfInteger().get("testKey"); - boolean condition = obj instanceof Integer; - assertThat(condition).isTrue(); + assertThat(obj instanceof Integer).isTrue(); } @Test - void testGenericTypeNestingMapOfListOfInteger() throws Exception { + void testGenericTypeNestingMapOfListOfInteger() { Map> map = new HashMap<>(); List list = Arrays.asList("1", "2", "3"); map.put("testKey", list); @@ -339,13 +334,12 @@ void testGenericTypeNestingMapOfListOfInteger() throws Exception { bw.setPropertyValue("mapOfListOfInteger", map); Object obj = gb.getMapOfListOfInteger().get("testKey").get(0); - boolean condition = obj instanceof Integer; - assertThat(condition).isTrue(); + assertThat(obj instanceof Integer).isTrue(); assertThat(((Integer) obj).intValue()).isEqualTo(1); } @Test - void testGenericTypeNestingListOfMapOfInteger() throws Exception { + void testGenericTypeNestingListOfMapOfInteger() { List> list = new ArrayList<>(); Map map = new HashMap<>(); map.put("testKey", "5"); @@ -356,13 +350,12 @@ void testGenericTypeNestingListOfMapOfInteger() throws Exception { bw.setPropertyValue("listOfMapOfInteger", list); Object obj = gb.getListOfMapOfInteger().get(0).get("testKey"); - boolean condition = obj instanceof Integer; - assertThat(condition).isTrue(); + assertThat(obj instanceof Integer).isTrue(); assertThat(((Integer) obj).intValue()).isEqualTo(5); } @Test - void testGenericTypeNestingMapOfListOfListOfInteger() throws Exception { + void testGenericTypeNestingMapOfListOfListOfInteger() { Map>> map = new HashMap<>(); List list = Arrays.asList("1", "2", "3"); map.put("testKey", Collections.singletonList(list)); @@ -372,8 +365,7 @@ void testGenericTypeNestingMapOfListOfListOfInteger() throws Exception { bw.setPropertyValue("mapOfListOfListOfInteger", map); Object obj = gb.getMapOfListOfListOfInteger().get("testKey").get(0).get(0); - boolean condition = obj instanceof Integer; - assertThat(condition).isTrue(); + assertThat(obj instanceof Integer).isTrue(); assertThat(((Integer) obj).intValue()).isEqualTo(1); } From 434cbab6a7147ebb7f51078cb14422fe26f1798a Mon Sep 17 00:00:00 2001 From: Leeseojune Date: Fri, 3 Sep 2021 17:50:50 +0900 Subject: [PATCH 034/735] Update copyright date in tests in spring-test Closes gh-27354 --- .../org/springframework/test/web/servlet/StubMvcResult.java | 2 +- .../test/web/servlet/htmlunit/DelegatingWebConnectionTests.java | 2 +- .../test/web/servlet/htmlunit/UrlRegexRequestMatcherTests.java | 2 +- .../test/web/servlet/result/HeaderResultMatchersTests.java | 2 +- .../test/web/servlet/samples/context/PersonController.java | 2 +- .../test/web/servlet/samples/context/PersonDao.java | 2 +- .../resulthandlers/PrintingResultHandlerSmokeTests.java | 2 +- .../standalone/resultmatchers/FlashAttributeAssertionTests.java | 2 +- .../samples/standalone/resultmatchers/ModelAssertionTests.java | 2 +- .../resultmatchers/RequestAttributeAssertionTests.java | 2 +- .../resultmatchers/SessionAttributeAssertionTests.java | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/StubMvcResult.java b/spring-test/src/test/java/org/springframework/test/web/servlet/StubMvcResult.java index 12bde4ea41aa..f5c3bba6d6a7 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/StubMvcResult.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/StubMvcResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/DelegatingWebConnectionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/DelegatingWebConnectionTests.java index 1a093caf907f..05506cfbe3b2 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/DelegatingWebConnectionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/DelegatingWebConnectionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/UrlRegexRequestMatcherTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/UrlRegexRequestMatcherTests.java index ba7e3cda66c9..457e8fc4750d 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/UrlRegexRequestMatcherTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/UrlRegexRequestMatcherTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/result/HeaderResultMatchersTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/result/HeaderResultMatchersTests.java index 19d79f1f4c75..496e9e7834b8 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/result/HeaderResultMatchersTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/result/HeaderResultMatchersTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/PersonController.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/PersonController.java index 31781062ba63..0ef78f3a6d4f 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/PersonController.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/PersonController.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/PersonDao.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/PersonDao.java index 4001526e94c7..e06c983d720d 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/PersonDao.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/PersonDao.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resulthandlers/PrintingResultHandlerSmokeTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resulthandlers/PrintingResultHandlerSmokeTests.java index 7d23bebc0b56..1600c095263a 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resulthandlers/PrintingResultHandlerSmokeTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resulthandlers/PrintingResultHandlerSmokeTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/FlashAttributeAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/FlashAttributeAssertionTests.java index a6a5b7fc086b..0ffc879e9029 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/FlashAttributeAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/FlashAttributeAssertionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/ModelAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/ModelAssertionTests.java index 11473a31ab1f..a22b760bc82f 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/ModelAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/ModelAssertionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/RequestAttributeAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/RequestAttributeAssertionTests.java index 7f98ce330070..c28a9190c67b 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/RequestAttributeAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/RequestAttributeAssertionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/SessionAttributeAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/SessionAttributeAssertionTests.java index d60a4c1428b8..9479894033a4 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/SessionAttributeAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/SessionAttributeAssertionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From bec0bb0c53a4e2a3cee0c03b3bd274953c93e7ae Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 2 Sep 2021 20:12:41 +0100 Subject: [PATCH 035/735] Revert "Add doOnDiscard hook for streaming mode" This reverts commit 77a562dfee04cfb4a76a84257cf33fd73ab6b696. As per findings under https://github.com/reactor/reactor-netty/issues/1746 it looks this wasn't the issue and isn't required. --- .../http/codec/EncoderHttpMessageWriter.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java index cf1d14644673..3fe192077388 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java +++ b/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java @@ -141,18 +141,16 @@ public Mono write(Publisher inputStream, ResolvableType eleme } if (isStreamingMediaType(contentType)) { - return message - .writeAndFlushWith(body.map(buffer -> { - Hints.touchDataBuffer(buffer, hints, logger); - return Mono.just(buffer).doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release); - })) - .doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release); + return message.writeAndFlushWith(body.map(buffer -> { + Hints.touchDataBuffer(buffer, hints, logger); + return Mono.just(buffer).doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release); + })); } if (logger.isDebugEnabled()) { body = body.doOnNext(buffer -> Hints.touchDataBuffer(buffer, hints, logger)); } - return message.writeWith(body).doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release); + return message.writeWith(body); } @Nullable From b2a17a8d86a50dc8844edfa9b9c1dd3fc7519132 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 3 Sep 2021 18:44:42 +0200 Subject: [PATCH 036/735] Fix typo --- .../build/optional/OptionalDependenciesPlugin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java b/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java index 55537c2d8259..93ae77995d10 100644 --- a/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java +++ b/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ /** * A {@code Plugin} that adds support for Maven-style optional dependencies. Creates a new * {@code optional} configuration. The {@code optional} configuration is part of the - * project's compile and runtime classpath's but does not affect the classpath of + * project's compile and runtime classpaths but does not affect the classpath of * dependent projects. * * @author Andy Wilkinson From 9cf8cca96d9c8280eac87595a7933aa338ec5599 Mon Sep 17 00:00:00 2001 From: Manish Date: Sun, 5 Sep 2021 15:44:44 +0530 Subject: [PATCH 037/735] Minor language corrections. --- src/docs/asciidoc/integration.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index dae0ac82ac01..aa17752e28e5 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -7,8 +7,8 @@ :tabsize: 4 :docinfo1: -This part of the reference documentation covers the Spring Framework's integration with -a number technologies. +This part of the reference documentation covers Spring Framework's integration with +a number of technologies. [[rest-client-access]] @@ -63,7 +63,7 @@ overloaded methods: | `patchForObject` | Updates a resource by using PATCH and returns the representation from the response. -Note that the JDK `HttpURLConnection` does not support the `PATCH`, but Apache +Note that the JDK `HttpURLConnection` does not support `PATCH`, but Apache HttpComponents and others do. | `delete` From 5ea7592d7014c19140a867c9b57e8026653a80d3 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 6 Sep 2021 13:56:27 +0100 Subject: [PATCH 038/735] Polishing in ExchangeResult --- .../test/web/reactive/server/ExchangeResult.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java index 2359b1384738..27c93773bfa2 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java @@ -56,7 +56,7 @@ */ public class ExchangeResult { - private static Log logger = LogFactory.getLog(ExchangeResult.class); + private static final Log logger = LogFactory.getLog(ExchangeResult.class); private static final List PRINTABLE_MEDIA_TYPES = Arrays.asList( MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, @@ -77,7 +77,7 @@ public class ExchangeResult { private final String uriTemplate; @Nullable - final Object mockServerResult; + private final Object mockServerResult; /** @@ -218,9 +218,9 @@ public Object getMockServerResult() { } /** - * Execute the given Runnable, catch any {@link AssertionError}, decorate - * with {@code AssertionError} containing diagnostic information about the - * request and response, and then re-throw. + * Execute the given Runnable, catch any {@link AssertionError}, log details + * about the request and response at ERROR level under the class log + * category, and after that re-throw the error. */ public void assertWithDiagnostics(Runnable assertion) { try { From 1b3fd9edfffd78a90da820d04455acbdbc3d4661 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 6 Sep 2021 13:53:30 +0100 Subject: [PATCH 039/735] Ensure one time logging for request details Closes gh-26969 --- .../web/reactive/server/ExchangeResult.java | 7 ++++++- .../server/samples/SoftAssertionTests.java | 20 +++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java index 27c93773bfa2..e44c3b9f06c8 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java @@ -79,6 +79,9 @@ public class ExchangeResult { @Nullable private final Object mockServerResult; + /** Ensure single logging, e.g. for expectAll. */ + private boolean diagnosticsLogged; + /** * Create an instance with an HTTP request and response along with promises @@ -121,6 +124,7 @@ public class ExchangeResult { this.timeout = other.timeout; this.uriTemplate = other.uriTemplate; this.mockServerResult = other.mockServerResult; + this.diagnosticsLogged = other.diagnosticsLogged; } @@ -227,7 +231,8 @@ public void assertWithDiagnostics(Runnable assertion) { assertion.run(); } catch (AssertionError ex) { - if (logger.isErrorEnabled()) { + if (!this.diagnosticsLogged && logger.isErrorEnabled()) { + this.diagnosticsLogged = true; logger.error("Request details for assertion failure:\n" + this); } throw ex; diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/SoftAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/SoftAssertionTests.java index a4d4bb8c72fe..db7b242fffd9 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/SoftAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/SoftAssertionTests.java @@ -46,15 +46,19 @@ void expectAll() { } @Test - void expectAllWithMultipleFailures() throws Exception { - assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> - this.webTestClient.get().uri("/test").exchange() - .expectAll( - responseSpec -> responseSpec.expectStatus().isBadRequest(), - responseSpec -> responseSpec.expectStatus().isOk(), - responseSpec -> responseSpec.expectBody(String.class).isEqualTo("bogus") + void expectAllWithMultipleFailures() { + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(() -> + this.webTestClient.get().uri("/test").exchange() + .expectAll( + responseSpec -> responseSpec.expectStatus().isBadRequest(), + responseSpec -> responseSpec.expectStatus().isOk(), + responseSpec -> responseSpec.expectBody(String.class).isEqualTo("bogus") + ) ) - ).withMessage("Multiple Exceptions (2):\nStatus expected:<400 BAD_REQUEST> but was:<200 OK>\nResponse body expected: but was:"); + .withMessage("Multiple Exceptions (2):\n" + + "Status expected:<400 BAD_REQUEST> but was:<200 OK>\n" + + "Response body expected: but was:"); } From 87d3d1bbd1e5620fb8c2583c487507bab9614fb2 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 6 Sep 2021 16:52:23 +0200 Subject: [PATCH 040/735] Throw UnsupportedOperationException in defaultResponseCharacterEncoding() This commit updates the defaultResponseCharacterEncoding() `default` method in ConfigurableMockMvcBuilder so that it throws an UnsupportedOperationException instead of silently ignoring the user's request to set the default response character encoding. Note, however, that AbstractMockMvcBuilder already overrides the default method with a concrete implementation which is used by default in MockMvc. See gh-27230 --- .../web/servlet/setup/ConfigurableMockMvcBuilder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.java index 43ef6ca9547e..145dccc8a3aa 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.java @@ -86,14 +86,14 @@ public interface ConfigurableMockMvcBuilderThe default implementation of this method ignores the supplied value. - * Concrete implementations are therefore encouraged to override this method. + *

The default implementation of this method throws an + * {@link UnsupportedOperationException}. Concrete implementations are therefore + * encouraged to override this method. * @param defaultResponseCharacterEncoding the default response character encoding * @since 5.3.10 */ - @SuppressWarnings("unchecked") default T defaultResponseCharacterEncoding(Charset defaultResponseCharacterEncoding) { - return (T) this; + throw new UnsupportedOperationException(); } /** From d1a00b43019843c59a24b89ff97ed43d00768cf9 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 6 Sep 2021 16:58:32 +0200 Subject: [PATCH 041/735] Polishing See gh-27230 --- .../test/web/servlet/setup/ConfigurableMockMvcBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.java index 145dccc8a3aa..45b9f05d04a4 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.java @@ -93,7 +93,7 @@ public interface ConfigurableMockMvcBuilder T defaultResponseCharacterEncoding(Charset defaultResponseCharacterEncoding) { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("defaultResponseCharacterEncoding is not supported by this MockMvcBuilder"); } /** From 532b4b636d6b347df18f897aaa769aa734477f8b Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 6 Sep 2021 18:13:41 +0200 Subject: [PATCH 042/735] Update CI pipeline with JDK16 This commit replaces the JDK15 build with a JDK16 variant. This also updates the CI image with a new OS version and updated JDK versions. --- ci/images/ci-image/Dockerfile | 4 ++-- ci/images/get-jdk-url.sh | 8 ++++---- ci/images/setup.sh | 2 +- ci/pipeline.yml | 18 +++++++++--------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ci/images/ci-image/Dockerfile b/ci/images/ci-image/Dockerfile index 1ce41f37a932..df1be9f33457 100644 --- a/ci/images/ci-image/Dockerfile +++ b/ci/images/ci-image/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:focal-20210119 +FROM ubuntu:focal-20210827 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh @@ -6,6 +6,6 @@ RUN ./setup.sh java8 ENV JAVA_HOME /opt/openjdk/java8 ENV JDK11 /opt/openjdk/java11 -ENV JDK15 /opt/openjdk/java15 +ENV JDK16 /opt/openjdk/java16 ENV PATH $JAVA_HOME/bin:$PATH diff --git a/ci/images/get-jdk-url.sh b/ci/images/get-jdk-url.sh index f4f3ab84cf40..e170d55171c3 100755 --- a/ci/images/get-jdk-url.sh +++ b/ci/images/get-jdk-url.sh @@ -3,13 +3,13 @@ set -e case "$1" in java8) - echo "https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u282-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u282b08.tar.gz" + echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u302-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u302b08.tar.gz" ;; java11) - echo "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.10_9.tar.gz" + echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.12%2B7/OpenJDK11U-jdk_x64_linux_hotspot_11.0.12_7.tar.gz" ;; - java15) - echo "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.2%2B7/OpenJDK15U-jdk_x64_linux_hotspot_15.0.2_7.tar.gz" + java16) + echo "https://github.com/adoptium/temurin16-binaries/releases/download/jdk-16.0.2%2B7/OpenJDK16U-jdk_x64_linux_hotspot_16.0.2_7.tar.gz" ;; *) echo $"Unknown java version" diff --git a/ci/images/setup.sh b/ci/images/setup.sh index b226ab7de75c..ff18f849f40c 100755 --- a/ci/images/setup.sh +++ b/ci/images/setup.sh @@ -22,7 +22,7 @@ curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/ mkdir -p /opt/openjdk pushd /opt/openjdk > /dev/null -for jdk in java8 java11 java15 +for jdk in java8 java11 java16 do JDK_URL=$( /get-jdk-url.sh $jdk ) mkdir $jdk diff --git a/ci/pipeline.yml b/ci/pipeline.yml index eb752fe705cc..f919a1b681fc 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -45,7 +45,7 @@ resource_types: type: registry-image source: repository: springio/artifactory-resource - tag: 0.0.13 + tag: 0.0.17 - name: github-status-resource type: registry-image source: @@ -119,14 +119,14 @@ resources: access_token: ((github-ci-status-token)) branch: ((branch)) context: jdk11-build -- name: repo-status-jdk15-build +- name: repo-status-jdk16-build type: github-status-resource icon: eye-check-outline source: repository: ((github-repo-name)) access_token: ((github-ci-status-token)) branch: ((branch)) - context: jdk15-build + context: jdk16-build - name: slack-alert type: slack-notification icon: slack @@ -244,7 +244,7 @@ jobs: <<: *slack-fail-params - put: repo-status-jdk11-build params: { state: "success", commit: "git-repo" } -- name: jdk15-build +- name: jdk16-build serial: true public: true plan: @@ -252,7 +252,7 @@ jobs: - get: git-repo - get: every-morning trigger: true - - put: repo-status-jdk15-build + - put: repo-status-jdk16-build params: { state: "pending", commit: "git-repo" } - do: - task: check-project @@ -265,12 +265,12 @@ jobs: <<: *build-project-task-params on_failure: do: - - put: repo-status-jdk15-build + - put: repo-status-jdk16-build params: { state: "failure", commit: "git-repo" } - put: slack-alert params: <<: *slack-fail-params - - put: repo-status-jdk15-build + - put: repo-status-jdk16-build params: { state: "success", commit: "git-repo" } - name: build-pull-requests serial: true @@ -292,7 +292,7 @@ jobs: privileged: true timeout: ((task-timeout)) params: - <<: *build-project-task-params + BRANCH: ((branch)) on_success: put: git-pull-request params: @@ -453,7 +453,7 @@ jobs: groups: - name: "builds" - jobs: ["build", "jdk11-build", "jdk15-build"] + jobs: ["build", "jdk11-build", "jdk16-build"] - name: "releases" jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"] - name: "ci-images" From 0ec4be37d591bcc8a3f5ae10ac3daa905599bb84 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 6 Sep 2021 16:21:24 +0100 Subject: [PATCH 043/735] Configure optional configuration to consume its dependencies' API Previously, the optional configuration had no usage attribute. This resulted in it using the default, JAVA_RUNTIME, which caused it to only consume the runtime produced by its dependencies and not the API. Given that the optional configuration is added to the compile classpath, this was incorrect. This commit updates the optional configuration to be configured to consume the Java API of its dependencies. The configuration has also been marked as not being for consumption. This prevents other projects attempting to consume the optional variant of a project that has the optional dependencies plugin applied and further aligns it with Gradle's built-in configurations of a similar nature. See gh-27365 --- .../build/optional/OptionalDependenciesPlugin.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java b/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java index 93ae77995d10..f4a51cb0e8b8 100644 --- a/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java +++ b/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java @@ -19,6 +19,7 @@ import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; +import org.gradle.api.attributes.Usage; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.tasks.SourceSetContainer; @@ -43,6 +44,10 @@ public class OptionalDependenciesPlugin implements Plugin { @Override public void apply(Project project) { Configuration optional = project.getConfigurations().create("optional"); + optional.attributes((attributes) -> attributes.attribute(Usage.USAGE_ATTRIBUTE, + project.getObjects().named(Usage.class, Usage.JAVA_API))); + optional.setCanBeConsumed(false); + optional.setCanBeResolved(true); project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> { SourceSetContainer sourceSets = project.getConvention() .getPlugin(JavaPluginConvention.class).getSourceSets(); From d23afea168b8360d08bf296ac2189239ab9db7fc Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 6 Sep 2021 17:19:29 +0100 Subject: [PATCH 044/735] Extend optional rather than adding it to existing classpath This allows the attributes configured on compileClasspath and runtimeClasspath to independently influence the variant selection when resolving the optional configuration, allowing it to contribute compile dependencies (JAVA_API) to the former and runtime dependencies (JAVA_RUNTIME) to the latter. Fixes gh-27365 --- .../build/optional/OptionalDependenciesPlugin.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java b/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java index f4a51cb0e8b8..ec4f8b4b1939 100644 --- a/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java +++ b/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java @@ -44,18 +44,14 @@ public class OptionalDependenciesPlugin implements Plugin { @Override public void apply(Project project) { Configuration optional = project.getConfigurations().create("optional"); - optional.attributes((attributes) -> attributes.attribute(Usage.USAGE_ATTRIBUTE, - project.getObjects().named(Usage.class, Usage.JAVA_API))); optional.setCanBeConsumed(false); - optional.setCanBeResolved(true); + optional.setCanBeResolved(false); project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> { - SourceSetContainer sourceSets = project.getConvention() - .getPlugin(JavaPluginConvention.class).getSourceSets(); + SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class) + .getSourceSets(); sourceSets.all((sourceSet) -> { - sourceSet.setCompileClasspath( - sourceSet.getCompileClasspath().plus(optional)); - sourceSet.setRuntimeClasspath( - sourceSet.getRuntimeClasspath().plus(optional)); + project.getConfigurations().getByName(sourceSet.getCompileClasspathConfigurationName()).extendsFrom(optional); + project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName()).extendsFrom(optional); }); }); project.getPlugins().withType(EclipsePlugin.class, (eclipePlugin) -> { From 77a6dce1b58bbd11ec4c7c110c08cb20af38d8d8 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 6 Sep 2021 19:15:00 +0200 Subject: [PATCH 045/735] Review Servlet API version in Spring OXM tests This commit ensures that Servlet 4.0+ is used in the Spring OXM test suite, as Servlet 4 specific APIs are used in the tests. This problem was uncovered while fixing gh-27365 --- spring-orm/spring-orm.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-orm/spring-orm.gradle b/spring-orm/spring-orm.gradle index 8a8ad57ac4c3..285e044a14b4 100644 --- a/spring-orm/spring-orm.gradle +++ b/spring-orm/spring-orm.gradle @@ -10,7 +10,7 @@ dependencies { optional(project(":spring-web")) optional("org.eclipse.persistence:org.eclipse.persistence.jpa") optional("org.hibernate:hibernate-core") - optional("javax.servlet:javax.servlet-api:3.1.0") + optional("javax.servlet:javax.servlet-api") testCompile(testFixtures(project(":spring-beans"))) testCompile(testFixtures(project(":spring-context"))) testCompile(testFixtures(project(":spring-core"))) From e7b499f7b6d0020e0c8ac38bd9e267f1e7f2506c Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 7 Sep 2021 10:45:44 +0200 Subject: [PATCH 046/735] Upgrade to JMH 1.32 and avoid accidental dependency on jopt-simple 4.6 JMH is now implicitly configured to use jopt-simple 5.0.4 instead of 4.6. This problem was uncovered while fixing gh-27365 --- gradle/spring-module.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/spring-module.gradle b/gradle/spring-module.gradle index e0faef367adb..4b2b23d60ade 100644 --- a/gradle/spring-module.gradle +++ b/gradle/spring-module.gradle @@ -8,9 +8,9 @@ apply plugin: 'me.champeau.jmh' apply from: "$rootDir/gradle/publications.gradle" dependencies { - jmh 'org.openjdk.jmh:jmh-core:1.28' - jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.28' - jmh 'net.sf.jopt-simple:jopt-simple:4.6' + jmh 'org.openjdk.jmh:jmh-core:1.32' + jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.32' + jmh 'net.sf.jopt-simple:jopt-simple' } jmh { From d7ea4d230f3e00b54e12c823d710b2f3c8422524 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 7 Sep 2021 10:49:48 +0200 Subject: [PATCH 047/735] Remove Eclipse-specific code from OptionalDependenciesPlugin To support the recent changes to our `optional` dependencies plugin, this commit removes the Eclipse-specific code which no longer appears to be necessary. Closes gh-27365 --- .../build/optional/OptionalDependenciesPlugin.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java b/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java index ec4f8b4b1939..a7e7101daee7 100644 --- a/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java +++ b/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java @@ -54,12 +54,6 @@ public void apply(Project project) { project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName()).extendsFrom(optional); }); }); - project.getPlugins().withType(EclipsePlugin.class, (eclipePlugin) -> { - project.getExtensions().getByType(EclipseModel.class) - .classpath((classpath) -> { - classpath.getPlusConfigurations().add(optional); - }); - }); } } \ No newline at end of file From 19283c92459aef68cdfe738fd8bdf17b49597058 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 7 Sep 2021 11:32:28 +0200 Subject: [PATCH 048/735] Avoid accidental dependency on older version of Byte Buddy This commit allows Mockito-based tests in spring-test to work again in Eclipse IDE. This problem was uncovered while fixing gh-27365 --- spring-test/spring-test.gradle | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/spring-test/spring-test.gradle b/spring-test/spring-test.gradle index 1223fdff57a9..e27977c1af02 100644 --- a/spring-test/spring-test.gradle +++ b/spring-test/spring-test.gradle @@ -30,8 +30,12 @@ dependencies { optional("org.hamcrest:hamcrest") optional("org.apache.taglibs:taglibs-standard-jstlel") optional("net.sourceforge.htmlunit:htmlunit") - optional("org.seleniumhq.selenium:htmlunit-driver") - optional("org.seleniumhq.selenium:selenium-java") + optional("org.seleniumhq.selenium:htmlunit-driver") { + exclude group: "net.bytebuddy", module: "byte-buddy" + } + optional("org.seleniumhq.selenium:selenium-java") { + exclude group: "net.bytebuddy", module: "byte-buddy" + } optional("org.xmlunit:xmlunit-matchers") optional("org.skyscreamer:jsonassert") optional("com.jayway.jsonpath:json-path") From 417bce8be5e32ae43c2e3b25de1e24cd03c71e93 Mon Sep 17 00:00:00 2001 From: Yin-Jui Date: Thu, 27 May 2021 01:38:49 -0700 Subject: [PATCH 049/735] Add tests for MessageBodyClientHttpResponseWrapper Closes gh-26984 --- ...ageBodyClientHttpResponseWrapperTests.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 spring-web/src/test/java/org/springframework/web/client/MessageBodyClientHttpResponseWrapperTests.java diff --git a/spring-web/src/test/java/org/springframework/web/client/MessageBodyClientHttpResponseWrapperTests.java b/spring-web/src/test/java/org/springframework/web/client/MessageBodyClientHttpResponseWrapperTests.java new file mode 100644 index 000000000000..2c116ac5a917 --- /dev/null +++ b/spring-web/src/test/java/org/springframework/web/client/MessageBodyClientHttpResponseWrapperTests.java @@ -0,0 +1,55 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.web.client; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.client.ClientHttpResponse; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Unit tests for {MessageBodyClientHttpResponseWrapper}. + * + * @author Yin-Jui Liao + */ +class MessageBodyClientHttpResponseWrapperTests { + + private final ClientHttpResponse response = mock(ClientHttpResponse.class); + + @Test + void testMessageBodyNotExist() throws IOException { + given(response.getBody()).willReturn(null); + MessageBodyClientHttpResponseWrapper responseWrapper = new MessageBodyClientHttpResponseWrapper(response); + assertThat(responseWrapper.hasEmptyMessageBody()).isTrue(); + } + + @Test + void testMessageBodyExist() throws IOException { + String body = "Accepted request"; + InputStream stream = new ByteArrayInputStream(body.getBytes()); + given(response.getBody()).willReturn(stream); + MessageBodyClientHttpResponseWrapper responseWrapper = new MessageBodyClientHttpResponseWrapper(response); + assertThat(responseWrapper.hasEmptyMessageBody()).isFalse(); + } +} From d8191b48088b0ac2843b64beac861ddfcb99d9dd Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 7 Sep 2021 14:23:58 +0200 Subject: [PATCH 050/735] Polish contribution See gh-26984 --- .../MessageBodyClientHttpResponseWrapper.java | 4 +-- ...ageBodyClientHttpResponseWrapperTests.java | 27 ++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/client/MessageBodyClientHttpResponseWrapper.java b/spring-web/src/main/java/org/springframework/web/client/MessageBodyClientHttpResponseWrapper.java index 85e1c8f1b7e8..6565adc45f93 100644 --- a/spring-web/src/main/java/org/springframework/web/client/MessageBodyClientHttpResponseWrapper.java +++ b/spring-web/src/main/java/org/springframework/web/client/MessageBodyClientHttpResponseWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ class MessageBodyClientHttpResponseWrapper implements ClientHttpResponse { private PushbackInputStream pushbackInputStream; - public MessageBodyClientHttpResponseWrapper(ClientHttpResponse response) throws IOException { + public MessageBodyClientHttpResponseWrapper(ClientHttpResponse response) { this.response = response; } diff --git a/spring-web/src/test/java/org/springframework/web/client/MessageBodyClientHttpResponseWrapperTests.java b/spring-web/src/test/java/org/springframework/web/client/MessageBodyClientHttpResponseWrapperTests.java index 2c116ac5a917..19568910672d 100644 --- a/spring-web/src/test/java/org/springframework/web/client/MessageBodyClientHttpResponseWrapperTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/MessageBodyClientHttpResponseWrapperTests.java @@ -13,43 +13,44 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.client; +import java.io.ByteArrayInputStream; +import java.io.InputStream; + import org.junit.jupiter.api.Test; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; + import org.springframework.http.client.ClientHttpResponse; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; - /** - * Unit tests for {MessageBodyClientHttpResponseWrapper}. + * Unit tests for {@link MessageBodyClientHttpResponseWrapper}. * + * @since 5.3.10 * @author Yin-Jui Liao */ class MessageBodyClientHttpResponseWrapperTests { private final ClientHttpResponse response = mock(ClientHttpResponse.class); + private final MessageBodyClientHttpResponseWrapper responseWrapper = new MessageBodyClientHttpResponseWrapper(response); + + @Test - void testMessageBodyNotExist() throws IOException { + void messageBodyDoesNotExist() throws Exception { given(response.getBody()).willReturn(null); - MessageBodyClientHttpResponseWrapper responseWrapper = new MessageBodyClientHttpResponseWrapper(response); assertThat(responseWrapper.hasEmptyMessageBody()).isTrue(); } @Test - void testMessageBodyExist() throws IOException { - String body = "Accepted request"; - InputStream stream = new ByteArrayInputStream(body.getBytes()); + void messageBodyExists() throws Exception { + InputStream stream = new ByteArrayInputStream("content".getBytes()); given(response.getBody()).willReturn(stream); - MessageBodyClientHttpResponseWrapper responseWrapper = new MessageBodyClientHttpResponseWrapper(response); assertThat(responseWrapper.hasEmptyMessageBody()).isFalse(); } + } From 3f66ef7aeebdcc9f599487357294143099242abd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Tue, 7 Sep 2021 15:08:15 +0200 Subject: [PATCH 051/735] Compile with parameter names Compiled code should contain parameter names to avoid the need for class resources to be included in native image builds. Closes gh-27369 --- .../build/compile/CompilerConventionsPlugin.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java b/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java index 5284df28f124..f2424c549e50 100644 --- a/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java +++ b/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java @@ -32,6 +32,7 @@ * * @author Brian Clozel * @author Sam Brannen + * @author Sebastien Deleuze */ public class CompilerConventionsPlugin implements Plugin { @@ -43,7 +44,8 @@ public class CompilerConventionsPlugin implements Plugin { List commonCompilerArgs = Arrays.asList( "-Xlint:serial", "-Xlint:cast", "-Xlint:classfile", "-Xlint:dep-ann", "-Xlint:divzero", "-Xlint:empty", "-Xlint:finally", "-Xlint:overrides", - "-Xlint:path", "-Xlint:processing", "-Xlint:static", "-Xlint:try", "-Xlint:-options" + "-Xlint:path", "-Xlint:processing", "-Xlint:static", "-Xlint:try", "-Xlint:-options", + "-parameters" ); COMPILER_ARGS = new ArrayList<>(); COMPILER_ARGS.addAll(commonCompilerArgs); @@ -54,7 +56,7 @@ public class CompilerConventionsPlugin implements Plugin { TEST_COMPILER_ARGS = new ArrayList<>(); TEST_COMPILER_ARGS.addAll(commonCompilerArgs); TEST_COMPILER_ARGS.addAll(Arrays.asList("-Xlint:-varargs", "-Xlint:-fallthrough", "-Xlint:-rawtypes", - "-Xlint:-deprecation", "-Xlint:-unchecked", "-parameters")); + "-Xlint:-deprecation", "-Xlint:-unchecked")); } @Override From a3655c48581dd3977de02f13dd3a7ecc3dcde6c2 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 7 Sep 2021 16:33:31 +0100 Subject: [PATCH 052/735] Add tip related to user destinations in STOMP See gh-26986 --- src/docs/asciidoc/web/websocket.adoc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/docs/asciidoc/web/websocket.adoc b/src/docs/asciidoc/web/websocket.adoc index 080a75e0ab3f..07751ff57317 100644 --- a/src/docs/asciidoc/web/websocket.adoc +++ b/src/docs/asciidoc/web/websocket.adoc @@ -1818,12 +1818,16 @@ its own implementation of `WebSocketMessageBrokerConfigurer` that is marked with An application can send messages that target a specific user, and Spring's STOMP support recognizes destinations prefixed with `/user/` for this purpose. For example, a client might subscribe to the `/user/queue/position-updates` destination. -This destination is handled by the `UserDestinationMessageHandler` and -transformed into a destination unique to the user session -(such as `/queue/position-updates-user123`). This provides the convenience of subscribing -to a generically named destination while, at the same time, ensuring no collisions -with other users who subscribe to the same destination so that each user can receive -unique stock position updates. +`UserDestinationMessageHandler` handles this destination and transforms it into a +destination unique to the user session (such as `/queue/position-updates-user123`). +This provides the convenience of subscribing to a generically named destination while, +at the same time, ensuring no collisions with other users who subscribe to the same +destination so that each user can receive unique stock position updates. + +TIP: When working with user destinations, it is important to configure broker and +application destination prefixes as shown in <>, or otherwise the +broker would handle "/user" prefixed messages that should only be handled by +`UserDestinationMessageHandler`. On the sending side, messages can be sent to a destination such as pass:q[`/user/{username}/queue/position-updates`], which in turn is translated From 55b3e064e93c376b9c60ec9458b56b0b20f6f184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Wed, 8 Sep 2021 09:32:25 +0200 Subject: [PATCH 053/735] Upgrade to Kotlin 1.5.30 Also upgrades related libraries: - Coroutines upgraded to 1.5.2 - Serialization upgraded to 1.2.2 Closes gh-27371 --- build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 69b6cf85bb30..2236e11b462e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'io.spring.dependency-management' version '1.0.9.RELEASE' apply false id 'io.spring.nohttp' version '0.0.5.RELEASE' - id 'org.jetbrains.kotlin.jvm' version '1.5.21' apply false + id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false id 'org.jetbrains.dokka' version '0.10.1' apply false id 'org.asciidoctor.jvm.convert' version '3.1.0' id 'org.asciidoctor.jvm.pdf' version '3.1.0' @@ -10,7 +10,7 @@ plugins { id "com.github.ben-manes.versions" version '0.28.0' id "com.github.johnrengelman.shadow" version "6.1.0" apply false id "me.champeau.jmh" version "0.6.4" apply false - id "org.jetbrains.kotlin.plugin.serialization" version "1.5.21" apply false + id "org.jetbrains.kotlin.plugin.serialization" version "1.5.30" apply false id "org.unbroken-dome.xjc" version '2.0.0' apply false } @@ -33,9 +33,9 @@ configure(allprojects) { project -> mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" mavenBom "io.rsocket:rsocket-bom:1.1.1" mavenBom "org.eclipse.jetty:jetty-bom:9.4.43.v20210629" - mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.21" - mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.1" - mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.1" + mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.30" + mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2" + mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2" mavenBom "org.junit:junit-bom:5.7.2" } dependencies { From 8f33450df20352ad6eabe632c082d9b02cb46c9a Mon Sep 17 00:00:00 2001 From: Grant Fleming Date: Thu, 9 Sep 2021 12:26:44 +0100 Subject: [PATCH 054/735] Fix typo in core-beans.adoc Closes gh-27377 --- src/docs/asciidoc/core/core-beans.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/asciidoc/core/core-beans.adoc b/src/docs/asciidoc/core/core-beans.adoc index 487ef6f4a1ea..2a8c526d2617 100644 --- a/src/docs/asciidoc/core/core-beans.adoc +++ b/src/docs/asciidoc/core/core-beans.adoc @@ -11188,7 +11188,7 @@ The following table lists features provided by the `BeanFactory` and | No | Yes -| Convenient `MessageSource` access (for internalization) +| Convenient `MessageSource` access (for internationalization) | No | Yes From 1dc128361f87b3708f796ec0b4b3565ca28f8ba6 Mon Sep 17 00:00:00 2001 From: hantsy Date: Sat, 28 Aug 2021 11:20:12 +0800 Subject: [PATCH 055/735] Add SmallRye Mutiny adapters Closes gh-26222 --- build.gradle | 1 + spring-core/spring-core.gradle | 1 + .../core/ReactiveAdapterRegistry.java | 27 +++++++++++ .../core/ReactiveAdapterRegistryTests.java | 48 +++++++++++++++++++ 4 files changed, 77 insertions(+) diff --git a/build.gradle b/build.gradle index 2236e11b462e..b7a5d0330faa 100644 --- a/build.gradle +++ b/build.gradle @@ -68,6 +68,7 @@ configure(allprojects) { project -> dependency "io.reactivex:rxjava-reactive-streams:1.2.1" dependency "io.reactivex.rxjava2:rxjava:2.2.21" dependency "io.reactivex.rxjava3:rxjava:3.1.1" + dependency "io.smallrye.reactive:mutiny:1.0.0" dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE" dependency "com.caucho:hessian:4.0.63" diff --git a/spring-core/spring-core.gradle b/spring-core/spring-core.gradle index a4166705d32d..822b6ed58acd 100644 --- a/spring-core/spring-core.gradle +++ b/spring-core/spring-core.gradle @@ -49,6 +49,7 @@ dependencies { optional("io.reactivex:rxjava-reactive-streams") optional("io.reactivex.rxjava2:rxjava") optional("io.reactivex.rxjava3:rxjava") + optional("io.smallrye.reactive:mutiny") optional("io.netty:netty-buffer") testCompile("io.projectreactor:reactor-test") testCompile("com.google.code.findbugs:jsr305") diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java index a5a8b9295092..4cbb90c0c606 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -24,6 +24,8 @@ import java.util.concurrent.CompletionStage; import java.util.function.Function; +import io.smallrye.mutiny.Multi; +import io.smallrye.mutiny.Uni; import kotlinx.coroutines.CompletableDeferredKt; import kotlinx.coroutines.Deferred; import org.reactivestreams.Publisher; @@ -72,6 +74,8 @@ public class ReactiveAdapterRegistry { private static final boolean kotlinCoroutinesPresent; + private static final boolean mutinyPresent; + static { ClassLoader classLoader = ReactiveAdapterRegistry.class.getClassLoader(); reactorPresent = ClassUtils.isPresent("reactor.core.publisher.Flux", classLoader); @@ -81,6 +85,7 @@ public class ReactiveAdapterRegistry { rxjava3Present = ClassUtils.isPresent("io.reactivex.rxjava3.core.Flowable", classLoader); flowPublisherPresent = ClassUtils.isPresent("java.util.concurrent.Flow.Publisher", classLoader); kotlinCoroutinesPresent = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt", classLoader); + mutinyPresent = ClassUtils.isPresent("io.smallrye.mutiny.Uni", classLoader); } private final List adapters = new ArrayList<>(); @@ -121,6 +126,11 @@ public ReactiveAdapterRegistry() { if (reactorPresent && kotlinCoroutinesPresent) { new CoroutinesRegistrar().registerAdapters(this); } + + // SmallRye Mutiny + if (mutinyPresent) { + new MutinyRegistrar().registerAdapters(this); + } } @@ -417,6 +427,23 @@ void registerAdapters(ReactiveAdapterRegistry registry) { } } + private static class MutinyRegistrar { + + void registerAdapters(ReactiveAdapterRegistry registry) { + registry.registerReactiveType( + ReactiveTypeDescriptor.singleOptionalValue(Uni.class, ()-> Uni.createFrom().nothing()), + uni ->((Uni)uni).convert().toPublisher(), + publisher -> Uni.createFrom().publisher(publisher) + ); + + registry.registerReactiveType( + ReactiveTypeDescriptor.multiValue(Multi.class, ()-> Multi.createFrom().empty()), + multi -> (Multi) multi, + publisher-> Multi.createFrom().publisher(publisher) + ); + } + } + /** * {@code BlockHoundIntegration} for spring-core classes. diff --git a/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java b/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java index 4dc08a704f29..535891e6ff3e 100644 --- a/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java +++ b/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java @@ -21,6 +21,8 @@ import java.util.List; import java.util.concurrent.CompletableFuture; +import io.smallrye.mutiny.Multi; +import io.smallrye.mutiny.Uni; import kotlinx.coroutines.Deferred; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -357,6 +359,52 @@ void deferred() { } } + // SmallRye Mutiny + @Nested + class Mutiny { + + @Test + void defaultAdapterRegistrations() { + assertThat(getAdapter(io.smallrye.mutiny.Uni.class)).isNotNull(); + assertThat(getAdapter(io.smallrye.mutiny.Multi.class)).isNotNull(); + } + + @Test + void toUni() { + Publisher source = Mono.just(1); + Object target = getAdapter(Uni.class).fromPublisher(source); + assertThat(target).isInstanceOf(Uni.class); + assertThat(((Uni) target).await().atMost(Duration.ofMillis(1000))).isEqualTo(Integer.valueOf(1)); + } + + @Test + void fromUni() { + Uni source = Uni.createFrom().item(1); + Object target = getAdapter(Uni.class).toPublisher(source); + assertThat(target).isInstanceOf(Mono.class); + assertThat(((Mono) target).block(Duration.ofMillis(1000))).isEqualTo(Integer.valueOf(1)); + } + + @Test + void toMulti() { + List sequence = Arrays.asList(1, 2, 3); + Publisher source = Flux.fromIterable(sequence); + Object target = getAdapter(Multi.class).fromPublisher(source); + assertThat(target).isInstanceOf(Multi.class); + assertThat(((Multi) target).collect().asList().await().atMost(Duration.ofMillis(1000))).isEqualTo(sequence); + } + + @Test + void fromMulti() { + List sequence = Arrays.asList(1, 2, 3); + Multi source = Multi.createFrom().iterable(sequence); + Object target = getAdapter(Multi.class).toPublisher(source); + assertThat(target).isInstanceOf(Flux.class); + assertThat(((Flux) target).blockLast(Duration.ofMillis(1000))).isEqualTo(Integer.valueOf(3)); + } + + } + private ReactiveAdapter getAdapter(Class reactiveType) { ReactiveAdapter adapter = this.registry.getAdapter(reactiveType); assertThat(adapter).isNotNull(); From 41ab2687338c6419cb0f04c1bf79a9c52157a861 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 8 Sep 2021 16:59:28 +0100 Subject: [PATCH 056/735] Polishing contribution See gh-27331 --- .../core/ReactiveAdapterRegistry.java | 21 +++++----- .../core/ReactiveAdapterRegistryTests.java | 40 ++++++++++--------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java index 4cbb90c0c606..cfeaffcaf734 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -24,8 +24,6 @@ import java.util.concurrent.CompletionStage; import java.util.function.Function; -import io.smallrye.mutiny.Multi; -import io.smallrye.mutiny.Uni; import kotlinx.coroutines.CompletableDeferredKt; import kotlinx.coroutines.Deferred; import org.reactivestreams.Publisher; @@ -85,7 +83,7 @@ public class ReactiveAdapterRegistry { rxjava3Present = ClassUtils.isPresent("io.reactivex.rxjava3.core.Flowable", classLoader); flowPublisherPresent = ClassUtils.isPresent("java.util.concurrent.Flow.Publisher", classLoader); kotlinCoroutinesPresent = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt", classLoader); - mutinyPresent = ClassUtils.isPresent("io.smallrye.mutiny.Uni", classLoader); + mutinyPresent = ClassUtils.isPresent("io.smallrye.mutiny.Multi", classLoader); } private final List adapters = new ArrayList<>(); @@ -427,19 +425,24 @@ void registerAdapters(ReactiveAdapterRegistry registry) { } } + private static class MutinyRegistrar { void registerAdapters(ReactiveAdapterRegistry registry) { registry.registerReactiveType( - ReactiveTypeDescriptor.singleOptionalValue(Uni.class, ()-> Uni.createFrom().nothing()), - uni ->((Uni)uni).convert().toPublisher(), - publisher -> Uni.createFrom().publisher(publisher) + ReactiveTypeDescriptor.singleOptionalValue( + io.smallrye.mutiny.Uni.class, + () -> io.smallrye.mutiny.Uni.createFrom().nothing()), + uni -> ((io.smallrye.mutiny.Uni) uni).convert().toPublisher(), + publisher -> io.smallrye.mutiny.Uni.createFrom().publisher(publisher) ); registry.registerReactiveType( - ReactiveTypeDescriptor.multiValue(Multi.class, ()-> Multi.createFrom().empty()), - multi -> (Multi) multi, - publisher-> Multi.createFrom().publisher(publisher) + ReactiveTypeDescriptor.multiValue( + io.smallrye.mutiny.Multi.class, + () -> io.smallrye.mutiny.Multi.createFrom().empty()), + multi -> (io.smallrye.mutiny.Multi) multi, + publisher -> io.smallrye.mutiny.Multi.createFrom().publisher(publisher) ); } } diff --git a/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java b/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java index 535891e6ff3e..579e1a463afc 100644 --- a/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java +++ b/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java @@ -40,6 +40,9 @@ @SuppressWarnings("unchecked") class ReactiveAdapterRegistryTests { + private static final Duration ONE_SECOND = Duration.ofSeconds(1); + + private final ReactiveAdapterRegistry registry = ReactiveAdapterRegistry.getSharedInstance(); @@ -85,7 +88,7 @@ void toFlux() { Publisher source = io.reactivex.rxjava3.core.Flowable.fromIterable(sequence); Object target = getAdapter(Flux.class).fromPublisher(source); assertThat(target instanceof Flux).isTrue(); - assertThat(((Flux) target).collectList().block(Duration.ofMillis(1000))).isEqualTo(sequence); + assertThat(((Flux) target).collectList().block(ONE_SECOND)).isEqualTo(sequence); } @Test @@ -93,7 +96,7 @@ void toMono() { Publisher source = io.reactivex.rxjava3.core.Flowable.fromArray(1, 2, 3); Object target = getAdapter(Mono.class).fromPublisher(source); assertThat(target instanceof Mono).isTrue(); - assertThat(((Mono) target).block(Duration.ofMillis(1000))).isEqualTo(Integer.valueOf(1)); + assertThat(((Mono) target).block(ONE_SECOND)).isEqualTo(Integer.valueOf(1)); } @Test @@ -110,7 +113,7 @@ void fromCompletableFuture() { future.complete(1); Object target = getAdapter(CompletableFuture.class).toPublisher(future); assertThat(target instanceof Mono).as("Expected Mono Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Mono) target).block(Duration.ofMillis(1000))).isEqualTo(Integer.valueOf(1)); + assertThat(((Mono) target).block(ONE_SECOND)).isEqualTo(Integer.valueOf(1)); } } @@ -155,7 +158,7 @@ void fromObservable() { Object source = rx.Observable.from(sequence); Object target = getAdapter(rx.Observable.class).toPublisher(source); assertThat(target instanceof Flux).as("Expected Flux Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Flux) target).collectList().block(Duration.ofMillis(1000))).isEqualTo(sequence); + assertThat(((Flux) target).collectList().block(ONE_SECOND)).isEqualTo(sequence); } @Test @@ -163,7 +166,7 @@ void fromSingle() { Object source = rx.Single.just(1); Object target = getAdapter(rx.Single.class).toPublisher(source); assertThat(target instanceof Mono).as("Expected Mono Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Mono) target).block(Duration.ofMillis(1000))).isEqualTo(Integer.valueOf(1)); + assertThat(((Mono) target).block(ONE_SECOND)).isEqualTo(Integer.valueOf(1)); } @Test @@ -171,7 +174,7 @@ void fromCompletable() { Object source = rx.Completable.complete(); Object target = getAdapter(rx.Completable.class).toPublisher(source); assertThat(target instanceof Mono).as("Expected Mono Publisher: " + target.getClass().getName()).isTrue(); - ((Mono) target).block(Duration.ofMillis(1000)); + ((Mono) target).block(ONE_SECOND); } } @@ -229,7 +232,7 @@ void fromFlowable() { Object source = io.reactivex.Flowable.fromIterable(sequence); Object target = getAdapter(io.reactivex.Flowable.class).toPublisher(source); assertThat(target instanceof Flux).as("Expected Flux Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Flux) target).collectList().block(Duration.ofMillis(1000))).isEqualTo(sequence); + assertThat(((Flux) target).collectList().block(ONE_SECOND)).isEqualTo(sequence); } @Test @@ -238,7 +241,7 @@ void fromObservable() { Object source = io.reactivex.Observable.fromIterable(sequence); Object target = getAdapter(io.reactivex.Observable.class).toPublisher(source); assertThat(target instanceof Flux).as("Expected Flux Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Flux) target).collectList().block(Duration.ofMillis(1000))).isEqualTo(sequence); + assertThat(((Flux) target).collectList().block(ONE_SECOND)).isEqualTo(sequence); } @Test @@ -246,7 +249,7 @@ void fromSingle() { Object source = io.reactivex.Single.just(1); Object target = getAdapter(io.reactivex.Single.class).toPublisher(source); assertThat(target instanceof Mono).as("Expected Mono Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Mono) target).block(Duration.ofMillis(1000))).isEqualTo(Integer.valueOf(1)); + assertThat(((Mono) target).block(ONE_SECOND)).isEqualTo(Integer.valueOf(1)); } @Test @@ -254,7 +257,7 @@ void fromCompletable() { Object source = io.reactivex.Completable.complete(); Object target = getAdapter(io.reactivex.Completable.class).toPublisher(source); assertThat(target instanceof Mono).as("Expected Mono Publisher: " + target.getClass().getName()).isTrue(); - ((Mono) target).block(Duration.ofMillis(1000)); + ((Mono) target).block(ONE_SECOND); } } @@ -312,7 +315,7 @@ void fromFlowable() { Object source = io.reactivex.rxjava3.core.Flowable.fromIterable(sequence); Object target = getAdapter(io.reactivex.rxjava3.core.Flowable.class).toPublisher(source); assertThat(target instanceof Flux).as("Expected Flux Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Flux) target).collectList().block(Duration.ofMillis(1000))).isEqualTo(sequence); + assertThat(((Flux) target).collectList().block(ONE_SECOND)).isEqualTo(sequence); } @Test @@ -321,7 +324,7 @@ void fromObservable() { Object source = io.reactivex.rxjava3.core.Observable.fromIterable(sequence); Object target = getAdapter(io.reactivex.rxjava3.core.Observable.class).toPublisher(source); assertThat(target instanceof Flux).as("Expected Flux Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Flux) target).collectList().block(Duration.ofMillis(1000))).isEqualTo(sequence); + assertThat(((Flux) target).collectList().block(ONE_SECOND)).isEqualTo(sequence); } @Test @@ -329,7 +332,7 @@ void fromSingle() { Object source = io.reactivex.rxjava3.core.Single.just(1); Object target = getAdapter(io.reactivex.rxjava3.core.Single.class).toPublisher(source); assertThat(target instanceof Mono).as("Expected Mono Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Mono) target).block(Duration.ofMillis(1000))).isEqualTo(Integer.valueOf(1)); + assertThat(((Mono) target).block(ONE_SECOND)).isEqualTo(Integer.valueOf(1)); } @Test @@ -337,7 +340,7 @@ void fromCompletable() { Object source = io.reactivex.rxjava3.core.Completable.complete(); Object target = getAdapter(io.reactivex.rxjava3.core.Completable.class).toPublisher(source); assertThat(target instanceof Mono).as("Expected Mono Publisher: " + target.getClass().getName()).isTrue(); - ((Mono) target).block(Duration.ofMillis(1000)); + ((Mono) target).block(ONE_SECOND); } } @@ -359,7 +362,6 @@ void deferred() { } } - // SmallRye Mutiny @Nested class Mutiny { @@ -374,7 +376,7 @@ void toUni() { Publisher source = Mono.just(1); Object target = getAdapter(Uni.class).fromPublisher(source); assertThat(target).isInstanceOf(Uni.class); - assertThat(((Uni) target).await().atMost(Duration.ofMillis(1000))).isEqualTo(Integer.valueOf(1)); + assertThat(((Uni) target).await().atMost(ONE_SECOND)).isEqualTo(Integer.valueOf(1)); } @Test @@ -382,7 +384,7 @@ void fromUni() { Uni source = Uni.createFrom().item(1); Object target = getAdapter(Uni.class).toPublisher(source); assertThat(target).isInstanceOf(Mono.class); - assertThat(((Mono) target).block(Duration.ofMillis(1000))).isEqualTo(Integer.valueOf(1)); + assertThat(((Mono) target).block(ONE_SECOND)).isEqualTo(Integer.valueOf(1)); } @Test @@ -391,7 +393,7 @@ void toMulti() { Publisher source = Flux.fromIterable(sequence); Object target = getAdapter(Multi.class).fromPublisher(source); assertThat(target).isInstanceOf(Multi.class); - assertThat(((Multi) target).collect().asList().await().atMost(Duration.ofMillis(1000))).isEqualTo(sequence); + assertThat(((Multi) target).collect().asList().await().atMost(ONE_SECOND)).isEqualTo(sequence); } @Test @@ -400,7 +402,7 @@ void fromMulti() { Multi source = Multi.createFrom().iterable(sequence); Object target = getAdapter(Multi.class).toPublisher(source); assertThat(target).isInstanceOf(Flux.class); - assertThat(((Flux) target).blockLast(Duration.ofMillis(1000))).isEqualTo(Integer.valueOf(3)); + assertThat(((Flux) target).blockLast(ONE_SECOND)).isEqualTo(Integer.valueOf(3)); } } From b6037d0d07efee37ddc7200f80f31b862cbed04c Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 9 Sep 2021 15:37:58 +0100 Subject: [PATCH 057/735] Correctly format class name in default package Closes gh-27247 --- .../invocation/AbstractMethodMessageHandler.java | 12 ++++++++---- .../reactive/AbstractMethodMessageHandler.java | 12 ++++++++---- .../result/method/AbstractHandlerMethodMapping.java | 10 +++++++--- .../handler/AbstractHandlerMethodMapping.java | 10 +++++++--- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java index fc50155039c4..f160d506eed7 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,6 +53,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFutureCallback; @@ -319,9 +320,12 @@ protected final void detectHandlerMethods(final Object handler) { } private String formatMappings(Class userType, Map methods) { - String formattedType = Arrays.stream(ClassUtils.getPackageName(userType).split("\\.")) - .map(p -> p.substring(0, 1)) - .collect(Collectors.joining(".", "", "." + userType.getSimpleName())); + String packageName = ClassUtils.getPackageName(userType); + String formattedType = (StringUtils.hasText(packageName) ? + Arrays.stream(packageName.split("\\.")) + .map(packageSegment -> packageSegment.substring(0, 1)) + .collect(Collectors.joining(".", "", "." + userType.getSimpleName())) : + userType.getSimpleName()); Function methodFormatter = method -> Arrays.stream(method.getParameterTypes()) .map(Class::getSimpleName) .collect(Collectors.joining(",", "(", ")")); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java index 1d85930585cb..a240f4d8efa0 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,6 +54,7 @@ import org.springframework.util.MultiValueMap; import org.springframework.util.ObjectUtils; import org.springframework.util.RouteMatcher; +import org.springframework.util.StringUtils; /** * Abstract base class for reactive HandlerMethod-based message handling. @@ -341,9 +342,12 @@ protected final void detectHandlerMethods(Object handler) { } private String formatMappings(Class userType, Map methods) { - String formattedType = Arrays.stream(ClassUtils.getPackageName(userType).split("\\.")) - .map(p -> p.substring(0, 1)) - .collect(Collectors.joining(".", "", "." + userType.getSimpleName())); + String packageName = ClassUtils.getPackageName(userType); + String formattedType = (StringUtils.hasText(packageName) ? + Arrays.stream(packageName.split("\\.")) + .map(packageSegment -> packageSegment.substring(0, 1)) + .collect(Collectors.joining(".", "", "." + userType.getSimpleName())) : + userType.getSimpleName()); Function methodFormatter = method -> Arrays.stream(method.getParameterTypes()) .map(Class::getSimpleName) .collect(Collectors.joining(",", "(", ")")); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java index 93ff062651e1..c2e01aaeff70 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java @@ -42,6 +42,7 @@ import org.springframework.util.ClassUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.reactive.CorsUtils; import org.springframework.web.method.HandlerMethod; @@ -222,9 +223,12 @@ else if (mappingsLogger.isDebugEnabled()) { } private String formatMappings(Class userType, Map methods) { - String formattedType = Arrays.stream(ClassUtils.getPackageName(userType).split("\\.")) - .map(p -> p.substring(0, 1)) - .collect(Collectors.joining(".", "", "." + userType.getSimpleName())); + String packageName = ClassUtils.getPackageName(userType); + String formattedType = (StringUtils.hasText(packageName) ? + Arrays.stream(packageName.split("\\.")) + .map(packageSegment -> packageSegment.substring(0, 1)) + .collect(Collectors.joining(".", "", "." + userType.getSimpleName())) : + userType.getSimpleName()); Function methodFormatter = method -> Arrays.stream(method.getParameterTypes()) .map(Class::getSimpleName) .collect(Collectors.joining(",", "(", ")")); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java index 367ca74997da..46f1707d1cfb 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java @@ -44,6 +44,7 @@ import org.springframework.util.ClassUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsUtils; import org.springframework.web.method.HandlerMethod; @@ -301,9 +302,12 @@ else if (mappingsLogger.isDebugEnabled()) { } private String formatMappings(Class userType, Map methods) { - String formattedType = Arrays.stream(ClassUtils.getPackageName(userType).split("\\.")) - .map(p -> p.substring(0, 1)) - .collect(Collectors.joining(".", "", "." + userType.getSimpleName())); + String packageName = ClassUtils.getPackageName(userType); + String formattedType = (StringUtils.hasText(packageName) ? + Arrays.stream(packageName.split("\\.")) + .map(packageSegment -> packageSegment.substring(0, 1)) + .collect(Collectors.joining(".", "", "." + userType.getSimpleName())) : + userType.getSimpleName()); Function methodFormatter = method -> Arrays.stream(method.getParameterTypes()) .map(Class::getSimpleName) .collect(Collectors.joining(",", "(", ")")); From 63ffa710d6d9b8f5b6e615b7c7c92ff62f6c421a Mon Sep 17 00:00:00 2001 From: Ruslan Stelmachenko Date: Thu, 9 Sep 2021 01:43:20 +0300 Subject: [PATCH 058/735] Include all bytes of body in UnknownContentTypeException HttpMessageConverterExtractor uses MessageBodyClientHttpResponseWrapper which may read the first byte of the response stream to check if there is content. After that it is necessary to use the wrapper to get the full body. This commit ensures that when UnknownContentTypeException is raised it gets the body through the wrapper, or otherwise the first byte is missed if the InputStream is not markable. Closes gh-27374 --- .../client/HttpMessageConverterExtractor.java | 4 ++-- .../HttpMessageConverterExtractorTests.java | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/client/HttpMessageConverterExtractor.java b/spring-web/src/main/java/org/springframework/web/client/HttpMessageConverterExtractor.java index 771a444bd731..dc515cc91d6a 100644 --- a/spring-web/src/main/java/org/springframework/web/client/HttpMessageConverterExtractor.java +++ b/spring-web/src/main/java/org/springframework/web/client/HttpMessageConverterExtractor.java @@ -122,8 +122,8 @@ public T extractData(ClientHttpResponse response) throws IOException { } throw new UnknownContentTypeException(this.responseType, contentType, - response.getRawStatusCode(), response.getStatusText(), response.getHeaders(), - getResponseBody(response)); + responseWrapper.getRawStatusCode(), responseWrapper.getStatusText(), responseWrapper.getHeaders(), + getResponseBody(responseWrapper)); } /** diff --git a/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java b/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java index 2374a0d95487..de86b8671de0 100644 --- a/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java @@ -38,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.catchThrowableOfType; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; @@ -194,4 +195,23 @@ public void converterThrowsHttpMessageNotReadableException() throws IOException .withCauseInstanceOf(HttpMessageNotReadableException.class); } + @Test + public void unknownContentTypeExceptionContainsCorrectResponseBody() throws IOException { + responseHeaders.setContentType(contentType); + given(response.getRawStatusCode()).willReturn(HttpStatus.OK.value()); + given(response.getHeaders()).willReturn(responseHeaders); + given(response.getBody()).willReturn(new ByteArrayInputStream("Foobar".getBytes()) { + @Override + public boolean markSupported() { + return false; + } + }); + given(converter.canRead(String.class, contentType)).willReturn(false); + + UnknownContentTypeException unknownContentTypeException = + catchThrowableOfType(() -> extractor.extractData(response), UnknownContentTypeException.class); + assertThat(unknownContentTypeException).isNotNull(); + assertThat(unknownContentTypeException.getResponseBodyAsString()).isEqualTo("Foobar"); + } + } From c23f0cd070aa2e5429fadf4a41e670533c4016c8 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 10 Sep 2021 11:22:01 +0100 Subject: [PATCH 059/735] Polishing contribution See gh-27374 --- .../web/client/HttpMessageConverterExtractor.java | 4 ++-- .../web/client/HttpMessageConverterExtractorTests.java | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/client/HttpMessageConverterExtractor.java b/spring-web/src/main/java/org/springframework/web/client/HttpMessageConverterExtractor.java index dc515cc91d6a..45cc426a0679 100644 --- a/spring-web/src/main/java/org/springframework/web/client/HttpMessageConverterExtractor.java +++ b/spring-web/src/main/java/org/springframework/web/client/HttpMessageConverterExtractor.java @@ -122,8 +122,8 @@ public T extractData(ClientHttpResponse response) throws IOException { } throw new UnknownContentTypeException(this.responseType, contentType, - responseWrapper.getRawStatusCode(), responseWrapper.getStatusText(), responseWrapper.getHeaders(), - getResponseBody(responseWrapper)); + responseWrapper.getRawStatusCode(), responseWrapper.getStatusText(), + responseWrapper.getHeaders(), getResponseBody(responseWrapper)); } /** diff --git a/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java b/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java index de86b8671de0..bb4acdf5e061 100644 --- a/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -208,10 +208,10 @@ public boolean markSupported() { }); given(converter.canRead(String.class, contentType)).willReturn(false); - UnknownContentTypeException unknownContentTypeException = - catchThrowableOfType(() -> extractor.extractData(response), UnknownContentTypeException.class); - assertThat(unknownContentTypeException).isNotNull(); - assertThat(unknownContentTypeException.getResponseBodyAsString()).isEqualTo("Foobar"); + UnknownContentTypeException exception = catchThrowableOfType( + () -> extractor.extractData(response), UnknownContentTypeException.class); + assertThat(exception).isNotNull(); + assertThat(exception.getResponseBodyAsString()).isEqualTo("Foobar"); } } From c3e424c29a5c72c3e9d69e9722f91d52f4a0c6fe Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 10 Sep 2021 16:01:23 +0200 Subject: [PATCH 060/735] Polishing --- .../HttpMessageConverterExtractorTests.java | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java b/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java index bb4acdf5e061..e9d6bd1da382 100644 --- a/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java @@ -38,7 +38,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.assertj.core.api.Assertions.catchThrowableOfType; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; @@ -51,7 +50,7 @@ * @author Brian Clozel * @author Sam Brannen */ -public class HttpMessageConverterExtractorTests { +class HttpMessageConverterExtractorTests { @SuppressWarnings("unchecked") private final HttpMessageConverter converter = mock(HttpMessageConverter.class); @@ -62,7 +61,7 @@ public class HttpMessageConverterExtractorTests { @Test - public void constructorPreconditions() { + void constructorPreconditions() { assertThatIllegalArgumentException() .isThrownBy(() -> new HttpMessageConverterExtractor<>(String.class, (List>) null)) .withMessage("'messageConverters' must not be empty"); @@ -72,7 +71,7 @@ public void constructorPreconditions() { } @Test - public void noContent() throws IOException { + void noContent() throws IOException { given(response.getRawStatusCode()).willReturn(HttpStatus.NO_CONTENT.value()); Object result = extractor.extractData(response); @@ -80,7 +79,7 @@ public void noContent() throws IOException { } @Test - public void notModified() throws IOException { + void notModified() throws IOException { given(response.getRawStatusCode()).willReturn(HttpStatus.NOT_MODIFIED.value()); Object result = extractor.extractData(response); @@ -88,7 +87,7 @@ public void notModified() throws IOException { } @Test - public void informational() throws IOException { + void informational() throws IOException { given(response.getRawStatusCode()).willReturn(HttpStatus.CONTINUE.value()); Object result = extractor.extractData(response); @@ -96,7 +95,7 @@ public void informational() throws IOException { } @Test - public void zeroContentLength() throws IOException { + void zeroContentLength() throws IOException { responseHeaders.setContentLength(0); given(response.getRawStatusCode()).willReturn(HttpStatus.OK.value()); given(response.getHeaders()).willReturn(responseHeaders); @@ -106,7 +105,7 @@ public void zeroContentLength() throws IOException { } @Test - public void emptyMessageBody() throws IOException { + void emptyMessageBody() throws IOException { given(response.getRawStatusCode()).willReturn(HttpStatus.OK.value()); given(response.getHeaders()).willReturn(responseHeaders); given(response.getBody()).willReturn(new ByteArrayInputStream("".getBytes())); @@ -116,7 +115,7 @@ public void emptyMessageBody() throws IOException { } @Test // gh-22265 - public void nullMessageBody() throws IOException { + void nullMessageBody() throws IOException { given(response.getRawStatusCode()).willReturn(HttpStatus.OK.value()); given(response.getHeaders()).willReturn(responseHeaders); given(response.getBody()).willReturn(null); @@ -126,7 +125,7 @@ public void nullMessageBody() throws IOException { } @Test - public void normal() throws IOException { + void normal() throws IOException { responseHeaders.setContentType(contentType); String expected = "Foo"; given(response.getRawStatusCode()).willReturn(HttpStatus.OK.value()); @@ -140,7 +139,7 @@ public void normal() throws IOException { } @Test - public void cannotRead() throws IOException { + void cannotRead() throws IOException { responseHeaders.setContentType(contentType); given(response.getRawStatusCode()).willReturn(HttpStatus.OK.value()); given(response.getHeaders()).willReturn(responseHeaders); @@ -151,7 +150,7 @@ public void cannotRead() throws IOException { @Test @SuppressWarnings("unchecked") - public void generics() throws IOException { + void generics() throws IOException { responseHeaders.setContentType(contentType); String expected = "Foo"; ParameterizedTypeReference> reference = new ParameterizedTypeReference>() {}; @@ -171,7 +170,7 @@ public void generics() throws IOException { } @Test // SPR-13592 - public void converterThrowsIOException() throws IOException { + void converterThrowsIOException() throws IOException { responseHeaders.setContentType(contentType); given(response.getRawStatusCode()).willReturn(HttpStatus.OK.value()); given(response.getHeaders()).willReturn(responseHeaders); @@ -184,7 +183,7 @@ public void converterThrowsIOException() throws IOException { } @Test // SPR-13592 - public void converterThrowsHttpMessageNotReadableException() throws IOException { + void converterThrowsHttpMessageNotReadableException() throws IOException { responseHeaders.setContentType(contentType); given(response.getRawStatusCode()).willReturn(HttpStatus.OK.value()); given(response.getHeaders()).willReturn(responseHeaders); @@ -196,7 +195,7 @@ public void converterThrowsHttpMessageNotReadableException() throws IOException } @Test - public void unknownContentTypeExceptionContainsCorrectResponseBody() throws IOException { + void unknownContentTypeExceptionContainsCorrectResponseBody() throws IOException { responseHeaders.setContentType(contentType); given(response.getRawStatusCode()).willReturn(HttpStatus.OK.value()); given(response.getHeaders()).willReturn(responseHeaders); @@ -208,10 +207,8 @@ public boolean markSupported() { }); given(converter.canRead(String.class, contentType)).willReturn(false); - UnknownContentTypeException exception = catchThrowableOfType( - () -> extractor.extractData(response), UnknownContentTypeException.class); - assertThat(exception).isNotNull(); - assertThat(exception.getResponseBodyAsString()).isEqualTo("Foobar"); + assertThatExceptionOfType(UnknownContentTypeException.class).isThrownBy(() -> extractor.extractData(response)) + .satisfies(exception -> assertThat(exception.getResponseBodyAsString()).isEqualTo("Foobar")); } } From bb45a7ae5ea45670884434ba15924d3490527e8a Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 11 Sep 2021 00:00:57 +0200 Subject: [PATCH 061/735] Fix bug fix icon in changelog configuration Closes gh-27384 --- ci/config/changelog-generator.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/config/changelog-generator.yml b/ci/config/changelog-generator.yml index 248e58db739e..a029e25582e4 100644 --- a/ci/config/changelog-generator.yml +++ b/ci/config/changelog-generator.yml @@ -4,7 +4,7 @@ changelog: - title: ":star: New Features" labels: - "type: enhancement" - - title: ":beetle: Bug Fixes" + - title: ":lady_beetle: Bug Fixes" labels: - "type: bug" - "type: regression" From 78dd219787c7087a4804c5b3a815ee1c614324a5 Mon Sep 17 00:00:00 2001 From: Radek Crlik Date: Sat, 11 Sep 2021 17:42:51 +0200 Subject: [PATCH 062/735] Fix misplaced comma in AOP doc See gh-27387 --- src/docs/asciidoc/core/core-aop.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/asciidoc/core/core-aop.adoc b/src/docs/asciidoc/core/core-aop.adoc index d4e4a9a6e7ce..a6412096e492 100644 --- a/src/docs/asciidoc/core/core-aop.adoc +++ b/src/docs/asciidoc/core/core-aop.adoc @@ -2830,7 +2830,7 @@ The corresponding Spring configuration is as follows: ---- -Notice that, for the time, being we assume that all business services are idempotent. If +Notice that, for the time being, we assume that all business services are idempotent. If this is not the case, we can refine the aspect so that it retries only genuinely idempotent operations, by introducing an `Idempotent` annotation and using the annotation to annotate the implementation of service operations, as the following example shows: From cecc0849a8c9a912004a843561a8458e7925ce3c Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Fri, 21 May 2021 21:16:30 +0200 Subject: [PATCH 063/735] Upgrade to Gradle 7.2 This commit upgrades Gradle to 7.2. Gradle configuration names are updated accordingly. This also upgrades Gradle build plugins. See gh-26870 --- build.gradle | 38 +-- gradle/docs.gradle | 79 +++--- gradle/spring-module.gradle | 4 + gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 59536 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 257 +++++++++++------- integration-tests/integration-tests.gradle | 40 +-- spring-aop/spring-aop.gradle | 9 +- spring-aspects/spring-aspects.gradle | 16 +- spring-beans/spring-beans.gradle | 6 +- .../spring-context-indexer.gradle | 10 +- .../spring-context-support.gradle | 30 +- spring-context/spring-context.gradle | 38 +-- .../kotlin-coroutines.gradle | 10 +- spring-core/spring-core.gradle | 32 +-- spring-expression/spring-expression.gradle | 8 +- spring-jdbc/spring-jdbc.gradle | 10 +- spring-jms/spring-jms.gradle | 14 +- spring-messaging/spring-messaging.gradle | 46 ++-- spring-orm/spring-orm.gradle | 22 +- spring-oxm/spring-oxm.gradle | 22 +- spring-r2dbc/spring-r2dbc.gradle | 24 +- spring-test/spring-test.gradle | 64 ++--- spring-tx/spring-tx.gradle | 18 +- spring-web/spring-web.gradle | 52 ++-- spring-webflux/spring-webflux.gradle | 66 ++--- spring-webmvc/spring-webmvc.gradle | 72 ++--- spring-websocket/spring-websocket.gradle | 16 +- 28 files changed, 521 insertions(+), 484 deletions(-) diff --git a/build.gradle b/build.gradle index b7a5d0330faa..059b5fec1d3d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,15 +1,15 @@ plugins { - id 'io.spring.dependency-management' version '1.0.9.RELEASE' apply false + id 'io.spring.dependency-management' version '1.0.11.RELEASE' apply false id 'io.spring.nohttp' version '0.0.5.RELEASE' id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false - id 'org.jetbrains.dokka' version '0.10.1' apply false + id 'org.jetbrains.dokka' version '1.5.0' apply false id 'org.asciidoctor.jvm.convert' version '3.1.0' id 'org.asciidoctor.jvm.pdf' version '3.1.0' - id 'de.undercouch.download' version '4.1.1' - id "io.freefair.aspectj" version '5.1.1' apply false - id "com.github.ben-manes.versions" version '0.28.0' - id "com.github.johnrengelman.shadow" version "6.1.0" apply false - id "me.champeau.jmh" version "0.6.4" apply false + id 'de.undercouch.download' version '4.1.2' + id "io.freefair.aspectj" version '6.1.0' apply false + id "com.github.ben-manes.versions" version '0.39.0' + id "com.github.johnrengelman.shadow" version '7.0.0' apply false + id "me.champeau.jmh" version "0.6.6" apply false id "org.jetbrains.kotlin.plugin.serialization" version "1.5.30" apply false id "org.unbroken-dome.xjc" version '2.0.0' apply false } @@ -342,18 +342,18 @@ configure([rootProject] + javaProjects) { project -> } dependencies { - testCompile("org.junit.jupiter:junit-jupiter-api") - testCompile("org.junit.jupiter:junit-jupiter-params") - testCompile("org.mockito:mockito-core") - testCompile("org.mockito:mockito-junit-jupiter") - testCompile("io.mockk:mockk") - testCompile("org.assertj:assertj-core") + testImplementation("org.junit.jupiter:junit-jupiter-api") + testImplementation("org.junit.jupiter:junit-jupiter-params") + testImplementation("org.mockito:mockito-core") + testImplementation("org.mockito:mockito-junit-jupiter") + testImplementation("io.mockk:mockk") + testImplementation("org.assertj:assertj-core") // Pull in the latest JUnit 5 Launcher API to ensure proper support in IDEs. - testRuntime("org.junit.platform:junit-platform-launcher") - testRuntime("org.junit.jupiter:junit-jupiter-engine") - testRuntime("org.apache.logging.log4j:log4j-core") - testRuntime("org.apache.logging.log4j:log4j-slf4j-impl") - testRuntime("org.apache.logging.log4j:log4j-jul") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") + testRuntimeOnly("org.apache.logging.log4j:log4j-core") + testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl") + testRuntimeOnly("org.apache.logging.log4j:log4j-jul") // JSR-305 only used for non-required meta-annotations compileOnly("com.google.code.findbugs:jsr305") testCompileOnly("com.google.code.findbugs:jsr305") @@ -364,7 +364,7 @@ configure([rootProject] + javaProjects) { project -> "https://docs.oracle.com/javase/8/docs/api/", "https://docs.oracle.com/javaee/7/api/", "https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ - "https://www.ibm.com/support/knowledgecenter/SS7JFU_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/", + "https://www.ibm.com/docs/api/v1/content/SSEQTP_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/", "https://glassfish.java.net/nonav/docs/v3/api/", "https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/", "https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/", diff --git a/gradle/docs.gradle b/gradle/docs.gradle index 4b6e139b6513..3d1ee01934b8 100644 --- a/gradle/docs.gradle +++ b/gradle/docs.gradle @@ -61,58 +61,41 @@ task api(type: Javadoc) { /** * Produce KDoc for all Spring Framework modules in "build/docs/kdoc" */ -dokka { - dependsOn { - tasks.getByName("api") - } - - doFirst { - configuration { - classpath = moduleProjects.collect { project -> project.jar.outputs.files.getFiles() }.flatten() - classpath += files(moduleProjects.collect { it.sourceSets.main.compileClasspath }) - - moduleProjects.findAll { - it.pluginManager.hasPlugin("kotlin") - }.each { project -> - def kotlinDirs = project.sourceSets.main.kotlin.srcDirs.collect() - kotlinDirs -= project.sourceSets.main.java.srcDirs - kotlinDirs.each { dir -> - if (dir.exists()) { - sourceRoot { - path = dir.path - } - } +/* +moduleProjects.each { module -> + dokkaHtmlPartial { + dokkaSourceSets { + configureEach { + externalDocumentationLink { + url.set(URL("https://docs.spring.io/spring-framework/docs/$version/javadoc-api/")) + packageListUrl = new File(buildDir, "docs/javadoc/package-list").toURI().toURL() + } + externalDocumentationLink { + url.set(URL("https://projectreactor.io/docs/core/release/api/")) + } + externalDocumentationLink { + url.set(URL("https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/")) + } + /* + This link causes errors, removing to fix the build. + externalDocumentationLink { + url.set(URL("https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/")) + } + // + externalDocumentationLink { + url.set(URL("https://r2dbc.io/spec/0.8.3.RELEASE/api/")) } } } } - - outputFormat = "html" - outputDirectory = "$buildDir/docs/kdoc" - - configuration { - moduleName = "spring-framework" - - externalDocumentationLink { - url = new URL("https://docs.spring.io/spring-framework/docs/$version/javadoc-api/") - packageListUrl = new File(buildDir, "docs/javadoc/package-list").toURI().toURL() - } - externalDocumentationLink { - url = new URL("https://projectreactor.io/docs/core/release/api/") - } - externalDocumentationLink { - url = new URL("https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/") - } -/* - This link causes errors, removing to fix the build. - externalDocumentationLink { - url = new URL("https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/") - } +} */ - externalDocumentationLink { - url = new URL("https://r2dbc.io/spec/0.8.3.RELEASE/api/") - } +tasks.dokkaHtmlMultiModule.configure { + dependsOn { + tasks.getByName("api") } + moduleName.set("spring-framework") + outputDirectory.set(project.file("$buildDir/docs/kdoc")) } task downloadResources(type: Download) { @@ -193,7 +176,7 @@ asciidoctorPdf { /** * Zip all docs (API and reference) into a single archive */ -task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dokka']) { +task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dokkaHtmlMultiModule']) { group = "Distribution" description = "Builds -${archiveClassifier} archive containing api and reference " + "for deployment at https://docs.spring.io/spring-framework/docs." @@ -212,7 +195,7 @@ task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dok from ("$asciidoctorPdf.outputDir") { into "reference/pdf" } - from (dokka) { + from (dokkaHtmlMultiModule) { into "kdoc-api" } } diff --git a/gradle/spring-module.gradle b/gradle/spring-module.gradle index 4b2b23d60ade..7628127cb5d4 100644 --- a/gradle/spring-module.gradle +++ b/gradle/spring-module.gradle @@ -17,6 +17,10 @@ jmh { duplicateClassesStrategy = DuplicatesStrategy.EXCLUDE } +tasks.findByName("processJmhResources").configure { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE +} + jmhJar { // Uncomment the following for Shadow's Transformer support. // mergeServiceFiles() diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..7454180f2ae8848c63b8b4dea2cb829da983f2fa 100644 GIT binary patch delta 18435 zcmY&<19zBR)MXm8v2EM7ZQHi-#I|kQZfv7Tn#Q)%81v4zX3d)U4d4 zYYc!v@NU%|U;_sM`2z(4BAilWijmR>4U^KdN)D8%@2KLcqkTDW%^3U(Wg>{qkAF z&RcYr;D1I5aD(N-PnqoEeBN~JyXiT(+@b`4Pv`;KmkBXYN48@0;iXuq6!ytn`vGp$ z6X4DQHMx^WlOek^bde&~cvEO@K$oJ}i`T`N;M|lX0mhmEH zuRpo!rS~#&rg}ajBdma$$}+vEhz?JAFUW|iZEcL%amAg_pzqul-B7Itq6Y_BGmOCC zX*Bw3rFz3R)DXpCVBkI!SoOHtYstv*e-May|+?b80ZRh$MZ$FerlC`)ZKt} zTd0Arf9N2dimjs>mg5&@sfTPsRXKXI;0L~&t+GH zkB<>wxI9D+k5VHHcB7Rku{Z>i3$&hgd9Mt_hS_GaGg0#2EHzyV=j=u5xSyV~F0*qs zW{k9}lFZ?H%@4hII_!bzao!S(J^^ZZVmG_;^qXkpJb7OyR*sPL>))Jx{K4xtO2xTr@St!@CJ=y3q2wY5F`77Tqwz8!&Q{f7Dp zifvzVV1!Dj*dxG%BsQyRP6${X+Tc$+XOG zzvq5xcC#&-iXlp$)L=9t{oD~bT~v^ZxQG;FRz|HcZj|^L#_(VNG)k{=_6|6Bs-tRNCn-XuaZ^*^hpZ@qwi`m|BxcF6IWc?_bhtK_cDZRTw#*bZ2`1@1HcB`mLUmo_>@2R&nj7&CiH zF&laHkG~7#U>c}rn#H)q^|sk+lc!?6wg0xy`VPn!{4P=u@cs%-V{VisOxVqAR{XX+ zw}R;{Ux@6A_QPka=48|tph^^ZFjSHS1BV3xfrbY84^=?&gX=bmz(7C({=*oy|BEp+ zYgj;<`j)GzINJA>{HeSHC)bvp6ucoE`c+6#2KzY9)TClmtEB1^^Mk)(mXWYvup02e%Ghm9qyjz#fO3bNGBX} zFiB>dvc1+If!>I10;qZk`?6pEd*(?bI&G*3YLt;MWw&!?=Mf7%^Op?qnyXWur- zwX|S^P>jF?{m9c&mmK-epCRg#WB+-VDe!2d2~YVoi%7_q(dyC{(}zB${!ElKB2D}P z7QNFM!*O^?FrPMGZ}wQ0TrQAVqZy!weLhu_Zq&`rlD39r*9&2sJHE(JT0EY5<}~x@ z1>P0!L2IFDqAB!($H9s2fI`&J_c+5QT|b#%99HA3@zUWOuYh(~7q7!Pf_U3u!ij5R zjFzeZta^~RvAmd_TY+RU@e}wQaB_PNZI26zmtzT4iGJg9U(Wrgrl>J%Z3MKHOWV(? zj>~Ph$<~8Q_sI+)$DOP^9FE6WhO09EZJ?1W|KidtEjzBX3RCLUwmj9qH1CM=^}MaK z59kGxRRfH(n|0*lkE?`Rpn6d^u5J6wPfi0WF(rucTv(I;`aW)3;nY=J=igkjsn?ED ztH&ji>}TW8)o!Jg@9Z}=i2-;o4#xUksQHu}XT~yRny|kg-$Pqeq!^78xAz2mYP9+4 z9gwAoti2ICvUWxE&RZ~}E)#M8*zy1iwz zHqN%q;u+f6Ti|SzILm0s-)=4)>eb5o-0K zbMW8ecB4p^6OuIX@u`f{>Yn~m9PINEl#+t*jqalwxIx=TeGB9(b6jA}9VOHnE$9sC zH`;epyH!k-3kNk2XWXW!K`L_G!%xOqk0ljPCMjK&VweAxEaZ==cT#;!7)X&C|X{dY^IY(e4D#!tx^vV3NZqK~--JW~wtXJ8X19adXim?PdN(|@o(OdgH3AiHts~?#QkolO?*=U_buYC&tQ3sc(O5HGHN~=6wB@dgIAVT$ z_OJWJ^&*40Pw&%y^t8-Wn4@l9gOl`uU z{Uda_uk9!Iix?KBu9CYwW9Rs=yt_lE11A+k$+)pkY5pXpocxIEJe|pTxwFgB%Kpr&tH;PzgOQ&m|(#Otm?@H^r`v)9yiR8v&Uy>d#TNdRfyN4Jk;`g zp+jr5@L2A7TS4=G-#O<`A9o;{En5!I8lVUG?!PMsv~{E_yP%QqqTxxG%8%KxZ{uwS zOT+EA5`*moN8wwV`Z=wp<3?~f#frmID^K?t7YL`G^(X43gWbo!6(q*u%HxWh$$^2EOq`Hj zp=-fS#Av+s9r-M)wGIggQ)b<@-BR`R8l1G@2+KODmn<_$Tzb7k35?e8;!V0G>`(!~ zY~qZz!6*&|TupOcnvsQYPbcMiJ!J{RyfezB^;fceBk znpA1XS)~KcC%0^_;ihibczSxwBuy;^ksH7lwfq7*GU;TLt*WmUEVQxt{ zKSfJf;lk$0XO8~48Xn2dnh8tMC9WHu`%DZj&a`2!tNB`5%;Md zBs|#T0Ktf?vkWQ)Y+q!At1qgL`C|nbzvgc(+28Q|4N6Geq)Il%+I5c@t02{9^=QJ?=h2BTe`~BEu=_u3xX2&?^zwcQWL+)7dI>JK0g8_`W1n~ zMaEP97X>Ok#=G*nkPmY`VoP8_{~+Rp7DtdSyWxI~?TZHxJ&=6KffcO2Qx1?j7=LZA z?GQt`oD9QpXw+s7`t+eeLO$cpQpl9(6h3_l9a6OUpbwBasCeCw^UB6we!&h9Ik@1zvJ`j4i=tvG9X8o34+N|y(ay~ho$f=l z514~mP>Z>#6+UxM<6@4z*|hFJ?KnkQBs_9{H(-v!_#Vm6Z4(xV5WgWMd3mB9A(>@XE292#k(HdI7P zJkQ2)`bQXTKlr}{VrhSF5rK9TsjtGs0Rs&nUMcH@$ZX_`Hh$Uje*)(Wd&oLW($hZQ z_tPt`{O@f8hZ<}?aQc6~|9iHt>=!%We3=F9yIfiqhXqp=QUVa!@UY@IF5^dr5H8$R zIh{=%S{$BHG+>~a=vQ={!B9B=<-ID=nyjfA0V8->gN{jRL>Qc4Rc<86;~aY+R!~Vs zV7MI~gVzGIY`B*Tt@rZk#Lg}H8sL39OE31wr_Bm%mn}8n773R&N)8B;l+-eOD@N$l zh&~Wz`m1qavVdxwtZLACS(U{rAa0;}KzPq9r76xL?c{&GaG5hX_NK!?)iq`t7q*F# zFoKI{h{*8lb>&sOeHXoAiqm*vV6?C~5U%tXR8^XQ9Y|(XQvcz*>a?%HQ(Vy<2UhNf zVmGeOO#v159KV@1g`m%gJ)XGPLa`a|?9HSzSSX{j;)xg>G(Ncc7+C>AyAWYa(k}5B3mtzg4tsA=C^Wfezb1&LlyrBE1~kNfeiubLls{C)!<%#m@f}v^o+7<VZ6!FZ;JeiAG@5vw7Li{flC8q1%jD_WP2ApBI{fQ}kN zhvhmdZ0bb5(qK@VS5-)G+@GK(tuF6eJuuV5>)Odgmt?i_`tB69DWpC~e8gqh!>jr_ zL1~L0xw@CbMSTmQflpRyjif*Y*O-IVQ_OFhUw-zhPrXXW>6X}+73IoMsu2?uuK3lT>;W#38#qG5tDl66A7Y{mYh=jK8Se!+f=N7%nv zYSHr6a~Nxd`jqov9VgII{%EpC_jFCEc>>SND0;}*Ja8Kv;G)MK7?T~h((c&FEBcQq zvUU1hW2^TX(dDCeU@~a1LF-(+#lz3997A@pipD53&Dr@III2tlw>=!iGabjXzbyUJ z4Hi~M1KCT-5!NR#I%!2Q*A>mqI{dpmUa_mW)%SDs{Iw1LG}0y=wbj@0ba-`q=0!`5 zr(9q1p{#;Rv2CY!L#uTbs(UHVR5+hB@m*zEf4jNu3(Kj$WwW|v?YL*F_0x)GtQC~! zzrnZRmBmwt+i@uXnk05>uR5&1Ddsx1*WwMrIbPD3yU*2By`71pk@gt{|H0D<#B7&8 z2dVmXp*;B)SWY)U1VSNs4ds!yBAj;P=xtatUx^7_gC5tHsF#vvdV;NmKwmNa1GNWZ zi_Jn-B4GnJ%xcYWD5h$*z^haku#_Irh818x^KB)3-;ufjf)D0TE#6>|zFf@~pU;Rs zNw+}c9S+6aPzxkEA6R%s*xhJ37wmgc)-{Zd1&mD5QT}4BQvczWr-Xim>(P^)52`@R z9+Z}44203T5}`AM_G^Snp<_KKc!OrA(5h7{MT^$ZeDsSr(R@^kI?O;}QF)OU zQ9-`t^ys=6DzgLcWt0U{Q(FBs22=r zKD%fLQ^5ZF24c-Z)J{xv?x$&4VhO^mswyb4QTIofCvzq+27*WlYm;h@;Bq%i;{hZA zM97mHI6pP}XFo|^pRTuWQzQs3B-8kY@ajLV!Fb?OYAO3jFv*W-_;AXd;G!CbpZt04iW`Ie^_+cQZGY_Zd@P<*J9EdRsc>c=edf$K|;voXRJ zk*aC@@=MKwR120(%I_HX`3pJ+8GMeO>%30t?~uXT0O-Tu-S{JA;zHoSyXs?Z;fy58 zi>sFtI7hoxNAdOt#3#AWFDW)4EPr4kDYq^`s%JkuO7^efX+u#-qZ56aoRM!tC^P6O zP(cFuBnQGjhX(^LJ(^rVe4-_Vk*3PkBCj!?SsULdmVr0cGJM^=?8b0^DuOFq>0*yA zk1g|C7n%pMS0A8@Aintd$fvRbH?SNdRaFrfoAJ=NoX)G5Gr}3-$^IGF+eI&t{I-GT zp=1fj)2|*ur1Td)+s&w%p#E6tDXX3YYOC{HGHLiCvv?!%%3DO$B$>A}aC;8D0Ef#b z{7NNqC8j+%1n95zq8|hFY`afAB4E)w_&7?oqG0IPJZv)lr{MT}>9p?}Y`=n+^CZ6E zKkjIXPub5!82(B-O2xQojW^P(#Q*;ETpEr^+Wa=qDJ9_k=Wm@fZB6?b(u?LUzX(}+ zE6OyapdG$HC& z&;oa*ALoyIxVvB2cm_N&h&{3ZTuU|aBrJlGOLtZc3KDx)<{ z27@)~GtQF@%6B@w3emrGe?Cv_{iC@a#YO8~OyGRIvp@%RRKC?fclXMP*6GzBFO z5U4QK?~>AR>?KF@I;|(rx(rKxdT9-k-anYS+#S#e1SzKPslK!Z&r8iomPsWG#>`Ld zJ<#+8GFHE!^wsXt(s=CGfVz5K+FHYP5T0E*?0A-z*lNBf)${Y`>Gwc@?j5{Q|6;Bl zkHG1%r$r&O!N^><8AEL+=y(P$7E6hd=>BZ4ZZ9ukJ2*~HR4KGvUR~MUOe$d>E5UK3 z*~O2LK4AnED}4t1Fs$JgvPa*O+WeCji_cn1@Tv7XQ6l@($F1K%{E$!naeX)`bfCG> z8iD<%_M6aeD?a-(Qqu61&fzQqC(E8ksa%CulMnPvR35d{<`VsmaHyzF+B zF6a@1$CT0xGVjofcct4SyxA40uQ`b#9kI)& z?B67-12X-$v#Im4CVUGZHXvPWwuspJ610ITG*A4xMoRVXJl5xbk;OL(;}=+$9?H`b z>u2~yd~gFZ*V}-Q0K6E@p}mtsri&%Zep?ZrPJmv`Qo1>94Lo||Yl)nqwHXEbe)!g( zo`w|LU@H14VvmBjjkl~=(?b{w^G$~q_G(HL`>|aQR%}A64mv0xGHa`S8!*Wb*eB}` zZh)&rkjLK!Rqar)UH)fM<&h&@v*YyOr!Xk2OOMV%$S2mCRdJxKO1RL7xP_Assw)bb z9$sQ30bapFfYTS`i1PihJZYA#0AWNmp>x(;C!?}kZG7Aq?zp!B+gGyJ^FrXQ0E<>2 zCjqZ(wDs-$#pVYP3NGA=en<@_uz!FjFvn1&w1_Igvqs_sL>ExMbcGx4X5f%`Wrri@ z{&vDs)V!rd=pS?G(ricfwPSg(w<8P_6=Qj`qBC7_XNE}1_5>+GBjpURPmvTNE7)~r)Y>ZZecMS7Ro2` z0}nC_GYo3O7j|Wux?6-LFZs%1IV0H`f`l9or-8y0=5VGzjPqO2cd$RRHJIY06Cnh- ztg@Pn1OeY=W`1Mv3`Ti6!@QIT{qcC*&vptnX4Pt1O|dWv8u2s|(CkV`)vBjAC_U5` zCw1f&c4o;LbBSp0=*q z3Y^horBAnR)u=3t?!}e}14%K>^562K!)Vy6r~v({5{t#iRh8WIL|U9H6H97qX09xp zjb0IJ^9Lqxop<-P*VA0By@In*5dq8Pr3bTPu|ArID*4tWM7w+mjit0PgmwLV4&2PW z3MnIzbdR`3tPqtUICEuAH^MR$K_u8~-U2=N1)R=l>zhygus44>6V^6nJFbW-`^)f} zI&h$FK)Mo*x?2`0npTD~jRd}5G~-h8=wL#Y-G+a^C?d>OzsVl7BFAaM==(H zR;ARWa^C3J)`p~_&FRsxt|@e+M&!84`eq)@aO9yBj8iifJv0xVW4F&N-(#E=k`AwJ z3EFXWcpsRlB%l_0Vdu`0G(11F7( zsl~*@XP{jS@?M#ec~%Pr~h z2`M*lIQaolzWN&;hkR2*<=!ORL(>YUMxOzj(60rQfr#wTrkLO!t{h~qg% zv$R}0IqVIg1v|YRu9w7RN&Uh7z$ijV=3U_M(sa`ZF=SIg$uY|=NdC-@%HtkUSEqJv zg|c}mKTCM=Z8YmsFQu7k{VrXtL^!Cts-eb@*v0B3M#3A7JE*)MeW1cfFqz~^S6OXFOIP&iL;Vpy z4dWKsw_1Wn%Y;eW1YOfeP_r1s4*p1C(iDG_hrr~-I%kA>ErxnMWRYu{IcG{sAW;*t z9T|i4bI*g)FXPpKM@~!@a7LDVVGqF}C@mePD$ai|I>73B+9!Ks7W$pw;$W1B%-rb; zJ*-q&ljb=&41dJ^*A0)7>Wa@khGZ;q1fL(2qW=|38j43mTl_;`PEEw07VKY%71l6p z@F|jp88XEnm1p~<5c*cVXvKlj0{THF=n3sU7g>Ki&(ErR;!KSmfH=?49R5(|c_*xw z4$jhCJ1gWT6-g5EV)Ahg?Nw=}`iCyQ6@0DqUb%AZEM^C#?B-@Hmw?LhJ^^VU>&phJ zlB!n5&>I>@sndh~v$2I2Ue23F?0!0}+9H~jg7E`?CS_ERu75^jSwm%!FTAegT`6s7 z^$|%sj2?8wtPQR>@D3sA0-M-g-vL@47YCnxdvd|1mPymvk!j5W1jHnVB&F-0R5e-vs`@u8a5GKdv`LF7uCfKncI4+??Z4iG@AxuX7 z6+@nP^TZ5HX#*z(!y+-KJ3+Ku0M90BTY{SC^{ z&y2#RZPjfX_PE<<>XwGp;g4&wcXsQ0T&XTi(^f+}4qSFH1%^GYi+!rJo~t#ChTeAX zmR0w(iODzQOL+b&{1OqTh*psAb;wT*drr^LKdN?c?HJ*gJl+%kEH&48&S{s28P=%p z7*?(xFW_RYxJxxILS!kdLIJYu@p#mnQ(?moGD1)AxQd66X6b*KN?o&e`u9#N4wu8% z^Gw#G!@|>c740RXziOR=tdbkqf(v~wS_N^CS^1hN-N4{Dww1lvSWcBTX*&9}Cz|s@ z*{O@jZ4RVHq19(HC9xSBZI0M)E;daza+Q*zayrX~N5H4xJ33BD4gn5Ka^Hj{995z4 zzm#Eo?ntC$q1a?)dD$qaC_M{NW!5R!vVZ(XQqS67xR3KP?rA1^+s3M$60WRTVHeTH z6BJO$_jVx0EGPXy}XK_&x597 zt(o6ArN8vZX0?~(lFGHRtHP{gO0y^$iU6Xt2e&v&ugLxfsl;GD)nf~3R^ACqSFLQ< zV7`cXgry((wDMJB55a6D4J;13$z6pupC{-F+wpToW%k1qKjUS^$Mo zN3@}T!ZdpiV7rkNvqP3KbpEn|9aB;@V;gMS1iSb@ zwyD7!5mfj)q+4jE1dq3H`sEKgrVqk|y8{_vmn8bMOi873!rmnu5S=1=-DFx+Oj)Hi zx?~ToiJqOrvSou?RVALltvMADodC7BOg7pOyc4m&6yd(qIuV5?dYUpYzpTe!BuWKi zpTg(JHBYzO&X1e{5o|ZVU-X5e?<}mh=|eMY{ldm>V3NsOGwyxO2h)l#)rH@BI*TN; z`yW26bMSp=k6C4Ja{xB}s`dNp zE+41IwEwo>7*PA|7v-F#jLN>h#a`Er9_86!fwPl{6yWR|fh?c%qc44uP~Ocm2V*(* zICMpS*&aJjxutxKC0Tm8+FBz;3;R^=ajXQUB*nTN*Lb;mruQHUE<&=I7pZ@F-O*VMkJbI#FOrBM8`QEL5Uy=q5e2 z_BwVH%c0^uIWO0*_qD;0jlPoA@sI7BPwOr-mrp7y`|EF)j;$GYdOtEPFRAKyUuUZS z(N4)*6R*ux8s@pMdC*TP?Hx`Zh{{Ser;clg&}CXriXZCr2A!wIoh;j=_eq3_%n7V} za?{KhXg2cXPpKHc90t6=`>s@QF-DNcTJRvLTS)E2FTb+og(wTV7?$kI?QZYgVBn)& zdpJf@tZ{j>B;<MVHiPl_U&KlqBT)$ic+M0uUQWK|N1 zCMl~@o|}!!7yyT%7p#G4?T^Azxt=D(KP{tyx^lD_(q&|zNFgO%!i%7T`>mUuU^FeR zHP&uClWgXm6iXgI8*DEA!O&X#X(zdrNctF{T#pyax16EZ5Lt5Z=RtAja!x+0Z31U8 zjfaky?W)wzd+66$L>o`n;DISQNs09g{GAv%8q2k>2n8q)O^M}=5r#^WR^=se#WSCt zQ`7E1w4qdChz4r@v6hgR?nsaE7pg2B6~+i5 zcTTbBQ2ghUbC-PV(@xvIR(a>Kh?{%YAsMV#4gt1nxBF?$FZ2~nFLKMS!aK=(`WllA zHS<_7ugqKw!#0aUtQwd#A$8|kPN3Af?Tkn)dHF?_?r#X68Wj;|$aw)Wj2Dkw{6)*^ zZfy!TWwh=%g~ECDCy1s8tTgWCi}F1BvTJ9p3H6IFq&zn#3FjZoecA_L_bxGWgeQup zAAs~1IPCnI@H>g|6Lp^Bk)mjrA3_qD4(D(65}l=2RzF-8@h>|Aq!2K-qxt(Q9w7c^ z;gtx`I+=gKOl;h=#fzSgw-V*YT~2_nnSz|!9hIxFb{~dKB!{H zSi??dnmr@%(1w^Be=*Jz5bZeofEKKN&@@uHUMFr-DHS!pb1I&;x9*${bmg6=2I4Zt zHb5LSvojY7ubCNGhp)=95jQ00sMAC{IZdAFsN!lAVQDeiec^HAu=8);2AKqNTT!&E zo+FAR`!A1#T6w@0A+o%&*yzkvxsrqbrfVTG+@z8l4+mRi@j<&)U9n6L>uZoezW>qS zA4YfO;_9dQSyEYpkWnsk0IY}Nr2m(ql@KuQjLgY-@g z4=$uai6^)A5+~^TvLdvhgfd+y?@+tRE^AJabamheJFnpA#O*5_B%s=t8<;?I;qJ}j z&g-9?hbwWEez-!GIhqpB>nFvyi{>Yv>dPU=)qXnr;3v-cd`l}BV?6!v{|cHDOx@IG z;TSiQQ(8=vlH^rCEaZ@Yw}?4#a_Qvx=}BJuxACxm(E7tP4hki^jU@8A zUS|4tTLd)gr@T|F$1eQXPY%fXb7u}(>&9gsd3It^B{W#6F2_g40cgo1^)@-xO&R5X z>qKon+Nvp!4v?-rGQu#M_J2v+3e+?N-WbgPQWf`ZL{Xd9KO^s{uIHTJ6~@d=mc7i z+##ya1p+ZHELmi%3C>g5V#yZt*jMv( zc{m*Y;7v*sjVZ-3mBuaT{$g+^sbs8Rp7BU%Ypi+c%JxtC4O}|9pkF-p-}F{Z7-+45 zDaJQx&CNR)8x~0Yf&M|-1rw%KW3ScjWmKH%J1fBxUp(;F%E+w!U470e_3%+U_q7~P zJm9VSWmZ->K`NfswW(|~fGdMQ!K2z%k-XS?Bh`zrjZDyBMu74Fb4q^A=j6+Vg@{Wc zPRd5Vy*-RS4p1OE-&8f^Fo}^yDj$rb+^>``iDy%t)^pHSV=En5B5~*|32#VkH6S%9 zxgIbsG+|{-$v7mhOww#v-ejaS>u(9KV9_*X!AY#N*LXIxor9hDv%aie@+??X6@Et=xz>6ev9U>6Pn$g4^!}w2Z%Kpqpp+M%mk~?GE-jL&0xLC zy(`*|&gm#mLeoRU8IU?Ujsv=;ab*URmsCl+r?%xcS1BVF*rP}XRR%MO_C!a9J^fOe>U;Y&3aj3 zX`3?i12*^W_|D@VEYR;h&b^s#Kd;JMNbZ#*x8*ZXm(jgw3!jyeHo14Zq!@_Q`V;Dv zKik~!-&%xx`F|l^z2A92aCt4x*I|_oMH9oeqsQgQDgI0j2p!W@BOtCTK8Jp#txi}7 z9kz);EX-2~XmxF5kyAa@n_$YYP^Hd4UPQ>O0-U^-pw1*n{*kdX`Jhz6{!W=V8a$0S z9mYboj#o)!d$gs6vf8I$OVOdZu7L5%)Vo0NhN`SwrQFhP3y4iXe2uV@(G{N{yjNG( zKvcN{k@pXkxyB~9ucR(uPSZ7{~sC=lQtz&V(^A^HppuN!@B4 zS>B=kb14>M-sR>{`teApuHlca6YXs6&sRvRV;9G!XI08CHS~M$=%T~g5Xt~$exVk` zWP^*0h{W%`>K{BktGr@+?ZP}2t0&smjKEVw@3=!rSjw5$gzlx`{dEajg$A58m|Okx zG8@BTPODSk@iqLbS*6>FdVqk}KKHuAHb0UJNnPm!(XO{zg--&@#!niF4T!dGVdNif z3_&r^3+rfQuV^8}2U?bkI5Ng*;&G>(O4&M<86GNxZK{IgKNbRfpg>+32I>(h`T&uv zUN{PRP&onFj$tn1+Yh|0AF330en{b~R+#i9^QIbl9fBv>pN|k&IL2W~j7xbkPyTL^ z*TFONZUS2f33w3)fdzr?)Yg;(s|||=aWZV(nkDaACGSxNCF>XLJSZ=W@?$*` z#sUftY&KqTV+l@2AP5$P-k^N`Bme-xcWPS|5O~arUq~%(z8z87JFB|llS&h>a>Som zC34(_uDViE!H2jI3<@d+F)LYhY)hoW6)i=9u~lM*WH?hI(yA$X#ip}yYld3RAv#1+sBt<)V_9c4(SN9Fn#$}_F}A-}P>N+8io}I3mh!}> z*~*N}ZF4Zergb;`R_g49>ZtTCaEsCHiFb(V{9c@X0`YV2O^@c6~LXg2AE zhA=a~!ALnP6aO9XOC^X15(1T)3!1lNXBEVj5s*G|Wm4YBPV`EOhU&)tTI9-KoLI-U zFI@adu6{w$dvT(zu*#aW*4F=i=!7`P!?hZy(9iL;Z^De3?AW`-gYTPALhrZ*K2|3_ zfz;6xQN9?|;#_U=4t^uS2VkQ8$|?Ub5CgKOj#Ni5j|(zX>x#K(h7LgDP-QHwok~-I zOu9rn%y97qrtKdG=ep)4MKF=TY9^n6CugQ3#G2yx;{))hvlxZGE~rzZ$qEHy-8?pU#G;bwufgSN6?*BeA!7N3RZEh{xS>>-G1!C(e1^ zzd#;39~PE_wFX3Tv;zo>5cc=md{Q}(Rb?37{;YPtAUGZo7j*yHfGH|TOVR#4ACaM2 z;1R0hO(Gl}+0gm9Bo}e@lW)J2OU4nukOTVKshHy7u)tLH^9@QI-jAnDBp(|J8&{fKu=_97$v&F67Z zq+QsJ=gUx3_h_%=+q47msQ*Ub=gMzoSa@S2>`Y9Cj*@Op4plTc!jDhu51nSGI z^sfZ(4=yzlR}kP2rcHRzAY9@T7f`z>fdCU0zibx^gVg&fMkcl)-0bRyWe12bT0}<@ z^h(RgGqS|1y#M;mER;8!CVmX!j=rfNa6>#_^j{^C+SxGhbSJ_a0O|ae!ZxiQCN2qA zKs_Z#Zy|9BOw6x{0*APNm$6tYVG2F$K~JNZ!6>}gJ_NLRYhcIsxY1z~)mt#Yl0pvC zO8#Nod;iow5{B*rUn(0WnN_~~M4|guwfkT(xv;z)olmj=f=aH#Y|#f_*d1H!o( z!EXNxKxth9w1oRr0+1laQceWfgi8z`YS#uzg#s9-QlTT7y2O^^M1PZx z3YS7iegfp6Cs0-ixlG93(JW4wuE7)mfihw}G~Uue{Xb+#F!BkDWs#*cHX^%(We}3% zT%^;m&Juw{hLp^6eyM}J({luCL_$7iRFA6^8B!v|B9P{$42F>|M`4Z_yA{kK()WcM zu#xAZWG%QtiANfX?@+QQOtbU;Avr*_>Yu0C2>=u}zhH9VLp6M>fS&yp*-7}yo8ZWB z{h>ce@HgV?^HgwRThCYnHt{Py0MS=Ja{nIj5%z;0S@?nGQ`z`*EVs&WWNwbzlk`(t zxDSc)$dD+4G6N(p?K>iEKXIk>GlGKTH{08WvrehnHhh%tgpp&8db4*FLN zETA@<$V=I7S^_KxvYv$Em4S{gO>(J#(Wf;Y%(NeECoG3n+o;d~Bjme-4dldKukd`S zRVAnKxOGjWc;L#OL{*BDEA8T=zL8^`J=2N)d&E#?OMUqk&9j_`GX*A9?V-G zdA5QQ#(_Eb^+wDkDiZ6RXL`fck|rVy%)BVv;dvY#`msZ}{x5fmd! zInmWSxvRgXbJ{unxAi*7=Lt&7_e0B#8M5a=Ad0yX#0rvMacnKnXgh>4iiRq<&wit93n!&p zeq~-o37qf)L{KJo3!{l9l9AQb;&>)^-QO4RhG>j`rBlJ09~cbfNMR_~pJD1$UzcGp zOEGTzz01j$=-kLC+O$r8B|VzBotz}sj(rUGOa7PDYwX~9Tum^sW^xjjoncxSz;kqz z$Pz$Ze|sBCTjk7oM&`b5g2mFtuTx>xl{dj*U$L%y-xeQL~|i>KzdUHeep-Yd@}p&L*ig< zgg__3l9T=nbM3bw0Sq&Z2*FA)P~sx0h634BXz0AxV69cED7QGTbK3?P?MENkiy-mV zZ1xV5ry3zIpy>xmThBL0Q!g+Wz@#?6fYvzmEczs(rcujrfCN=^!iWQ6$EM zaCnRThqt~gI-&6v@KZ78unqgv9j6-%TOxpbV`tK{KaoBbhc}$h+rK)5h|bT6wY*t6st-4$e99+Egb#3ip+ERbve08G@Ref&hP)qB&?>B94?eq5i3k;dOuU#!y-@+&5>~!FZik=z4&4|YHy=~!F254 zQAOTZr26}Nc7jzgJ;V~+9ry#?7Z0o*;|Q)k+@a^87lC}}1C)S))f5tk+lMNqw>vh( z`A9E~5m#b9!ZDBltf7QIuMh+VheCoD7nCFhuzThlhA?|8NCt3w?oWW|NDin&&eDU6 zwH`aY=))lpWG?{fda=-auXYp1WIPu&3 zwK|t(Qiqvc@<;1_W#ALDJ}bR;3&v4$9rP)eAg`-~iCte`O^MY+SaP!w%~+{{1tMo` zbp?T%ENs|mHP)Lsxno=nWL&qizR+!Ib=9i%4=B@(Umf$|7!WVxkD%hfRjvxV`Co<; zG*g4QG_>;RE{3V_DOblu$GYm&!+}%>G*yO{-|V9GYG|bH2JIU2iO}ZvY>}Fl%1!OE zZFsirH^$G>BDIy`8;R?lZl|uu@qWj2T5}((RG``6*05AWsVVa2Iu>!F5U>~7_Tlv{ zt=Dpgm~0QVa5mxta+fUt)I0gToeEm9eJX{yYZ~3sLR&nCuyuFWuiDIVJ+-lwViO(E zH+@Rg$&GLueMR$*K8kOl>+aF84Hss5p+dZ8hbW$=bWNIk0paB!qEK$xIm5{*^ad&( zgtA&gb&6FwaaR2G&+L+Pp>t^LrG*-B&Hv;-s(h0QTuYWdnUObu8LRSZoAVd7SJ;%$ zh%V?58mD~3G2X<$H7I)@x?lmbeeSY7X~QiE`dfQ5&K^FB#9e!6!@d9vrSt!);@ZQZ zO#84N5yH$kjm9X4iY#f+U`FKhg=x*FiDoUeu1O5LcC2w&$~5hKB9ZnH+8BpbTGh5T zi_nfmyQY$vQh%ildbR7T;7TKPxSs#vhKR|uup`qi1PufMa(tNCjRbllakshQgn1)a8OO-j8W&aBc_#q1hKDF5-X$h`!CeT z+c#Ial~fDsGAenv7~f@!icm(~)a3OKi((=^zcOb^qH$#DVciGXslUwTd$gt{7)&#a`&Lp ze%AnL0#U?lAl8vUkv$n>bxH*`qOujO0HZkPWZnE0;}0DSEu1O!hg-d9#{&#B1Dm)L zvN%r^hdEt1vR<4zwshg*0_BNrDWjo65be1&_82SW8#iKWs7>TCjUT;-K~*NxpG2P% zovXUo@S|fMGudVSRQrP}J3-Wxq;4xIxJJC|Y#TQBr>pwfy*%=`EUNE*dr-Y?9y9xK zmh1zS@z{^|UL}v**LNYY!?1qIRPTvr!gNXzE{%=-`oKclPrfMKwn` zUwPeIvLcxkIV>(SZ-SeBo-yw~{p!<&_}eELG?wxp zee-V59%@BtB+Z&Xs=O(@P$}v_qy1m=+`!~r^aT> zY+l?+6(L-=P%m4ScfAYR8;f9dyVw)@(;v{|nO#lAPI1xDHXMYt~-BGiP&9y2OQsYdh7-Q1(vL<$u6W0nxVn-qh=nwuRk}{d!uACozccRGx6~xZQ;=#JCE?OuA@;4 zadp$sm}jfgW4?La(pb!3f0B=HUI{5A4b$2rsB|ZGb?3@CTA{|zBf07pYpQ$NM({C6Srv6%_{rVkCndT=1nS}qyEf}Wjtg$e{ng7Wgz$7itYy0sWW_$qld);iUm85GBH)fk3b=2|5mvflm?~inoVo zDH_%e;y`DzoNj|NgZ`U%a9(N*=~8!qqy0Etkxo#`r!!{|(NyT0;5= z8nVZ6AiM+SjMG8J@6c4_f-KXd_}{My?Se1GWP|@wROFpD^5_lu?I%CBzpwi(`x~xh B8dv}T delta 17845 zcmV)CK*GO}(F4QI1F(Jx4W$DjNjn4p0N4ir06~)x5+0MO2`GQvQyWzj|J`gh3(E#l zNGO!HfVMRRN~%`0q^)g%XlN*vP!O#;m*h5VyX@j-1N|HN;8S1vqEAj=eCdn`)tUB9 zXZjcT^`bL6qvL}gvXj%9vrOD+x!Gc_0{$Zg+6lTXG$bmoEBV z*%y^c-mV0~Rjzv%e6eVI)yl>h;TMG)Ft8lqpR`>&IL&`>KDi5l$AavcVh9g;CF0tY zw_S0eIzKD?Nj~e4raA8wxiiImTRzv6;b6|LFmw)!E4=CiJ4I%&axSey4zE-MIh@*! z*P;K2Mx{xVYPLeagKA}Hj=N=1VrWU`ukuBnc14iBG?B}Uj>?=2UMk4|42=()8KOnc zrJzAxxaEIfjw(CKV6F$35u=1qyf(%cY8fXaS9iS?yetY{mQ#Xyat*7sSoM9fJlZqq zyasQ3>D>6p^`ck^Y|kYYZB*G})uAbQ#7)Jeb~glGz@2rPu}zBWDzo5K$tP<|meKV% z{Swf^eq6NBioF)v&~9NLIxHMTKe6gJ@QQ^A6fA!n#u1C&n`aG7TDXKM1Jly-DwTB` z+6?=Y)}hj;C#r5>&x;MCM4U13nuXVK*}@yRY~W3X%>U>*CB2C^K6_OZsXD!nG2RSX zQg*0)$G3%Es$otA@p_1N!hIPT(iSE=8OPZG+t)oFyD~{nevj0gZen$p>U<7}uRE`t5Mk1f4M0K*5 zbn@3IG5I2mk;8K>*RZ zPV6iL006)S001s%0eYj)9hu1 z9o)iQT9(v*sAuZ|ot){RrZ0Qw4{E0A+!Yx_M~#Pj&OPUM&i$RU=Uxu}e*6Sr2ror= z&?lmvFCO$)BY+^+21E>ENWe`I0{02H<-lz&?})gIVFyMWxX0B|0b?S6?qghp3lDgz z2?0|ALJU=7s-~Lb3>9AA5`#UYCl!Xeh^i@bxs5f&SdiD!WN}CIgq&WI4VCW;M!UJL zX2};d^sVj5oVl)OrkapV-C&SrG)*x=X*ru!2s04TjZ`pY$jP)4+%)7&MlpiZ`lgoF zo_p>^4qGz^(Y*uB10dY2kcIbt=$FIdYNqk;~47wf@)6|nJp z1cocL3zDR9N2Pxkw)dpi&_rvMW&Dh0@T*_}(1JFSc0S~Ph2Sr=vy)u*=TY$i_IHSo zR+&dtWFNxHE*!miRJ%o5@~GK^G~4$LzEYR-(B-b(L*3jyTq}M3d0g6sdx!X3-m&O% zK5g`P179KHJKXpIAAX`A2MFUA;`nXx^b?mboVbQgigIHTU8FI>`q53AjWaD&aowtj z{XyIX>c)*nLO~-WZG~>I)4S1d2q@&?nwL)CVSWqWi&m1&#K1!gt`g%O4s$u^->Dwq ziKc&0O9KQ7000OG0000%03-m(e&Y`S09YWC4iYDSty&3q8^?8ij|8zxaCt!zCFq1@ z9TX4Hl68`nY>}cQNW4Ullqp$~SHO~l1!CdFLKK}ij_t^a?I?C^CvlvnZkwiVn>dl2 z2$V(JN{`5`-8ShF_ek6HNRPBlPuIPYu>TAeAV5O2)35r3*_k(Q-h1+h5pb(Zu%oJ__pBsW0n5ILw`!&QR&YV`g0Fe z(qDM!FX_7;`U3rxX#QHT{f%h;)Eursw=*#qvV)~y%^Uo^% zi-%sMe^uz;#Pe;@{JUu05zT*i=u7mU9{MkT`ft(vPdQZoK&2mg=tnf8FsaNQ+QcPg zB>vP8Rd6Z0JoH5_Q`zldg;hx4azQCq*rRZThqlqTRMzn1O3_rQTrHk8LQ<{5UYN~` zM6*~lOGHyAnx&#yCK{i@%N1Us@=6cw=UQxpSE;<(LnnES%6^q^QhBYQ-VCSmIu8wh z@_LmwcFDfAhIn>`%h7L{)iGBzu`Md4dj-m3C8mA9+BL*<>q z#$7^ttIBOE-=^|zmG`K8yUKT{yjLu2SGYsreN0*~9yhFxn4U};Nv1XXj1fH*v-g=3 z@tCPc`YdzQGLp%zXwo*o$m9j-+~nSWls#s|?PyrHO%SUGdk**X9_=|b)Y%^j_V$3S z>mL2A-V)Q}qb(uZipEFVm?}HWc+%G6_K+S+87g-&RkRQ8-{0APDil115eG|&>WQhU zufO*|e`hFks^cJJmx_qNx{ltSp3aT|XgD5-VxGGXb7gkiOG$w^qMVBDjR8%!Sbh72niHRDV* ziFy8LE+*$j?t^6aZP9qt-ow;hzkmhvy*Hn-X^6?yVMbtNbyqZQ^rXg58`gk+I%Wv} zn_)dRq+3xjc8D%}EQ%nnTF7L7m}o9&*^jf`_qvUhVKY7w9Zgxr-0YHWFRd3$l_6UX zpXt^U&TiC*qZWx#pOG6k?3Tg)pra*fw(O6_45>lUBN1U5Qmc>^DHt)5b~Ntjsw!NI z1n4{$HWFeIi)*qvgK^ui;(81VQc1(wJ8C#tjR>Dkjf{xYC^_B^#qrdCc)uZxtgua6 zk98UGQF|;;k`c+0_z)tQ&9DwLB~&12@D1!*mTz_!3Mp=cg;B7Oq4cKN>5v&dW7q@H zal=g6Ipe`siZN4NZiBrkJCU*x216gmbV(FymgHuG@%%|8sgD?gR&0*{y4n=pukZnd z4=Nl~_>jVfbIehu)pG)WvuUpLR}~OKlW|)=S738Wh^a&L+Vx~KJU25o6%G7+Cy5mB zgmYsgkBC|@K4Jm_PwPoz`_|5QSk}^p`XV`649#jr4Lh^Q>Ne~#6Cqxn$7dNMF=%Va z%z9Ef6QmfoXAlQ3)PF8#3Y% zadcE<1`fd1&Q9fMZZnyI;&L;YPuy#TQ8b>AnXr*SGY&xUb>2678A+Y z8K%HOdgq_4LRFu_M>Ou|kj4W%sPPaV)#zDzN~25klE!!PFz_>5wCxglj7WZI13U5| zEq_YLKPH;v8sEhyG`dV_jozR);a6dBvkauhC;1dk%mr+J*Z6MMH9jqxFk@)&h{mHl zrf^i_d-#mTF=6-T8Rk?(1+rPGgl$9=j%#dkf@x6>czSc`jk7$f!9SrV{do%m!t8{? z_iAi$Qe&GDR#Nz^#uJ>-_?(E$ns)(3)X3cYY)?gFvU+N>nnCoBSmwB2<4L|xH19+4 z`$u#*Gt%mRw=*&|em}h_Y`Pzno?k^8e*hEwfM`A_yz-#vJtUfkGb=s>-!6cHfR$Mz z`*A8jVcz7T{n8M>ZTb_sl{EZ9Ctau4naX7TX?&g^VLE?wZ+}m)=YW4ODRy*lV4%-0 zG1XrPs($mVVfpnqoSihnIFkLdxG9um&n-U|`47l{bnr(|8dmglO7H~yeK7-wDwZXq zaHT($Qy2=MMuj@lir(iyxI1HnMlaJwpX86je}e=2n|Esb6hB?SmtDH3 z2qH6o`33b{;M{mDa5@@~1or8+Zcio*97pi1Jkx6v5MXCaYsb~Ynq)eWpKnF{n)FXZ z?Xd;o7ESu&rtMFr5(yJ(B7V>&0gnDdL*4MZH&eO+r*t!TR98ssbMRaw`7;`SLI8mT z=)hSAt~F=mz;JbDI6g~J%w!;QI(X14AnOu;uve^4wyaP3>(?jSLp+LQ7uU(iib%IyB(d&g@+hg;78M>h7yAeq$ALRoHGkKXA+E z$Sk-hd$Fs2nL4w9p@O*Y$c;U)W#d~)&8Js;i^Dp^* z0*7*zEGj~VehF4sRqSGny*K_CxeF=T^8;^lb}HF125G{kMRV?+hYktZWfNA^Mp7y8 zK~Q?ycf%rr+wgLaHQ|_<6z^eTG7izr@99SG9Q{$PCjJabSz`6L_QJJe7{LzTc$P&pwTy<&3RRUlSHmK;?}=QAhQaDW3#VWcNAH3 zeBPRTDf3?3mfdI$&WOg(nr9Gyzg`&u^o!f2rKJ57D_>p z6|?Vg?h(@(*X=o071{g^le>*>qSbVam`o}sAK8>b|11%e&;%`~b2OP7--q%0^2YDS z`2M`{2QYr1VC)sIW9WOu8<~7Q>^$*Og{KF+kI;wFegvaIDkB%3*%PWtWKSq7l`1YcDxQQ2@nv{J!xWV?G+w6C zhUUxUYVf%(Q(40_xrZB@rbxL=Dj3RV^{*yHd>4n-TOoHVRnazDOxxkS9kiZyN}IN3 zB^5N=* zRSTO+rA<{*P8-$GZdyUNOB=MzddG$*@q>mM;pUIiQ_z)hbE#Ze-IS)9G}Rt$5PSB{ zZZ;#h9nS7Rf1ecW&n(Gpu9}{vXQZ-f`UHIvD?cTbF`YvH*{rgE(zE22pLAQfhg-`U zuh612EpByB(~{w7svCylrBk%5$LCIyuhrGi=yOfca`=8ltKxHcSNfDRt@62QH^R_0 z&eQL6rRk>Dvf6rjMQv5ZXzg}S`HqV69hJT^pPHtdhqsrPJWs|IT9>BvpQa@*(FX6v zG}TYjreQCnH(slMt5{NgUf)qsS1F&Bb(M>$X}tWI&yt2I&-rJbqveuj?5J$`Dyfa2 z)m6Mq0XH@K)Y2v8X=-_4=4niodT&Y7W?$KLQhjA<+R}WTdYjX9>kD+SRS^oOY1{A= zZTId-(@wF^UEWso($wZtrs%e7t<}YaC_;#@`r0LUzKY&|qPJz*y~RHG`E6bypP5AX zN!p0^AUu8uDR>xM-ALFzBxXM~Q3z=}fHWCIG>0&I6x2Iu7&U)49j7qeMI&?qb$=4I zdMmhAJrO%@0f%YW! z^gLByEGSk+R0v4*d4w*N$Ju6z#j%HBI}6y$2en=-@S3=6+yZX94m&1j@s- z7T6|#0$c~dYq9IkA!P)AGkp~S$zYJ1SXZ#RM0|E~Q0PSm?DsT4N3f^)b#h(u9%_V5 zX*&EIX|gD~P!vtx?ra71pl%v)F!W~X2hcE!h8cu@6uKURdmo1-7icN4)ej4H1N~-C zjXgOK+mi#aJv4;`DZ%QUbVVZclkx;9`2kgbAhL^d{@etnm+5N8pB#fyH)bxtZGCAv z(%t0kPgBS{Q2HtjrfI0B$$M0c?{r~2T=zeXo7V&&aprCzww=i*}Atu7g^(*ivauMz~kkB%Vt{Wydlz%%2c26%>0PAbZO zVHx%tK(uzDl#ZZK`cW8TD2)eD77wB@gum{B2bO_jnqGl~01EF_^jx4Uqu1yfA~*&g zXJ`-N?D-n~5_QNF_5+Un-4&l$1b zVlHFqtluoN85b^C{A==lp#hS9J(npJ#6P4aY41r) zzCmv~c77X5L}H%sj>5t&@0heUDy;S1gSOS>JtH1v-k5l}z2h~i3^4NF6&iMb;ZYVE zMw*0%-9GdbpF1?HHim|4+)Zed=Fk<2Uz~GKc^P(Ig@x0&XuX0<-K(gA*KkN&lY2Xu zG054Q8wbK~$jE32#Ba*Id2vkqmfV{U$Nx9vJ;jeI`X+j1kh7hB8$CBTe@ANmT^tI8 z%U>zrTKuECin-M|B*gy(SPd`(_xvxjUL?s137KOyH>U{z01cBcFFt=Fp%d+BK4U;9 zQG_W5i)JASNpK)Q0wQpL<+Ml#cei41kCHe&P9?>p+KJN>I~`I^vK1h`IKB7k^xi`f z$H_mtr_+@M>C5+_xt%v}{#WO{86J83;VS@Ei3JLtp<*+hsY1oGzo z0?$?OJO$79;{|@aP!fO6t9TJ!?8i&|c&UPWRMbkwT3nEeFH`Yyyh6b%Rm^nBuTt@9 z+$&-4lf!G|@LCo3<8=yN@5dYbc%uq|Hz|0tiiLQKiUoM9g14zyECKGv0}3AWv2WJ zUAXGUhvkNk`0-H%ACsRSmy4fJ@kxBD3ZKSj6g(n1KPw?g{v19phcBr3BEF>J%lL|d zud3LNuL;cR*xS+;X+N^Br+x2{&hDMhb-$6_fKU(Pt0FQUXgNrZvzsVCnsFqv?#L z4-FYsQ-?D>;LdjHu_TT1CHN~aGkmDjWJkJg4G^!+V_APd%_48tErDv6BW5;ji^UDD zRu5Sw7wwplk`w{OGEKWJM&61c-AWn!SeUP8G#+beH4_Ov*)NUV?eGw&GHNDI6G(1Y zTfCv?T*@{QyK|!Q09wbk5koPD>=@(cA<~i4pSO?f(^5sSbdhUc+K$DW#_7^d7i%At z?KBg#vm$?P4h%?T=XymU;w*AsO_tJr)`+HUll+Uk_zx6vNw>G3jT){w3ck+Z=>7f0 zZVkM*!k^Z_E@_pZK6uH#|vzoL{-j1VFlUHP&5~q?j=UvJJNQG ztQdiCF$8_EaN_Pu8+afN6n8?m5UeR_p_6Log$5V(n9^W)-_vS~Ws`RJhQNPb1$C?| zd9D_ePe*`aI9AZ~Ltbg)DZ;JUo@-tu*O7CJ=T)ZI1&tn%#cisS85EaSvpS~c#CN9B z#Bx$vw|E@gm{;cJOuDi3F1#fxWZ9+5JCqVRCz5o`EDW890NUfNCuBn)3!&vFQE{E$L`Cf7FMSSX%ppLH+Z}#=p zSow$)$z3IL7frW#M>Z4|^9T!=Z8}B0h*MrWXXiVschEA=$a|yX9T~o!=%C?T+l^Cc zJx&MB$me(a*@lLLWZ=>PhKs!}#!ICa0! zq%jNgnF$>zrBZ3z%)Y*yOqHbKzEe_P=@<5$u^!~9G2OAzi#}oP&UL9JljG!zf{JIK z++G*8j)K=$#57N)hj_gSA8golO7xZP|KM?elUq)qLS)i(?&lk{oGMJh{^*FgklBY@Xfl<_Q zXP~(}ST6V01$~VfOmD6j!Hi}lsE}GQikW1YmBH)`f_+)KI!t#~B7=V;{F*`umxy#2Wt8(EbQ~ks9wZS(KV5#5Tn3Ia90r{}fI%pfbqBAG zhZ)E7)ZzqA672%@izC5sBpo>dCcpXi$VNFztSQnmI&u`@zQ#bqFd9d&ls?RomgbSh z9a2rjfNiKl2bR!$Y1B*?3Ko@s^L5lQN|i6ZtiZL|w5oq%{Fb@@E*2%%j=bcma{K~9 z*g1%nEZ;0g;S84ZZ$+Rfurh;Nhq0;{t~(EIRt}D@(Jb7fbe+_@H=t&)I)gPCtj*xI z9S>k?WEAWBmJZ|gs}#{3*pR`-`!HJ)1Dkx8vAM6Tv1bHZhH=MLI;iC#Y!$c|$*R>h zjP{ETat(izXB{@tTOAC4nWNhh1_%7AVaf!kVI5D=Jf5I1!?}stbx_Yv23hLf$iUTb z-)WrTtd2X+;vBW_q*Z6}B!10fs=2FA=3gy*dljsE43!G*3Uw(Is>(-a*5E!T4}b-Y zfvOC)-HYjNfcpi`=kG%(X3XcP?;p&=pz+F^6LKqRom~pA}O* zitR+Np{QZ(D2~p_Jh-k|dL!LPmexLM?tEqI^qRDq9Mg z5XBftj3z}dFir4oScbB&{m5>s{v&U=&_trq#7i&yQN}Z~OIu0}G)>RU*`4<}@7bB% zKYxGx0#L#u199YKSWZwV$nZd>D>{mDTs4qDNyi$4QT6z~D_%Bgf?>3L#NTtvX;?2D zS3IT*2i$Snp4fjDzR#<)A``4|dA(}wv^=L?rB!;kiotwU_gma`w+@AUtkSyhwp{M} z!e`jbUR3AG4XvnBVcyIZht6Vi~?pCC!$XF2 z*V~)DBVm8H7$*OZQJYl3482hadhsI2NCz~_NINtpC?|KI6H3`SG@1d%PsDdw{u}hq zN;OU~F7L1jT&KAitilb&Fl3X12zfSuFm;X)xQWOHL&7d)Q5wgn{78QJ6k5J;is+XP zCPO8_rlGMJB-kuQ*_=Yo1TswG4xnZd&eTjc8=-$6J^8TAa~kEnRQ@Zp-_W&B(4r@F zA==}0vBzsF1mB~743XqBmL9=0RSkGn$cvHf*hyc{<2{@hW+jKjbC|y%CNupHY_NC% zivz^btBLP-cDyV8j>u)=loBs>HoI5ME)xg)oK-Q0wAy|8WD$fm>K{-`0|W{H00;;G z000j`0OWQ8aHA9e04^;603eeQIvtaXMG=2tcr1y8Fl-J;AS+=<0%DU8Bp3oEEDhA^ zOY)M8%o5+cF$rC?trfMcty*f)R;^v=f~}||Xe!#;T3eTDZELN&-50xk+J1heP5AQ>h5O#S_uO;O@;~REd*_G$x$hVeE#bchX)otXQy|S5(oB)2a2%Sc(iDHm z=d>V|a!BLp9^#)o7^EQ2kg=K4%nI^sK2w@-kmvB+ARXYdq?xC2age6)e4$^UaY=wn zgLD^{X0A+{ySY+&7RpldwpC6=E zSPq?y(rl8ZN%(A*sapd4PU+dIakIwT0=zxIJEUW0kZSo|(zFEWdETY*ZjIk9uNMUA ze11=mHu8lUUlgRx!hItf0dAF#HfdIB+#aOuY--#QN9Ry zbx|XkG?PrBb@l6Owl{9Oa9w{x^R}%GwcEEfY;L-6OU8|9RXvu`-ECS`jcO1x1MP{P zcr;Bw##*Dod9K@pEx9z9G~MiNi>8v1OU-}vk*HbI)@CM? zn~b=jWUF%HP=CS+VCP>GiAU_UOz$aq3%%Z2laq^Gx`WAEmuNScCN)OlW>YHGYFgV2 z42lO5ZANs5VMXLS-RZTvBJkWy*OeV#L;7HwWg51*E|RpFR=H}h(|N+79g)tIW!RBK ze08bg^hlygY$C2`%N>7bDm`UZ(5M~DTanh3d~dg+OcNdUanr8azO?})g}EfnUB;5- zE1FX=ru?X=zAk4_6@__o1fE+ml1r&u^f1Kb24Jf-)zKla%-dbd>UZ1 zrj3!RR!Jg`ZnllKJ)4Yfg)@z>(fFepeOcp=F-^VHv?3jSxfa}-NB~*qkJ5Uq(yn+( z<8)qbZh{C!xnO@-XC~XMNVnr-Z+paowv!$H7>`ypMwA(X4(knx7z{UcWWe-wXM!d? zYT}xaVy|7T@yCbNOoy)$D=E%hUNTm(lPZqL)?$v+-~^-1P8m@Jm2t^L%4#!JK#Vtg zyUjM+Y*!$);1<)0MUqL00L0*EZcsE&usAK-?|{l|-)b7|PBKl}?TM6~#j9F+eZq25_L&oSl}DOMv^-tacpDI)l*Ws3u+~jO@;t(T)P=HCEZ#s_5q=m zOsVY!QsOJn)&+Ge6Tm)Ww_Bd@0PY(78ZJ)7_eP-cnXYk`>j9q`x2?Xc6O@55wF+6R zUPdIX!2{VGA;FSivN@+;GNZ7H2(pTDnAOKqF*ARg+C54vZ@Ve`i?%nDDvQRh?m&`1 zq46gH)wV=;UrwfCT3F(m!Q5qYpa!#f6qr0wF=5b9rk%HF(ITc!*R3wIFaCcftGwPt z(kzx{$*>g5L<;u}HzS4XD%ml zmdStbJcY@pn`!fUmkzJ8N>*8Y+DOO^r}1f4ix-`?x|khoRvF%jiA)8)P{?$8j2_qN zcl3Lm9-s$xdYN9)>3j6BPFK)Jbovl|Sf_p((CHe!4hx@F)hd&&*Xb&{TBj>%pT;-n z{3+hA^QZYnjXxtF2XwxPZ`S#J8h>5qLwtwM-{5abbEnRS z`9_`Zq8FJiI#0syE_V_3M&trw$P=ezkHosV$8&I5c0(*-9KBE5DJOC-Xv zw}1bq~AD0_Xerm`%ryiG9_$S z5G|btfiAUNdV09SO2l9v+e#(H6HYOdQs=^ z@xwZQU)~;p1L*~ciC}9ao{nQ-@B>rpUzKBxv=cUusOP5Trs3QnvHxGh9e>s7AM{V1|HfYe z3QwH;nHHR49fYzuGc3W3l5xrDAI392SFXx>lWE3V9Ds9il3PyZaN5>oC3>9W-^7vC z3~KZ-@iD?tIkhg+6t{m;RGk2%>@I0&kf)o$+-^ls0(YABNbM(=l#ad@nKp_j=b~Xs ziR;xu_+)lxy6|+af!@}gO2H_x)p;nZ-tYxW5Omq=l`GzMp*GTLr>vZN1?e}^C$t*Z zvzEdIc2|HA2RFN_4#EkzMqKnbbw!?!?%B@M0^^5Z;K?x-%lg?Z>}wMV8zEqHZ$cr~Y#Wv>9+)KMUZatUqbRU8 z8t9qrek(H^C0Tuzq|cP2$WL7tzj+Dj5y^2SF1D154CnsB$xbz`$wV||n-cG%rsT$p z+3RHdadK(3-noj(2L#8c5lODg)V8pv(GEnNb@F>dEHQr>!qge@L>#qg)RAUtiOYqF ziiV_ETExwD)bQ<))?-9$)E(FiRBYyC@}issHS!j9n)~I1tarxnQ2LfjdIJ)*jp{0E z&1oTd%!Qbw$W58s!6ms>F z=p0!~_Mv~8jyaicOS*t(ntw`5uFi0Bc4*mH8kSkk$>!f0;FM zX_t14I55!ZVsg0O$D2iuEDb7(J>5|NKW^Z~kzm@dax z9(|As$U7^}LF%#`6r&UPB*6`!Rf74h~*C=ami6xUxYCwiJxdr$+`z zKSC4A%8!s%R&j*2si(OEc*fy!q)?%=TjDZJ2}O zxT6o>jlKXz_7_Y$N})}IG`*#KfMzs#R(SI#)3*ZEzCv%_tu(VTZ5J| zw2$5kK)xTa>xGFgS0?X(NecjzFVKG%VVn?neu=&eQ+DJ1APlY1E?Q1s!Kk=yf7Uho z>8mg_!U{cKqpvI3ucSkC2V`!d^XMDk;>GG~>6>&X_z75-kv0UjevS5ORHV^e8r{tr z-9z*y&0eq3k-&c_AKw~<`8dtjsP0XgFv6AnG?0eo5P14T{xW#b*Hn2gEnt5-KvN1z zy!TUSi>IRbD3u+h@;fn7fy{F&hAKx7dG4i!c?5_GnvYV|_d&F16p;)pzEjB{zL-zr z(0&AZUkQ!(A>ghC5U-)t7(EXb-3)tNgb=z`>8m8n+N?vtl-1i&*ftMbE~0zsKG^I$ zSbh+rUiucsb!Ax@yB}j>yGeiKIZk1Xj!i#K^I*LZW_bWQIA-}FmJ~^}>p=K$bX9F{}z{s^KWc~OK(zl_X57aB^J9v}yQ5h#BE$+C)WOglV)nd0WWtaF{7`_Ur`my>4*NleQG#xae4fIo(b zW(&|g*#YHZNvDtE|6}yHvu(hDekJ-t*f!2RK;FZHRMb*l@Qwkh*~CqQRNLaepXypX z1?%ATf_nHIu3z6gK<7Dmd;{`0a!|toT0ck|TL$U;7Wr-*piO@R)KrbUz8SXO0vr1K z>76arfrqImq!ny+VkH!4?x*IR$d6*;ZA}Mhro(mzUa?agrFZpHi*)P~4~4N;XoIvH z9N%4VK|j4mV2DRQUD!_-9fmfA2(YVYyL#S$B;vqu7fnTbAFMqH``wS7^B5=|1O&fL z)qq(oV6_u4x(I(**#mD}MnAy(C&B4a1n6V%$&=vrIDq^F_KhE5Uw8_@{V`_#M0vCu zaNUXB=n0HT@D+ppDXi8-vp{tj)?7+k>1j}VvEKRgQ~DWva}8*pp`W8~KRo*kJ*&X} zP!~2fxQr@dM*q0dI|)Fux=pZWBk==RI7i{^BQf`kWlD2%|@R9!JA7& zLbM$uJ12y}_62$|T|{)@OJZtzfpL^t@1nMTYHutrF#D+^?~CN~9`YQ@#&&@c_Zf)( zbC~y8!2LO8jHwQXv>G~1q?c68ipT*%dY&c{8wd_!Y#~tMJ7yk!F8| zt?m_CLVw6cU@@p(#h4cY&Qsfz2Xp3w^4Cg%m03Tmq~9n%hyoMH^KY7{(QkRyn_!YB zzZa!Tgr~5$MAG$x)Fs71#6j}Kvcv3=9VUX8CH< zbP3|fY8f#$K*<5JQ7whM(v=GN2k26Xsh)#0!HKS(koLgAp-;)8z0w&_Z=nG4v6n8u z&Tm0Fi){4_!Y5Kp?!zv$FKfUifQ{%c82uYfrvE{%ejUd72aNYmI*0z3-a-EYr+bB->oH3#t(AY3 zV{Z=(SJr;D#0(`u*dc*~9T7D8Pudw894%!>c4wU&V1m<~0InidR6fbi?yPl(z+sKa zdF*kS>_4^1UO>y4T%Ar>epSr5&vp`$KdY7B(F%P0@VyHk@1fJ=6X0=aGjD-)BrOJD zW}IU@hg~^2r>a1fQvjTtvL*mKJ7q;pfP*U2=URL`VB_Y_JojbZ+MS=vaVN0C6L_MV zG1#5=35-E`KsD%r>-Q_ndvJ2tOYcMMP9f*t0iJ`(Z`^+YP)h>@lR(@Wvrt-`0tHG+ zuP2R@@mx=T@fPoQ1s`e^1I0H*kQPBGDky@!ZQG@8jY-+2ihreG5q$6i{3vmDTg0j$ zzRb*-nKN@{_wD`V6+i*YS)?$XfrA-sW?js?SYU8#vXxxQCc|*K!EbpWfu)3~jwq6_@KC0m;3A%jH^18_a0;ksC2DEwa@2{9@{ z9@T??<4QwR69zk{UvcHHX;`ICOwrF;@U;etd@YE)4MzI1WCsadP=`%^B>xPS-{`=~ zZ+2im8meb#4p~XIL9}ZOBg7D8R=PC8V}ObDcxEEK(4yGKcyCQWUe{9jCs+@k!_y|I z%s{W(&>P4w@hjQ>PQL$zY+=&aDU6cWr#hG)BVCyfP)h>@3IG5I2mk;8K>)Ppba*!h z005B=001VF5fT=Y4_ytCUk`sv8hJckqSy&Gc2Jx^WJ$J~08N{il-M$fz_ML$)Cpil z(nOv_nlZB^c4s&&O3h=OLiCz&(|f0 zxWU_-JZy>hxP*gvR>CLnNeQ1~g;6{g#-}AbkIzWR;j=8=6!AHpKQCbjFYxf9h%bov zVi;eNa1>t-<14KERUW>^KwoF+8zNo`Y*WiQwq}3m0_2RYtL9Wmu`JaRaQMQ)`Si^6+VbM`!rH~T?DX2=(n4nT zf`G`(Rpq*pDk*v~wMYPZ@vMNZDMPnxMYmU!lA{Xfo?n=Ibb4y3eyY1@Dut4|Y^ml& zqs$r}jAo=B(Ml>ogeEjyv(E`=kBzPf2uv9TQtO$~bamD#=Tv`lNy(K|w$J2O6jS51 zzZtOCHDWz7W0=L1XDW5WR5mtLGc~W+>*vX5{e~U@rE~?7e>vKU-v8bj;F4#abtcV(3ZtwXo9ia93HiETyQXwW4a-0){;$OU*l` zW^bjkyZTJ6_DL^0}`*)#EZ|2nvKRzMLH9-~@Z6$v#t8Dm%(qpP+DgzNe6d)1q zBqhyF$jJTyYFvl_=a>#I8jhJ)d6SBNPg#xg2^kZ3NX8kQ74ah(Y5Z8mlXyzTD&}Q8 ziY(pj-N-V2f>&hZQJ`Di%wp2fN(I%F@l)3M8GcSdNy+#HuO{$I8NXubRlFkL)cY@b z#`v{}-^hRXEq*8B_cG=%PZvI$eo(|8Wc(2o8L#0_GX9L$1@yV>%7mGk)QTD1R*OvS z4OW;ym1)%k9Bfem0tOqq3yyAUWp&q|LsN!RDnxa|j;>R|Mm2rIv7=tej5GFaa+`#| z;7u9Z_^XV+vD@2hF8Xe63+Qd`oig6S9jX(*DbjzPb*K-H7c^7E-(~!R6E%TrgW;RvG;WS{Ziv*W*a*`9Bb;$Er3?MyF~5GcXv`k>U)n}lwv$Sp+H@IKA5$mKk0g*4Ln{!tfvITeY zzr%8JJ5BdcEYsR9eGzJ4B&$}4FMmbRU6{8{_w7Kl77@PNe7|Bc#c?5(C5&Z=kJ#(oM90D4`rh2S!|^L!P#e#1hkD5@~-- z`63GV0~*rOZSqw7k^#-Y$Q4z3Oa2SPRURqEahB1B^h{7~+p03SwzqL9QU#$3-X zdYtQ?-K5xDAdfomEd6(yPtZ!yY_<35bMedeq`z2JWorljz5-f9<^93HM-$#+acw%9r!JOM%O<|BR`W& zd-%j_?b^q7Kl6{q^N{cg2u;11rFB5EP+oqG9&pHD#_Mo@aNMj;LUvsl&nK(ca(hT( zzFc2oHC6WQv8g7jo+3ZSwK+9G$cvfRnql)?g=XeQ3+LTh3)79nhEle8OqS3T$qn(> z(=5Bg?EWq-ldEywgzXW965%H(9^ik*rH(8dNdkbcS9|ow&_r`X~R^R?B+(oTiMzzlx8KnHqUi z8Rh-)VAnS-CO+3}yxqm8)X+N+uzieFVm-F#syP#M1p5&$wX3MJ8 z+R@grZ*5G^Uh4I@VT=>C4RJNc^~3mx$kS1F{L?3)BzdduD2MZKdu#jNno&f2&d{?` zW(>$oktzY@GO{|Ln~Bt^A4)(%?l-&(Dm!iL#$K_xOyhwAf=K2<+Bom zw7|hl6E5}B$d%n0sfZvfQRy9Fyz2~ z83#=#LaHnf1th^k*p|ux8!!8pfHE!)x*%=_hAddl)P%4h4%&8!5-W#xqqb}c=H(i|wqcIS&oDQ{ zhI7N-$f$ra3=RjPmMh?-IEkJYQ<}R9Z!}wmp$#~Uc%u1oh#TP}wF*kJJmQX2#27kL z_dz(yKufo<=m71bZfLp^Ll#t3(IHkrgMcvx@~om%Ib(h(<$Da7urTI`x|%`wD--sN zJEEa>4DGSEG?0ulkosfj8IMNN4)B=ZtvGG{|4Fp=Xhg!wPNgYzS>{Bp%%Qa+624X@ X49Luk)baa85H9$5YCsTPT`SVRWMtMW diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 442d9132ea32..ffed3a254e91 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0c811f..1b6c787337ff 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,101 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -106,80 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/integration-tests/integration-tests.gradle b/integration-tests/integration-tests.gradle index 71e23b906049..f7408e5c6ec4 100644 --- a/integration-tests/integration-tests.gradle +++ b/integration-tests/integration-tests.gradle @@ -1,26 +1,26 @@ description = "Spring Integration Tests" dependencies { - testCompile(project(":spring-aop")) - testCompile(project(":spring-beans")) - testCompile(project(":spring-context")) - testCompile(project(":spring-core")) - testCompile(testFixtures(project(":spring-aop"))) - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-core"))) - testCompile(testFixtures(project(":spring-tx"))) - testCompile(project(":spring-expression")) - testCompile(project(":spring-jdbc")) - testCompile(project(":spring-orm")) - testCompile(project(":spring-test")) - testCompile(project(":spring-tx")) - testCompile(project(":spring-web")) - testCompile("javax.inject:javax.inject") - testCompile("javax.resource:javax.resource-api") - testCompile("javax.servlet:javax.servlet-api") - testCompile("org.aspectj:aspectjweaver") - testCompile("org.hsqldb:hsqldb") - testCompile("org.hibernate:hibernate-core") + testImplementation(project(":spring-aop")) + testImplementation(project(":spring-beans")) + testImplementation(project(":spring-context")) + testImplementation(project(":spring-core")) + testImplementation(testFixtures(project(":spring-aop"))) + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation(testFixtures(project(":spring-tx"))) + testImplementation(project(":spring-expression")) + testImplementation(project(":spring-jdbc")) + testImplementation(project(":spring-orm")) + testImplementation(project(":spring-test")) + testImplementation(project(":spring-tx")) + testImplementation(project(":spring-web")) + testImplementation("javax.inject:javax.inject") + testImplementation("javax.resource:javax.resource-api") + testImplementation("javax.servlet:javax.servlet-api") + testImplementation("org.aspectj:aspectjweaver") + testImplementation("org.hsqldb:hsqldb") + testImplementation("org.hibernate:hibernate-core") } normalization { diff --git a/spring-aop/spring-aop.gradle b/spring-aop/spring-aop.gradle index 73bb378f39a7..67bf95e8dd6c 100644 --- a/spring-aop/spring-aop.gradle +++ b/spring-aop/spring-aop.gradle @@ -1,12 +1,13 @@ description = "Spring AOP" dependencies { - compile(project(":spring-beans")) - compile(project(":spring-core")) + api(project(":spring-beans")) + api(project(":spring-core")) optional("org.aspectj:aspectjweaver") optional("org.apache.commons:commons-pool2") optional("com.jamonapi:jamon") - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-core"))) + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-core"))) + testFixturesImplementation(testFixtures(project(":spring-beans"))) testFixturesImplementation(testFixtures(project(":spring-core"))) } diff --git a/spring-aspects/spring-aspects.gradle b/spring-aspects/spring-aspects.gradle index 12adbfb7e5f4..4ee0ef3fda68 100644 --- a/spring-aspects/spring-aspects.gradle +++ b/spring-aspects/spring-aspects.gradle @@ -11,7 +11,7 @@ sourceSets.test.java.srcDirs = files() aspectj.version = dependencyManagement.managedVersions['org.aspectj:aspectjweaver'] dependencies { - compile("org.aspectj:aspectjweaver") + api("org.aspectj:aspectjweaver") compileOnly("org.aspectj:aspectjrt") optional(project(":spring-aop")) // for @Async support optional(project(":spring-beans")) // for @Configurable support @@ -21,13 +21,13 @@ dependencies { optional(project(":spring-tx")) // for JPA, @Transactional support optional("javax.cache:cache-api") // for JCache aspect optional("javax.transaction:javax.transaction-api") // for @javax.transaction.Transactional support - testCompile(project(":spring-core")) // for CodeStyleAspect - testCompile(project(":spring-test")) - testCompile(testFixtures(project(":spring-context"))) - testCompile(testFixtures(project(":spring-context-support"))) - testCompile(testFixtures(project(":spring-core"))) - testCompile(testFixtures(project(":spring-tx"))) - testCompile("javax.mail:javax.mail-api") + testImplementation(project(":spring-core")) // for CodeStyleAspect + testImplementation(project(":spring-test")) + testImplementation(testFixtures(project(":spring-context"))) + testImplementation(testFixtures(project(":spring-context-support"))) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation(testFixtures(project(":spring-tx"))) + testImplementation("javax.mail:javax.mail-api") testCompileOnly("org.aspectj:aspectjrt") } diff --git a/spring-beans/spring-beans.gradle b/spring-beans/spring-beans.gradle index db894e8b83bc..e3f6f73b763b 100644 --- a/spring-beans/spring-beans.gradle +++ b/spring-beans/spring-beans.gradle @@ -4,14 +4,14 @@ apply plugin: "groovy" apply plugin: "kotlin" dependencies { - compile(project(":spring-core")) + api(project(":spring-core")) optional("javax.inject:javax.inject") optional("org.yaml:snakeyaml") optional("org.codehaus.groovy:groovy-xml") optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") - testCompile(testFixtures(project(":spring-core"))) - testCompile("javax.annotation:javax.annotation-api") + testImplementation(testFixtures(project(":spring-core"))) + testImplementation("javax.annotation:javax.annotation-api") testFixturesApi("org.junit.jupiter:junit-jupiter-api") testFixturesImplementation("org.assertj:assertj-core") } diff --git a/spring-context-indexer/spring-context-indexer.gradle b/spring-context-indexer/spring-context-indexer.gradle index a9769ada026a..2c1df2e91dc3 100644 --- a/spring-context-indexer/spring-context-indexer.gradle +++ b/spring-context-indexer/spring-context-indexer.gradle @@ -1,9 +1,9 @@ description = "Spring Context Indexer" dependencies { - testCompile(project(":spring-context")) - testCompile("javax.inject:javax.inject") - testCompile("javax.annotation:javax.annotation-api") - testCompile("javax.transaction:javax.transaction-api") - testCompile("org.eclipse.persistence:javax.persistence") + testImplementation(project(":spring-context")) + testImplementation("javax.inject:javax.inject") + testImplementation("javax.annotation:javax.annotation-api") + testImplementation("javax.transaction:javax.transaction-api") + testImplementation("org.eclipse.persistence:javax.persistence") } diff --git a/spring-context-support/spring-context-support.gradle b/spring-context-support/spring-context-support.gradle index f8a8631293ad..843d1920ebe4 100644 --- a/spring-context-support/spring-context-support.gradle +++ b/spring-context-support/spring-context-support.gradle @@ -1,9 +1,9 @@ description = "Spring Context Support" dependencies { - compile(project(":spring-beans")) - compile(project(":spring-context")) - compile(project(":spring-core")) + api(project(":spring-beans")) + api(project(":spring-context")) + api(project(":spring-core")) optional(project(":spring-jdbc")) // for Quartz support optional(project(":spring-tx")) // for Quartz support optional("javax.activation:javax.activation-api") @@ -14,18 +14,18 @@ dependencies { optional("org.quartz-scheduler:quartz") optional("org.codehaus.fabric3.api:commonj") optional("org.freemarker:freemarker") - testCompile(project(":spring-context")) - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-context"))) - testCompile(testFixtures(project(":spring-core"))) - testCompile(testFixtures(project(":spring-tx"))) - testCompile("org.hsqldb:hsqldb") - testCompile("org.hibernate:hibernate-validator") - testCompile("javax.annotation:javax.annotation-api") - testRuntime("org.ehcache:jcache") - testRuntime("org.ehcache:ehcache") - testRuntime("org.glassfish:javax.el") - testRuntime("com.sun.mail:javax.mail") + testImplementation(project(":spring-context")) + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-context"))) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation(testFixtures(project(":spring-tx"))) + testImplementation("org.hsqldb:hsqldb") + testImplementation("org.hibernate:hibernate-validator") + testImplementation("javax.annotation:javax.annotation-api") + testRuntimeOnly("org.ehcache:jcache") + testRuntimeOnly("org.ehcache:ehcache") + testRuntimeOnly("org.glassfish:javax.el") + testRuntimeOnly("com.sun.mail:javax.mail") testFixturesApi("org.junit.jupiter:junit-jupiter-api") testFixturesImplementation("org.assertj:assertj-core") testFixturesImplementation("org.mockito:mockito-core") diff --git a/spring-context/spring-context.gradle b/spring-context/spring-context.gradle index 0b06a7c56f0f..221e0f12fe1a 100644 --- a/spring-context/spring-context.gradle +++ b/spring-context/spring-context.gradle @@ -4,10 +4,10 @@ apply plugin: "groovy" apply plugin: "kotlin" dependencies { - compile(project(":spring-aop")) - compile(project(":spring-beans")) - compile(project(":spring-core")) - compile(project(":spring-expression")) + api(project(":spring-aop")) + api(project(":spring-beans")) + api(project(":spring-core")) + api(project(":spring-expression")) optional(project(":spring-instrument")) optional("javax.annotation:javax.annotation-api") optional("javax.ejb:javax.ejb-api") @@ -26,22 +26,22 @@ dependencies { optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") optional("org.reactivestreams:reactive-streams") - testCompile(testFixtures(project(":spring-aop"))) - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-core"))) - testCompile("io.projectreactor:reactor-core") - testCompile("org.codehaus.groovy:groovy-jsr223") - testCompile("org.codehaus.groovy:groovy-test") - testCompile("org.codehaus.groovy:groovy-xml") - testCompile("org.apache.commons:commons-pool2") - testCompile("javax.inject:javax.inject-tck") - testCompile("org.awaitility:awaitility") - testRuntime("javax.xml.bind:jaxb-api") - testRuntime("org.glassfish:javax.el") + testImplementation(testFixtures(project(":spring-aop"))) + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation("io.projectreactor:reactor-core") + testImplementation("org.codehaus.groovy:groovy-jsr223") + testImplementation("org.codehaus.groovy:groovy-test") + testImplementation("org.codehaus.groovy:groovy-xml") + testImplementation("org.apache.commons:commons-pool2") + testImplementation("javax.inject:javax.inject-tck") + testImplementation("org.awaitility:awaitility") + testRuntimeOnly("javax.xml.bind:jaxb-api") + testRuntimeOnly("org.glassfish:javax.el") // Substitute for javax.management:jmxremote_optional:1.0.1_04 (not available on Maven Central) - testRuntime("org.glassfish.external:opendmk_jmxremote_optional_jar") - testRuntime("org.javamoney:moneta") - testRuntime("org.junit.vintage:junit-vintage-engine") // for @Inject TCK + testRuntimeOnly("org.glassfish.external:opendmk_jmxremote_optional_jar") + testRuntimeOnly("org.javamoney:moneta") + testRuntimeOnly("org.junit.vintage:junit-vintage-engine") // for @Inject TCK testFixturesApi("org.junit.jupiter:junit-jupiter-api") testFixturesImplementation(testFixtures(project(":spring-beans"))) testFixturesImplementation("com.google.code.findbugs:jsr305") diff --git a/spring-core/kotlin-coroutines/kotlin-coroutines.gradle b/spring-core/kotlin-coroutines/kotlin-coroutines.gradle index 24efbb4fea70..94d7f1531456 100644 --- a/spring-core/kotlin-coroutines/kotlin-coroutines.gradle +++ b/spring-core/kotlin-coroutines/kotlin-coroutines.gradle @@ -14,11 +14,11 @@ artifacts { } dependencies { - compile("org.jetbrains.kotlin:kotlin-reflect") - compile("org.jetbrains.kotlin:kotlin-stdlib") - compile("io.projectreactor:reactor-core") - compile("org.jetbrains.kotlinx:kotlinx-coroutines-core") - compile("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") + api("org.jetbrains.kotlin:kotlin-reflect") + api("org.jetbrains.kotlin:kotlin-stdlib") + api("io.projectreactor:reactor-core") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core") + api("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") } eclipse { diff --git a/spring-core/spring-core.gradle b/spring-core/spring-core.gradle index 822b6ed58acd..d0b294876ef3 100644 --- a/spring-core/spring-core.gradle +++ b/spring-core/spring-core.gradle @@ -17,16 +17,16 @@ configurations { } task cglibRepackJar(type: ShadowJar) { - archiveBaseName = 'spring-cglib-repack' - archiveVersion = cglibVersion + archiveBaseName.set('spring-cglib-repack') + archiveVersion.set(cglibVersion) configurations = [project.configurations.cglib] relocate 'net.sf.cglib', 'org.springframework.cglib' relocate 'org.objectweb.asm', 'org.springframework.asm' } task objenesisRepackJar(type: ShadowJar) { - archiveBaseName = 'spring-objenesis-repack' - archiveVersion = objenesisVersion + archiveBaseName.set('spring-objenesis-repack') + archiveVersion.set(objenesisVersion) configurations = [project.configurations.objenesis] relocate 'org.objenesis', 'org.springframework.objenesis' } @@ -35,9 +35,9 @@ dependencies { cglib("cglib:cglib:${cglibVersion}@jar") objenesis("org.objenesis:objenesis:${objenesisVersion}@jar") coroutines(project(path: ":kotlin-coroutines", configuration: 'classesOnlyElements')) - compile(files(cglibRepackJar)) - compile(files(objenesisRepackJar)) - compile(project(":spring-jcl")) + api(files(cglibRepackJar)) + api(files(objenesisRepackJar)) + api(project(":spring-jcl")) compileOnly(project(":kotlin-coroutines")) compileOnly("io.projectreactor.tools:blockhound") optional("net.sf.jopt-simple:jopt-simple") @@ -51,15 +51,15 @@ dependencies { optional("io.reactivex.rxjava3:rxjava") optional("io.smallrye.reactive:mutiny") optional("io.netty:netty-buffer") - testCompile("io.projectreactor:reactor-test") - testCompile("com.google.code.findbugs:jsr305") - testCompile("javax.annotation:javax.annotation-api") - testCompile("javax.xml.bind:jaxb-api") - testCompile("com.fasterxml.woodstox:woodstox-core") - testCompile("org.xmlunit:xmlunit-assertj") - testCompile("org.xmlunit:xmlunit-matchers") - testCompile(project(":kotlin-coroutines")) - testCompile("io.projectreactor.tools:blockhound") + testImplementation("io.projectreactor:reactor-test") + testImplementation("com.google.code.findbugs:jsr305") + testImplementation("javax.annotation:javax.annotation-api") + testImplementation("javax.xml.bind:jaxb-api") + testImplementation("com.fasterxml.woodstox:woodstox-core") + testImplementation("org.xmlunit:xmlunit-assertj") + testImplementation("org.xmlunit:xmlunit-matchers") + testImplementation(project(":kotlin-coroutines")) + testImplementation("io.projectreactor.tools:blockhound") testFixturesImplementation("io.projectreactor:reactor-test") testFixturesImplementation("com.google.code.findbugs:jsr305") testFixturesImplementation("org.junit.platform:junit-platform-launcher") diff --git a/spring-expression/spring-expression.gradle b/spring-expression/spring-expression.gradle index 9f8299d4db90..920f7c7bc07f 100644 --- a/spring-expression/spring-expression.gradle +++ b/spring-expression/spring-expression.gradle @@ -3,8 +3,8 @@ description = "Spring Expression Language (SpEL)" apply plugin: "kotlin" dependencies { - compile(project(":spring-core")) - testCompile(testFixtures(project(":spring-core"))) - testCompile("org.jetbrains.kotlin:kotlin-reflect") - testCompile("org.jetbrains.kotlin:kotlin-stdlib") + api(project(":spring-core")) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation("org.jetbrains.kotlin:kotlin-reflect") + testImplementation("org.jetbrains.kotlin:kotlin-stdlib") } diff --git a/spring-jdbc/spring-jdbc.gradle b/spring-jdbc/spring-jdbc.gradle index e0737be91f53..41aa3f198720 100644 --- a/spring-jdbc/spring-jdbc.gradle +++ b/spring-jdbc/spring-jdbc.gradle @@ -3,9 +3,9 @@ description = "Spring JDBC" apply plugin: "kotlin" dependencies { - compile(project(":spring-beans")) - compile(project(":spring-core")) - compile(project(":spring-tx")) + api(project(":spring-beans")) + api(project(":spring-core")) + api(project(":spring-tx")) optional(project(":spring-context")) // for JndiDataSourceLookup optional("javax.transaction:javax.transaction-api") optional("org.hsqldb:hsqldb") @@ -14,6 +14,6 @@ dependencies { optional("org.apache.derby:derbyclient") optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-core"))) + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-core"))) } diff --git a/spring-jms/spring-jms.gradle b/spring-jms/spring-jms.gradle index a447c97a8084..32485dff84ba 100644 --- a/spring-jms/spring-jms.gradle +++ b/spring-jms/spring-jms.gradle @@ -1,10 +1,10 @@ description = "Spring JMS" dependencies { - compile(project(":spring-beans")) - compile(project(":spring-core")) - compile(project(":spring-messaging")) - compile(project(":spring-tx")) + api(project(":spring-beans")) + api(project(":spring-core")) + api(project(":spring-messaging")) + api(project(":spring-tx")) compileOnly("javax.jms:javax.jms-api") optional(project(":spring-aop")) optional(project(":spring-context")) @@ -12,8 +12,8 @@ dependencies { optional("javax.resource:javax.resource-api") optional("javax.transaction:javax.transaction-api") optional("com.fasterxml.jackson.core:jackson-databind") - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-tx"))) - testCompile("org.apache.activemq:activemq-broker") + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-tx"))) + testImplementation("org.apache.activemq:activemq-broker") testImplementation("javax.jms:javax.jms-api") } diff --git a/spring-messaging/spring-messaging.gradle b/spring-messaging/spring-messaging.gradle index 2973da314984..eed544b526b3 100644 --- a/spring-messaging/spring-messaging.gradle +++ b/spring-messaging/spring-messaging.gradle @@ -4,8 +4,8 @@ apply plugin: "kotlin" apply plugin: "kotlinx-serialization" dependencies { - compile(project(":spring-beans")) - compile(project(":spring-core")) + api(project(":spring-beans")) + api(project(":spring-core")) compileOnly(project(":kotlin-coroutines")) optional(project(":spring-context")) optional(project(":spring-oxm")) @@ -19,25 +19,25 @@ dependencies { optional("com.google.protobuf:protobuf-java-util") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") optional("org.jetbrains.kotlinx:kotlinx-serialization-json") - testCompile(project(":kotlin-coroutines")) - testCompile(testFixtures(project(":spring-core"))) - testCompile("javax.inject:javax.inject-tck") - testCompile("javax.servlet:javax.servlet-api") - testCompile("javax.validation:validation-api") - testCompile("com.thoughtworks.xstream:xstream") - testCompile("org.apache.activemq:activemq-broker") - testCompile("org.apache.activemq:activemq-kahadb-store") - testCompile("org.apache.activemq:activemq-stomp") - testCompile("io.projectreactor:reactor-test") - testCompile "io.reactivex.rxjava3:rxjava" - testCompile("org.jetbrains.kotlin:kotlin-reflect") - testCompile("org.jetbrains.kotlin:kotlin-stdlib") - testCompile("org.xmlunit:xmlunit-assertj") - testCompile("org.xmlunit:xmlunit-matchers") - testRuntime("com.sun.activation:javax.activation") - testRuntime("com.sun.xml.bind:jaxb-core") - testRuntime("com.sun.xml.bind:jaxb-impl") - testRuntime("javax.json:javax.json-api") - testRuntime("org.apache.johnzon:johnzon-jsonb") - testRuntime(project(":spring-context")) + testImplementation(project(":kotlin-coroutines")) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation("javax.inject:javax.inject-tck") + testImplementation("javax.servlet:javax.servlet-api") + testImplementation("javax.validation:validation-api") + testImplementation("com.thoughtworks.xstream:xstream") + testImplementation("org.apache.activemq:activemq-broker") + testImplementation("org.apache.activemq:activemq-kahadb-store") + testImplementation("org.apache.activemq:activemq-stomp") + testImplementation("io.projectreactor:reactor-test") + testImplementation("io.reactivex.rxjava3:rxjava") + testImplementation("org.jetbrains.kotlin:kotlin-reflect") + testImplementation("org.jetbrains.kotlin:kotlin-stdlib") + testImplementation("org.xmlunit:xmlunit-assertj") + testImplementation("org.xmlunit:xmlunit-matchers") + testRuntimeOnly("com.sun.activation:javax.activation") + testRuntimeOnly("com.sun.xml.bind:jaxb-core") + testRuntimeOnly("com.sun.xml.bind:jaxb-impl") + testRuntimeOnly("javax.json:javax.json-api") + testRuntimeOnly("org.apache.johnzon:johnzon-jsonb") + testRuntimeOnly(project(":spring-context")) } diff --git a/spring-orm/spring-orm.gradle b/spring-orm/spring-orm.gradle index 285e044a14b4..7870f5d77d72 100644 --- a/spring-orm/spring-orm.gradle +++ b/spring-orm/spring-orm.gradle @@ -1,21 +1,21 @@ description = "Spring Object/Relational Mapping" dependencies { - compile(project(":spring-beans")) - compile(project(":spring-core")) - compile(project(":spring-jdbc")) - compile(project(":spring-tx")) + api(project(":spring-beans")) + api(project(":spring-core")) + api(project(":spring-jdbc")) + api(project(":spring-tx")) optional(project(":spring-aop")) optional(project(":spring-context")) optional(project(":spring-web")) optional("org.eclipse.persistence:org.eclipse.persistence.jpa") optional("org.hibernate:hibernate-core") optional("javax.servlet:javax.servlet-api") - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-context"))) - testCompile(testFixtures(project(":spring-core"))) - testCompile(testFixtures(project(":spring-web"))) - testCompile("org.aspectj:aspectjweaver") - testCompile("org.hsqldb:hsqldb") - testRuntime("javax.xml.bind:jaxb-api") + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-context"))) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation(testFixtures(project(":spring-web"))) + testImplementation("org.aspectj:aspectjweaver") + testImplementation("org.hsqldb:hsqldb") + testRuntimeOnly("javax.xml.bind:jaxb-api") } diff --git a/spring-oxm/spring-oxm.gradle b/spring-oxm/spring-oxm.gradle index 901c4ba072b4..a78b41049e0c 100644 --- a/spring-oxm/spring-oxm.gradle +++ b/spring-oxm/spring-oxm.gradle @@ -23,23 +23,23 @@ sourceSets { } dependencies { - compile(project(":spring-beans")) - compile(project(":spring-core")) + api(project(":spring-beans")) + api(project(":spring-core")) optional("javax.xml.bind:jaxb-api") optional("javax.activation:javax.activation-api") optional("com.thoughtworks.xstream:xstream") optional("org.jibx:jibx-run") - testCompile(project(":spring-context")) - testCompile(testFixtures(project(":spring-core"))) - testCompile("org.ogce:xpp3") - testCompile("org.codehaus.jettison:jettison") { + testImplementation(project(":spring-context")) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation("org.ogce:xpp3") + testImplementation("org.codehaus.jettison:jettison") { exclude group: "stax", module: "stax-api" } - //testCompile(files(genJaxb.classesDir).builtBy(genJaxb)) - testCompile("org.xmlunit:xmlunit-assertj") - testCompile("org.xmlunit:xmlunit-matchers") - testRuntime("com.sun.xml.bind:jaxb-core") - testRuntime("com.sun.xml.bind:jaxb-impl") + //testImplementation(files(genJaxb.classesDir).builtBy(genJaxb)) + testImplementation("org.xmlunit:xmlunit-assertj") + testImplementation("org.xmlunit:xmlunit-matchers") + testRuntimeOnly("com.sun.xml.bind:jaxb-core") + testRuntimeOnly("com.sun.xml.bind:jaxb-impl") } // JiBX compiler is currently not compatible with JDK 9+. diff --git a/spring-r2dbc/spring-r2dbc.gradle b/spring-r2dbc/spring-r2dbc.gradle index 8fd50bf2e780..5c60dd7d3ad6 100644 --- a/spring-r2dbc/spring-r2dbc.gradle +++ b/spring-r2dbc/spring-r2dbc.gradle @@ -3,23 +3,23 @@ description = "Spring R2DBC" apply plugin: "kotlin" dependencies { - compile(project(":spring-beans")) - compile(project(":spring-core")) - compile(project(":spring-tx")) - compile("io.r2dbc:r2dbc-spi") - compile("io.projectreactor:reactor-core") + api(project(":spring-beans")) + api(project(":spring-core")) + api(project(":spring-tx")) + api("io.r2dbc:r2dbc-spi") + api("io.projectreactor:reactor-core") compileOnly(project(":kotlin-coroutines")) optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") optional("org.jetbrains.kotlinx:kotlinx-coroutines-core") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") - testCompile(project(":kotlin-coroutines")) - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-core"))) - testCompile(testFixtures(project(":spring-context"))) - testCompile("io.projectreactor:reactor-test") - testCompile("io.r2dbc:r2dbc-h2") - testCompile("io.r2dbc:r2dbc-spi-test:0.8.1.RELEASE") { + testImplementation(project(":kotlin-coroutines")) + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation(testFixtures(project(":spring-context"))) + testImplementation("io.projectreactor:reactor-test") + testImplementation("io.r2dbc:r2dbc-h2") + testImplementation("io.r2dbc:r2dbc-spi-test:0.8.1.RELEASE") { exclude group: "org.springframework", module: "spring-jdbc" } } diff --git a/spring-test/spring-test.gradle b/spring-test/spring-test.gradle index e27977c1af02..e15134600b87 100644 --- a/spring-test/spring-test.gradle +++ b/spring-test/spring-test.gradle @@ -3,7 +3,7 @@ description = "Spring TestContext Framework" apply plugin: "kotlin" dependencies { - compile(project(":spring-core")) + api(project(":spring-core")) optional(project(":spring-aop")) optional(project(":spring-beans")) optional(project(":spring-context")) @@ -45,41 +45,41 @@ dependencies { optional("io.projectreactor:reactor-test") optional("org.jetbrains.kotlinx:kotlinx-coroutines-core") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") - testCompile(project(":spring-context-support")) - testCompile(project(":spring-oxm")) - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-context"))) - testCompile(testFixtures(project(":spring-core"))) - testCompile(testFixtures(project(":spring-tx"))) - testCompile(testFixtures(project(":spring-web"))) - testCompile("javax.annotation:javax.annotation-api") - testCompile("javax.cache:cache-api") - testCompile("javax.ejb:javax.ejb-api") - testCompile("javax.interceptor:javax.interceptor-api") - testCompile("javax.mail:javax.mail-api") - testCompile("org.hibernate:hibernate-core") - testCompile("org.hibernate:hibernate-validator") - testCompile("javax.validation:validation-api") - testCompile("org.junit.platform:junit-platform-runner") { + testImplementation(project(":spring-context-support")) + testImplementation(project(":spring-oxm")) + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-context"))) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation(testFixtures(project(":spring-tx"))) + testImplementation(testFixtures(project(":spring-web"))) + testImplementation("javax.annotation:javax.annotation-api") + testImplementation("javax.cache:cache-api") + testImplementation("javax.ejb:javax.ejb-api") + testImplementation("javax.interceptor:javax.interceptor-api") + testImplementation("javax.mail:javax.mail-api") + testImplementation("org.hibernate:hibernate-core") + testImplementation("org.hibernate:hibernate-validator") + testImplementation("javax.validation:validation-api") + testImplementation("org.junit.platform:junit-platform-runner") { exclude group: "junit", module: "junit" } - testCompile("org.junit.platform:junit-platform-testkit") - testCompile("com.fasterxml.jackson.core:jackson-databind") - testCompile("com.thoughtworks.xstream:xstream") - testCompile("com.rometools:rome") - testCompile("org.apache.tiles:tiles-api") - testCompile("org.apache.tiles:tiles-core") - testCompile("org.apache.tiles:tiles-servlet") - testCompile("org.hsqldb:hsqldb") - testCompile("org.apache.httpcomponents:httpclient") - testCompile("io.projectreactor.netty:reactor-netty-http") - testCompile("de.bechte.junit:junit-hierarchicalcontextrunner") - testRuntime("org.junit.vintage:junit-vintage-engine") { + testImplementation("org.junit.platform:junit-platform-testkit") + testImplementation("com.fasterxml.jackson.core:jackson-databind") + testImplementation("com.thoughtworks.xstream:xstream") + testImplementation("com.rometools:rome") + testImplementation("org.apache.tiles:tiles-api") + testImplementation("org.apache.tiles:tiles-core") + testImplementation("org.apache.tiles:tiles-servlet") + testImplementation("org.hsqldb:hsqldb") + testImplementation("org.apache.httpcomponents:httpclient") + testImplementation("io.projectreactor.netty:reactor-netty-http") + testImplementation("de.bechte.junit:junit-hierarchicalcontextrunner") + testRuntimeOnly("org.junit.vintage:junit-vintage-engine") { exclude group: "junit", module: "junit" } - testRuntime("org.glassfish:javax.el") - testRuntime("com.sun.xml.bind:jaxb-core") - testRuntime("com.sun.xml.bind:jaxb-impl") + testRuntimeOnly("org.glassfish:javax.el") + testRuntimeOnly("com.sun.xml.bind:jaxb-core") + testRuntimeOnly("com.sun.xml.bind:jaxb-impl") } task junit(type: Test) { diff --git a/spring-tx/spring-tx.gradle b/spring-tx/spring-tx.gradle index 99c829892646..c9447732bc59 100644 --- a/spring-tx/spring-tx.gradle +++ b/spring-tx/spring-tx.gradle @@ -3,8 +3,8 @@ description = "Spring Transaction" apply plugin: "kotlin" dependencies { - compile(project(":spring-beans")) - compile(project(":spring-core")) + api(project(":spring-beans")) + api(project(":spring-core")) optional(project(":spring-aop")) optional(project(":spring-context")) // for JCA, @EnableTransactionManagement optional(project(":kotlin-coroutines")) @@ -19,11 +19,11 @@ dependencies { optional("org.jetbrains.kotlin:kotlin-stdlib") optional("org.jetbrains.kotlinx:kotlinx-coroutines-core") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-context"))) - testCompile(testFixtures(project(":spring-core"))) - testCompile("org.aspectj:aspectjweaver") - testCompile("org.codehaus.groovy:groovy") - testCompile("org.eclipse.persistence:javax.persistence") - testCompile("io.projectreactor:reactor-test") + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-context"))) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation("org.aspectj:aspectjweaver") + testImplementation("org.codehaus.groovy:groovy") + testImplementation("org.eclipse.persistence:javax.persistence") + testImplementation("io.projectreactor:reactor-test") } diff --git a/spring-web/spring-web.gradle b/spring-web/spring-web.gradle index 6d1ca73a86b2..f774f0afb8a9 100644 --- a/spring-web/spring-web.gradle +++ b/spring-web/spring-web.gradle @@ -4,8 +4,8 @@ apply plugin: "kotlin" apply plugin: "kotlinx-serialization" dependencies { - compile(project(":spring-beans")) - compile(project(":spring-core")) + api(project(":spring-beans")) + api(project(":spring-core")) compileOnly(project(":kotlin-coroutines")) compileOnly("io.projectreactor.tools:blockhound") optional(project(":spring-aop")) @@ -58,30 +58,30 @@ dependencies { optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") optional("org.jetbrains.kotlinx:kotlinx-serialization-json") - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-context"))) - testCompile(testFixtures(project(":spring-core"))) - testCompile("io.projectreactor:reactor-test") - testCompile("org.apache.taglibs:taglibs-standard-jstlel") - testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jdk8") - testCompile("com.fasterxml.jackson.datatype:jackson-datatype-joda") - testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") - testCompile("com.fasterxml.jackson.module:jackson-module-kotlin") - testCompile("org.apache.tomcat:tomcat-util") - testCompile("org.apache.tomcat.embed:tomcat-embed-core") - testCompile("org.eclipse.jetty:jetty-server") - testCompile("org.eclipse.jetty:jetty-servlet") - testCompile("com.squareup.okhttp3:mockwebserver") - testCompile("org.jetbrains.kotlin:kotlin-reflect") - testCompile("org.skyscreamer:jsonassert") - testCompile("org.xmlunit:xmlunit-assertj") - testCompile("org.xmlunit:xmlunit-matchers") - testCompile("io.projectreactor.tools:blockhound") - testRuntime("com.sun.mail:javax.mail") - testRuntime("com.sun.xml.bind:jaxb-core") - testRuntime("com.sun.xml.bind:jaxb-impl") - testRuntime("javax.json:javax.json-api") - testRuntime("org.apache.johnzon:johnzon-jsonb") + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-context"))) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation("io.projectreactor:reactor-test") + testImplementation("org.apache.taglibs:taglibs-standard-jstlel") + testImplementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8") + testImplementation("com.fasterxml.jackson.datatype:jackson-datatype-joda") + testImplementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") + testImplementation("com.fasterxml.jackson.module:jackson-module-kotlin") + testImplementation("org.apache.tomcat:tomcat-util") + testImplementation("org.apache.tomcat.embed:tomcat-embed-core") + testImplementation("org.eclipse.jetty:jetty-server") + testImplementation("org.eclipse.jetty:jetty-servlet") + testImplementation("com.squareup.okhttp3:mockwebserver") + testImplementation("org.jetbrains.kotlin:kotlin-reflect") + testImplementation("org.skyscreamer:jsonassert") + testImplementation("org.xmlunit:xmlunit-assertj") + testImplementation("org.xmlunit:xmlunit-matchers") + testImplementation("io.projectreactor.tools:blockhound") + testRuntimeOnly("com.sun.mail:javax.mail") + testRuntimeOnly("com.sun.xml.bind:jaxb-core") + testRuntimeOnly("com.sun.xml.bind:jaxb-impl") + testRuntimeOnly("javax.json:javax.json-api") + testRuntimeOnly("org.apache.johnzon:johnzon-jsonb") testFixturesApi("javax.servlet:javax.servlet-api") testFixturesApi("org.junit.jupiter:junit-jupiter-api") testFixturesApi("org.junit.jupiter:junit-jupiter-params") diff --git a/spring-webflux/spring-webflux.gradle b/spring-webflux/spring-webflux.gradle index c793b31804ea..7e9e49c69fde 100644 --- a/spring-webflux/spring-webflux.gradle +++ b/spring-webflux/spring-webflux.gradle @@ -3,10 +3,10 @@ description = "Spring WebFlux" apply plugin: "kotlin" dependencies { - compile(project(":spring-beans")) - compile(project(":spring-core")) - compile(project(":spring-web")) - compile("io.projectreactor:reactor-core") + api(project(":spring-beans")) + api(project(":spring-core")) + api(project(":spring-web")) + api("io.projectreactor:reactor-core") compileOnly(project(":kotlin-coroutines")) optional(project(":spring-context")) optional(project(":spring-context-support")) // for FreeMarker support @@ -27,35 +27,35 @@ dependencies { optional("org.jetbrains.kotlin:kotlin-stdlib") optional("com.google.protobuf:protobuf-java-util") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") - testCompile(project(":kotlin-coroutines")) - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-core"))) - testCompile(testFixtures(project(":spring-web"))) - testCompile("javax.xml.bind:jaxb-api") - testCompile("com.fasterxml:aalto-xml") - testCompile("org.hibernate:hibernate-validator") - testCompile("javax.validation:validation-api") - testCompile("io.reactivex.rxjava3:rxjava") - testCompile("io.projectreactor:reactor-test") - testCompile("io.undertow:undertow-core") - testCompile("org.apache.tomcat.embed:tomcat-embed-core") - testCompile("org.apache.tomcat:tomcat-util") - testCompile("org.eclipse.jetty:jetty-server") - testCompile("org.eclipse.jetty:jetty-servlet") - testCompile("org.eclipse.jetty:jetty-reactive-httpclient") - testCompile('org.apache.httpcomponents.client5:httpclient5') - testCompile('org.apache.httpcomponents.core5:httpcore5-reactive') - testCompile("com.squareup.okhttp3:mockwebserver") - testCompile("org.jetbrains.kotlin:kotlin-script-runtime") - testRuntime("org.jetbrains.kotlin:kotlin-scripting-jsr223") - testRuntime("org.jruby:jruby") - testRuntime("org.python:jython-standalone") - testRuntime("org.synchronoss.cloud:nio-multipart-parser") - testRuntime("org.webjars:underscorejs") - testRuntime("org.glassfish:javax.el") - testRuntime("com.sun.xml.bind:jaxb-core") - testRuntime("com.sun.xml.bind:jaxb-impl") - testRuntime("com.sun.activation:javax.activation") + testImplementation(project(":kotlin-coroutines")) + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation(testFixtures(project(":spring-web"))) + testImplementation("javax.xml.bind:jaxb-api") + testImplementation("com.fasterxml:aalto-xml") + testImplementation("org.hibernate:hibernate-validator") + testImplementation("javax.validation:validation-api") + testImplementation("io.reactivex.rxjava3:rxjava") + testImplementation("io.projectreactor:reactor-test") + testImplementation("io.undertow:undertow-core") + testImplementation("org.apache.tomcat.embed:tomcat-embed-core") + testImplementation("org.apache.tomcat:tomcat-util") + testImplementation("org.eclipse.jetty:jetty-server") + testImplementation("org.eclipse.jetty:jetty-servlet") + testImplementation("org.eclipse.jetty:jetty-reactive-httpclient") + testImplementation('org.apache.httpcomponents.client5:httpclient5') + testImplementation('org.apache.httpcomponents.core5:httpcore5-reactive') + testImplementation("com.squareup.okhttp3:mockwebserver") + testImplementation("org.jetbrains.kotlin:kotlin-script-runtime") + testRuntimeOnly("org.jetbrains.kotlin:kotlin-scripting-jsr223") + testRuntimeOnly("org.jruby:jruby") + testRuntimeOnly("org.python:jython-standalone") + testRuntimeOnly("org.synchronoss.cloud:nio-multipart-parser") + testRuntimeOnly("org.webjars:underscorejs") + testRuntimeOnly("org.glassfish:javax.el") + testRuntimeOnly("com.sun.xml.bind:jaxb-core") + testRuntimeOnly("com.sun.xml.bind:jaxb-impl") + testRuntimeOnly("com.sun.activation:javax.activation") } test { diff --git a/spring-webmvc/spring-webmvc.gradle b/spring-webmvc/spring-webmvc.gradle index 92deba6aa2f6..36ad9f649ef3 100644 --- a/spring-webmvc/spring-webmvc.gradle +++ b/spring-webmvc/spring-webmvc.gradle @@ -3,12 +3,12 @@ description = "Spring Web MVC" apply plugin: "kotlin" dependencies { - compile(project(":spring-aop")) - compile(project(":spring-beans")) - compile(project(":spring-context")) - compile(project(":spring-core")) - compile(project(":spring-expression")) - compile(project(":spring-web")) + api(project(":spring-aop")) + api(project(":spring-beans")) + api(project(":spring-context")) + api(project(":spring-core")) + api(project(":spring-expression")) + api(project(":spring-web")) compileOnly("javax.servlet:javax.servlet-api") compileOnly("com.google.code.findbugs:findbugs") // for groovy-templates optional(project(":spring-context-support")) // for FreeMarker support @@ -37,38 +37,38 @@ dependencies { optional("org.jetbrains.kotlin:kotlin-stdlib") optional("org.reactivestreams:reactive-streams") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") - testCompile(project(":kotlin-coroutines")) - testCompile(testFixtures(project(":spring-beans"))) - testCompile(testFixtures(project(":spring-core"))) - testCompile(testFixtures(project(":spring-context"))) - testCompile(testFixtures(project(":spring-web"))) - testCompile("javax.servlet:javax.servlet-api") - testCompile("org.eclipse.jetty:jetty-servlet") { + testImplementation(project(":kotlin-coroutines")) + testImplementation(testFixtures(project(":spring-beans"))) + testImplementation(testFixtures(project(":spring-core"))) + testImplementation(testFixtures(project(":spring-context"))) + testImplementation(testFixtures(project(":spring-web"))) + testImplementation("javax.servlet:javax.servlet-api") + testImplementation("org.eclipse.jetty:jetty-servlet") { exclude group: "javax.servlet", module: "javax.servlet" } - testCompile("org.eclipse.jetty:jetty-server") { + testImplementation("org.eclipse.jetty:jetty-server") { exclude group: "javax.servlet", module: "javax.servlet" } - testCompile("org.apache.httpcomponents:httpclient") - testCompile("commons-fileupload:commons-fileupload") - testCompile("commons-io:commons-io") - testCompile("joda-time:joda-time") - testCompile("org.mozilla:rhino") - testCompile("org.dom4j:dom4j") - testCompile("jaxen:jaxen") - testCompile("org.xmlunit:xmlunit-assertj") - testCompile("org.xmlunit:xmlunit-matchers") - testCompile("org.hibernate:hibernate-validator") - testCompile("javax.validation:validation-api") - testCompile("io.projectreactor:reactor-core") - testCompile("io.reactivex.rxjava3:rxjava") - testCompile("org.jetbrains.kotlin:kotlin-script-runtime") - testRuntime("org.jetbrains.kotlin:kotlin-scripting-jsr223") - testRuntime("org.jruby:jruby") - testRuntime("org.python:jython-standalone") - testRuntime("org.webjars:underscorejs") - testRuntime("org.glassfish:javax.el") - testRuntime("com.sun.xml.bind:jaxb-core") - testRuntime("com.sun.xml.bind:jaxb-impl") - testRuntime("com.sun.activation:javax.activation") + testImplementation("org.apache.httpcomponents:httpclient") + testImplementation("commons-fileupload:commons-fileupload") + testImplementation("commons-io:commons-io") + testImplementation("joda-time:joda-time") + testImplementation("org.mozilla:rhino") + testImplementation("org.dom4j:dom4j") + testImplementation("jaxen:jaxen") + testImplementation("org.xmlunit:xmlunit-assertj") + testImplementation("org.xmlunit:xmlunit-matchers") + testImplementation("org.hibernate:hibernate-validator") + testImplementation("javax.validation:validation-api") + testImplementation("io.projectreactor:reactor-core") + testImplementation("io.reactivex.rxjava3:rxjava") + testImplementation("org.jetbrains.kotlin:kotlin-script-runtime") + testRuntimeOnly("org.jetbrains.kotlin:kotlin-scripting-jsr223") + testRuntimeOnly("org.jruby:jruby") + testRuntimeOnly("org.python:jython-standalone") + testRuntimeOnly("org.webjars:underscorejs") + testRuntimeOnly("org.glassfish:javax.el") + testRuntimeOnly("com.sun.xml.bind:jaxb-core") + testRuntimeOnly("com.sun.xml.bind:jaxb-impl") + testRuntimeOnly("com.sun.activation:javax.activation") } diff --git a/spring-websocket/spring-websocket.gradle b/spring-websocket/spring-websocket.gradle index 6b311234386b..4ffe0ef667bd 100644 --- a/spring-websocket/spring-websocket.gradle +++ b/spring-websocket/spring-websocket.gradle @@ -1,9 +1,9 @@ description = "Spring WebSocket" dependencies { - compile(project(":spring-context")) - compile(project(":spring-core")) - compile(project(":spring-web")) + api(project(":spring-context")) + api(project(":spring-core")) + api(project(":spring-web")) optional(project(":spring-messaging")) optional(project(":spring-webmvc")) optional("javax.servlet:javax.servlet-api") @@ -21,9 +21,9 @@ dependencies { optional("io.undertow:undertow-servlet") optional("io.undertow:undertow-websockets-jsr") optional("com.fasterxml.jackson.core:jackson-databind") - testCompile(testFixtures(project(":spring-core"))) - testCompile(testFixtures(project(":spring-web"))) - testCompile("org.apache.tomcat.embed:tomcat-embed-core") - testCompile("org.apache.tomcat.embed:tomcat-embed-websocket") - testCompile("io.projectreactor.netty:reactor-netty-http") + testImplementation(testFixtures(project(":spring-core"))) + testImplementation(testFixtures(project(":spring-web"))) + testImplementation("org.apache.tomcat.embed:tomcat-embed-core") + testImplementation("org.apache.tomcat.embed:tomcat-embed-websocket") + testImplementation("io.projectreactor.netty:reactor-netty-http") } From ab41db474e2a94d672fa44f4f66c34c136f7db46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Sat, 12 Sep 2020 19:41:08 +0200 Subject: [PATCH 064/735] Update dokka to 1.5.0 See gh-26870 --- build.gradle | 2 ++ gradle/docs-dokka.gradle | 30 ++++++++++++++++++++++++++++++ settings.gradle | 2 +- 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 gradle/docs-dokka.gradle diff --git a/build.gradle b/build.gradle index 059b5fec1d3d..474a370a7657 100644 --- a/build.gradle +++ b/build.gradle @@ -313,6 +313,8 @@ configure([rootProject] + javaProjects) { project -> pluginManager.withPlugin("kotlin") { apply plugin: "org.jetbrains.dokka" + apply from: "${rootDir}/gradle/docs-dokka.gradle" + compileKotlin { kotlinOptions { languageVersion = "1.3" diff --git a/gradle/docs-dokka.gradle b/gradle/docs-dokka.gradle new file mode 100644 index 000000000000..ee5e4f15d701 --- /dev/null +++ b/gradle/docs-dokka.gradle @@ -0,0 +1,30 @@ +tasks.findByName("dokkaHtmlPartial")?.configure { + outputDirectory.set(new File(buildDir, "docs/kdoc")) + dokkaSourceSets { + configureEach { + sourceRoots.setFrom(file("src/main/kotlin")) + classpath.from(sourceSets["main"].runtimeClasspath) + externalDocumentationLink { + url.set(new URL("https://docs.spring.io/spring-framework/docs/current/javadoc-api/")) + } + externalDocumentationLink { + url.set(new URL("https://projectreactor.io/docs/core/release/api/")) + } + externalDocumentationLink { + url.set(new URL("https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/")) + } + externalDocumentationLink { + url.set(new URL("https://kotlin.github.io/kotlinx.coroutines/")) + } + externalDocumentationLink { + url.set(new URL("http://hamcrest.org/JavaHamcrest/javadoc/2.1/")) + } + externalDocumentationLink { + url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/")) + } + externalDocumentationLink { + url.set(new URL("https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/")) + } + } + } +} diff --git a/settings.gradle b/settings.gradle index 6c2fb1952c6b..8af23c7ca953 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,7 @@ pluginManagement { repositories { gradlePluginPortal() - maven { url 'https://repo.spring.io/plugins-release' } + maven { url "https://repo.spring.io/plugins-release" } } } From ca34d0cce8cb10a989ad60f98114c62c734f834c Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 13 Sep 2021 09:36:07 +0200 Subject: [PATCH 065/735] Polish Gradle upgrade Closes gh-26870 --- build.gradle | 9 +++++--- gradle/docs-dokka.gradle | 48 ++++++++++++++++++++-------------------- gradle/docs.gradle | 45 ++++++++----------------------------- 3 files changed, 39 insertions(+), 63 deletions(-) diff --git a/build.gradle b/build.gradle index 474a370a7657..5d930a2240cf 100644 --- a/build.gradle +++ b/build.gradle @@ -3,8 +3,8 @@ plugins { id 'io.spring.nohttp' version '0.0.5.RELEASE' id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false id 'org.jetbrains.dokka' version '1.5.0' apply false - id 'org.asciidoctor.jvm.convert' version '3.1.0' - id 'org.asciidoctor.jvm.pdf' version '3.1.0' + id 'org.asciidoctor.jvm.convert' version '3.3.2' + id 'org.asciidoctor.jvm.pdf' version '3.3.2' id 'de.undercouch.download' version '4.1.2' id "io.freefair.aspectj" version '6.1.0' apply false id "com.github.ben-manes.versions" version '0.39.0' @@ -381,7 +381,10 @@ configure([rootProject] + javaProjects) { project -> "https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/", "https://projectreactor.io/docs/test/release/api/", "https://junit.org/junit4/javadoc/4.13.2/", - "https://junit.org/junit5/docs/5.7.2/api/" + "https://junit.org/junit5/docs/5.7.2/api/", + "https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/", + "https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/", + "https://r2dbc.io/spec/0.8.5.RELEASE/api/" ] as String[] } diff --git a/gradle/docs-dokka.gradle b/gradle/docs-dokka.gradle index ee5e4f15d701..85c7a62468a2 100644 --- a/gradle/docs-dokka.gradle +++ b/gradle/docs-dokka.gradle @@ -2,29 +2,29 @@ tasks.findByName("dokkaHtmlPartial")?.configure { outputDirectory.set(new File(buildDir, "docs/kdoc")) dokkaSourceSets { configureEach { - sourceRoots.setFrom(file("src/main/kotlin")) - classpath.from(sourceSets["main"].runtimeClasspath) - externalDocumentationLink { - url.set(new URL("https://docs.spring.io/spring-framework/docs/current/javadoc-api/")) - } - externalDocumentationLink { - url.set(new URL("https://projectreactor.io/docs/core/release/api/")) - } - externalDocumentationLink { - url.set(new URL("https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/")) - } - externalDocumentationLink { - url.set(new URL("https://kotlin.github.io/kotlinx.coroutines/")) - } - externalDocumentationLink { - url.set(new URL("http://hamcrest.org/JavaHamcrest/javadoc/2.1/")) - } - externalDocumentationLink { - url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/")) - } - externalDocumentationLink { - url.set(new URL("https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/")) - } - } + sourceRoots.setFrom(file("src/main/kotlin")) + classpath.from(sourceSets["main"].runtimeClasspath) + externalDocumentationLink { + url.set(new URL("https://docs.spring.io/spring-framework/docs/current/javadoc-api/")) + } + externalDocumentationLink { + url.set(new URL("https://projectreactor.io/docs/core/release/api/")) + } + externalDocumentationLink { + url.set(new URL("https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/")) + } + externalDocumentationLink { + url.set(new URL("https://kotlin.github.io/kotlinx.coroutines/")) + } + externalDocumentationLink { + url.set(new URL("http://hamcrest.org/JavaHamcrest/javadoc/2.1/")) + } + externalDocumentationLink { + url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/")) + } + externalDocumentationLink { + url.set(new URL("https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/")) + } + } } } diff --git a/gradle/docs.gradle b/gradle/docs.gradle index 3d1ee01934b8..bfb26d152b9c 100644 --- a/gradle/docs.gradle +++ b/gradle/docs.gradle @@ -61,42 +61,15 @@ task api(type: Javadoc) { /** * Produce KDoc for all Spring Framework modules in "build/docs/kdoc" */ -/* -moduleProjects.each { module -> - dokkaHtmlPartial { - dokkaSourceSets { - configureEach { - externalDocumentationLink { - url.set(URL("https://docs.spring.io/spring-framework/docs/$version/javadoc-api/")) - packageListUrl = new File(buildDir, "docs/javadoc/package-list").toURI().toURL() - } - externalDocumentationLink { - url.set(URL("https://projectreactor.io/docs/core/release/api/")) - } - externalDocumentationLink { - url.set(URL("https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/")) - } - /* - This link causes errors, removing to fix the build. - externalDocumentationLink { - url.set(URL("https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/")) - } - // - externalDocumentationLink { - url.set(URL("https://r2dbc.io/spec/0.8.3.RELEASE/api/")) - } - } +pluginManager.withPlugin("kotlin") { + tasks.dokkaHtmlMultiModule.configure { + dependsOn { + tasks.getByName("api") } + moduleName.set("spring-framework") + outputDirectory.set(project.file("$buildDir/docs/kdoc")) } } -*/ -tasks.dokkaHtmlMultiModule.configure { - dependsOn { - tasks.getByName("api") - } - moduleName.set("spring-framework") - outputDirectory.set(project.file("$buildDir/docs/kdoc")) -} task downloadResources(type: Download) { def version = "0.2.5" @@ -195,7 +168,7 @@ task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dok from ("$asciidoctorPdf.outputDir") { into "reference/pdf" } - from (dokkaHtmlMultiModule) { + from (dokkaHtmlMultiModule.outputDirectory) { into "kdoc-api" } } @@ -252,11 +225,11 @@ task distZip(type: Zip, dependsOn: [docsZip, schemaZip]) { expand(copyright: new Date().format("yyyy"), version: project.version) } - from(zipTree(docsZip.archivePath)) { + from(zipTree(docsZip.archiveFile)) { into "${baseDir}/docs" } - from(zipTree(schemaZip.archivePath)) { + from(zipTree(schemaZip.archiveFile)) { into "${baseDir}/schema" } From c02ae7bcb86a0aeddc66812d8cadec6cd45a6037 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 13 Sep 2021 10:14:58 +0200 Subject: [PATCH 066/735] Fix noHttp failure --- gradle/docs-dokka.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/docs-dokka.gradle b/gradle/docs-dokka.gradle index 85c7a62468a2..ef06f904185c 100644 --- a/gradle/docs-dokka.gradle +++ b/gradle/docs-dokka.gradle @@ -17,7 +17,7 @@ tasks.findByName("dokkaHtmlPartial")?.configure { url.set(new URL("https://kotlin.github.io/kotlinx.coroutines/")) } externalDocumentationLink { - url.set(new URL("http://hamcrest.org/JavaHamcrest/javadoc/2.1/")) + url.set(new URL("https://hamcrest.org/JavaHamcrest/javadoc/2.1/")) } externalDocumentationLink { url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/")) From a087d13aea77cd93b39b36b6e9b68270b140f9da Mon Sep 17 00:00:00 2001 From: Mustafa Ulu Date: Sun, 12 Sep 2021 14:18:54 +0300 Subject: [PATCH 067/735] Fix wording in Javadoc of ClientResponse.mutate() Removed an extra "the". --- .../web/reactive/function/client/ClientResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientResponse.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientResponse.java index 897a1a28b5d7..5895c4294b00 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientResponse.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientResponse.java @@ -193,7 +193,7 @@ public interface ClientResponse { String logPrefix(); /** - * Return a builder to mutate the this response, for example to change + * Return a builder to mutate this response, for example to change * the status, headers, cookies, and replace or transform the body. * @return a builder to mutate the request with * @since 5.3 From db424d0bc5b5a8b6d77062039f260edea02bfb66 Mon Sep 17 00:00:00 2001 From: Mustafa Ulu Date: Sun, 12 Sep 2021 14:27:33 +0300 Subject: [PATCH 068/735] Replace word "request" with "response" --- .../web/reactive/function/client/ClientResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientResponse.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientResponse.java index 5895c4294b00..90384a6ede04 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientResponse.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientResponse.java @@ -195,7 +195,7 @@ public interface ClientResponse { /** * Return a builder to mutate this response, for example to change * the status, headers, cookies, and replace or transform the body. - * @return a builder to mutate the request with + * @return a builder to mutate the response with * @since 5.3 */ default Builder mutate() { From 04e6b233cade1510a2d32bc2f7bfcf2d6e21b9c7 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 6 Sep 2021 16:38:37 +0200 Subject: [PATCH 069/735] Upgrade to JUnit 5.8 Closes gh-27392 --- build.gradle | 6 ++++-- .../SpringTestContextFrameworkTestSuite.java | 11 ++++------- .../context/env/TestPropertySourceTestSuite.java | 11 ++++------- .../junit/SpringJUnitJupiterTestSuite.java | 16 +++++----------- .../reactive/ClientHttpConnectorTests.java | 11 +++++++---- .../handler/PathPatternsParameterizedTest.java | 7 +++++-- 6 files changed, 29 insertions(+), 33 deletions(-) diff --git a/build.gradle b/build.gradle index 5d930a2240cf..f5419026e941 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,7 @@ configure(allprojects) { project -> mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.30" mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2" mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2" - mavenBom "org.junit:junit-bom:5.7.2" + mavenBom "org.junit:junit-bom:5.8.0" } dependencies { dependencySet(group: 'org.apache.logging.log4j', version: '2.14.1') { @@ -346,6 +346,7 @@ configure([rootProject] + javaProjects) { project -> dependencies { testImplementation("org.junit.jupiter:junit-jupiter-api") testImplementation("org.junit.jupiter:junit-jupiter-params") + testImplementation("org.junit.platform:junit-platform-suite-api") testImplementation("org.mockito:mockito-core") testImplementation("org.mockito:mockito-junit-jupiter") testImplementation("io.mockk:mockk") @@ -353,6 +354,7 @@ configure([rootProject] + javaProjects) { project -> // Pull in the latest JUnit 5 Launcher API to ensure proper support in IDEs. testRuntimeOnly("org.junit.platform:junit-platform-launcher") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") + testRuntimeOnly("org.junit.platform:junit-platform-suite-engine") testRuntimeOnly("org.apache.logging.log4j:log4j-core") testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl") testRuntimeOnly("org.apache.logging.log4j:log4j-jul") @@ -381,7 +383,7 @@ configure([rootProject] + javaProjects) { project -> "https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/", "https://projectreactor.io/docs/test/release/api/", "https://junit.org/junit4/javadoc/4.13.2/", - "https://junit.org/junit5/docs/5.7.2/api/", + "https://junit.org/junit5/docs/5.8.0/api/", "https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/", "https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/", "https://r2dbc.io/spec/0.8.5.RELEASE/api/" diff --git a/spring-test/src/test/java/org/springframework/test/context/SpringTestContextFrameworkTestSuite.java b/spring-test/src/test/java/org/springframework/test/context/SpringTestContextFrameworkTestSuite.java index d1532dfcffc1..4500d5566899 100644 --- a/spring-test/src/test/java/org/springframework/test/context/SpringTestContextFrameworkTestSuite.java +++ b/spring-test/src/test/java/org/springframework/test/context/SpringTestContextFrameworkTestSuite.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,10 @@ package org.springframework.test.context; -import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.suite.api.ExcludeTags; import org.junit.platform.suite.api.IncludeClassNamePatterns; import org.junit.platform.suite.api.SelectPackages; -import org.junit.platform.suite.api.UseTechnicalNames; -import org.junit.runner.RunWith; +import org.junit.platform.suite.api.Suite; /** * JUnit Platform based test suite for tests that involve the Spring TestContext @@ -42,10 +40,9 @@ * @author Sam Brannen * @since 5.2 */ -@RunWith(JUnitPlatform.class) +@Suite @SelectPackages("org.springframework.test.context") @IncludeClassNamePatterns(".*Tests?$") @ExcludeTags("failing-test-case") -@UseTechnicalNames -public class SpringTestContextFrameworkTestSuite { +class SpringTestContextFrameworkTestSuite { } diff --git a/spring-test/src/test/java/org/springframework/test/context/env/TestPropertySourceTestSuite.java b/spring-test/src/test/java/org/springframework/test/context/env/TestPropertySourceTestSuite.java index 97c5c62e2527..e67528774a8b 100644 --- a/spring-test/src/test/java/org/springframework/test/context/env/TestPropertySourceTestSuite.java +++ b/spring-test/src/test/java/org/springframework/test/context/env/TestPropertySourceTestSuite.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,10 @@ package org.springframework.test.context.env; -import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.suite.api.IncludeClassNamePatterns; import org.junit.platform.suite.api.IncludeEngines; import org.junit.platform.suite.api.SelectPackages; -import org.junit.platform.suite.api.UseTechnicalNames; -import org.junit.runner.RunWith; +import org.junit.platform.suite.api.Suite; import org.springframework.test.context.TestPropertySource; @@ -35,10 +33,9 @@ * @author Sam Brannen * @since 5.2 */ -@RunWith(JUnitPlatform.class) +@Suite @IncludeEngines("junit-jupiter") @SelectPackages("org.springframework.test.context.env") @IncludeClassNamePatterns(".*Tests$") -@UseTechnicalNames -public class TestPropertySourceTestSuite { +class TestPropertySourceTestSuite { } diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/SpringJUnitJupiterTestSuite.java b/spring-test/src/test/java/org/springframework/test/context/junit/SpringJUnitJupiterTestSuite.java index 0a0cf2f84ead..28c8071e1c8c 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit/SpringJUnitJupiterTestSuite.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit/SpringJUnitJupiterTestSuite.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,22 +16,17 @@ package org.springframework.test.context.junit; -import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.suite.api.ExcludeTags; import org.junit.platform.suite.api.IncludeClassNamePatterns; import org.junit.platform.suite.api.IncludeEngines; import org.junit.platform.suite.api.SelectPackages; -import org.junit.platform.suite.api.UseTechnicalNames; -import org.junit.runner.RunWith; +import org.junit.platform.suite.api.Suite; /** - * JUnit 4 based test suite for tests that involve the Spring TestContext + * JUnit Platform based test suite for tests that involve the Spring TestContext * Framework and JUnit Jupiter (i.e., JUnit 5's programming model). * - *

This class intentionally does not reside in the "jupiter" package - * so that the entire "jupiter" package can be excluded from the Gradle - * build. This class is therefore responsible for executing all JUnit - * Jupiter based tests in Spring's official test suite. + *

This suite is only intended to be used manually within an IDE. * *

Logging Configuration

* @@ -46,11 +41,10 @@ * @author Sam Brannen * @since 5.0 */ -@RunWith(JUnitPlatform.class) +@Suite @IncludeEngines("junit-jupiter") @SelectPackages("org.springframework.test.context.junit.jupiter") @IncludeClassNamePatterns(".*Tests$") @ExcludeTags("failing-test-case") -@UseTechnicalNames public class SpringJUnitJupiterTestSuite { } diff --git a/spring-web/src/test/java/org/springframework/http/client/reactive/ClientHttpConnectorTests.java b/spring-web/src/test/java/org/springframework/http/client/reactive/ClientHttpConnectorTests.java index 3c3debef9790..0f30c2391e05 100644 --- a/spring-web/src/test/java/org/springframework/http/client/reactive/ClientHttpConnectorTests.java +++ b/spring-web/src/test/java/org/springframework/http/client/reactive/ClientHttpConnectorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,7 +77,9 @@ void stopServer() throws IOException { server.shutdown(); } - @ParameterizedTest + // Do not auto-close arguments since HttpComponentsClientHttpConnector implements + // AutoCloseable and is shared between parameterized test invocations. + @ParameterizedTest(autoCloseArguments = false) @MethodSource("org.springframework.http.client.reactive.ClientHttpConnectorTests#methodsWithConnectors") void basic(ClientHttpConnector connector, HttpMethod method) throws Exception { URI uri = this.server.url("/").uri(); @@ -198,10 +200,11 @@ private void expectRequest(Consumer consumer) { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) - @ParameterizedTest + // Do not auto-close arguments since HttpComponentsClientHttpConnector implements + // AutoCloseable and is shared between parameterized test invocations. + @ParameterizedTest(autoCloseArguments = false) @MethodSource("org.springframework.http.client.reactive.ClientHttpConnectorTests#connectors") public @interface ParameterizedConnectorTest { - } static List connectors() { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/PathPatternsParameterizedTest.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/PathPatternsParameterizedTest.java index 7dc77ff73d18..ead6e38ab1da 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/PathPatternsParameterizedTest.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/PathPatternsParameterizedTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.handler; import java.lang.annotation.ElementType; @@ -30,7 +31,9 @@ */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) -@org.junit.jupiter.params.ParameterizedTest +// Do not auto-close arguments since ConfigurableWebApplicationContext implements +// AutoCloseable and is shared between parameterized test invocations. +@org.junit.jupiter.params.ParameterizedTest(autoCloseArguments = false) @org.junit.jupiter.params.provider.MethodSource("pathPatternsArguments") public @interface PathPatternsParameterizedTest { } From d55cbf8b4dc2c45259bf69bf983f6b575e188938 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 13 Sep 2021 16:52:00 +0200 Subject: [PATCH 070/735] Avoid use of deprecated API in aggregateTestReports task See gh-26870 --- spring-test/spring-test.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-test/spring-test.gradle b/spring-test/spring-test.gradle index e15134600b87..365ce7d316f9 100644 --- a/spring-test/spring-test.gradle +++ b/spring-test/spring-test.gradle @@ -112,7 +112,7 @@ test { task aggregateTestReports(type: TestReport) { description = "Aggregates JUnit and TestNG test reports." - destinationDir = test.reports.html.destination + destinationDir = test.reports.html.outputLocation.get().getAsFile() reportOn junit, testNG } From 52b03e3326559189c329ec3851164a76cc4ee530 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 2 Aug 2021 10:28:20 -0700 Subject: [PATCH 071/735] Migrate CoroutinesUtils to Java Migrate `CoroutinesUtils` from Kotlin code to Java and drop the `kotlin-coroutines` module. This update removes the need for Kotlin tooling IDE plugins to be installed. Closes gh-27379 --- settings.gradle | 4 +- .../kotlin-coroutines.gradle | 35 ------- .../springframework/core/CoroutinesUtils.kt | 71 -------------- spring-core/spring-core.gradle | 8 +- .../springframework/core/CoroutinesUtils.java | 98 +++++++++++++++++++ spring-messaging/spring-messaging.gradle | 2 - spring-r2dbc/spring-r2dbc.gradle | 2 - spring-tx/spring-tx.gradle | 1 - spring-web/spring-web.gradle | 1 - spring-webflux/spring-webflux.gradle | 2 - spring-webmvc/spring-webmvc.gradle | 1 - 11 files changed, 101 insertions(+), 124 deletions(-) delete mode 100644 spring-core/kotlin-coroutines/kotlin-coroutines.gradle delete mode 100644 spring-core/kotlin-coroutines/src/main/kotlin/org/springframework/core/CoroutinesUtils.kt create mode 100644 spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java diff --git a/settings.gradle b/settings.gradle index 8af23c7ca953..811aa851d64e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,8 +17,6 @@ include "spring-context" include "spring-context-indexer" include "spring-context-support" include "spring-core" -include "kotlin-coroutines" -project(':kotlin-coroutines').projectDir = file('spring-core/kotlin-coroutines') include "spring-expression" include "spring-instrument" include "spring-jcl" @@ -51,7 +49,7 @@ settings.gradle.projectsLoaded { buildScanPublished { scan -> if (buildDir.exists()) { new File(buildDir, "build-scan-uri.txt").text = "${scan.buildScanUri}\n" - } + } } } } diff --git a/spring-core/kotlin-coroutines/kotlin-coroutines.gradle b/spring-core/kotlin-coroutines/kotlin-coroutines.gradle deleted file mode 100644 index 94d7f1531456..000000000000 --- a/spring-core/kotlin-coroutines/kotlin-coroutines.gradle +++ /dev/null @@ -1,35 +0,0 @@ -description = "Spring Core Coroutines support" - -apply plugin: "kotlin" - -configurations { - classesOnlyElements { - canBeConsumed = true - canBeResolved = false - } -} - -artifacts { - classesOnlyElements(compileKotlin.destinationDir) -} - -dependencies { - api("org.jetbrains.kotlin:kotlin-reflect") - api("org.jetbrains.kotlin:kotlin-stdlib") - api("io.projectreactor:reactor-core") - api("org.jetbrains.kotlinx:kotlinx-coroutines-core") - api("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") -} - -eclipse { - project { - buildCommand "org.jetbrains.kotlin.ui.kotlinBuilder" - buildCommand "org.eclipse.jdt.core.javabuilder" - natures "org.jetbrains.kotlin.core.kotlinNature" - natures "org.eclipse.jdt.core.javanature" - linkedResource name: "kotlin_bin", type: "2", locationUri: "org.jetbrains.kotlin.core.filesystem:/" + project.name + "/kotlin_bin" - } - classpath { - containers "org.jetbrains.kotlin.core.KOTLIN_CONTAINER" - } -} diff --git a/spring-core/kotlin-coroutines/src/main/kotlin/org/springframework/core/CoroutinesUtils.kt b/spring-core/kotlin-coroutines/src/main/kotlin/org/springframework/core/CoroutinesUtils.kt deleted file mode 100644 index 3d716bb685e0..000000000000 --- a/spring-core/kotlin-coroutines/src/main/kotlin/org/springframework/core/CoroutinesUtils.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@file:JvmName("CoroutinesUtils") -package org.springframework.core - -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.reactive.awaitSingleOrNull -import kotlinx.coroutines.reactor.asFlux - -import kotlinx.coroutines.reactor.mono -import org.reactivestreams.Publisher -import reactor.core.publisher.Mono -import java.lang.reflect.InvocationTargetException -import java.lang.reflect.Method -import kotlin.reflect.full.callSuspend -import kotlin.reflect.jvm.kotlinFunction - -/** - * Convert a [Deferred] instance to a [Mono] one. - * - * @author Sebastien Deleuze - * @since 5.2 - */ -internal fun deferredToMono(source: Deferred) = - mono(Dispatchers.Unconfined) { source.await() } - -/** - * Convert a [Mono] instance to a [Deferred] one. - * - * @author Sebastien Deleuze - * @since 5.2 - */ -@Suppress("DEPRECATION") -@OptIn(DelicateCoroutinesApi::class) -internal fun monoToDeferred(source: Mono) = - GlobalScope.async(Dispatchers.Unconfined) { source.awaitSingleOrNull() } - -/** - * Invoke a suspending function and converts it to [Mono] or [reactor.core.publisher.Flux]. - * - * @author Sebastien Deleuze - * @since 5.2 - */ -@Suppress("UNCHECKED_CAST") -fun invokeSuspendingFunction(method: Method, target: Any, vararg args: Any?): Publisher<*> { - val function = method.kotlinFunction!! - val mono = mono(Dispatchers.Unconfined) { - function.callSuspend(target, *args.sliceArray(0..(args.size-2))).let { if (it == Unit) null else it } - }.onErrorMap(InvocationTargetException::class.java) { it.targetException } - return if (function.returnType.classifier == Flow::class) { - mono.flatMapMany { (it as Flow).asFlux() } - } - else { - mono - } -} diff --git a/spring-core/spring-core.gradle b/spring-core/spring-core.gradle index d0b294876ef3..a6e5e309b073 100644 --- a/spring-core/spring-core.gradle +++ b/spring-core/spring-core.gradle @@ -13,7 +13,6 @@ def objenesisVersion = "3.2" configurations { cglib objenesis - coroutines } task cglibRepackJar(type: ShadowJar) { @@ -34,16 +33,16 @@ task objenesisRepackJar(type: ShadowJar) { dependencies { cglib("cglib:cglib:${cglibVersion}@jar") objenesis("org.objenesis:objenesis:${objenesisVersion}@jar") - coroutines(project(path: ":kotlin-coroutines", configuration: 'classesOnlyElements')) api(files(cglibRepackJar)) api(files(objenesisRepackJar)) api(project(":spring-jcl")) - compileOnly(project(":kotlin-coroutines")) compileOnly("io.projectreactor.tools:blockhound") optional("net.sf.jopt-simple:jopt-simple") optional("org.aspectj:aspectjweaver") optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") + optional("org.jetbrains.kotlinx:kotlinx-coroutines-core") + optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") optional("io.projectreactor:reactor-core") optional("io.reactivex:rxjava") optional("io.reactivex:rxjava-reactive-streams") @@ -58,7 +57,6 @@ dependencies { testImplementation("com.fasterxml.woodstox:woodstox-core") testImplementation("org.xmlunit:xmlunit-assertj") testImplementation("org.xmlunit:xmlunit-matchers") - testImplementation(project(":kotlin-coroutines")) testImplementation("io.projectreactor.tools:blockhound") testFixturesImplementation("io.projectreactor:reactor-test") testFixturesImplementation("com.google.code.findbugs:jsr305") @@ -91,8 +89,6 @@ jar { from(zipTree(objenesisRepackJar.archivePath)) { include "org/springframework/objenesis/**" } - - from configurations.coroutines } test { diff --git a/spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java b/spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java new file mode 100644 index 000000000000..e942ff48ee11 --- /dev/null +++ b/spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java @@ -0,0 +1,98 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Objects; + +import kotlin.Unit; +import kotlin.jvm.JvmClassMappingKt; +import kotlin.reflect.KClassifier; +import kotlin.reflect.KFunction; +import kotlin.reflect.full.KCallables; +import kotlin.reflect.jvm.ReflectJvmMapping; +import kotlinx.coroutines.BuildersKt; +import kotlinx.coroutines.CoroutineStart; +import kotlinx.coroutines.Deferred; +import kotlinx.coroutines.Dispatchers; +import kotlinx.coroutines.GlobalScope; +import kotlinx.coroutines.flow.Flow; +import kotlinx.coroutines.reactor.MonoKt; +import kotlinx.coroutines.reactor.ReactorFlowKt; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * Utilities for working with Kotlin Coroutines. + * + * @author Sebastien Deleuze + * @author Phillip Webb + * @since 5.2 + */ +public final class CoroutinesUtils { + + private CoroutinesUtils() { + } + + /** + * Convert a {@link Deferred} instance to a {@link Mono}. + */ + public static Mono deferredToMono(Deferred source) { + return MonoKt.mono(Dispatchers.getUnconfined(), + (scope, continuation) -> source.await(continuation)); + } + + /** + * Convert a {@link Mono} instance to a {@link Deferred}. + */ + public static Deferred monoToDeferred(Mono source) { + return BuildersKt.async(GlobalScope.INSTANCE, Dispatchers.getUnconfined(), + CoroutineStart.DEFAULT, + (scope, continuation) -> MonoKt.awaitSingleOrNull(source, continuation)); + } + + /** + * Invoke a suspending function and converts it to {@link Mono} or + * {@link Flux}. + */ + public static Publisher invokeSuspendingFunction(Method method, Object target, Object... args) { + KFunction function = Objects.requireNonNull(ReflectJvmMapping.getKotlinFunction(method)); + KClassifier classifier = function.getReturnType().getClassifier(); + Mono mono = MonoKt.mono(Dispatchers.getUnconfined(), (scope, continuation) -> + KCallables.callSuspend(function, getSuspendedFunctionArgs(target, args), continuation)) + .filter(result -> !Objects.equals(result, Unit.INSTANCE)) + .onErrorMap(InvocationTargetException.class, InvocationTargetException::getTargetException); + if (classifier.equals(JvmClassMappingKt.getKotlinClass(Flow.class))) { + return mono.flatMapMany(CoroutinesUtils::asFlux); + } + return mono; + } + + private static Object[] getSuspendedFunctionArgs(Object target, Object... args) { + Object[] functionArgs = new Object[args.length]; + functionArgs[0] = target; + System.arraycopy(args, 0, functionArgs, 1, args.length - 1); + return functionArgs; + } + + private static Flux asFlux(Object flow) { + return ReactorFlowKt.asFlux(((Flow) flow)); + } + +} diff --git a/spring-messaging/spring-messaging.gradle b/spring-messaging/spring-messaging.gradle index eed544b526b3..c0c7270ebde2 100644 --- a/spring-messaging/spring-messaging.gradle +++ b/spring-messaging/spring-messaging.gradle @@ -6,7 +6,6 @@ apply plugin: "kotlinx-serialization" dependencies { api(project(":spring-beans")) api(project(":spring-core")) - compileOnly(project(":kotlin-coroutines")) optional(project(":spring-context")) optional(project(":spring-oxm")) optional("io.projectreactor.netty:reactor-netty-http") @@ -19,7 +18,6 @@ dependencies { optional("com.google.protobuf:protobuf-java-util") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") optional("org.jetbrains.kotlinx:kotlinx-serialization-json") - testImplementation(project(":kotlin-coroutines")) testImplementation(testFixtures(project(":spring-core"))) testImplementation("javax.inject:javax.inject-tck") testImplementation("javax.servlet:javax.servlet-api") diff --git a/spring-r2dbc/spring-r2dbc.gradle b/spring-r2dbc/spring-r2dbc.gradle index 5c60dd7d3ad6..dfb6b1ece9d6 100644 --- a/spring-r2dbc/spring-r2dbc.gradle +++ b/spring-r2dbc/spring-r2dbc.gradle @@ -8,12 +8,10 @@ dependencies { api(project(":spring-tx")) api("io.r2dbc:r2dbc-spi") api("io.projectreactor:reactor-core") - compileOnly(project(":kotlin-coroutines")) optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") optional("org.jetbrains.kotlinx:kotlinx-coroutines-core") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") - testImplementation(project(":kotlin-coroutines")) testImplementation(testFixtures(project(":spring-beans"))) testImplementation(testFixtures(project(":spring-core"))) testImplementation(testFixtures(project(":spring-context"))) diff --git a/spring-tx/spring-tx.gradle b/spring-tx/spring-tx.gradle index c9447732bc59..f3ec8c3f3ac3 100644 --- a/spring-tx/spring-tx.gradle +++ b/spring-tx/spring-tx.gradle @@ -7,7 +7,6 @@ dependencies { api(project(":spring-core")) optional(project(":spring-aop")) optional(project(":spring-context")) // for JCA, @EnableTransactionManagement - optional(project(":kotlin-coroutines")) optional("javax.ejb:javax.ejb-api") optional("javax.interceptor:javax.interceptor-api") optional("javax.resource:javax.resource-api") diff --git a/spring-web/spring-web.gradle b/spring-web/spring-web.gradle index f774f0afb8a9..716ecb4cecf3 100644 --- a/spring-web/spring-web.gradle +++ b/spring-web/spring-web.gradle @@ -6,7 +6,6 @@ apply plugin: "kotlinx-serialization" dependencies { api(project(":spring-beans")) api(project(":spring-core")) - compileOnly(project(":kotlin-coroutines")) compileOnly("io.projectreactor.tools:blockhound") optional(project(":spring-aop")) optional(project(":spring-context")) diff --git a/spring-webflux/spring-webflux.gradle b/spring-webflux/spring-webflux.gradle index 7e9e49c69fde..b762e09c5cb6 100644 --- a/spring-webflux/spring-webflux.gradle +++ b/spring-webflux/spring-webflux.gradle @@ -7,7 +7,6 @@ dependencies { api(project(":spring-core")) api(project(":spring-web")) api("io.projectreactor:reactor-core") - compileOnly(project(":kotlin-coroutines")) optional(project(":spring-context")) optional(project(":spring-context-support")) // for FreeMarker support optional("javax.servlet:javax.servlet-api") @@ -27,7 +26,6 @@ dependencies { optional("org.jetbrains.kotlin:kotlin-stdlib") optional("com.google.protobuf:protobuf-java-util") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") - testImplementation(project(":kotlin-coroutines")) testImplementation(testFixtures(project(":spring-beans"))) testImplementation(testFixtures(project(":spring-core"))) testImplementation(testFixtures(project(":spring-web"))) diff --git a/spring-webmvc/spring-webmvc.gradle b/spring-webmvc/spring-webmvc.gradle index 36ad9f649ef3..99e70f68f622 100644 --- a/spring-webmvc/spring-webmvc.gradle +++ b/spring-webmvc/spring-webmvc.gradle @@ -37,7 +37,6 @@ dependencies { optional("org.jetbrains.kotlin:kotlin-stdlib") optional("org.reactivestreams:reactive-streams") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") - testImplementation(project(":kotlin-coroutines")) testImplementation(testFixtures(project(":spring-beans"))) testImplementation(testFixtures(project(":spring-core"))) testImplementation(testFixtures(project(":spring-context"))) From 0a776a76d114c95361105a9b7917874815bf3a2e Mon Sep 17 00:00:00 2001 From: yokotaso Date: Thu, 9 Sep 2021 13:58:05 +0900 Subject: [PATCH 072/735] Fix memory leak on AOP Proxy class definition cache --- .../org/springframework/aop/framework/AdvisedSupport.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java b/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java index 5664cf7ffd55..b2b8060b8a6a 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java @@ -521,8 +521,8 @@ AdvisedSupport getConfigurationOnlyCopy() { copy.copyFrom(this); copy.targetSource = EmptyTargetSource.forClass(getTargetClass(), getTargetSource().isStatic()); copy.advisorChainFactory = this.advisorChainFactory; - copy.interfaces = this.interfaces; - copy.advisors = this.advisors; + copy.interfaces = new ArrayList<>(this.interfaces); + copy.advisors = new ArrayList<>(this.advisors); return copy; } From 6c17e9375b0d277ea28cb7220b4a162cc9ec0436 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 13 Sep 2021 18:13:41 +0200 Subject: [PATCH 073/735] Reduce log statement for non-unique JavaBean property to debug level Closes gh-27372 --- .../beans/GenericTypeAwarePropertyDescriptor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java b/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java index 603f5aae150e..b4052b7b84e9 100644 --- a/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java +++ b/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -138,7 +138,7 @@ public Method getWriteMethodForActualAccess() { Set ambiguousCandidates = this.ambiguousWriteMethods; if (ambiguousCandidates != null) { this.ambiguousWriteMethods = null; - LogFactory.getLog(GenericTypeAwarePropertyDescriptor.class).warn("Invalid JavaBean property '" + + LogFactory.getLog(GenericTypeAwarePropertyDescriptor.class).debug("Non-unique JavaBean property '" + getName() + "' being accessed! Ambiguous write methods found next to actually used [" + this.writeMethod + "]: " + ambiguousCandidates); } From 6540e87ac0660f5ec0bc9610656fe658ea75159f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 13 Sep 2021 18:14:05 +0200 Subject: [PATCH 074/735] Upgrade to Netty 4.1.68, Jackson 2.12.5, Mockito 3.12.4, MockK 1.12, JsonPath 2.6 --- build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index f5419026e941..881ed62e7ea2 100644 --- a/build.gradle +++ b/build.gradle @@ -27,8 +27,8 @@ configure(allprojects) { project -> dependencyManagement { imports { - mavenBom "com.fasterxml.jackson:jackson-bom:2.12.4" - mavenBom "io.netty:netty-bom:4.1.67.Final" + mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5" + mavenBom "io.netty:netty-bom:4.1.68.Final" mavenBom "io.projectreactor:reactor-bom:2020.0.10" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" mavenBom "io.rsocket:rsocket-bom:1.1.1" @@ -197,13 +197,13 @@ configure(allprojects) { project -> exclude group: "org.hamcrest", name: "hamcrest-core" } } - dependencySet(group: 'org.mockito', version: '3.11.0') { + dependencySet(group: 'org.mockito', version: '3.12.4') { entry('mockito-core') { exclude group: "org.hamcrest", name: "hamcrest-core" } entry 'mockito-junit-jupiter' } - dependency "io.mockk:mockk:1.11.0" + dependency "io.mockk:mockk:1.12.0" dependency("net.sourceforge.htmlunit:htmlunit:2.52.0") { exclude group: "commons-logging", name: "commons-logging" @@ -216,7 +216,7 @@ configure(allprojects) { project -> exclude group: "io.netty", name: "netty" } dependency "org.skyscreamer:jsonassert:1.5.0" - dependency "com.jayway.jsonpath:json-path:2.5.0" + dependency "com.jayway.jsonpath:json-path:2.6.0" dependency "org.bouncycastle:bcpkix-jdk15on:1.66" dependencySet(group: 'org.apache.tiles', version: '3.0.8') { From 18ee308e4e3c59117f4bd41da16e837f88db0933 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 14 Sep 2021 10:58:38 +0200 Subject: [PATCH 075/735] Delete obsolete Assume test utility --- .../core/testfixture/Assume.java | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 spring-core/src/testFixtures/java/org/springframework/core/testfixture/Assume.java diff --git a/spring-core/src/testFixtures/java/org/springframework/core/testfixture/Assume.java b/spring-core/src/testFixtures/java/org/springframework/core/testfixture/Assume.java deleted file mode 100644 index 83c3dd8d9e90..000000000000 --- a/spring-core/src/testFixtures/java/org/springframework/core/testfixture/Assume.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.testfixture; - -import org.apache.commons.logging.Log; - -import static org.junit.jupiter.api.Assumptions.assumeFalse; - -/** - * Utility methods that allow JUnit tests to assume certain conditions hold - * {@code true}. If an assumption fails, it means the test should be aborted. - * - * @author Rob Winch - * @author Phillip Webb - * @author Sam Brannen - * @since 3.2 - * @see #notLogging(Log) - * @see EnabledForTestGroups @EnabledForTestGroups - */ -public abstract class Assume { - - /** - * Assume that the specified log is not set to Trace or Debug. - * @param log the log to test - * @throws org.opentest4j.TestAbortedException if the assumption fails - */ - public static void notLogging(Log log) { - assumeFalse(log.isTraceEnabled()); - assumeFalse(log.isDebugEnabled()); - } - -} From 8c14251a1a9b0d0f5a2c4fbdcd1d1703fb07cea3 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 14 Sep 2021 11:24:28 +0200 Subject: [PATCH 076/735] Upgrade to nohttp 0.0.10 This upgrade avoids warnings about the following on Gradle 7.1+. - The Report.destination property has been deprecated. - The JavaExec.main property has been deprecated. See gh-26870 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 881ed62e7ea2..c7fb7843f22f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id 'io.spring.dependency-management' version '1.0.11.RELEASE' apply false - id 'io.spring.nohttp' version '0.0.5.RELEASE' + id 'io.spring.nohttp' version '0.0.10' id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false id 'org.jetbrains.dokka' version '1.5.0' apply false id 'org.asciidoctor.jvm.convert' version '3.3.2' From b1a4d3033be769073d3b4408ececf2cef63164d9 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 14 Sep 2021 11:35:12 +0200 Subject: [PATCH 077/735] Avoid usage of deprecated Gradle API in spring-oxm.gradle This upgrade avoids the warning about the following on Gradle 7.1+. - The SourceDirectorySet.outputDir property has been deprecated. Closes gh-26870 --- spring-oxm/spring-oxm.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-oxm/spring-oxm.gradle b/spring-oxm/spring-oxm.gradle index a78b41049e0c..f47726a8bd5b 100644 --- a/spring-oxm/spring-oxm.gradle +++ b/spring-oxm/spring-oxm.gradle @@ -16,6 +16,7 @@ dependencies { xjc { xjcVersion = '2.2' } + sourceSets { test { xjcTargetPackage = 'org.springframework.oxm.jaxb.test' @@ -55,7 +56,7 @@ if ((JavaVersion.current() == JavaVersion.VERSION_1_8) && !project.hasProperty(" classpath: configurations.jibx.asPath) jibx(verbose: false, load: true, binding: bindingXml) { - classpathset(dir: sourceSets.test.java.outputDir) { + classpathset(dir: sourceSets.test.java.classesDirectory.get().getAsFile()) { include(name: "**/jibx/**/*") } } From 8adf28763bd01bec4647ce70f9111481141cf5f1 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 14 Sep 2021 14:24:47 +0200 Subject: [PATCH 078/735] Upgrade to Reactor 2020.0.11 Closes gh-27399 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c7fb7843f22f..8a3207ccc859 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ configure(allprojects) { project -> imports { mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5" mavenBom "io.netty:netty-bom:4.1.68.Final" - mavenBom "io.projectreactor:reactor-bom:2020.0.10" + mavenBom "io.projectreactor:reactor-bom:2020.0.11" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" mavenBom "io.rsocket:rsocket-bom:1.1.1" mavenBom "org.eclipse.jetty:jetty-bom:9.4.43.v20210629" From 674dc2f2039fb6186b35ab674c3046ecd5809bb3 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 14 Sep 2021 13:40:26 +0100 Subject: [PATCH 079/735] Do not log request parameters for multipart requests Closes gh-27350 --- .../org/springframework/web/servlet/DispatcherServlet.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java index 19cb32564ce7..5be28f3e13e0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java @@ -978,7 +978,10 @@ protected void doService(HttpServletRequest request, HttpServletResponse respons private void logRequest(HttpServletRequest request) { LogFormatUtils.traceDebug(logger, traceOn -> { String params; - if (isEnableLoggingRequestDetails()) { + if (StringUtils.startsWithIgnoreCase(request.getContentType(), "multipart/")) { + params = "multipart"; + } + else if (isEnableLoggingRequestDetails()) { params = request.getParameterMap().entrySet().stream() .map(entry -> entry.getKey() + ":" + Arrays.toString(entry.getValue())) .collect(Collectors.joining(", ")); From c46cc666d6bd5b26860964d8bceddb528d7897b2 Mon Sep 17 00:00:00 2001 From: Dmitriy Bogdanov Date: Fri, 10 Sep 2021 17:38:42 +0400 Subject: [PATCH 080/735] Fix some typos and mistakes in ref docs Closes gh-27388 --- src/docs/asciidoc/core/core-aop.adoc | 4 +- src/docs/asciidoc/core/core-beans.adoc | 99 ++++++++++--------- .../asciidoc/core/core-databuffer-codec.adoc | 6 +- src/docs/asciidoc/core/core-expressions.adoc | 4 +- src/docs/asciidoc/core/core-validation.adoc | 9 +- src/docs/asciidoc/data-access.adoc | 43 ++++---- src/docs/asciidoc/integration.adoc | 27 ++--- src/docs/asciidoc/overview.adoc | 2 +- src/docs/asciidoc/testing.adoc | 1 + src/docs/asciidoc/web/integration.adoc | 6 +- src/docs/asciidoc/web/web-uris.adoc | 6 +- src/docs/asciidoc/web/webflux-view.adoc | 2 +- src/docs/asciidoc/web/webmvc-cors.adoc | 2 +- src/docs/asciidoc/web/webmvc-functional.adoc | 4 +- src/docs/asciidoc/web/webmvc-view.adoc | 4 +- src/docs/asciidoc/web/webmvc.adoc | 38 +++---- src/docs/asciidoc/web/websocket.adoc | 6 +- 17 files changed, 134 insertions(+), 129 deletions(-) diff --git a/src/docs/asciidoc/core/core-aop.adoc b/src/docs/asciidoc/core/core-aop.adoc index a6412096e492..6479f329b5d9 100644 --- a/src/docs/asciidoc/core/core-aop.adoc +++ b/src/docs/asciidoc/core/core-aop.adoc @@ -366,7 +366,7 @@ the https://www.eclipse.org/aspectj/doc/released/progguide/index.html[AspectJ Programming Guide] (and, for extensions, the https://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html[AspectJ 5 Developer's Notebook]) or one of the books on AspectJ (such as _Eclipse AspectJ_, by Colyer -et. al., or _AspectJ in Action_, by Ramnivas Laddad). +et al., or _AspectJ in Action_, by Ramnivas Laddad). [[aop-pointcuts-designators]] @@ -893,7 +893,7 @@ scoping). You can include the contextual designators to match based on join point context or bind that context for use in the advice. Supplying only a kinded designator or only a contextual designator works but could affect weaving performance (time and memory used), due to extra processing and analysis. Scoping -designators are very fast to match, and using them usage means AspectJ can very quickly +designators are very fast to match, and using them means AspectJ can very quickly dismiss groups of join points that should not be further processed. A good pointcut should always include one if possible. diff --git a/src/docs/asciidoc/core/core-beans.adoc b/src/docs/asciidoc/core/core-beans.adoc index 2a8c526d2617..5ba741761f28 100644 --- a/src/docs/asciidoc/core/core-beans.adoc +++ b/src/docs/asciidoc/core/core-beans.adoc @@ -1024,7 +1024,7 @@ by type without help. Consider the following class: class ExampleBean( private val years: Int, // Number of years to calculate the Ultimate Answer - private val ultimateAnswer: String// The Answer to Life, the Universe, and Everything + private val ultimateAnswer: String // The Answer to Life, the Universe, and Everything ) ---- @@ -1608,7 +1608,7 @@ listings shows how to use the `parent` attribute: ---- - + ---- @@ -1690,7 +1690,7 @@ respectively. The following example shows how to use them: - + @@ -1834,7 +1834,7 @@ class SomeClass { When the `accounts` property of the `something` bean is prepared for injection, the generics information about the element type of the strongly-typed `Map` is available by reflection. Thus, Spring's type conversion infrastructure recognizes the -various value elements as being of type `Float`, and the string values (`9.99, 2.75`, and +various value elements as being of type `Float`, and the string values (`9.99`, `2.75`, and `3.99`) are converted into an actual `Float` type. @@ -2028,7 +2028,7 @@ not commonly used since the plain order of declaration is usually sufficient the In practice, the constructor resolution <> is quite efficient in matching arguments, so unless you really need to, we recommend using the name notation -through-out your configuration. +throughout your configuration. [[beans-compound-property-names]] @@ -2503,13 +2503,13 @@ declared return type of the lookup method: public abstract class CommandManager { public Object process(Object commandState) { - MyCommand command = createCommand(); + Command command = createCommand(); command.setState(commandState); return command.execute(); } @Lookup - protected abstract MyCommand createCommand(); + protected abstract Command createCommand(); } ---- [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] @@ -2604,9 +2604,9 @@ interface provides the new method definition, as the following example shows: .Kotlin ---- /** - * meant to be used to override the existing computeValue(String) - * implementation in MyValueCalculator - */ + * meant to be used to override the existing computeValue(String) + * implementation in MyValueCalculator + */ class ReplacementComputeValue : MethodReplacer { override fun reimplement(obj: Any, method: Method, args: Array): Any { @@ -2806,7 +2806,7 @@ prototype-scoped bean repeatedly at runtime. You cannot dependency-inject a prototype-scoped bean into your singleton bean, because that injection occurs only once, when the Spring container instantiates the singleton bean and resolves and injects its dependencies. If you need a new instance of a prototype bean at -runtime more than once, see <> +runtime more than once, see <>. @@ -2984,7 +2984,7 @@ The Spring container creates a new instance of the `AppPreferences` bean by usin `appPreferences` bean is scoped at the `ServletContext` level and stored as a regular `ServletContext` attribute. This is somewhat similar to a Spring singleton bean but differs in two important ways: It is a singleton per `ServletContext`, not per Spring -'ApplicationContext' (for which there may be several in any given web application), +`ApplicationContext` (for which there may be several in any given web application), and it is actually exposed and therefore visible as a `ServletContext` attribute. When using annotation-driven components or Java configuration, you can use the @@ -3100,7 +3100,7 @@ to the HTTP `Session`-scoped bean (`userPreferences`). The salient point here is `userManager` bean is a singleton: it is instantiated exactly once per container, and its dependencies (in this case only one, the `userPreferences` bean) are also injected only once. This means that the `userManager` bean operates only on the -exact same `userPreferences` object (that is, the one with which it was originally injected. +exact same `userPreferences` object (that is, the one with which it was originally injected). This is not the behavior you want when injecting a shorter-lived scoped bean into a longer-lived scoped bean (for example, injecting an HTTP `Session`-scoped collaborating @@ -3928,7 +3928,7 @@ shows the definition of the BeanNameAware interface: ---- The callback is invoked after population of normal bean properties but before an -initialization callback such as `InitializingBean`, `afterPropertiesSet`, or a custom +initialization callback such as `InitializingBean.afterPropertiesSet()` or a custom init-method. @@ -3960,7 +3960,7 @@ dependency type. The following table summarizes the most important `Aware` inter | `BeanFactoryAware` | Declaring `BeanFactory`. -| <> +| <> | `BeanNameAware` | Name of the declaring bean. @@ -4142,7 +4142,7 @@ or it may wrap a bean with a proxy. Some Spring AOP infrastructure classes are implemented as bean post-processors in order to provide proxy-wrapping logic. An `ApplicationContext` automatically detects any beans that are defined in the -configuration metadata that implements the `BeanPostProcessor` interface. The +configuration metadata that implement the `BeanPostProcessor` interface. The `ApplicationContext` registers these beans as post-processors so that they can be called later, upon bean creation. Bean post-processors can be deployed in the container in the same fashion as any other beans. @@ -4673,11 +4673,11 @@ example: ---- class SimpleMovieLister { - @Required - lateinit var movieFinder: MovieFinder + @Required + lateinit var movieFinder: MovieFinder - // ... -} + // ... + } ---- This annotation indicates that the affected bean property must be populated at @@ -5373,7 +5373,7 @@ Letting qualifier values select against target bean names, within the type-match candidates, does not require a `@Qualifier` annotation at the injection point. If there is no other resolution indicator (such as a qualifier or a primary marker), for a non-unique dependency situation, Spring matches the injection point name -(that is, the field name or parameter name) against the target bean names and choose the +(that is, the field name or parameter name) against the target bean names and chooses the same-named candidate, if any. ==== @@ -6042,14 +6042,14 @@ example shows: [source,java,indent=0,subs="verbatim,quotes",role="primary"] .Java ---- - @Configuration - public class AppConfig { + @Configuration + public class AppConfig { - @Bean - public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - } + @Bean + public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } + } ---- [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] .Kotlin @@ -6075,7 +6075,7 @@ will get properties from `application.properties` and `application.yml` files. Built-in converter support provided by Spring allows simple type conversion (to `Integer` or `int` for example) to be automatically handled. Multiple comma-separated values can be -automatically converted to String array without extra effort. +automatically converted to `String` array without extra effort. It is possible to provide a default value as following: @@ -6099,8 +6099,8 @@ It is possible to provide a default value as following: class MovieRecommender(@Value("\${catalog.name:defaultCatalog}") private val catalog: String) ---- -A Spring `BeanPostProcessor` uses a `ConversionService` behind the scene to handle the -process for converting the String value in `@Value` to the target type. If you want to +A Spring `BeanPostProcessor` uses a `ConversionService` behind the scenes to handle the +process for converting the `String` value in `@Value` to the target type. If you want to provide conversion support for your own custom type, you can provide your own `ConversionService` bean instance as the following example shows: @@ -6126,7 +6126,7 @@ provide conversion support for your own custom type, you can provide your own @Bean fun conversionService(): ConversionService { - return DefaultFormattingConversionService().apply { + return DefaultFormattingConversionService().apply { addConverter(MyCustomConverter()) } } @@ -6315,7 +6315,7 @@ is meta-annotated with `@Component`, as the following example shows: // ... } ---- -<1> The `Component` causes `@Service` to be treated in the same way as `@Component`. +<1> The `@Component` causes `@Service` to be treated in the same way as `@Component`. [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] .Kotlin @@ -6329,7 +6329,7 @@ is meta-annotated with `@Component`, as the following example shows: // ... } ---- -<1> The `Component` causes `@Service` to be treated in the same way as `@Component`. +<1> The `@Component` causes `@Service` to be treated in the same way as `@Component`. You can also combine meta-annotations to create "`composed annotations`". For example, the `@RestController` annotation from Spring MVC is composed of `@Controller` and @@ -6591,7 +6591,7 @@ and using "`stub`" repositories instead: includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"), excludeFilters = @Filter(Repository.class)) public class AppConfig { - ... + // ... } ---- [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] @@ -7157,7 +7157,7 @@ configuration, as shown in the following example: With Gradle 4.6 and later, the dependency should be declared in the `annotationProcessor` configuration, as shown in the following example: -[source,groovy,indent=0subs="verbatim,quotes,attributes"] +[source,groovy,indent=0,subs="verbatim,quotes,attributes"] ---- dependencies { annotationProcessor "org.springframework:spring-context-indexer:{spring-version}" @@ -7631,7 +7631,7 @@ to reduce subtle bugs that can be hard to track down when operating in "`lite`" **** The `@Bean` and `@Configuration` annotations are discussed in depth in the following sections. -First, however, we cover the various ways of creating a spring container using by +First, however, we cover the various ways of creating a spring container by using Java-based configuration. @@ -7758,7 +7758,7 @@ To enable component scanning, you can annotate your `@Configuration` class as fo @Configuration @ComponentScan(basePackages = "com.acme") // <1> public class AppConfig { - ... + // ... } ---- <1> This annotation enables component scanning. @@ -7892,6 +7892,7 @@ init-param): `@Bean` is a method-level annotation and a direct analog of the XML `` element. The annotation supports some of the attributes offered by ``, such as: + * <> * <> * <> @@ -7980,7 +7981,7 @@ return type, as the following example shows: However, this limits the visibility for advance type prediction to the specified interface type (`TransferService`). Then, with the full type (`TransferServiceImpl`) -known to the container only once, the affected singleton bean has been instantiated. +known to the container only once the affected singleton bean has been instantiated. Non-lazy singleton beans get instantiated according to their declaration order, so you may see different type matching results depending on when another component tries to match by a non-declared type (such as `@Autowired TransferServiceImpl`, @@ -8295,7 +8296,7 @@ as the following example shows: @Configuration public class AppConfig { - @Bean(name = "myThing") + @Bean("myThing") public Thing thing() { return new Thing(); } @@ -8388,7 +8389,7 @@ annotation, as the following example shows: === Using the `@Configuration` annotation `@Configuration` is a class-level annotation indicating that an object is a source of -bean definitions. `@Configuration` classes declare beans through `@Bean` annotated +bean definitions. `@Configuration` classes declare beans through `@Bean`-annotated methods. Calls to `@Bean` methods on `@Configuration` classes can also be used to define inter-bean dependencies. See <> for a general introduction. @@ -9137,7 +9138,7 @@ method that returns `true` or `false`. For example, the following listing shows val attrs = metadata.getAllAnnotationAttributes(Profile::class.java.name) if (attrs != null) { for (value in attrs["value"]!!) { - if (context.environment.acceptsProfiles(Profiles .of(*value as Array))) { + if (context.environment.acceptsProfiles(Profiles.of(*value as Array))) { return true } } @@ -9901,7 +9902,7 @@ as a way to provide a default definition for one or more beans. If any profile is enabled, the default profile does not apply. You can change the name of the default profile by using `setDefaultProfiles()` on -the `Environment` or ,declaratively, by using the `spring.profiles.default` property. +the `Environment` or, declaratively, by using the `spring.profiles.default` property. @@ -10720,7 +10721,7 @@ following example shows how to do so: ---- It is also possible to add additional runtime filtering by using the `condition` attribute -of the annotation that defines a <> , which should match +of the annotation that defines a <>, which should match to actually invoke the method for a particular event. The following example shows how our notifier can be rewritten to be invoked only if the @@ -10832,10 +10833,12 @@ The following example shows how to do so: Be aware of the following limitations when using asynchronous events: * If an asynchronous event listener throws an `Exception`, it is not propagated to the - caller. See `AsyncUncaughtExceptionHandler` for more details. + caller. See + {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`] + for more details. * Asynchronous event listener methods cannot publish a subsequent event by returning a value. If you need to publish another event as the result of the processing, inject an - {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`ApplicationEventPublisher`] + {api-spring-framework}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`] to publish the event manually. @@ -11093,8 +11096,8 @@ For a simple deployment of a Spring ApplicationContext as a Java EE RAR file: . Package all application classes into a RAR file (which is a standard JAR file with a different file extension). -.Add all required library JARs into the root of the RAR archive. -.Add a +. Add all required library JARs into the root of the RAR archive. +. Add a `META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`]) and the corresponding Spring XML bean definition file(s) (typically `META-INF/applicationContext.xml`). diff --git a/src/docs/asciidoc/core/core-databuffer-codec.adoc b/src/docs/asciidoc/core/core-databuffer-codec.adoc index ca5065144961..7abf40a0cdaa 100644 --- a/src/docs/asciidoc/core/core-databuffer-codec.adoc +++ b/src/docs/asciidoc/core/core-databuffer-codec.adoc @@ -12,7 +12,7 @@ APIs as follows: * <> represents a byte buffer, which may be <>. * <> offers utility methods for data buffers. -* <> decode or encode streams data buffer streams into higher level objects. +* <> decode or encode data buffer streams into higher level objects. @@ -127,9 +127,9 @@ others that prefetch and cache data items internally, or is using operators such `filter`, `skip`, and others that leave out items, then `doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release)` must be added to the composition chain to ensure such buffers are released prior to being discarded, possibly -also as a result an error or cancellation signal. +also as a result of an error or cancellation signal. . If a `Decoder` holds on to one or more data buffers in any other way, it must -ensure they are released when fully read, or in case an error or cancellation signals that +ensure they are released when fully read, or in case of an error or cancellation signals that take place before the cached data buffers have been read and released. Note that `DataBufferUtils#join` offers a safe and efficient way to aggregate a data diff --git a/src/docs/asciidoc/core/core-expressions.adoc b/src/docs/asciidoc/core/core-expressions.adoc index c0cd157e2fb2..074523d392d1 100644 --- a/src/docs/asciidoc/core/core-expressions.adoc +++ b/src/docs/asciidoc/core/core-expressions.adoc @@ -357,7 +357,7 @@ the list: // Turn on: // - auto null reference initialization // - auto collection growing - SpelParserConfiguration config = new SpelParserConfiguration(true,true); + SpelParserConfiguration config = new SpelParserConfiguration(true, true); ExpressionParser parser = new SpelExpressionParser(config); @@ -465,7 +465,7 @@ following example shows how to do so: .Java ---- SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, - this.getClass().getClassLoader()); + this.getClass().getClassLoader()); SpelExpressionParser parser = new SpelExpressionParser(config); diff --git a/src/docs/asciidoc/core/core-validation.adoc b/src/docs/asciidoc/core/core-validation.adoc index 5d80f2a0820a..cded5e664ee0 100644 --- a/src/docs/asciidoc/core/core-validation.adoc +++ b/src/docs/asciidoc/core/core-validation.adoc @@ -382,7 +382,7 @@ properties: ---- The following code snippets show some examples of how to retrieve and manipulate some of -the properties of instantiated `Companies` and `Employees`: +the properties of instantiated ``Company``s and ``Employee``s: [source,java,indent=0,subs="verbatim,quotes",role="primary"] .Java @@ -629,7 +629,7 @@ Note that all bean factories and application contexts automatically use a number built-in property editors, through their use of a `BeanWrapper` to handle property conversions. The standard property editors that the `BeanWrapper` registers are listed in the <>. -Additionally, `ApplicationContexts` also override or add additional editors to handle +Additionally, ``ApplicationContext``s also override or add additional editors to handle resource lookups in a manner appropriate to the specific application context type. Standard JavaBeans `PropertyEditor` instances are used to convert property values @@ -790,7 +790,7 @@ The following example shows how to create your own `PropertyEditorRegistrar` imp See also the `org.springframework.beans.support.ResourceEditorRegistrar` for an example `PropertyEditorRegistrar` implementation. Notice how in its implementation of the -`registerCustomEditors(..)` method ,it creates new instances of each property editor. +`registerCustomEditors(..)` method, it creates new instances of each property editor. The next example shows how to configure a `CustomEditorConfigurer` and inject an instance of our `CustomPropertyEditorRegistrar` into it: @@ -1347,6 +1347,7 @@ listing shows the definition of the `AnnotationFormatterFactory` interface: ---- To create an implementation: + . Parameterize A to be the field `annotationType` with which you wish to associate formatting logic -- for example `org.springframework.format.annotation.DateTimeFormat`. . Have `getFieldTypes()` return the types of fields on which the annotation can be used. @@ -1470,7 +1471,7 @@ The following example uses `@DateTimeFormat` to format a `java.util.Date` as an .Kotlin ---- class MyModel( - @DateTimeFormat(iso= ISO.DATE) private val date: Date + @DateTimeFormat(iso=ISO.DATE) private val date: Date ) ---- diff --git a/src/docs/asciidoc/data-access.adoc b/src/docs/asciidoc/data-access.adoc index 61c8b6330c6f..388e4bbf5cd8 100644 --- a/src/docs/asciidoc/data-access.adoc +++ b/src/docs/asciidoc/data-access.adoc @@ -445,7 +445,7 @@ relevant `TransactionManager`. [[tx-resource-synchronization-high]] ==== High-level Synchronization Approach -The preferred approach is to use Spring's highest-level template based persistence +The preferred approach is to use Spring's highest-level template-based persistence integration APIs or to use native ORM APIs with transaction-aware factory beans or proxies for managing the native resource factories. These transaction-aware solutions internally handle resource creation and reuse, cleanup, optional transaction @@ -1878,7 +1878,7 @@ rollback rules, timeouts, and other features. ==== Transaction Propagation This section describes some semantics of transaction propagation in Spring. Note -that this section is not an introduction to transaction propagation proper. Rather, it +that this section is not a proper introduction to transaction propagation. Rather, it details some of the semantics regarding transaction propagation in Spring. In Spring-managed transactions, be aware of the difference between physical and @@ -2121,7 +2121,7 @@ declarative approach: - + @@ -2164,7 +2164,7 @@ container by means of an AspectJ aspect. To do so, first annotate your classes (and optionally your classes' methods) with the `@Transactional` annotation, and then link (weave) your application with the `org.springframework.transaction.aspectj.AnnotationTransactionAspect` defined in the -`spring-aspects.jar` file. You must also configure The aspect with a transaction +`spring-aspects.jar` file. You must also configure the aspect with a transaction manager. You can use the Spring Framework's IoC container to take care of dependency-injecting the aspect. The simplest way to configure the transaction management aspect is to use the `` element and specify the `mode` @@ -2585,8 +2585,7 @@ following example shows how to do so: TransactionStatus status = txManager.getTransaction(def); try { // put your business logic here - } - catch (MyException ex) { + } catch (MyException ex) { txManager.rollback(status); throw ex; } @@ -3295,7 +3294,7 @@ For example, it may be better to write the preceding code snippet as follows: }; public List findAllActors() { - return this.jdbcTemplate.query( "select first_name, last_name from t_actor", actorRowMapper); + return this.jdbcTemplate.query("select first_name, last_name from t_actor", actorRowMapper); } ---- [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] @@ -3605,7 +3604,7 @@ variable and the corresponding value that is plugged into the `namedParameters` variable (of type `MapSqlParameterSource`). Alternatively, you can pass along named parameters and their corresponding values to a -`NamedParameterJdbcTemplate` instance by using the `Map`-based style.The remaining +`NamedParameterJdbcTemplate` instance by using the `Map`-based style. The remaining methods exposed by the `NamedParameterJdbcOperations` and implemented by the `NamedParameterJdbcTemplate` class follow a similar pattern and are not covered here. @@ -3743,7 +3742,7 @@ See also <> for guidelines on using the ==== Using `SQLExceptionTranslator` `SQLExceptionTranslator` is an interface to be implemented by classes that can translate -between `SQLExceptions` and Spring's own `org.springframework.dao.DataAccessException`, +between ``SQLException``s and Spring's own `org.springframework.dao.DataAccessException`, which is agnostic in regard to data access strategy. Implementations can be generic (for example, using SQLState codes for JDBC) or proprietary (for example, using Oracle error codes) for greater precision. @@ -3799,9 +3798,9 @@ You can extend `SQLErrorCodeSQLExceptionTranslator`, as the following example sh override fun customTranslate(task: String, sql: String?, sqlEx: SQLException): DataAccessException? { if (sqlEx.errorCode == -12345) { - return DeadlockLoserDataAccessException(task, sqlEx) - } - return null; + return DeadlockLoserDataAccessException(task, sqlEx) + } + return null } } ---- @@ -4034,7 +4033,7 @@ The following example updates a column for a certain primary key: In the preceding example, an SQL statement has placeholders for row parameters. You can pass the parameter values -in as varargs or ,alternatively, as an array of objects. Thus, you should explicitly wrap primitives +in as varargs or, alternatively, as an array of objects. Thus, you should explicitly wrap primitives in the primitive wrapper classes, or you should use auto-boxing. @@ -4577,7 +4576,7 @@ The following example shows a batch update that uses a batch size of 100: } ---- -The batch update methods for this call returns an array of `int` arrays that contains an +The batch update method for this call returns an array of `int` arrays that contains an array entry for each batch with an array of the number of affected rows for each update. The top-level array's length indicates the number of batches run, and the second level array's length indicates the number of updates in that batch. The number of updates in @@ -5173,11 +5172,9 @@ as the following example shows: ---- public class JdbcActorDao implements ActorDao { - private JdbcTemplate jdbcTemplate; private SimpleJdbcCall funcGetActorName; public void setDataSource(DataSource dataSource) { - this.jdbcTemplate = new JdbcTemplate(dataSource); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.setResultsMapCaseInsensitive(true); this.funcGetActorName = new SimpleJdbcCall(jdbcTemplate) @@ -5443,7 +5440,7 @@ example shows such a method: The `SqlUpdate` class encapsulates an SQL update. As with a query, an update object is reusable, and, as with all `RdbmsOperation` classes, an update can have parameters and is defined in SQL. This class provides a number of `update(..)` methods analogous to the -`execute(..)` methods of query objects. The `SQLUpdate` class is concrete. It can be +`execute(..)` methods of query objects. The `SqlUpdate` class is concrete. It can be subclassed -- for example, to add a custom update method. However, you do not have to subclass the `SqlUpdate` class, since it can easily be parameterized by setting SQL and declaring parameters. @@ -6031,7 +6028,7 @@ limit is 1000. In addition to the primitive values in the value list, you can create a `java.util.List` of object arrays. This list can support multiple expressions being defined for the `in` clause, such as `select * from T_ACTOR where (id, last_name) in \((1, 'Johnson'), (2, -'Harrop'\))`. This, of course, requires that your database supports this syntax. +'Harrop'))`. This, of course, requires that your database supports this syntax. [[jdbc-complex-types]] @@ -7093,7 +7090,7 @@ databases, you may want multiple `DatabaseClient` instances, which requires mult instances. [[r2dbc-auto-generated-keys]] -== Retrieving Auto-generated Keys +=== Retrieving Auto-generated Keys `INSERT` statements may generate keys when inserting rows into a table that defines an auto-increment or identity column. To get full control over @@ -7387,7 +7384,9 @@ examples (one for Java configuration and one for XML configuration) show how to ---- @Repository class ProductDaoImpl : ProductDao { + // class body here... + } ---- @@ -7427,7 +7426,7 @@ cover the other ORM technologies and show brief examples. NOTE: As of Spring Framework 5.3, Spring requires Hibernate ORM 5.2+ for Spring's `HibernateJpaVendorAdapter` as well as for a native Hibernate `SessionFactory` setup. -Is is strongly recommended to go with Hibernate ORM 5.4 for a newly started application. +It is strongly recommended to go with Hibernate ORM 5.4 for a newly started application. For use with `HibernateJpaVendorAdapter`, Hibernate Search needs to be upgraded to 5.11.6. @@ -7958,7 +7957,7 @@ persistence unit name. The following XML example configures such a bean: This form of JPA deployment is the simplest and the most limited. You cannot refer to an existing JDBC `DataSource` bean definition, and no support for global transactions exists. Furthermore, weaving (byte-code transformation) of persistent classes is -provider-specific, often requiring a specific JVM agent to specified on startup. This +provider-specific, often requiring a specific JVM agent to be specified on startup. This option is sufficient only for stand-alone applications and test environments, for which the JPA specification is designed. @@ -8093,7 +8092,7 @@ more insight regarding the `LoadTimeWeaver` implementations and their setup, eit generic or customized to various platforms (such as Tomcat, JBoss and WebSphere). As described in <>, you can configure -a context-wide `LoadTimeWeaver` by using the `@EnableLoadTimeWeaving` annotation of the +a context-wide `LoadTimeWeaver` by using the `@EnableLoadTimeWeaving` annotation or the `context:load-time-weaver` XML element. Such a global weaver is automatically picked up by all JPA `LocalContainerEntityManagerFactoryBean` instances. The following example shows the preferred way of setting up a load-time weaver, delivering auto-detection diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index aa17752e28e5..883acc17867a 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -390,7 +390,7 @@ model and corresponding services: [source,java,indent=0,subs="verbatim,quotes"] ---- - public class Account implements Serializable{ + public class Account implements Serializable { private String name; @@ -445,7 +445,7 @@ section of the Spring AMQP reference. [[remoting-autodection-remote-interfaces]] [NOTE] ==== -Auto-detection is not implemented for remote interfaces +Auto-detection is not implemented for remote interfaces. The main reason why auto-detection of implemented interfaces does not occur for remote interfaces is to avoid opening too many doors to remote callers. The target object might @@ -514,7 +514,7 @@ Spring provides full support for the standard Java web services APIs: * Accessing web services using JAX-WS In addition to stock support for JAX-WS in Spring Core, the Spring portfolio also -features http://www.springframework.org/spring-ws[Spring Web Services], which is a solution for +features https://projects.spring.io/spring-ws[Spring Web Services], which is a solution for contract-first, document-driven web services -- highly recommended for building modern, future-proof web services. @@ -711,7 +711,7 @@ as the following example shows: ---- NOTE: The above is slightly simplified in that JAX-WS requires endpoint interfaces -and implementation classes to be annotated with `@WebService`, `@SOAPBinding` etc +and implementation classes to be annotated with `@WebService`, `@SOAPBinding`, etc. annotations. This means that you cannot (easily) use plain Java interfaces and implementation classes as JAX-WS endpoint artifacts; you need to annotate them accordingly first. Check the JAX-WS documentation for details on those requirements. @@ -1610,7 +1610,7 @@ cache size is set to `1`. You can use the `sessionCacheSize` property to increas cached sessions. Note that the number of actual cached sessions is more than that number, as sessions are cached based on their acknowledgment mode, so there can be up to four cached session instances (one for each -acknowledgment mode) when `sessionCacheSize` is set to one . `MessageProducer` and `MessageConsumer` instances are cached within their +acknowledgment mode) when `sessionCacheSize` is set to one. `MessageProducer` and `MessageConsumer` instances are cached within their owning session and also take into account the unique properties of the producers and consumers when caching. MessageProducers are cached based on their destination. MessageConsumers are cached based on a key composed of the destination, selector, @@ -1621,7 +1621,7 @@ noLocal delivery flag, and the durable subscription name (if creating durable co ==== Destination Management Destinations, as `ConnectionFactory` instances, are JMS administered objects that you can store -and retrieved in JNDI. When configuring a Spring application context, you can use the +and retrieve in JNDI. When configuring a Spring application context, you can use the JNDI `JndiObjectFactoryBean` factory class or `` to perform dependency injection on your object's references to JMS destinations. However, this strategy is often cumbersome if there are a large number of destinations in the application or if there @@ -1734,7 +1734,7 @@ use a proper cache level in such a case. This container also has recoverable capabilities when the broker goes down. By default, a simple `BackOff` implementation retries every five seconds. You can specify a custom `BackOff` implementation for more fine-grained recovery options. See -api-spring-framework/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example. +{api-spring-framework}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example. NOTE: Like its sibling (<>), `DefaultMessageListenerContainer` supports native JMS transactions and allows for @@ -1747,7 +1747,7 @@ Any such arrangements are significantly more efficient than the alternative: wrapping your entire processing with an XA transaction (through configuring your `DefaultMessageListenerContainer` with an `JtaTransactionManager`) to cover the reception of the JMS message as well as the execution of the business logic in your -message listener (including database operations etc). +message listener (including database operations, etc.). IMPORTANT: The default `AUTO_ACKNOWLEDGE` mode does not provide proper reliability guarantees. Messages can get lost when listener execution fails (since the provider automatically @@ -1864,7 +1864,7 @@ content. The overloaded methods `convertAndSend()` and `receiveAndConvert()` met `JmsTemplate` delegate the conversion process to an instance of the `MessageConverter` interface. This interface defines a simple contract to convert between Java objects and JMS messages. The default implementation (`SimpleMessageConverter`) supports conversion -between `String` and `TextMessage`, `byte[]` and `BytesMesssage`, and `java.util.Map` +between `String` and `TextMessage`, `byte[]` and `BytesMessage`, and `java.util.Map` and `MapMessage`. By using the converter, you and your application code can focus on the business object that is being sent or received through JMS and not be concerned with the details of how it is represented as a JMS message. @@ -4392,7 +4392,7 @@ email when someone places an order: + order.getCustomer().getLastName() + ", thank you for placing order. Your order number is " + order.getOrderNumber()); - try{ + try { this.mailSender.send(msg); } catch (MailException ex) { @@ -5646,15 +5646,16 @@ compliant caches (such as Ehcache 3.x). See <> for more information plugging in other cache stores and providers. IMPORTANT: The caching abstraction has no special handling for multi-threaded and -multi-process environments, as such features are handled by the cache implementation. . +multi-process environments, as such features are handled by the cache implementation. If you have a multi-process environment (that is, an application deployed on several nodes), you need to configure your cache provider accordingly. Depending on your use cases, a copy of the same data on several nodes can be enough. However, if you change the data during the course of the application, you may need to enable other propagation mechanisms. -Caching a particular item is a direct equivalent of the typical get-if-not-found-then- -proceed-and-put-eventually code blocks found with programmatic cache interaction. +Caching a particular item is a direct equivalent of the typical +get-if-not-found-then-proceed-and-put-eventually code blocks +found with programmatic cache interaction. No locks are applied, and several threads may try to load the same item concurrently. The same applies to eviction. If several threads are trying to update or evict data concurrently, you may use stale data. Certain cache providers offer advanced features diff --git a/src/docs/asciidoc/overview.adoc b/src/docs/asciidoc/overview.adoc index ba74cd35647b..fb24ceef6352 100644 --- a/src/docs/asciidoc/overview.adoc +++ b/src/docs/asciidoc/overview.adoc @@ -44,7 +44,7 @@ parallel, the Spring WebFlux reactive web framework. A note about modules: Spring's framework jars allow for deployment to JDK 9's module path ("Jigsaw"). For use in Jigsaw-enabled applications, the Spring Framework 5 jars come with "Automatic-Module-Name" manifest entries which define stable language-level module names -("spring.core", "spring.context" etc) independent from jar artifact names (the jars follow +("spring.core", "spring.context", etc.) independent from jar artifact names (the jars follow the same naming pattern with "-" instead of ".", e.g. "spring-core" and "spring-context"). Of course, Spring's framework jars keep working fine on the classpath on both JDK 8 and 9+. diff --git a/src/docs/asciidoc/testing.adoc b/src/docs/asciidoc/testing.adoc index 64f07918d46e..6c03726905f5 100644 --- a/src/docs/asciidoc/testing.adoc +++ b/src/docs/asciidoc/testing.adoc @@ -503,6 +503,7 @@ The following example shows such a case: // class body... } ---- +<1> Declaring an initializer class. [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] .Kotlin diff --git a/src/docs/asciidoc/web/integration.adoc b/src/docs/asciidoc/web/integration.adoc index 3bac6bb28b96..62d0ef27516b 100644 --- a/src/docs/asciidoc/web/integration.adoc +++ b/src/docs/asciidoc/web/integration.adoc @@ -29,12 +29,12 @@ entry points into a server-side application, and it delegates to service objects (facades) that are defined in a service layer to satisfy business-specific (and presentation-technology agnostic) use cases. In Spring, these service objects, any other business-specific objects, data-access objects, and others exist in a distinct "`business -context`", which contains no web or presentation layer objects (presentation objects -,such as Spring MVC controllers, are typically configured in a distinct "`presentation +context`", which contains no web or presentation layer objects (presentation objects, +such as Spring MVC controllers, are typically configured in a distinct "`presentation context`"). This section details how you can configure a Spring container (a `WebApplicationContext`) that contains all of the 'business beans' in your application. -Moving on to specifics, all you one need to do is declare a +Moving on to specifics, all you need to do is declare a {api-spring-framework}/web/context/ContextLoaderListener.html[`ContextLoaderListener`] in the standard Java EE servlet `web.xml` file of your web application and add a `contextConfigLocation` section (in the same file) that defines which diff --git a/src/docs/asciidoc/web/web-uris.adoc b/src/docs/asciidoc/web/web-uris.adoc index a36394043b10..11fffde9226f 100644 --- a/src/docs/asciidoc/web/web-uris.adoc +++ b/src/docs/asciidoc/web/web-uris.adoc @@ -95,8 +95,8 @@ You can shorten it further still with a full URI template, as the following exam .Kotlin ---- val uri = UriComponentsBuilder - .fromUriString("https://example.com/hotels/{hotel}?q={q}") - .build("Westin", "123") + .fromUriString("https://example.com/hotels/{hotel}?q={q}") + .build("Westin", "123") ---- @@ -278,7 +278,7 @@ You can shorten it further still with a full URI template, as the following exam ---- The `WebClient` and the `RestTemplate` expand and encode URI templates internally through -the `UriBuilderFactory` strategy. Both can be configured with a custom strategy. +the `UriBuilderFactory` strategy. Both can be configured with a custom strategy, as the following example shows: [source,java,indent=0,subs="verbatim,quotes",role="primary"] diff --git a/src/docs/asciidoc/web/webflux-view.adoc b/src/docs/asciidoc/web/webflux-view.adoc index 51a7a1500879..379d5e1a29ff 100644 --- a/src/docs/asciidoc/web/webflux-view.adoc +++ b/src/docs/asciidoc/web/webflux-view.adoc @@ -232,7 +232,7 @@ Java 8+. Using the latest update release available is highly recommended. line should be added for Kotlin script support. See https://github.com/sdeleuze/kotlin-script-templating[this example] for more detail. -You need to have the script templating library. One way to do that for Javascript is +You need to have the script templating library. One way to do that for JavaScript is through https://www.webjars.org/[WebJars]. diff --git a/src/docs/asciidoc/web/webmvc-cors.adoc b/src/docs/asciidoc/web/webmvc-cors.adoc index f86e775c39c6..c73e88bebf22 100644 --- a/src/docs/asciidoc/web/webmvc-cors.adoc +++ b/src/docs/asciidoc/web/webmvc-cors.adoc @@ -50,7 +50,7 @@ Each `HandlerMapping` can be {api-spring-framework}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured] individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications use the MVC Java configuration or the XML namespace to declare such mappings, which results -in a single global map being passed to all `HandlerMappping` instances. +in a single global map being passed to all `HandlerMapping` instances. You can combine global CORS configuration at the `HandlerMapping` level with more fine-grained, handler-level CORS configuration. For example, annotated controllers can use diff --git a/src/docs/asciidoc/web/webmvc-functional.adoc b/src/docs/asciidoc/web/webmvc-functional.adoc index 1dd3779e1ed4..e40758a781e6 100644 --- a/src/docs/asciidoc/web/webmvc-functional.adoc +++ b/src/docs/asciidoc/web/webmvc-functional.adoc @@ -103,7 +103,7 @@ as the following example shows: If you register the `RouterFunction` as a bean, for instance by exposing it in a -@Configuration class, it will be auto-detected by the servlet, as explained in <>. +`@Configuration` class, it will be auto-detected by the servlet, as explained in <>. @@ -475,7 +475,7 @@ For instance, the router function builder offers the method `GET(String, Handler Besides HTTP method-based mapping, the route builder offers a way to introduce additional predicates when mapping to requests. For each HTTP method there is an overloaded variant that takes a `RequestPredicate` as a -parameter, though which additional constraints can be expressed. +parameter, through which additional constraints can be expressed. [[webmvc-fn-predicates]] diff --git a/src/docs/asciidoc/web/webmvc-view.adoc b/src/docs/asciidoc/web/webmvc-view.adoc index fdca1d02bca4..c127d1ffe43a 100644 --- a/src/docs/asciidoc/web/webmvc-view.adoc +++ b/src/docs/asciidoc/web/webmvc-view.adoc @@ -615,7 +615,7 @@ Java 8+. Using the latest update release available is highly recommended. line should be added for Kotlin script support. See https://github.com/sdeleuze/kotlin-script-templating[this example] for more details. -You need to have the script templating library. One way to do that for Javascript is +You need to have the script templating library. One way to do that for JavaScript is through https://www.webjars.org/[WebJars]. @@ -1697,7 +1697,7 @@ located in the `WEB-INF/defs` directory. At initialization of the `WebApplicatio the files are loaded, and the definitions factory are initialized. After that has been done, the Tiles included in the definition files can be used as views within your Spring web application. To be able to use the views, you have to have a `ViewResolver` -as with any other view technology in Spring : typically a convenient `TilesViewResolver`. +as with any other view technology in Spring: typically a convenient `TilesViewResolver`. You can specify locale-specific Tiles definitions by adding an underscore and then the locale, as the following example shows: diff --git a/src/docs/asciidoc/web/webmvc.adoc b/src/docs/asciidoc/web/webmvc.adoc index 077bcf39cc56..d12b6ab923e8 100644 --- a/src/docs/asciidoc/web/webmvc.adoc +++ b/src/docs/asciidoc/web/webmvc.adoc @@ -580,12 +580,12 @@ itself, excluding the `contextPath` and any `servletMapping` prefix, if present. The `servletPath` and `pathInfo` are decoded and that makes them impossible to compare directly to the full `requestURI` in order to derive the lookupPath and that makes it -necessary to decode the `requestUri`. However this introduces its own issues because the +necessary to decode the `requestURI`. However this introduces its own issues because the path may contain encoded reserved characters such as `"/"` or `";"` that can in turn alter the structure of the path after they are decoded which can also lead to security issues. In addition, Servlet containers may normalize the `servletPath` to varying degrees which makes it further impossible to perform `startsWith` comparisons against -the `requestUri`. +the `requestURI`. This is why it is best to avoid reliance on the `servletPath` which comes with the prefix-based `servletPath` mapping type. If the `DispatcherServlet` is mapped as the @@ -597,7 +597,7 @@ a `UrlPathHelper` with `alwaysUseFullPath=true` via <> the MVC config. Fortunately the default Servlet mapping `"/"` is a good choice. However, there is still -an issue in that the `requestUri` needs to be decoded to make it possible to compare to +an issue in that the `requestURI` needs to be decoded to make it possible to compare to controller mappings. This is again undesirable because of the potential to decode reserved characters that alter the path structure. If such characters are not expected, then you can reject them (like the Spring Security HTTP firewall), or you can configure @@ -787,7 +787,7 @@ The following table provides more details on the `ViewResolver` hierarchy: you can use the `removeFromCache(String viewName, Locale loc)` method. | `UrlBasedViewResolver` -| Simple implementation of the `ViewResolver` interface that affects the direct +| Simple implementation of the `ViewResolver` interface that effects the direct resolution of logical view names to URLs without an explicit mapping definition. This is appropriate if your logical names match the names of your view resources in a straightforward manner, without the need for arbitrary mappings. @@ -1545,8 +1545,8 @@ There are also HTTP method specific shortcut variants of `@RequestMapping`: The shortcuts are <> that are provided because, arguably, most controller methods should be mapped to a specific HTTP method versus -using `@RequestMapping`, which, by default, matches to all HTTP methods. At the same, -a `@RequestMapping` is still needed at the class level to express shared mappings. +using `@RequestMapping`, which, by default, matches to all HTTP methods. +A `@RequestMapping` is still needed at the class level to express shared mappings. The following example has type and method level mappings: @@ -1723,7 +1723,7 @@ one of the following depending on whether use of parsed `PathPattern` is enabled * {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`] * {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`] -Both help to sorts patterns with more specific ones on top. A pattern is less specific if +Both help to sort patterns with more specific ones on top. A pattern is less specific if it has a lower count of URI variables (counted as 1), single wildcards (counted as 1), and double wildcards (counted as 2). Given an equal score, the longer pattern is chosen. Given the same score and length, the pattern with more URI variables than wildcards is @@ -1752,7 +1752,7 @@ using the `Accept` header should be the preferred choice. Over time, the use of file name extensions has proven problematic in a variety of ways. It can cause ambiguity when overlain with the use of URI variables, path parameters, and URI encoding. Reasoning about URL-based authorization -and security (see next section for more details) also become more difficult. +and security (see next section for more details) also becomes more difficult. To completely disable the use of path extensions in versions prior to 5.3, set the following: @@ -2171,7 +2171,7 @@ and others) and is equivalent to `required=false`. | If a method argument is not matched to any of the earlier values in this table and it is a simple type (as determined by {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty], - it is a resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`. + it is resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`. |=== @@ -2300,7 +2300,7 @@ argument as `@Nullable`. ==== As of 5.3, non-null arguments will be enforced even after type conversion. If your handler method intends to accept a null value as well, either declare your argument as `@Nullable` -or mark it as `required=false` in the corresponding `@RequestParam` etc annotation. This is +or mark it as `required=false` in the corresponding `@RequestParam`, etc. annotation. This is a best practice and the recommended solution for regressions encountered in a 5.3 upgrade. Alternatively, you may specifically handle e.g. the resulting `MissingPathVariableException` @@ -2777,8 +2777,8 @@ alternatively, set `@ModelAttribute(binding=false)`, as the following example sh <1> Setting `@ModelAttribute(binding=false)`. You can automatically apply validation after data binding by adding the -`javax.validation.Valid` annotation or Spring's `@Validated` annotation ( -<> and +`javax.validation.Valid` annotation or Spring's `@Validated` annotation +(<> and <>). The following example shows how to do so: [source,java,indent=0,subs="verbatim,quotes",role="primary"] @@ -2841,7 +2841,7 @@ The following example uses the `@SessionAttributes` annotation: ---- @Controller @SessionAttributes("pet") // <1> - public class EditPetForm { + class EditPetForm { // ... } ---- @@ -2866,9 +2866,8 @@ storage, as the following example shows: if (errors.hasErrors) { // ... } - status.setComplete(); // <2> - // ... - } + status.setComplete(); // <2> + // ... } } ---- @@ -4357,7 +4356,7 @@ Spring MVC has an extensive integration with Servlet 3.0 asynchronous request <>: * <> and <> -return values in controller methods and provide basic support for a single asynchronous +return values in controller methods provide basic support for a single asynchronous return value. * Controllers can <> multiple values, including <> and <>. @@ -4889,7 +4888,7 @@ use case-oriented approach that focuses on the common scenarios: val ccCustom = CacheControl.maxAge(10, TimeUnit.DAYS).noTransform().cachePublic() ---- -`WebContentGenerator` also accept a simpler `cachePeriod` property (defined in seconds) that +`WebContentGenerator` also accepts a simpler `cachePeriod` property (defined in seconds) that works as follows: * A `-1` value does not generate a `Cache-Control` response header. @@ -4941,7 +4940,7 @@ settings to a `ResponseEntity`, as the following example shows: } ---- -The preceding example sends an 304 (NOT_MODIFIED) response with an empty body if the comparison +The preceding example sends a 304 (NOT_MODIFIED) response with an empty body if the comparison to the conditional request headers indicates that the content has not changed. Otherwise, the `ETag` and `Cache-Control` headers are added to the response. @@ -5104,6 +5103,7 @@ following example shows: @Configuration @EnableWebMvc class WebConfig : WebMvcConfigurer { + // Implement configuration methods... } ---- diff --git a/src/docs/asciidoc/web/websocket.adoc b/src/docs/asciidoc/web/websocket.adoc index 07751ff57317..e4ee1e49c055 100644 --- a/src/docs/asciidoc/web/websocket.adoc +++ b/src/docs/asciidoc/web/websocket.adoc @@ -1118,7 +1118,7 @@ Contract for sending a message that enables loose coupling between producers and `SubscribableChannel` that uses an `Executor` for delivering messages. Both the Java configuration (that is, `@EnableWebSocketMessageBroker`) and the XML namespace configuration -(that is,``) use the preceding components to assemble a message +(that is, ``) use the preceding components to assemble a message workflow. The following diagram shows the components used when the simple built-in message broker is enabled: @@ -1191,7 +1191,7 @@ is established, STOMP frames begin to flow on it. . The client sends a SUBSCRIBE frame with a destination header of `/topic/greeting`. Once received and decoded, the message is sent to the `clientInboundChannel` and is then routed to the message broker, which stores the client subscription. -. The client sends a aSEND frame to `/app/greeting`. The `/app` prefix helps to route it to +. The client sends a SEND frame to `/app/greeting`. The `/app` prefix helps to route it to annotated controllers. After the `/app` prefix is stripped, the remaining `/greeting` part of the destination is mapped to the `@MessageMapping` method in `GreetingController`. . The value returned from `GreetingController` is turned into a Spring `Message` with @@ -1768,7 +1768,7 @@ WebSocket and SockJS requests. Therefore, applications that wish to avoid the use of cookies may not have any good alternatives for authentication at the HTTP protocol level. Instead of using cookies, -they may prefer to authenticate with headers at the STOMP messaging protocol level +they may prefer to authenticate with headers at the STOMP messaging protocol level. Doing so requires two simple steps: . Use the STOMP client to pass authentication headers at connect time. From 813dbbce5894231193a3006c5d72e8a58e0863f9 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 14 Sep 2021 15:05:45 +0200 Subject: [PATCH 081/735] Polish contribution See gh-27388 --- src/docs/asciidoc/data-access.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/asciidoc/data-access.adoc b/src/docs/asciidoc/data-access.adoc index 388e4bbf5cd8..fa0ccbe73f4a 100644 --- a/src/docs/asciidoc/data-access.adoc +++ b/src/docs/asciidoc/data-access.adoc @@ -6027,7 +6027,7 @@ limit is 1000. In addition to the primitive values in the value list, you can create a `java.util.List` of object arrays. This list can support multiple expressions being defined for the `in` -clause, such as `select * from T_ACTOR where (id, last_name) in \((1, 'Johnson'), (2, +clause, such as `select * from T_ACTOR where (id, last_name) in ((1, 'Johnson'), (2, 'Harrop'))`. This, of course, requires that your database supports this syntax. From caf88ff2cc311b345f5fc0a5ced54d24bd9d553f Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 14 Sep 2021 14:57:45 +0100 Subject: [PATCH 082/735] Improve HandlerMethod#bridgedMethod initialization Ensure makeAccessible is called once when the bridgedMethod is initialized. Closes gh-19795 --- .../springframework/messaging/handler/HandlerMethod.java | 6 +++++- .../handler/invocation/InvocableHandlerMethod.java | 4 +--- .../handler/invocation/reactive/InvocableHandlerMethod.java | 4 +--- .../java/org/springframework/web/method/HandlerMethod.java | 4 ++++ .../web/method/support/InvocableHandlerMethod.java | 2 -- .../web/reactive/result/method/InvocableHandlerMethod.java | 4 +--- 6 files changed, 12 insertions(+), 12 deletions(-) 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 496266b1089d..4ace844929fb 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; +import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; /** @@ -87,6 +88,7 @@ public HandlerMethod(Object bean, Method method) { this.beanType = ClassUtils.getUserClass(bean); this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); + ReflectionUtils.makeAccessible(this.bridgedMethod); this.parameters = initMethodParameters(); } @@ -102,6 +104,7 @@ public HandlerMethod(Object bean, String methodName, Class... parameterTypes) this.beanType = ClassUtils.getUserClass(bean); this.method = bean.getClass().getMethod(methodName, parameterTypes); this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(this.method); + ReflectionUtils.makeAccessible(this.bridgedMethod); this.parameters = initMethodParameters(); } @@ -123,6 +126,7 @@ public HandlerMethod(String beanName, BeanFactory beanFactory, Method method) { this.beanType = ClassUtils.getUserClass(beanType); this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); + ReflectionUtils.makeAccessible(this.bridgedMethod); this.parameters = initMethodParameters(); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java index b9430fdb9aa6..3dc5e2ec2630 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,6 @@ import org.springframework.messaging.Message; import org.springframework.messaging.handler.HandlerMethod; import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; /** * Extension of {@link HandlerMethod} that invokes the underlying method with @@ -166,7 +165,6 @@ protected Object[] getMethodArgumentValues(Message message, Object... provide */ @Nullable protected Object doInvoke(Object... args) throws Exception { - ReflectionUtils.makeAccessible(getBridgedMethod()); try { return getBridgedMethod().invoke(getBean(), args); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/InvocableHandlerMethod.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/InvocableHandlerMethod.java index d4dfe1530683..aad9384af251 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/InvocableHandlerMethod.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/InvocableHandlerMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,6 @@ import org.springframework.messaging.handler.HandlerMethod; import org.springframework.messaging.handler.invocation.MethodArgumentResolutionException; import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; /** * Extension of {@link HandlerMethod} that invokes the underlying method with @@ -130,7 +129,6 @@ public Mono invoke(Message message, Object... providedArgs) { boolean isSuspendingFunction = false; try { Method method = getBridgedMethod(); - ReflectionUtils.makeAccessible(method); if (KotlinDetector.isSuspendingFunction(method)) { isSuspendingFunction = true; value = CoroutinesUtils.invokeSuspendingFunction(method, getBean(), args); diff --git a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java index 35bf35ac01c5..80d6e7999eb4 100644 --- a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java @@ -42,6 +42,7 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; +import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.ResponseStatus; @@ -119,6 +120,7 @@ protected HandlerMethod(Object bean, Method method, @Nullable MessageSource mess this.beanType = ClassUtils.getUserClass(bean); this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); + ReflectionUtils.makeAccessible(this.bridgedMethod); this.parameters = initMethodParameters(); evaluateResponseStatus(); this.description = initDescription(this.beanType, this.method); @@ -137,6 +139,7 @@ public HandlerMethod(Object bean, String methodName, Class... parameterTypes) this.beanType = ClassUtils.getUserClass(bean); this.method = bean.getClass().getMethod(methodName, parameterTypes); this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(this.method); + ReflectionUtils.makeAccessible(this.bridgedMethod); this.parameters = initMethodParameters(); evaluateResponseStatus(); this.description = initDescription(this.beanType, this.method); @@ -172,6 +175,7 @@ public HandlerMethod( this.beanType = ClassUtils.getUserClass(beanType); this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); + ReflectionUtils.makeAccessible(this.bridgedMethod); this.parameters = initMethodParameters(); evaluateResponseStatus(); this.description = initDescription(this.beanType, this.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 80f98393f3a3..970afd65503d 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 @@ -28,7 +28,6 @@ import org.springframework.core.ParameterNameDiscoverer; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.support.SessionStatus; import org.springframework.web.bind.support.WebDataBinderFactory; @@ -199,7 +198,6 @@ protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable M @Nullable protected Object doInvoke(Object... args) throws Exception { Method method = getBridgedMethod(); - ReflectionUtils.makeAccessible(method); try { if (KotlinDetector.isSuspendingFunction(method)) { return CoroutinesUtils.invokeSuspendingFunction(method, getBean(), args); 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 fb2e31a52479..b117a197aa8e 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,6 @@ import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.BindingContext; import org.springframework.web.reactive.HandlerResult; @@ -137,7 +136,6 @@ public Mono invoke( return getMethodArgumentValues(exchange, bindingContext, providedArgs).flatMap(args -> { Object value; try { - ReflectionUtils.makeAccessible(getBridgedMethod()); Method method = getBridgedMethod(); if (KotlinDetector.isSuspendingFunction(method)) { value = CoroutinesUtils.invokeSuspendingFunction(method, getBean(), args); From 92cd680a2c3e93f7415562f03e3e96cc4d8fb526 Mon Sep 17 00:00:00 2001 From: takeaction21 <90566622+takeaction21@users.noreply.github.com> Date: Sun, 12 Sep 2021 23:50:07 +0800 Subject: [PATCH 083/735] Support float and double primitive default values in BeanUtils.instantiateClass() See gh-27390 --- .../src/main/java/org/springframework/beans/BeanUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index 6e97683f889a..3d9f9000efd4 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -88,6 +88,8 @@ public abstract class BeanUtils { values.put(short.class, (short) 0); values.put(int.class, 0); values.put(long.class, (long) 0); + values.put(float.class, (float) 0); + values.put(double.class, (double) 0); DEFAULT_TYPE_VALUES = Collections.unmodifiableMap(values); } From 5cc09849cedfc21a5922930d17bce7a61fccd238 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 14 Sep 2021 15:59:33 +0200 Subject: [PATCH 084/735] Introduce test for gh-27390 --- .../springframework/beans/BeanUtilsTests.java | 95 +++++++++++++++---- 1 file changed, 75 insertions(+), 20 deletions(-) diff --git a/spring-beans/src/test/java/org/springframework/beans/BeanUtilsTests.java b/spring-beans/src/test/java/org/springframework/beans/BeanUtilsTests.java index f3e9d2eaa9a1..5240d97f7a1e 100644 --- a/spring-beans/src/test/java/org/springframework/beans/BeanUtilsTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/BeanUtilsTests.java @@ -49,6 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.SoftAssertions.assertSoftly; /** * Unit tests for {@link BeanUtils}. @@ -85,19 +86,42 @@ void instantiateClassWithOptionalNullableType() throws NoSuchMethodException { } @Test // gh-22531 - void instantiateClassWithOptionalPrimitiveType() throws NoSuchMethodException { - Constructor ctor = BeanWithPrimitiveTypes.class.getDeclaredConstructor(int.class, boolean.class, String.class); - BeanWithPrimitiveTypes bean = BeanUtils.instantiateClass(ctor, null, null, "foo"); - assertThat(bean.getCounter()).isEqualTo(0); - assertThat(bean.isFlag()).isEqualTo(false); - assertThat(bean.getValue()).isEqualTo("foo"); + void instantiateClassWithFewerArgsThanParameters() throws NoSuchMethodException { + Constructor constructor = getBeanWithPrimitiveTypesConstructor(); + + assertThatExceptionOfType(BeanInstantiationException.class).isThrownBy(() -> + BeanUtils.instantiateClass(constructor, null, null, "foo")); } @Test // gh-22531 void instantiateClassWithMoreArgsThanParameters() throws NoSuchMethodException { - Constructor ctor = BeanWithPrimitiveTypes.class.getDeclaredConstructor(int.class, boolean.class, String.class); + Constructor constructor = getBeanWithPrimitiveTypesConstructor(); + assertThatExceptionOfType(BeanInstantiationException.class).isThrownBy(() -> - BeanUtils.instantiateClass(ctor, null, null, "foo", null)); + BeanUtils.instantiateClass(constructor, null, null, null, null, null, null, null, "foo", null)); + } + + @Test // gh-22531, gh-27390 + void instantiateClassWithOptionalPrimitiveTypes() throws NoSuchMethodException { + Constructor constructor = getBeanWithPrimitiveTypesConstructor(); + + BeanWithPrimitiveTypes bean = BeanUtils.instantiateClass(constructor, null, null, null, null, null, null, null, "foo"); + + assertSoftly(softly -> { + softly.assertThat(bean.isFlag()).isEqualTo(false); + softly.assertThat(bean.getByteCount()).isEqualTo((byte) 0); + softly.assertThat(bean.getShortCount()).isEqualTo((short) 0); + softly.assertThat(bean.getIntCount()).isEqualTo(0); + softly.assertThat(bean.getLongCount()).isEqualTo(0L); + softly.assertThat(bean.getFloatCount()).isEqualTo(0F); + softly.assertThat(bean.getDoubleCount()).isEqualTo(0D); + softly.assertThat(bean.getText()).isEqualTo("foo"); + }); + } + + private Constructor getBeanWithPrimitiveTypesConstructor() throws NoSuchMethodException { + return BeanWithPrimitiveTypes.class.getConstructor(boolean.class, byte.class, short.class, int.class, + long.class, float.class, double.class, String.class); } @Test @@ -628,30 +652,61 @@ public String getValue() { private static class BeanWithPrimitiveTypes { - private int counter; - private boolean flag; + private byte byteCount; + private short shortCount; + private int intCount; + private long longCount; + private float floatCount; + private double doubleCount; + private String text; - private String value; @SuppressWarnings("unused") - public BeanWithPrimitiveTypes(int counter, boolean flag, String value) { - this.counter = counter; + public BeanWithPrimitiveTypes(boolean flag, byte byteCount, short shortCount, int intCount, long longCount, + float floatCount, double doubleCount, String text) { this.flag = flag; - this.value = value; - } - - public int getCounter() { - return counter; + this.byteCount = byteCount; + this.shortCount = shortCount; + this.intCount = intCount; + this.longCount = longCount; + this.floatCount = floatCount; + this.doubleCount = doubleCount; + this.text = text; } public boolean isFlag() { return flag; } - public String getValue() { - return value; + public byte getByteCount() { + return byteCount; + } + + public short getShortCount() { + return shortCount; + } + + public int getIntCount() { + return intCount; + } + + public long getLongCount() { + return longCount; + } + + public float getFloatCount() { + return floatCount; + } + + public double getDoubleCount() { + return doubleCount; + } + + public String getText() { + return text; } + } private static class PrivateBeanWithPrivateConstructor { From f07e6a1b9de59331647b2c8dd54f696d59a8b902 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 14 Sep 2021 16:05:29 +0200 Subject: [PATCH 085/735] Support char primitive default values in BeanUtils.instantiateClass() Closes gh-27390 --- .../org/springframework/beans/BeanUtils.java | 7 ++++--- .../springframework/beans/BeanUtilsTests.java | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index 3d9f9000efd4..8ddd6ff74467 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -87,9 +87,10 @@ public abstract class BeanUtils { values.put(byte.class, (byte) 0); values.put(short.class, (short) 0); values.put(int.class, 0); - values.put(long.class, (long) 0); - values.put(float.class, (float) 0); - values.put(double.class, (double) 0); + values.put(long.class, 0L); + values.put(float.class, 0F); + values.put(double.class, 0D); + values.put(char.class, '\0'); DEFAULT_TYPE_VALUES = Collections.unmodifiableMap(values); } diff --git a/spring-beans/src/test/java/org/springframework/beans/BeanUtilsTests.java b/spring-beans/src/test/java/org/springframework/beans/BeanUtilsTests.java index 5240d97f7a1e..b90fd515dc36 100644 --- a/spring-beans/src/test/java/org/springframework/beans/BeanUtilsTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/BeanUtilsTests.java @@ -98,30 +98,31 @@ void instantiateClassWithMoreArgsThanParameters() throws NoSuchMethodException { Constructor constructor = getBeanWithPrimitiveTypesConstructor(); assertThatExceptionOfType(BeanInstantiationException.class).isThrownBy(() -> - BeanUtils.instantiateClass(constructor, null, null, null, null, null, null, null, "foo", null)); + BeanUtils.instantiateClass(constructor, null, null, null, null, null, null, null, null, "foo", null)); } @Test // gh-22531, gh-27390 void instantiateClassWithOptionalPrimitiveTypes() throws NoSuchMethodException { Constructor constructor = getBeanWithPrimitiveTypesConstructor(); - BeanWithPrimitiveTypes bean = BeanUtils.instantiateClass(constructor, null, null, null, null, null, null, null, "foo"); + BeanWithPrimitiveTypes bean = BeanUtils.instantiateClass(constructor, null, null, null, null, null, null, null, null, "foo"); assertSoftly(softly -> { - softly.assertThat(bean.isFlag()).isEqualTo(false); + softly.assertThat(bean.isFlag()).isFalse(); softly.assertThat(bean.getByteCount()).isEqualTo((byte) 0); softly.assertThat(bean.getShortCount()).isEqualTo((short) 0); softly.assertThat(bean.getIntCount()).isEqualTo(0); softly.assertThat(bean.getLongCount()).isEqualTo(0L); softly.assertThat(bean.getFloatCount()).isEqualTo(0F); softly.assertThat(bean.getDoubleCount()).isEqualTo(0D); + softly.assertThat(bean.getCharacter()).isEqualTo('\0'); softly.assertThat(bean.getText()).isEqualTo("foo"); }); } private Constructor getBeanWithPrimitiveTypesConstructor() throws NoSuchMethodException { return BeanWithPrimitiveTypes.class.getConstructor(boolean.class, byte.class, short.class, int.class, - long.class, float.class, double.class, String.class); + long.class, float.class, double.class, char.class, String.class); } @Test @@ -659,12 +660,14 @@ private static class BeanWithPrimitiveTypes { private long longCount; private float floatCount; private double doubleCount; + private char character; private String text; @SuppressWarnings("unused") public BeanWithPrimitiveTypes(boolean flag, byte byteCount, short shortCount, int intCount, long longCount, - float floatCount, double doubleCount, String text) { + float floatCount, double doubleCount, char character, String text) { + this.flag = flag; this.byteCount = byteCount; this.shortCount = shortCount; @@ -672,6 +675,7 @@ public BeanWithPrimitiveTypes(boolean flag, byte byteCount, short shortCount, in this.longCount = longCount; this.floatCount = floatCount; this.doubleCount = doubleCount; + this.character = character; this.text = text; } @@ -703,6 +707,10 @@ public double getDoubleCount() { return doubleCount; } + public char getCharacter() { + return character; + } + public String getText() { return text; } From 9e986c031b92ea7035e639436c79deb77c33e842 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 14 Sep 2021 20:51:59 +0200 Subject: [PATCH 086/735] Polish ide.gradle --- gradle/ide.gradle | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/gradle/ide.gradle b/gradle/ide.gradle index 7db543d3bc4d..6c112fd5b39e 100644 --- a/gradle/ide.gradle +++ b/gradle/ide.gradle @@ -1,7 +1,7 @@ import org.gradle.plugins.ide.eclipse.model.ProjectDependency import org.gradle.plugins.ide.eclipse.model.SourceFolder -apply plugin: "eclipse" +apply plugin: 'eclipse' eclipse.jdt { sourceCompatibility = 1.8 @@ -30,17 +30,17 @@ eclipse.classpath.file.whenMerged { classpath -> } // Use separate main/test outputs (prevents WTP from packaging test classes) -eclipse.classpath.defaultOutputDir = file(project.name+"/bin/eclipse") +eclipse.classpath.defaultOutputDir = file(project.name + '/bin/eclipse') eclipse.classpath.file.beforeMerged { classpath -> classpath.entries.findAll{ it instanceof SourceFolder }.each { - if (it.output.startsWith("bin/")) { + if (it.output.startsWith('bin/')) { it.output = null } } } eclipse.classpath.file.whenMerged { classpath -> classpath.entries.findAll{ it instanceof SourceFolder }.each { - it.output = "bin/" + it.path.split("/")[1] + it.output = 'bin/' + it.path.split('/')[1] } } @@ -65,46 +65,45 @@ eclipse.classpath.file.whenMerged { } // Allow projects to be used as WTP modules -eclipse.project.natures "org.eclipse.wst.common.project.facet.core.nature" +eclipse.project.natures 'org.eclipse.wst.common.project.facet.core.nature' // Include project specific settings task eclipseSettings(type: Copy) { from rootProject.files( - "src/eclipse/org.eclipse.jdt.ui.prefs", - "src/eclipse/org.eclipse.wst.common.project.facet.core.xml") + 'src/eclipse/org.eclipse.jdt.ui.prefs', + 'src/eclipse/org.eclipse.wst.common.project.facet.core.xml') into project.file('.settings/') outputs.upToDateWhen { false } } task eclipseWstComponent(type: Copy) { - from rootProject.files( - "src/eclipse/org.eclipse.wst.common.component") + from rootProject.files('src/eclipse/org.eclipse.wst.common.component') into project.file('.settings/') expand(deployname: project.name) outputs.upToDateWhen { false } } task eclipseJdtPrepare(type: Copy) { - from rootProject.file("src/eclipse/org.eclipse.jdt.core.prefs") - into project.file(".settings/") + from rootProject.file('src/eclipse/org.eclipse.jdt.core.prefs') + into project.file('.settings/') outputs.upToDateWhen { false } } task cleanEclipseJdtUi(type: Delete) { - delete project.file(".settings/org.eclipse.jdt.core.prefs") - delete project.file(".settings/org.eclipse.jdt.ui.prefs") - delete project.file(".settings/org.eclipse.wst.common.component") - delete project.file(".settings/org.eclipse.wst.common.project.facet.core.xml") + delete project.file('.settings/org.eclipse.jdt.core.prefs') + delete project.file('.settings/org.eclipse.jdt.ui.prefs') + delete project.file('.settings/org.eclipse.wst.common.component') + delete project.file('.settings/org.eclipse.wst.common.project.facet.core.xml') } task eclipseBuildship(type: Copy) { from rootProject.files( - "src/eclipse/org.eclipse.jdt.ui.prefs", - "src/eclipse/org.eclipse.jdt.core.prefs") + 'src/eclipse/org.eclipse.jdt.ui.prefs', + 'src/eclipse/org.eclipse.jdt.core.prefs') into project.file('.settings/') outputs.upToDateWhen { false } } -tasks["eclipseJdt"].dependsOn(eclipseJdtPrepare) -tasks["cleanEclipse"].dependsOn(cleanEclipseJdtUi) -tasks["eclipse"].dependsOn(eclipseSettings, eclipseWstComponent) +tasks['eclipseJdt'].dependsOn(eclipseJdtPrepare) +tasks['cleanEclipse'].dependsOn(cleanEclipseJdtUi) +tasks['eclipse'].dependsOn(eclipseSettings, eclipseWstComponent) From 3faf445603e760d0b9223c194861809b410577c9 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 14 Sep 2021 21:05:57 +0200 Subject: [PATCH 087/735] Re-enable import into Eclipse IDE The migration to Gradle 7.2 resulted in a regression for our Eclipse IDE support: several projects ended up with recursive classpath entries in their generated .classpath files which prevent those projects from being built within Eclipse. This commit addresses this issue with a solution that may well be a "hack". Nonetheless, a working hack is better than not being able to import into Eclipse at all. See gh-26870 --- gradle/ide.gradle | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gradle/ide.gradle b/gradle/ide.gradle index 6c112fd5b39e..20bf5f494e73 100644 --- a/gradle/ide.gradle +++ b/gradle/ide.gradle @@ -18,10 +18,13 @@ eclipse.classpath.file.whenMerged { classpath -> if (matcher) { def projectName = matcher[0][1] def path = "/${projectName}" - if(!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) { - def dependency = new ProjectDependency(path) - dependency.exported = true - classpath.entries.add(dependency) + if (!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) { + // Avoid recursive dependency on current project. + if (!entry.path.matches('.+/' + projectName + '/build/([^/]+/)+(?:main|test)')) { + def dependency = new ProjectDependency(path) + dependency.exported = true + classpath.entries.add(dependency) + } } classpath.entries.remove(entry) } From 4322ee194452bc1c2c1fb51932279b038c27205c Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 14 Sep 2021 21:42:00 +0200 Subject: [PATCH 088/735] Polish Eclipse IDE support --- gradle/ide.gradle | 42 +++++++++++++--------------- src/eclipse/org.eclipse.jdt.ui.prefs | 2 +- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/gradle/ide.gradle b/gradle/ide.gradle index 20bf5f494e73..913628b8e880 100644 --- a/gradle/ide.gradle +++ b/gradle/ide.gradle @@ -41,20 +41,20 @@ eclipse.classpath.file.beforeMerged { classpath -> } } } -eclipse.classpath.file.whenMerged { classpath -> - classpath.entries.findAll{ it instanceof SourceFolder }.each { +eclipse.classpath.file.whenMerged { + entries.findAll{ it instanceof SourceFolder }.each { it.output = 'bin/' + it.path.split('/')[1] } } // Ensure project dependencies come after 3rd-party libs (SPR-11836) // https://jira.spring.io/browse/SPR-11836 -eclipse.classpath.file.whenMerged { classpath -> - classpath.entries.findAll { it instanceof ProjectDependency }.each { +eclipse.classpath.file.whenMerged { + entries.findAll { it instanceof ProjectDependency }.each { // delete from original position - classpath.entries.remove(it) + entries.remove(it) // append to end of classpath - classpath.entries.add(it) + entries.add(it) } } @@ -79,34 +79,30 @@ task eclipseSettings(type: Copy) { outputs.upToDateWhen { false } } -task eclipseWstComponent(type: Copy) { - from rootProject.files('src/eclipse/org.eclipse.wst.common.component') +task eclipseJdtSettings(type: Copy) { + from rootProject.file('src/eclipse/org.eclipse.jdt.core.prefs') into project.file('.settings/') - expand(deployname: project.name) outputs.upToDateWhen { false } } -task eclipseJdtPrepare(type: Copy) { - from rootProject.file('src/eclipse/org.eclipse.jdt.core.prefs') +task eclipseBuildship { + dependsOn eclipseSettings, eclipseJdtSettings +} + +task eclipseWstComponentSettings(type: Copy) { + from rootProject.files('src/eclipse/org.eclipse.wst.common.component') into project.file('.settings/') + expand(deployname: project.name) outputs.upToDateWhen { false } } -task cleanEclipseJdtUi(type: Delete) { +task cleanEclipseSettings(type: Delete) { delete project.file('.settings/org.eclipse.jdt.core.prefs') delete project.file('.settings/org.eclipse.jdt.ui.prefs') delete project.file('.settings/org.eclipse.wst.common.component') delete project.file('.settings/org.eclipse.wst.common.project.facet.core.xml') } -task eclipseBuildship(type: Copy) { - from rootProject.files( - 'src/eclipse/org.eclipse.jdt.ui.prefs', - 'src/eclipse/org.eclipse.jdt.core.prefs') - into project.file('.settings/') - outputs.upToDateWhen { false } -} - -tasks['eclipseJdt'].dependsOn(eclipseJdtPrepare) -tasks['cleanEclipse'].dependsOn(cleanEclipseJdtUi) -tasks['eclipse'].dependsOn(eclipseSettings, eclipseWstComponent) +tasks['eclipse'].dependsOn(eclipseSettings, eclipseJdtSettings, eclipseWstComponentSettings) +tasks['eclipseJdt'].dependsOn(eclipseJdtSettings) +tasks['cleanEclipse'].dependsOn(cleanEclipseSettings) diff --git a/src/eclipse/org.eclipse.jdt.ui.prefs b/src/eclipse/org.eclipse.jdt.ui.prefs index 26c219437105..1685154bbab8 100644 --- a/src/eclipse/org.eclipse.jdt.ui.prefs +++ b/src/eclipse/org.eclipse.jdt.ui.prefs @@ -63,4 +63,4 @@ org.eclipse.jdt.ui.keywordthis=false org.eclipse.jdt.ui.ondemandthreshold=9999 org.eclipse.jdt.ui.overrideannotation=true org.eclipse.jdt.ui.staticondemandthreshold=9999 -org.eclipse.jdt.ui.text.custom_code_templates= +org.eclipse.jdt.ui.text.custom_code_templates= From 3baacedfd9c8d908ac95be00ee745d938033cd67 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 14 Sep 2021 21:49:12 +0200 Subject: [PATCH 089/735] Alignment with other abstract utils classes --- .../java/org/springframework/core/CoroutinesUtils.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java b/spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java index e942ff48ee11..50aec2deb3a6 100644 --- a/spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java +++ b/spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java @@ -45,10 +45,7 @@ * @author Phillip Webb * @since 5.2 */ -public final class CoroutinesUtils { - - private CoroutinesUtils() { - } +public abstract class CoroutinesUtils { /** * Convert a {@link Deferred} instance to a {@link Mono}. @@ -78,7 +75,7 @@ public static Publisher invokeSuspendingFunction(Method method, Object target KCallables.callSuspend(function, getSuspendedFunctionArgs(target, args), continuation)) .filter(result -> !Objects.equals(result, Unit.INSTANCE)) .onErrorMap(InvocationTargetException.class, InvocationTargetException::getTargetException); - if (classifier.equals(JvmClassMappingKt.getKotlinClass(Flow.class))) { + if (classifier != null && classifier.equals(JvmClassMappingKt.getKotlinClass(Flow.class))) { return mono.flatMapMany(CoroutinesUtils::asFlux); } return mono; From b8b85a6a59db19ae3283becadf7f60de606d5616 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 14 Sep 2021 21:49:23 +0200 Subject: [PATCH 090/735] Defensive handling of dimensions nullability --- .../spel/ast/ConstructorReference.java | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java index 7ccc4c16d962..d42a375410f6 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java @@ -57,7 +57,7 @@ */ public class ConstructorReference extends SpelNodeImpl { - private boolean isArrayConstructor = false; + private final boolean isArrayConstructor; @Nullable private SpelNodeImpl[] dimensions; @@ -234,6 +234,7 @@ private TypedValue createArray(ExpressionState state) throws EvaluationException FormatHelper.formatClassNameForMessage( intendedArrayType != null ? intendedArrayType.getClass() : null)); } + String type = (String) intendedArrayType; Class componentType; TypeCode arrayTypeCode = TypeCode.forName(type); @@ -243,7 +244,8 @@ private TypedValue createArray(ExpressionState state) throws EvaluationException else { componentType = arrayTypeCode.getType(); } - Object newArray; + + Object newArray = null; if (!hasInitializer()) { // Confirm all dimensions were specified (for example [3][][5] is missing the 2nd dimension) if (this.dimensions != null) { @@ -252,23 +254,22 @@ private TypedValue createArray(ExpressionState state) throws EvaluationException throw new SpelEvaluationException(getStartPosition(), SpelMessage.MISSING_ARRAY_DIMENSION); } } - } - TypeConverter typeConverter = state.getEvaluationContext().getTypeConverter(); - - // Shortcut for 1 dimensional - if (this.dimensions.length == 1) { - TypedValue o = this.dimensions[0].getTypedValue(state); - int arraySize = ExpressionUtils.toInt(typeConverter, o); - newArray = Array.newInstance(componentType, arraySize); - } - else { - // Multi-dimensional - hold onto your hat! - int[] dims = new int[this.dimensions.length]; - for (int d = 0; d < this.dimensions.length; d++) { - TypedValue o = this.dimensions[d].getTypedValue(state); - dims[d] = ExpressionUtils.toInt(typeConverter, o); + TypeConverter typeConverter = state.getEvaluationContext().getTypeConverter(); + if (this.dimensions.length == 1) { + // Shortcut for 1-dimensional + TypedValue o = this.dimensions[0].getTypedValue(state); + int arraySize = ExpressionUtils.toInt(typeConverter, o); + newArray = Array.newInstance(componentType, arraySize); + } + else { + // Multi-dimensional - hold onto your hat! + int[] dims = new int[this.dimensions.length]; + for (int d = 0; d < this.dimensions.length; d++) { + TypedValue o = this.dimensions[d].getTypedValue(state); + dims[d] = ExpressionUtils.toInt(typeConverter, o); + } + newArray = Array.newInstance(componentType, dims); } - newArray = Array.newInstance(componentType, dims); } } else { From 2d65bce18ee22e4eb5afde83b71033097f5bbf26 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 14 Sep 2021 21:58:22 +0200 Subject: [PATCH 091/735] Polish Eclipse IDE support --- gradle/ide.gradle | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gradle/ide.gradle b/gradle/ide.gradle index 913628b8e880..af4664e06018 100644 --- a/gradle/ide.gradle +++ b/gradle/ide.gradle @@ -19,16 +19,18 @@ eclipse.classpath.file.whenMerged { classpath -> def projectName = matcher[0][1] def path = "/${projectName}" if (!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) { + def recursiveDependency = entry.path.matches('.+/' + projectName + '/build/([^/]+/)+(?:main|test)') // Avoid recursive dependency on current project. - if (!entry.path.matches('.+/' + projectName + '/build/([^/]+/)+(?:main|test)')) { - def dependency = new ProjectDependency(path) - dependency.exported = true - classpath.entries.add(dependency) + if (!recursiveDependency) { + classpath.entries.add(new ProjectDependency(path)) } } classpath.entries.remove(entry) } } + + // Remove any remaining direct depencencies on JARs in the build/libs folder + // except Spring's spring-cglib-repack and spring-objenesis-repack JARs. classpath.entries.removeAll { entry -> (entry.path =~ /(?!.*?repack.*\.jar).*?\/([^\/]+)\/build\/libs\/[^\/]+\.jar/) } } From 4c720eaa38704cb97705b86761cd505ceb59835e Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Wed, 15 Sep 2021 08:41:10 +0200 Subject: [PATCH 092/735] Fix GitHub credentials to use token rather than password Closes gh-27402 --- ci/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/pipeline.yml b/ci/pipeline.yml index f919a1b681fc..b9fe3db2f917 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -2,7 +2,7 @@ anchors: git-repo-resource-source: &git-repo-resource-source uri: ((github-repo)) username: ((github-username)) - password: ((github-password)) + password: ((github-ci-release-token)) branch: ((branch)) gradle-enterprise-task-params: &gradle-enterprise-task-params GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key)) From aa14c248990bcfe8345bd1a93ef8f7fa0b415101 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Wed, 15 Sep 2021 09:06:44 +0200 Subject: [PATCH 093/735] Migrate to Spring Builds account --- ci/scripts/stage-version.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/scripts/stage-version.sh b/ci/scripts/stage-version.sh index 0b285de014bf..73c57755451c 100755 --- a/ci/scripts/stage-version.sh +++ b/ci/scripts/stage-version.sh @@ -29,8 +29,8 @@ fi echo "Staging $stageVersion (next version will be $nextVersion)" sed -i "s/version=$snapshotVersion/version=$stageVersion/" gradle.properties -git config user.name "Spring Buildmaster" > /dev/null -git config user.email "buildmaster@springframework.org" > /dev/null +git config user.name "Spring Builds" > /dev/null +git config user.email "spring-builds@users.noreply.github.com" > /dev/null git add gradle.properties > /dev/null git commit -m"Release v$stageVersion" > /dev/null git tag -a "v$stageVersion" -m"Release v$stageVersion" > /dev/null From c7cca2e8790509a56eac422fdd7515ea56a4dc5d Mon Sep 17 00:00:00 2001 From: Spring Builds Date: Wed, 15 Sep 2021 07:24:10 +0000 Subject: [PATCH 094/735] Next development version (v5.3.11-SNAPSHOT) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 28b12e96c3a3..237a595d4483 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=5.3.10-SNAPSHOT +version=5.3.11-SNAPSHOT org.gradle.jvmargs=-Xmx1536M org.gradle.caching=true org.gradle.parallel=true From 7907478d363ebf331b9e3c84adf3b3fec91bd594 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 15 Sep 2021 12:17:07 +0200 Subject: [PATCH 095/735] Watch 5.3.x branch in the CI pipeline Main branch has moved to the 6.0.x line, so this commit updates this CI pipeline to the new 5.3.x maintenance branch. --- ci/parameters.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/parameters.yml b/ci/parameters.yml index a30e8561a224..28486ecec729 100644 --- a/ci/parameters.yml +++ b/ci/parameters.yml @@ -5,7 +5,7 @@ github-repo: "https://github.com/spring-projects/spring-framework.git" github-repo-name: "spring-projects/spring-framework" docker-hub-organization: "springci" artifactory-server: "https://repo.spring.io" -branch: "main" +branch: "5.3.x" milestone: "5.3.x" build-name: "spring-framework" pipeline-name: "spring-framework" From c0e479460e09b7065a21ebfbd95cec7d213ca62e Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 15 Sep 2021 12:37:10 +0200 Subject: [PATCH 096/735] Switch CI pipeline to a JDK17 baseline This commit introduces a new `spring-framework-6.0.x` CI pipeline with JDK 17 baseline. Note that Kotlin still uses a JDK11 baseline for now, this will be addressed in gh-27413. Closes gh-27409 --- .../compile/CompilerConventionsPlugin.java | 2 - .../optional/OptionalDependenciesPlugin.java | 7 +- ci/images/ci-image/Dockerfile | 7 +- ci/images/get-jdk-url.sh | 10 +-- ci/images/setup.sh | 2 +- ci/parameters.yml | 5 +- ci/pipeline.yml | 83 +------------------ ci/scripts/check-project.sh | 2 +- gradle/toolchains.gradle | 20 ++--- 9 files changed, 22 insertions(+), 116 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java b/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java index f2424c549e50..0942ffd4fd55 100644 --- a/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java +++ b/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java @@ -24,7 +24,6 @@ import org.gradle.api.Project; import org.gradle.api.plugins.JavaLibraryPlugin; import org.gradle.api.plugins.JavaPlugin; -import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.tasks.compile.JavaCompile; /** @@ -70,7 +69,6 @@ public void apply(Project project) { * @param project the current project */ private void applyJavaCompileConventions(Project project) { - JavaPluginConvention java = project.getConvention().getPlugin(JavaPluginConvention.class); project.getTasks().withType(JavaCompile.class) .matching(compileTask -> compileTask.getName().equals(JavaPlugin.COMPILE_JAVA_TASK_NAME)) .forEach(compileTask -> { diff --git a/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java b/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java index a7e7101daee7..d8c188f4ce26 100644 --- a/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java +++ b/buildSrc/src/main/java/org/springframework/build/optional/OptionalDependenciesPlugin.java @@ -19,12 +19,9 @@ import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; -import org.gradle.api.attributes.Usage; import org.gradle.api.plugins.JavaPlugin; -import org.gradle.api.plugins.JavaPluginConvention; +import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.tasks.SourceSetContainer; -import org.gradle.plugins.ide.eclipse.EclipsePlugin; -import org.gradle.plugins.ide.eclipse.model.EclipseModel; /** * A {@code Plugin} that adds support for Maven-style optional dependencies. Creates a new @@ -47,7 +44,7 @@ public void apply(Project project) { optional.setCanBeConsumed(false); optional.setCanBeResolved(false); project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> { - SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class) + SourceSetContainer sourceSets = project.getExtensions().getByType(JavaPluginExtension.class) .getSourceSets(); sourceSets.all((sourceSet) -> { project.getConfigurations().getByName(sourceSet.getCompileClasspathConfigurationName()).extendsFrom(optional); diff --git a/ci/images/ci-image/Dockerfile b/ci/images/ci-image/Dockerfile index df1be9f33457..548a7cd7c233 100644 --- a/ci/images/ci-image/Dockerfile +++ b/ci/images/ci-image/Dockerfile @@ -2,10 +2,9 @@ FROM ubuntu:focal-20210827 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh -RUN ./setup.sh java8 +RUN ./setup.sh -ENV JAVA_HOME /opt/openjdk/java8 -ENV JDK11 /opt/openjdk/java11 -ENV JDK16 /opt/openjdk/java16 +ENV JAVA_HOME /opt/openjdk/java17 +ENV JDK17 /opt/openjdk/java17 ENV PATH $JAVA_HOME/bin:$PATH diff --git a/ci/images/get-jdk-url.sh b/ci/images/get-jdk-url.sh index e170d55171c3..48072fd2f9e2 100755 --- a/ci/images/get-jdk-url.sh +++ b/ci/images/get-jdk-url.sh @@ -2,15 +2,9 @@ set -e case "$1" in - java8) - echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u302-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u302b08.tar.gz" + java17) + echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk17-2021-09-15-08-15-beta/OpenJDK17-jdk_x64_linux_hotspot_2021-09-15-08-15.tar.gz" ;; - java11) - echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.12%2B7/OpenJDK11U-jdk_x64_linux_hotspot_11.0.12_7.tar.gz" - ;; - java16) - echo "https://github.com/adoptium/temurin16-binaries/releases/download/jdk-16.0.2%2B7/OpenJDK16U-jdk_x64_linux_hotspot_16.0.2_7.tar.gz" - ;; *) echo $"Unknown java version" exit 1 diff --git a/ci/images/setup.sh b/ci/images/setup.sh index ff18f849f40c..43af1979a261 100755 --- a/ci/images/setup.sh +++ b/ci/images/setup.sh @@ -22,7 +22,7 @@ curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/ mkdir -p /opt/openjdk pushd /opt/openjdk > /dev/null -for jdk in java8 java11 java16 +for jdk in java17 do JDK_URL=$( /get-jdk-url.sh $jdk ) mkdir $jdk diff --git a/ci/parameters.yml b/ci/parameters.yml index a30e8561a224..c392edf66e85 100644 --- a/ci/parameters.yml +++ b/ci/parameters.yml @@ -1,12 +1,9 @@ -email-server: "smtp.svc.pivotal.io" -email-from: "ci@spring.io" -email-to: ["spring-framework-dev@pivotal.io"] github-repo: "https://github.com/spring-projects/spring-framework.git" github-repo-name: "spring-projects/spring-framework" docker-hub-organization: "springci" artifactory-server: "https://repo.spring.io" branch: "main" -milestone: "5.3.x" +milestone: "6.0.x" build-name: "spring-framework" pipeline-name: "spring-framework" concourse-url: "https://ci.spring.io" diff --git a/ci/pipeline.yml b/ci/pipeline.yml index b9fe3db2f917..d2b922602225 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -67,13 +67,6 @@ resources: icon: github source: <<: *git-repo-resource-source -- name: every-morning - type: time - icon: alarm - source: - start: 8:00 AM - stop: 9:00 AM - location: Europe/Vienna - name: ci-images-git-repo type: git icon: github @@ -86,7 +79,7 @@ resources: icon: docker source: <<: *docker-resource-source - repository: ((docker-hub-organization))/spring-framework-ci + repository: ((docker-hub-organization))/spring-framework-ci-jdk17 - name: artifactory-repo type: artifactory-resource icon: package-variant @@ -111,22 +104,6 @@ resources: access_token: ((github-ci-status-token)) branch: ((branch)) context: build -- name: repo-status-jdk11-build - type: github-status-resource - icon: eye-check-outline - source: - repository: ((github-repo-name)) - access_token: ((github-ci-status-token)) - branch: ((branch)) - context: jdk11-build -- name: repo-status-jdk16-build - type: github-status-resource - icon: eye-check-outline - source: - repository: ((github-repo-name)) - access_token: ((github-ci-status-token)) - branch: ((branch)) - context: jdk16-build - name: slack-alert type: slack-notification icon: slack @@ -216,62 +193,6 @@ jobs: "zip.type": "schema" get_params: threads: 8 -- name: jdk11-build - serial: true - public: true - plan: - - get: ci-image - - get: git-repo - - get: every-morning - trigger: true - - put: repo-status-jdk11-build - params: { state: "pending", commit: "git-repo" } - - do: - - task: check-project - image: ci-image - file: git-repo/ci/tasks/check-project.yml - privileged: true - timeout: ((task-timeout)) - params: - TEST_TOOLCHAIN: 11 - <<: *build-project-task-params - on_failure: - do: - - put: repo-status-jdk11-build - params: { state: "failure", commit: "git-repo" } - - put: slack-alert - params: - <<: *slack-fail-params - - put: repo-status-jdk11-build - params: { state: "success", commit: "git-repo" } -- name: jdk16-build - serial: true - public: true - plan: - - get: ci-image - - get: git-repo - - get: every-morning - trigger: true - - put: repo-status-jdk16-build - params: { state: "pending", commit: "git-repo" } - - do: - - task: check-project - image: ci-image - file: git-repo/ci/tasks/check-project.yml - privileged: true - timeout: ((task-timeout)) - params: - TEST_TOOLCHAIN: 15 - <<: *build-project-task-params - on_failure: - do: - - put: repo-status-jdk16-build - params: { state: "failure", commit: "git-repo" } - - put: slack-alert - params: - <<: *slack-fail-params - - put: repo-status-jdk16-build - params: { state: "success", commit: "git-repo" } - name: build-pull-requests serial: true public: true @@ -453,7 +374,7 @@ jobs: groups: - name: "builds" - jobs: ["build", "jdk11-build", "jdk16-build"] + jobs: ["build"] - name: "releases" jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"] - name: "ci-images" diff --git a/ci/scripts/check-project.sh b/ci/scripts/check-project.sh index 7f6ca04cea9b..0620dc17164d 100755 --- a/ci/scripts/check-project.sh +++ b/ci/scripts/check-project.sh @@ -4,6 +4,6 @@ set -e source $(dirname $0)/common.sh pushd git-repo > /dev/null -./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK11,JDK15 \ +./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK17 \ -PmainToolchain=${MAIN_TOOLCHAIN} -PtestToolchain=${TEST_TOOLCHAIN} --no-daemon --max-workers=4 check popd > /dev/null diff --git a/gradle/toolchains.gradle b/gradle/toolchains.gradle index 5573efa1a52d..57ca9e51418d 100644 --- a/gradle/toolchains.gradle +++ b/gradle/toolchains.gradle @@ -11,7 +11,7 @@ *
  • a JDK11 toolchain for compiling and running the test SourceSet * * - * By default, the build will fall back to using the current JDK and 1.8 language level for all sourceSets. + * By default, the build will fall back to using the current JDK and 17 language level for all sourceSets. * * Gradle will automatically detect JDK distributions in well-known locations. * The following command will list the detected JDKs on the host. @@ -44,7 +44,7 @@ def mainToolchainLanguageVersion() { if (mainToolchainConfigured()) { return JavaLanguageVersion.of(project.mainToolchain.toString()) } - return JavaLanguageVersion.of(8) + return JavaLanguageVersion.of(17) } def testToolchainLanguageVersion() { @@ -64,9 +64,9 @@ plugins.withType(JavaPlugin) { } } else { - // Fallback to JDK8 + // Fallback to JDK17 java { - sourceCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 } } // Configure a specific Java Toolchain for compiling and running tests if the 'testToolchain' property is defined @@ -86,10 +86,10 @@ plugins.withType(JavaPlugin) { } plugins.withType(GroovyPlugin) { - // Fallback to JDK8 + // Fallback to JDK17 if (!mainToolchainConfigured()) { compileGroovy { - sourceCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 } } } @@ -102,7 +102,7 @@ pluginManager.withPlugin("kotlin") { languageVersion = mainLanguageVersion } // See https://kotlinlang.org/docs/gradle.html#attributes-specific-for-jvm - def javaVersion = mainLanguageVersion.toString() == '8' ? '1.8' : mainLanguageVersion.toString() + def javaVersion = mainLanguageVersion.toString() compileKotlin { kotlinOptions { jvmTarget = javaVersion @@ -118,15 +118,15 @@ pluginManager.withPlugin("kotlin") { } } else { - // Fallback to JDK8 + // Fallback to JDK11 compileKotlin { kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } } compileTestKotlin { kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } } } From 09b233365fe027a8295456bafc091ed8faac3dcd Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 15 Sep 2021 14:03:51 +0200 Subject: [PATCH 097/735] Update project version to 6.0.0-SNAPSHOT --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 237a595d4483..886369712793 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -version=5.3.11-SNAPSHOT +version=6.0.0-SNAPSHOT org.gradle.jvmargs=-Xmx1536M org.gradle.caching=true org.gradle.parallel=true -kotlin.stdlib.default.dependency=false \ No newline at end of file +kotlin.stdlib.default.dependency=false From 350d3e8b225181fa8a9bee6dd8e51f526262c75e Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 15 Sep 2021 14:24:14 +0200 Subject: [PATCH 098/735] Update @since tag in code template to 6.0 --- src/eclipse/org.eclipse.jdt.ui.prefs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eclipse/org.eclipse.jdt.ui.prefs b/src/eclipse/org.eclipse.jdt.ui.prefs index 1685154bbab8..1961fa953324 100644 --- a/src/eclipse/org.eclipse.jdt.ui.prefs +++ b/src/eclipse/org.eclipse.jdt.ui.prefs @@ -63,4 +63,4 @@ org.eclipse.jdt.ui.keywordthis=false org.eclipse.jdt.ui.ondemandthreshold=9999 org.eclipse.jdt.ui.overrideannotation=true org.eclipse.jdt.ui.staticondemandthreshold=9999 -org.eclipse.jdt.ui.text.custom_code_templates= +org.eclipse.jdt.ui.text.custom_code_templates= From 00eef79e5c29d953eb5c9a225ca31f5680952b00 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 15 Sep 2021 14:40:42 +0200 Subject: [PATCH 099/735] Upgrade to JApicmp Gradle Plugin 0.3.0 Fixes gh-27414 --- buildSrc/build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 03f629496a28..6f5712565d86 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -8,8 +8,7 @@ repositories { } dependencies { - implementation "me.champeau.gradle:japicmp-gradle-plugin:0.2.8" - implementation "com.google.guava:guava:28.2-jre" // required by japicmp-gradle-plugin + implementation "me.champeau.gradle:japicmp-gradle-plugin:0.3.0" } gradlePlugin { From 0640da74bcbeb9bf539e7574751df6b6d4d072a9 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 15 Sep 2021 15:26:13 +0200 Subject: [PATCH 100/735] Upgrade to Checkstyle 9.0, Groovy 3.0.9, Hibernate ORM 5.5.7 Includes downgrade of Kotlin language level to 1.8 (for KotlinScriptTemplateTests) --- build.gradle | 6 +++--- gradle/toolchains.gradle | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 8a3207ccc859..3cb2fa7f94c7 100644 --- a/build.gradle +++ b/build.gradle @@ -56,7 +56,7 @@ configure(allprojects) { project -> entry 'aspectjtools' entry 'aspectjweaver' } - dependencySet(group: 'org.codehaus.groovy', version: '3.0.8') { + dependencySet(group: 'org.codehaus.groovy', version: '3.0.9') { entry 'groovy' entry 'groovy-jsr223' entry 'groovy-templates' // requires findbugs for warning-free compilation @@ -123,7 +123,7 @@ configure(allprojects) { project -> dependency "net.sf.ehcache:ehcache:2.10.6" dependency "org.ehcache:jcache:1.0.1" dependency "org.ehcache:ehcache:3.4.0" - dependency "org.hibernate:hibernate-core:5.4.32.Final" + dependency "org.hibernate:hibernate-core:5.5.7.Final" dependency "org.hibernate:hibernate-validator:6.2.0.Final" dependency "org.webjars:webjars-locator-core:0.47" dependency "org.webjars:underscorejs:1.8.3" @@ -339,7 +339,7 @@ configure([rootProject] + javaProjects) { project -> } checkstyle { - toolVersion = "8.45.1" + toolVersion = "9.0" configDirectory.set(rootProject.file("src/checkstyle")) } diff --git a/gradle/toolchains.gradle b/gradle/toolchains.gradle index 57ca9e51418d..15ee3bcfc526 100644 --- a/gradle/toolchains.gradle +++ b/gradle/toolchains.gradle @@ -121,12 +121,12 @@ pluginManager.withPlugin("kotlin") { // Fallback to JDK11 compileKotlin { kotlinOptions { - jvmTarget = '11' + jvmTarget = '1.8' } } compileTestKotlin { kotlinOptions { - jvmTarget = '11' + jvmTarget = '1.8' } } } From cf2429b0f0ce2a5278bdc2556663caf6cf0b0cae Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 15 Sep 2021 15:30:25 +0200 Subject: [PATCH 101/735] Remove support for deprecated Java SecurityManager (-> JDK 17 build compatibility) Includes hard JDK 9+ API dependency in CGLIB ReflectUtils (Lookup.defineClass) and removal of OutputStream spy proxy usage (avoiding invalid Mockito proxy on JDK 17) Closes gh-26901 --- spring-beans/spring-beans.gradle | 3 +- .../beans/BeanWrapperImpl.java | 69 +-- .../config/ConfigurableBeanFactory.java | 10 +- .../AbstractAutowireCapableBeanFactory.java | 82 +-- .../factory/support/AbstractBeanFactory.java | 64 +-- .../factory/support/ConstructorResolver.java | 34 +- .../support/DefaultListableBeanFactory.java | 36 +- .../support/DisposableBeanAdapter.java | 53 +- .../support/FactoryBeanRegistrySupport.java | 38 +- .../support/SecurityContextProvider.java | 35 -- .../support/SimpleInstantiationStrategy.java | 30 +- .../SimpleSecurityContextProvider.java | 62 --- .../DefaultListableBeanFactoryTests.java | 54 -- .../security/CallbacksSecurityTests.java | 479 ------------------ .../security/support/ConstructorBean.java | 30 -- .../security/support/CustomCallbackBean.java | 30 -- .../security/support/CustomFactoryBean.java | 44 -- .../support/security/support/DestroyBean.java | 29 -- .../support/security/support/FactoryBean.java | 36 -- .../support/security/support/InitBean.java | 29 -- .../security/support/PropertyBean.java | 30 -- .../propertyeditors/CustomEditorTests.java | 2 +- .../ApplicationContextAwareProcessor.java | 23 +- .../support/ResourceBundleMessageSource.java | 36 +- .../ApplicationContextExpressionTests.java | 39 -- ...onmentSecurityManagerIntegrationTests.java | 119 ----- .../jmx/support/JmxUtilsTests.java | 31 +- .../support/MBeanServerFactoryBeanTests.java | 9 +- .../jndi/JndiLocatorDelegateTests.java | 52 -- .../springframework/util/MBeanTestUtils.java | 9 +- .../cglib/core/ReflectUtils.java | 100 +--- .../core/env/AbstractEnvironment.java | 48 +- .../core/env/ConfigurableEnvironment.java | 18 +- .../core/env/ReadOnlySystemAttributesMap.java | 123 ----- .../env/SystemEnvironmentPropertySource.java | 18 +- .../AbstractRecursiveAnnotationVisitor.java | 5 +- .../AnnotationAttributesReadingVisitor.java | 4 +- .../springframework/util/ReflectionUtils.java | 18 +- .../core/env/StandardEnvironmentTests.java | 105 +--- .../SystemEnvironmentPropertySourceTests.java | 31 +- .../util/StreamUtilsTests.java | 22 +- .../testfixture/env/EnvironmentTestUtils.java | 92 ---- .../http/MockHttpOutputMessage.java | 6 +- .../FormHttpMessageConverterTests.java | 7 +- .../StringHttpMessageConverterTests.java | 4 +- ...pingJackson2HttpMessageConverterTests.java | 5 +- .../ServletRequestAttributesTests.java | 22 +- 47 files changed, 147 insertions(+), 2078 deletions(-) delete mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/support/SecurityContextProvider.java delete mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java delete mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/support/security/CallbacksSecurityTests.java delete mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/ConstructorBean.java delete mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomCallbackBean.java delete mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomFactoryBean.java delete mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/DestroyBean.java delete mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/FactoryBean.java delete mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/InitBean.java delete mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/PropertyBean.java delete mode 100644 spring-context/src/test/java/org/springframework/context/support/EnvironmentSecurityManagerIntegrationTests.java delete mode 100644 spring-context/src/test/java/org/springframework/jndi/JndiLocatorDelegateTests.java delete mode 100644 spring-core/src/main/java/org/springframework/core/env/ReadOnlySystemAttributesMap.java delete mode 100644 spring-core/src/testFixtures/java/org/springframework/core/testfixture/env/EnvironmentTestUtils.java diff --git a/spring-beans/spring-beans.gradle b/spring-beans/spring-beans.gradle index e3f6f73b763b..bf5fad779f0f 100644 --- a/spring-beans/spring-beans.gradle +++ b/spring-beans/spring-beans.gradle @@ -23,7 +23,8 @@ sourceSets { } compileGroovy { - options.compilerArgs += "-Werror" + // Groovy generates Java code with "new Boolean" usage which is deprecated on JDK 17 + // options.compilerArgs += "-Werror" } // This module also builds Kotlin code and the compileKotlin task naturally depends on diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java b/spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java index c2fb1aca6f71..df6ee2cede91 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,11 +18,6 @@ import java.beans.PropertyDescriptor; import java.lang.reflect.Method; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import org.springframework.core.ResolvableType; import org.springframework.core.convert.Property; @@ -69,12 +64,6 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements @Nullable private CachedIntrospectionResults cachedIntrospectionResults; - /** - * The security context used for invoking the property methods. - */ - @Nullable - private AccessControlContext acc; - /** * Create a new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards. @@ -131,7 +120,6 @@ public BeanWrapperImpl(Object object, String nestedPath, Object rootObject) { */ private BeanWrapperImpl(Object object, String nestedPath, BeanWrapperImpl parent) { super(object, nestedPath, parent); - setSecurityContext(parent.acc); } @@ -176,23 +164,6 @@ private CachedIntrospectionResults getCachedIntrospectionResults() { return this.cachedIntrospectionResults; } - /** - * Set the security context used during the invocation of the wrapped instance methods. - * Can be null. - */ - public void setSecurityContext(@Nullable AccessControlContext acc) { - this.acc = acc; - } - - /** - * Return the security context used during the invocation of the wrapped instance methods. - * Can be null. - */ - @Nullable - public AccessControlContext getSecurityContext() { - return this.acc; - } - /** * Convert the given value for the specified property to the latter's type. @@ -290,23 +261,8 @@ public TypeDescriptor nested(int level) { @Nullable public Object getValue() throws Exception { Method readMethod = this.pd.getReadMethod(); - if (System.getSecurityManager() != null) { - AccessController.doPrivileged((PrivilegedAction) () -> { - ReflectionUtils.makeAccessible(readMethod); - return null; - }); - try { - return AccessController.doPrivileged((PrivilegedExceptionAction) - () -> readMethod.invoke(getWrappedInstance(), (Object[]) null), acc); - } - catch (PrivilegedActionException pae) { - throw pae.getException(); - } - } - else { - ReflectionUtils.makeAccessible(readMethod); - return readMethod.invoke(getWrappedInstance(), (Object[]) null); - } + ReflectionUtils.makeAccessible(readMethod); + return readMethod.invoke(getWrappedInstance(), (Object[]) null); } @Override @@ -314,23 +270,8 @@ public void setValue(@Nullable Object value) throws Exception { Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ? ((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() : this.pd.getWriteMethod()); - if (System.getSecurityManager() != null) { - AccessController.doPrivileged((PrivilegedAction) () -> { - ReflectionUtils.makeAccessible(writeMethod); - return null; - }); - try { - AccessController.doPrivileged((PrivilegedExceptionAction) - () -> writeMethod.invoke(getWrappedInstance(), value), acc); - } - catch (PrivilegedActionException ex) { - throw ex.getException(); - } - } - else { - ReflectionUtils.makeAccessible(writeMethod); - writeMethod.invoke(getWrappedInstance(), value); - } + ReflectionUtils.makeAccessible(writeMethod); + writeMethod.invoke(getWrappedInstance(), value); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java index 81f4d8760154..09460499e2be 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package org.springframework.beans.factory.config; import java.beans.PropertyEditor; -import java.security.AccessControlContext; import org.springframework.beans.PropertyEditorRegistrar; import org.springframework.beans.PropertyEditorRegistry; @@ -291,13 +290,6 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single */ ApplicationStartup getApplicationStartup(); - /** - * Provides a security access control context relevant to this factory. - * @return the applicable AccessControlContext (never {@code null}) - * @since 3.0 - */ - AccessControlContext getAccessControlContext(); - /** * Copy all relevant configuration from the given other factory. *

    Should include all standard configuration settings as well as diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 02b27fe30443..e1a2dbd1d375 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -21,10 +21,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -387,15 +383,7 @@ public Object autowire(Class beanClass, int autowireMode, boolean dependencyC return autowireConstructor(beanClass.getName(), bd, null, null).getWrappedInstance(); } else { - Object bean; - if (System.getSecurityManager() != null) { - bean = AccessController.doPrivileged( - (PrivilegedAction) () -> getInstantiationStrategy().instantiate(bd, null, this), - getAccessControlContext()); - } - else { - bean = getInstantiationStrategy().instantiate(bd, null, this); - } + Object bean = getInstantiationStrategy().instantiate(bd, null, this); populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean)); return bean; } @@ -463,8 +451,7 @@ public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, St @Override public void destroyBean(Object existingBean) { - new DisposableBeanAdapter( - existingBean, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy(); + new DisposableBeanAdapter(existingBean, getBeanPostProcessorCache().destructionAware).destroy(); } @@ -1316,15 +1303,7 @@ protected Constructor[] determineConstructorsFromBeanPostProcessors(@Nullable */ protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) { try { - Object beanInstance; - if (System.getSecurityManager() != null) { - beanInstance = AccessController.doPrivileged( - (PrivilegedAction) () -> getInstantiationStrategy().instantiate(mbd, beanName, this), - getAccessControlContext()); - } - else { - beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this); - } + Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this); BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; @@ -1655,10 +1634,6 @@ protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrap return; } - if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) { - ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); - } - MutablePropertyValues mpvs = null; List original; @@ -1781,15 +1756,7 @@ private Object convertForProperty( * @see #applyBeanPostProcessorsAfterInitialization */ protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { - if (System.getSecurityManager() != null) { - AccessController.doPrivileged((PrivilegedAction) () -> { - invokeAwareMethods(beanName, bean); - return null; - }, getAccessControlContext()); - } - else { - invokeAwareMethods(beanName, bean); - } + invokeAwareMethods(beanName, bean); Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { @@ -1848,20 +1815,7 @@ protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBea if (logger.isTraceEnabled()) { logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } - if (System.getSecurityManager() != null) { - try { - AccessController.doPrivileged((PrivilegedExceptionAction) () -> { - ((InitializingBean) bean).afterPropertiesSet(); - return null; - }, getAccessControlContext()); - } - catch (PrivilegedActionException pae) { - throw pae.getException(); - } - } - else { - ((InitializingBean) bean).afterPropertiesSet(); - } + ((InitializingBean) bean).afterPropertiesSet(); } if (mbd != null && bean.getClass() != NullBean.class) { @@ -1910,28 +1864,12 @@ protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefi } Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod); - if (System.getSecurityManager() != null) { - AccessController.doPrivileged((PrivilegedAction) () -> { - ReflectionUtils.makeAccessible(methodToInvoke); - return null; - }); - try { - AccessController.doPrivileged((PrivilegedExceptionAction) - () -> methodToInvoke.invoke(bean), getAccessControlContext()); - } - catch (PrivilegedActionException pae) { - InvocationTargetException ex = (InvocationTargetException) pae.getException(); - throw ex.getTargetException(); - } + try { + ReflectionUtils.makeAccessible(methodToInvoke); + methodToInvoke.invoke(bean); } - else { - try { - ReflectionUtils.makeAccessible(methodToInvoke); - methodToInvoke.invoke(bean); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } + catch (InvocationTargetException ex) { + throw ex.getTargetException(); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index 562c00fd55f1..91a0f6131ce9 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,6 @@ package org.springframework.beans.factory.support; import java.beans.PropertyEditor; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -166,10 +161,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp /** Map from scope identifier String to corresponding Scope. */ private final Map scopes = new LinkedHashMap<>(8); - /** Security context used when running with a SecurityManager. */ - @Nullable - private SecurityContextProvider securityContextProvider; - /** Map from bean name to merged RootBeanDefinition. */ private final Map mergedBeanDefinitions = new ConcurrentHashMap<>(256); @@ -495,17 +486,8 @@ public boolean isPrototype(String name) throws NoSuchBeanDefinitionException { } if (isFactoryBean(beanName, mbd)) { FactoryBean fb = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName); - if (System.getSecurityManager() != null) { - return AccessController.doPrivileged( - (PrivilegedAction) () -> - ((fb instanceof SmartFactoryBean && ((SmartFactoryBean) fb).isPrototype()) || - !fb.isSingleton()), - getAccessControlContext()); - } - else { - return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean) fb).isPrototype()) || - !fb.isSingleton()); - } + return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean) fb).isPrototype()) || + !fb.isSingleton()); } else { return false; @@ -1054,15 +1036,6 @@ public Scope getRegisteredScope(String scopeName) { return this.scopes.get(scopeName); } - /** - * Set the security context provider for this bean factory. If a security manager - * is set, interaction with the user code will be executed using the privileged - * of the provided security context. - */ - public void setSecurityContextProvider(SecurityContextProvider securityProvider) { - this.securityContextProvider = securityProvider; - } - @Override public void setApplicationStartup(ApplicationStartup applicationStartup) { Assert.notNull(applicationStartup, "applicationStartup should not be null"); @@ -1074,17 +1047,6 @@ public ApplicationStartup getApplicationStartup() { return this.applicationStartup; } - /** - * Delegate the creation of the access control context to the - * {@link #setSecurityContextProvider SecurityContextProvider}. - */ - @Override - public AccessControlContext getAccessControlContext() { - return (this.securityContextProvider != null ? - this.securityContextProvider.getAccessControlContext() : - AccessController.getContext()); - } - @Override public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) { Assert.notNull(otherFactory, "BeanFactory must not be null"); @@ -1099,7 +1061,6 @@ public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) { this.typeConverter = otherAbstractFactory.typeConverter; this.beanPostProcessors.addAll(otherAbstractFactory.beanPostProcessors); this.scopes.putAll(otherAbstractFactory.scopes); - this.securityContextProvider = otherAbstractFactory.securityContextProvider; } else { setTypeConverter(otherFactory.getTypeConverter()); @@ -1222,7 +1183,7 @@ public void destroyBean(String beanName, Object beanInstance) { */ protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) { new DisposableBeanAdapter( - bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy(); + bean, beanName, mbd, getBeanPostProcessorCache().destructionAware).destroy(); } @Override @@ -1526,17 +1487,7 @@ protected Class resolveBeanClass(RootBeanDefinition mbd, String beanName, Cla if (mbd.hasBeanClass()) { return mbd.getBeanClass(); } - if (System.getSecurityManager() != null) { - return AccessController.doPrivileged((PrivilegedExceptionAction>) - () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext()); - } - else { - return doResolveBeanClass(mbd, typesToMatch); - } - } - catch (PrivilegedActionException pae) { - ClassNotFoundException ex = (ClassNotFoundException) pae.getException(); - throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); + return doResolveBeanClass(mbd, typesToMatch); } catch (ClassNotFoundException ex) { throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); @@ -1925,14 +1876,13 @@ protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) { * @see #registerDependentBean */ protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { - AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { // Register a DisposableBean implementation that performs all destruction // work for the given bean: DestructionAwareBeanPostProcessors, // DisposableBean interface, custom destroy method. registerDisposableBean(beanName, new DisposableBeanAdapter( - bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc)); + bean, beanName, mbd, getBeanPostProcessorCache().destructionAware)); } else { // A bean with a custom scope... @@ -1941,7 +1891,7 @@ protected void registerDisposableBeanIfNecessary(String beanName, Object bean, R throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'"); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter( - bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc)); + bean, beanName, mbd, getBeanPostProcessorCache().destructionAware)); } } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java index 36190c3b817c..cfbc8a99269f 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java @@ -22,8 +22,6 @@ import java.lang.reflect.Executable; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; @@ -302,14 +300,7 @@ private Object instantiate( try { InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy(); - if (System.getSecurityManager() != null) { - return AccessController.doPrivileged((PrivilegedAction) () -> - strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse), - this.beanFactory.getAccessControlContext()); - } - else { - return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse); - } + return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, @@ -365,15 +356,8 @@ private boolean isParamMismatch(Method uniqueCandidate, Method candidate) { * Called as the starting point for factory method determination. */ private Method[] getCandidateMethods(Class factoryClass, RootBeanDefinition mbd) { - if (System.getSecurityManager() != null) { - return AccessController.doPrivileged((PrivilegedAction) () -> - (mbd.isNonPublicAccessAllowed() ? - ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods())); - } - else { - return (mbd.isNonPublicAccessAllowed() ? - ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods()); - } + return (mbd.isNonPublicAccessAllowed() ? + ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods()); } /** @@ -643,16 +627,8 @@ private Object instantiate(String beanName, RootBeanDefinition mbd, @Nullable Object factoryBean, Method factoryMethod, Object[] args) { try { - if (System.getSecurityManager() != null) { - return AccessController.doPrivileged((PrivilegedAction) () -> - this.beanFactory.getInstantiationStrategy().instantiate( - mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args), - this.beanFactory.getAccessControlContext()); - } - else { - return this.beanFactory.getInstantiationStrategy().instantiate( - mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args); - } + return this.beanFactory.getInstantiationStrategy().instantiate( + mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, 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 048612fbed73..a4f29b0ce879 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +25,6 @@ import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -296,15 +294,7 @@ public Comparator getDependencyComparator() { public void setAutowireCandidateResolver(AutowireCandidateResolver autowireCandidateResolver) { Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null"); if (autowireCandidateResolver instanceof BeanFactoryAware) { - if (System.getSecurityManager() != null) { - AccessController.doPrivileged((PrivilegedAction) () -> { - ((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this); - return null; - }, getAccessControlContext()); - } - else { - ((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this); - } + ((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this); } this.autowireCandidateResolver = autowireCandidateResolver; } @@ -925,16 +915,8 @@ public void preInstantiateSingletons() throws BeansException { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean factory = (FactoryBean) bean; - boolean isEagerInit; - if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { - isEagerInit = AccessController.doPrivileged( - (PrivilegedAction) ((SmartFactoryBean) factory)::isEagerInit, - getAccessControlContext()); - } - else { - isEagerInit = (factory instanceof SmartFactoryBean && - ((SmartFactoryBean) factory).isEagerInit()); - } + boolean isEagerInit = (factory instanceof SmartFactoryBean && + ((SmartFactoryBean) factory).isEagerInit()); if (isEagerInit) { getBean(beanName); } @@ -953,15 +935,7 @@ public void preInstantiateSingletons() throws BeansException { StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize") .tag("beanName", beanName); SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; - if (System.getSecurityManager() != null) { - AccessController.doPrivileged((PrivilegedAction) () -> { - smartSingleton.afterSingletonsInstantiated(); - return null; - }, getAccessControlContext()); - } - else { - smartSingleton.afterSingletonsInstantiated(); - } + smartSingleton.afterSingletonsInstantiated(); smartInitialize.end(); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java index 3e779752a952..3d8327a12f25 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java @@ -19,11 +19,6 @@ import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.List; @@ -76,9 +71,6 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { private final boolean nonPublicAccessAllowed; - @Nullable - private final AccessControlContext acc; - @Nullable private String destroyMethodName; @@ -98,7 +90,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { * (potentially DestructionAwareBeanPostProcessor), if any */ public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition, - List postProcessors, @Nullable AccessControlContext acc) { + List postProcessors) { Assert.notNull(bean, "Disposable bean must not be null"); this.bean = bean; @@ -106,7 +98,6 @@ public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition be this.invokeDisposableBean = (this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy")); this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed(); - this.acc = acc; String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition); if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) && !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) { @@ -143,15 +134,12 @@ else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) { * @param postProcessors the List of BeanPostProcessors * (potentially DestructionAwareBeanPostProcessor), if any */ - public DisposableBeanAdapter( - Object bean, List postProcessors, AccessControlContext acc) { - + public DisposableBeanAdapter(Object bean, List postProcessors) { Assert.notNull(bean, "Disposable bean must not be null"); this.bean = bean; this.beanName = bean.getClass().getName(); this.invokeDisposableBean = (this.bean instanceof DisposableBean); this.nonPublicAccessAllowed = true; - this.acc = acc; this.beanPostProcessors = filterPostProcessors(postProcessors, bean); } @@ -166,7 +154,6 @@ private DisposableBeanAdapter(Object bean, String beanName, boolean invokeDispos this.beanName = beanName; this.invokeDisposableBean = invokeDisposableBean; this.nonPublicAccessAllowed = nonPublicAccessAllowed; - this.acc = null; this.destroyMethodName = destroyMethodName; this.beanPostProcessors = postProcessors; } @@ -190,15 +177,7 @@ public void destroy() { logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'"); } try { - if (System.getSecurityManager() != null) { - AccessController.doPrivileged((PrivilegedExceptionAction) () -> { - ((DisposableBean) this.bean).destroy(); - return null; - }, this.acc); - } - else { - ((DisposableBean) this.bean).destroy(); - } + ((DisposableBean) this.bean).destroy(); } catch (Throwable ex) { String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'"; @@ -226,12 +205,7 @@ else if (this.destroyMethodName != null) { @Nullable private Method determineDestroyMethod(String name) { try { - if (System.getSecurityManager() != null) { - return AccessController.doPrivileged((PrivilegedAction) () -> findDestroyMethod(name)); - } - else { - return findDestroyMethod(name); - } + return findDestroyMethod(name); } catch (IllegalArgumentException ex) { throw new BeanDefinitionValidationException("Could not find unique destroy method on bean with name '" + @@ -263,23 +237,8 @@ private void invokeCustomDestroyMethod(final Method destroyMethod) { "' on bean with name '" + this.beanName + "'"); } try { - if (System.getSecurityManager() != null) { - AccessController.doPrivileged((PrivilegedAction) () -> { - ReflectionUtils.makeAccessible(destroyMethod); - return null; - }); - try { - AccessController.doPrivileged((PrivilegedExceptionAction) () -> - destroyMethod.invoke(this.bean, args), this.acc); - } - catch (PrivilegedActionException pax) { - throw (InvocationTargetException) pax.getException(); - } - } - else { - ReflectionUtils.makeAccessible(destroyMethod); - destroyMethod.invoke(this.bean, args); - } + ReflectionUtils.makeAccessible(destroyMethod); + destroyMethod.invoke(this.bean, args); } catch (InvocationTargetException ex) { String msg = "Destroy method '" + this.destroyMethodName + "' on bean with name '" + diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java index fc689a7aec32..6750414847c7 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,6 @@ package org.springframework.beans.factory.support; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -56,13 +51,7 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg @Nullable protected Class getTypeForFactoryBean(FactoryBean factoryBean) { try { - if (System.getSecurityManager() != null) { - return AccessController.doPrivileged( - (PrivilegedAction>) factoryBean::getObjectType, getAccessControlContext()); - } - else { - return factoryBean.getObjectType(); - } + return factoryBean.getObjectType(); } catch (Throwable ex) { // Thrown from the FactoryBean's getObjectType implementation. @@ -156,18 +145,7 @@ protected Object getObjectFromFactoryBean(FactoryBean factory, String beanNam private Object doGetObjectFromFactoryBean(FactoryBean factory, String beanName) throws BeanCreationException { Object object; try { - if (System.getSecurityManager() != null) { - AccessControlContext acc = getAccessControlContext(); - try { - object = AccessController.doPrivileged((PrivilegedExceptionAction) factory::getObject, acc); - } - catch (PrivilegedActionException pae) { - throw pae.getException(); - } - } - else { - object = factory.getObject(); - } + object = factory.getObject(); } catch (FactoryBeanNotInitializedException ex) { throw new BeanCurrentlyInCreationException(beanName, ex.toString()); @@ -239,14 +217,4 @@ protected void clearSingletonCache() { } } - /** - * Return the security context for this bean factory. If a security manager - * is set, interaction with the user code will be executed using the privileged - * of the security context returned by this method. - * @see AccessController#getContext() - */ - protected AccessControlContext getAccessControlContext() { - return AccessController.getContext(); - } - } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/SecurityContextProvider.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/SecurityContextProvider.java deleted file mode 100644 index d2f70c46ebf9..000000000000 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/SecurityContextProvider.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.support; - -import java.security.AccessControlContext; - -/** - * Provider of the security context of the code running inside the bean factory. - * - * @author Costin Leau - * @since 3.0 - */ -public interface SecurityContextProvider { - - /** - * Provides a security access control context relevant to a bean factory. - * @return bean factory security control context - */ - AccessControlContext getAccessControlContext(); - -} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java index 0b05cf50cc7e..0ae2e3a688c0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,6 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; import org.springframework.beans.BeanInstantiationException; import org.springframework.beans.BeanUtils; @@ -70,13 +67,7 @@ public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, Bean throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { - if (System.getSecurityManager() != null) { - constructorToUse = AccessController.doPrivileged( - (PrivilegedExceptionAction>) clazz::getDeclaredConstructor); - } - else { - constructorToUse = clazz.getDeclaredConstructor(); - } + constructorToUse = clazz.getDeclaredConstructor(); bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Throwable ex) { @@ -107,13 +98,6 @@ public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, Bean final Constructor ctor, Object... args) { if (!bd.hasMethodOverrides()) { - if (System.getSecurityManager() != null) { - // use own privileged to change accessibility (when security is on) - AccessController.doPrivileged((PrivilegedAction) () -> { - ReflectionUtils.makeAccessible(ctor); - return null; - }); - } return BeanUtils.instantiateClass(ctor, args); } else { @@ -138,15 +122,7 @@ public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, Bean @Nullable Object factoryBean, final Method factoryMethod, Object... args) { try { - if (System.getSecurityManager() != null) { - AccessController.doPrivileged((PrivilegedAction) () -> { - ReflectionUtils.makeAccessible(factoryMethod); - return null; - }); - } - else { - ReflectionUtils.makeAccessible(factoryMethod); - } + ReflectionUtils.makeAccessible(factoryMethod); Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get(); try { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java deleted file mode 100644 index b28fbffa3702..000000000000 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.support; - -import java.security.AccessControlContext; -import java.security.AccessController; - -import org.springframework.lang.Nullable; - -/** - * Simple {@link SecurityContextProvider} implementation. - * - * @author Costin Leau - * @since 3.0 - */ -public class SimpleSecurityContextProvider implements SecurityContextProvider { - - @Nullable - private final AccessControlContext acc; - - - /** - * Construct a new {@code SimpleSecurityContextProvider} instance. - *

    The security context will be retrieved on each call from the current - * thread. - */ - public SimpleSecurityContextProvider() { - this(null); - } - - /** - * Construct a new {@code SimpleSecurityContextProvider} instance. - *

    If the given control context is null, the security context will be - * retrieved on each call from the current thread. - * @param acc access control context (can be {@code null}) - * @see AccessController#getContext() - */ - public SimpleSecurityContextProvider(@Nullable AccessControlContext acc) { - this.acc = acc; - } - - - @Override - public AccessControlContext getAccessControlContext() { - return (this.acc != null ? this.acc : AccessController.getContext()); - } - -} 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 8d6f823a7583..2cb8d8a9cd1a 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 @@ -20,10 +20,6 @@ import java.io.Serializable; import java.lang.reflect.Field; import java.net.MalformedURLException; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.Principal; -import java.security.PrivilegedAction; import java.text.NumberFormat; import java.text.ParseException; import java.util.Arrays; @@ -41,7 +37,6 @@ import java.util.stream.IntStream; import javax.annotation.Priority; -import javax.security.auth.Subject; import org.junit.jupiter.api.Test; @@ -90,7 +85,6 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.core.testfixture.io.SerializationTestUtils; -import org.springframework.core.testfixture.security.TestPrincipal; import org.springframework.lang.Nullable; import org.springframework.util.StringValueResolver; @@ -2602,22 +2596,6 @@ public boolean postProcessAfterInstantiation(Object bean, String beanName) throw } } - @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) - void initSecurityAwarePrototypeBean() { - RootBeanDefinition bd = new RootBeanDefinition(TestSecuredBean.class); - bd.setScope(BeanDefinition.SCOPE_PROTOTYPE); - bd.setInitMethodName("init"); - lbf.registerBeanDefinition("test", bd); - final Subject subject = new Subject(); - subject.getPrincipals().add(new TestPrincipal("user1")); - - TestSecuredBean bean = (TestSecuredBean) Subject.doAsPrivileged(subject, - (PrivilegedAction) () -> lbf.getBean("test"), null); - assertThat(bean).isNotNull(); - assertThat(bean.getUserName()).isEqualTo("user1"); - } - @Test void containsBeanReturnsTrueEvenForAbstractBeanDefinition() { lbf.registerBeanDefinition("abs", BeanDefinitionBuilder @@ -3058,37 +3036,6 @@ public Object convertIfNecessary(Object value, @Nullable Class requiredType, @Nu } - @SuppressWarnings("unused") - private static class TestSecuredBean { - - private String userName; - - void init() { - AccessControlContext acc = AccessController.getContext(); - Subject subject = Subject.getSubject(acc); - if (subject == null) { - return; - } - setNameFromPrincipal(subject.getPrincipals()); - } - - private void setNameFromPrincipal(Set principals) { - if (principals == null) { - return; - } - for (Iterator it = principals.iterator(); it.hasNext();) { - Principal p = it.next(); - this.userName = p.getName(); - return; - } - } - - public String getUserName() { - return this.userName; - } - } - - @SuppressWarnings("unused") private static class KnowsIfInstantiated { @@ -3105,7 +3052,6 @@ public static boolean wasInstantiated() { public KnowsIfInstantiated() { instantiated = true; } - } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/CallbacksSecurityTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/CallbacksSecurityTests.java deleted file mode 100644 index 368e0b664725..000000000000 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/CallbacksSecurityTests.java +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.support.security; - -import java.lang.reflect.Method; -import java.net.URL; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.Permissions; -import java.security.Policy; -import java.security.Principal; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; -import java.security.ProtectionDomain; -import java.util.PropertyPermission; -import java.util.Set; -import java.util.function.Consumer; - -import javax.security.auth.AuthPermission; -import javax.security.auth.Subject; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.BeanNameAware; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.SmartFactoryBean; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.beans.factory.support.SecurityContextProvider; -import org.springframework.beans.factory.support.security.support.ConstructorBean; -import org.springframework.beans.factory.support.security.support.CustomCallbackBean; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.core.NestedRuntimeException; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.Resource; -import org.springframework.core.testfixture.security.TestPrincipal; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * Security test case. Checks whether the container uses its privileges for its - * internal work but does not leak them when touching/calling user code. - * - *

    The first half of the test case checks that permissions are downgraded when - * calling user code while the second half that the caller code permission get - * through and Spring doesn't override the permission stack. - * - * @author Costin Leau - */ -public class CallbacksSecurityTests { - - private DefaultListableBeanFactory beanFactory; - private SecurityContextProvider provider; - - @SuppressWarnings("unused") - private static class NonPrivilegedBean { - - private String expectedName; - public static boolean destroyed = false; - - public NonPrivilegedBean(String expected) { - this.expectedName = expected; - checkCurrentContext(); - } - - public void init() { - checkCurrentContext(); - } - - public void destroy() { - checkCurrentContext(); - destroyed = true; - } - - public void setProperty(Object value) { - checkCurrentContext(); - } - - public Object getProperty() { - checkCurrentContext(); - return null; - } - - public void setListProperty(Object value) { - checkCurrentContext(); - } - - public Object getListProperty() { - checkCurrentContext(); - return null; - } - - private void checkCurrentContext() { - assertThat(getCurrentSubjectName()).isEqualTo(expectedName); - } - } - - @SuppressWarnings("unused") - private static class NonPrivilegedSpringCallbacksBean implements - InitializingBean, DisposableBean, BeanClassLoaderAware, - BeanFactoryAware, BeanNameAware { - - private String expectedName; - public static boolean destroyed = false; - - public NonPrivilegedSpringCallbacksBean(String expected) { - this.expectedName = expected; - checkCurrentContext(); - } - - @Override - public void afterPropertiesSet() { - checkCurrentContext(); - } - - @Override - public void destroy() { - checkCurrentContext(); - destroyed = true; - } - - @Override - public void setBeanName(String name) { - checkCurrentContext(); - } - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - checkCurrentContext(); - } - - @Override - public void setBeanFactory(BeanFactory beanFactory) - throws BeansException { - checkCurrentContext(); - } - - private void checkCurrentContext() { - assertThat(getCurrentSubjectName()).isEqualTo(expectedName); - } - } - - @SuppressWarnings({ "unused", "rawtypes" }) - private static class NonPrivilegedFactoryBean implements SmartFactoryBean { - private String expectedName; - - public NonPrivilegedFactoryBean(String expected) { - this.expectedName = expected; - checkCurrentContext(); - } - - @Override - public boolean isEagerInit() { - checkCurrentContext(); - return false; - } - - @Override - public boolean isPrototype() { - checkCurrentContext(); - return true; - } - - @Override - public Object getObject() throws Exception { - checkCurrentContext(); - return new Object(); - } - - @Override - public Class getObjectType() { - checkCurrentContext(); - return Object.class; - } - - @Override - public boolean isSingleton() { - checkCurrentContext(); - return false; - } - - private void checkCurrentContext() { - assertThat(getCurrentSubjectName()).isEqualTo(expectedName); - } - } - - @SuppressWarnings("unused") - private static class NonPrivilegedFactory { - - private final String expectedName; - - public NonPrivilegedFactory(String expected) { - this.expectedName = expected; - assertThat(getCurrentSubjectName()).isEqualTo(expectedName); - } - - public static Object makeStaticInstance(String expectedName) { - assertThat(getCurrentSubjectName()).isEqualTo(expectedName); - return new Object(); - } - - public Object makeInstance() { - assertThat(getCurrentSubjectName()).isEqualTo(expectedName); - return new Object(); - } - } - - private static String getCurrentSubjectName() { - final AccessControlContext acc = AccessController.getContext(); - - return AccessController.doPrivileged(new PrivilegedAction() { - - @Override - public String run() { - Subject subject = Subject.getSubject(acc); - if (subject == null) { - return null; - } - - Set principals = subject.getPrincipals(); - - if (principals == null) { - return null; - } - for (Principal p : principals) { - return p.getName(); - } - return null; - } - }); - } - - public CallbacksSecurityTests() { - // setup security - if (System.getSecurityManager() == null) { - Policy policy = Policy.getPolicy(); - URL policyURL = getClass() - .getResource( - "/org/springframework/beans/factory/support/security/policy.all"); - System.setProperty("java.security.policy", policyURL.toString()); - System.setProperty("policy.allowSystemProperty", "true"); - policy.refresh(); - - System.setSecurityManager(new SecurityManager()); - } - } - - @BeforeEach - public void setUp() throws Exception { - - final ProtectionDomain empty = new ProtectionDomain(null, - new Permissions()); - - provider = new SecurityContextProvider() { - private final AccessControlContext acc = new AccessControlContext( - new ProtectionDomain[] { empty }); - - @Override - public AccessControlContext getAccessControlContext() { - return acc; - } - }; - - DefaultResourceLoader drl = new DefaultResourceLoader(); - Resource config = drl - .getResource("/org/springframework/beans/factory/support/security/callbacks.xml"); - beanFactory = new DefaultListableBeanFactory(); - new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(config); - beanFactory.setSecurityContextProvider(provider); - } - - @Test - public void testSecuritySanity() throws Exception { - AccessControlContext acc = provider.getAccessControlContext(); - assertThatExceptionOfType(SecurityException.class).as( - "Acc should not have any permissions").isThrownBy(() -> - acc.checkPermission(new PropertyPermission("*", "read"))); - - CustomCallbackBean bean = new CustomCallbackBean(); - Method method = bean.getClass().getMethod("destroy"); - method.setAccessible(true); - - assertThatExceptionOfType(Exception.class).isThrownBy(() -> - AccessController.doPrivileged((PrivilegedExceptionAction) () -> { - method.invoke(bean); - return null; - }, acc)); - - Class cl = ConstructorBean.class; - assertThatExceptionOfType(Exception.class).isThrownBy(() -> - AccessController.doPrivileged((PrivilegedExceptionAction) () -> - cl.newInstance(), acc)); - } - - @Test - public void testSpringInitBean() throws Exception { - assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() -> - beanFactory.getBean("spring-init")) - .withCauseInstanceOf(SecurityException.class); - } - - @Test - public void testCustomInitBean() throws Exception { - assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() -> - beanFactory.getBean("custom-init")) - .withCauseInstanceOf(SecurityException.class); - } - - @Test - public void testSpringDestroyBean() throws Exception { - beanFactory.getBean("spring-destroy"); - beanFactory.destroySingletons(); - assertThat(System.getProperty("security.destroy")).isNull(); - } - - @Test - public void testCustomDestroyBean() throws Exception { - beanFactory.getBean("custom-destroy"); - beanFactory.destroySingletons(); - assertThat(System.getProperty("security.destroy")).isNull(); - } - - @Test - public void testCustomFactoryObject() throws Exception { - assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() -> - beanFactory.getBean("spring-factory")) - .withCauseInstanceOf(SecurityException.class); - } - - @Test - public void testCustomFactoryType() throws Exception { - assertThat(beanFactory.getType("spring-factory")).isNull(); - assertThat(System.getProperty("factory.object.type")).isNull(); - } - - @Test - public void testCustomStaticFactoryMethod() throws Exception { - assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() -> - beanFactory.getBean("custom-static-factory-method")) - .satisfies(mostSpecificCauseOf(SecurityException.class)); - } - - @Test - public void testCustomInstanceFactoryMethod() throws Exception { - assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() -> - beanFactory.getBean("custom-factory-method")) - .satisfies(mostSpecificCauseOf(SecurityException.class)); - } - - @Test - public void testTrustedFactoryMethod() throws Exception { - assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() -> - beanFactory.getBean("privileged-static-factory-method")) - .satisfies(mostSpecificCauseOf(SecurityException.class)); - } - - @Test - public void testConstructor() throws Exception { - assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() -> - beanFactory.getBean("constructor")) - .satisfies(mostSpecificCauseOf(SecurityException.class)); - } - - @Test - public void testContainerPrivileges() throws Exception { - AccessControlContext acc = provider.getAccessControlContext(); - - AccessController.doPrivileged(new PrivilegedExceptionAction() { - - @Override - public Object run() throws Exception { - beanFactory.getBean("working-factory-method"); - beanFactory.getBean("container-execution"); - return null; - } - }, acc); - } - - @Test - public void testPropertyInjection() throws Exception { - assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() -> - beanFactory.getBean("property-injection")) - .withMessageContaining("security"); - beanFactory.getBean("working-property-injection"); - } - - @Test - public void testInitSecurityAwarePrototypeBean() { - final DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); - BeanDefinitionBuilder bdb = BeanDefinitionBuilder - .genericBeanDefinition(NonPrivilegedBean.class).setScope( - BeanDefinition.SCOPE_PROTOTYPE) - .setInitMethodName("init").setDestroyMethodName("destroy") - .addConstructorArgValue("user1"); - lbf.registerBeanDefinition("test", bdb.getBeanDefinition()); - final Subject subject = new Subject(); - subject.getPrincipals().add(new TestPrincipal("user1")); - - NonPrivilegedBean bean = Subject.doAsPrivileged( - subject, new PrivilegedAction() { - @Override - public NonPrivilegedBean run() { - return lbf.getBean("test", NonPrivilegedBean.class); - } - }, null); - assertThat(bean).isNotNull(); - } - - @Test - public void testTrustedExecution() throws Exception { - beanFactory.setSecurityContextProvider(null); - - Permissions perms = new Permissions(); - perms.add(new AuthPermission("getSubject")); - ProtectionDomain pd = new ProtectionDomain(null, perms); - - new AccessControlContext(new ProtectionDomain[] { pd }); - - final Subject subject = new Subject(); - subject.getPrincipals().add(new TestPrincipal("user1")); - - // request the beans from non-privileged code - Subject.doAsPrivileged(subject, new PrivilegedAction() { - - @Override - public Object run() { - // sanity check - assertThat(getCurrentSubjectName()).isEqualTo("user1"); - assertThat(NonPrivilegedBean.destroyed).isEqualTo(false); - - beanFactory.getBean("trusted-spring-callbacks"); - beanFactory.getBean("trusted-custom-init-destroy"); - // the factory is a prototype - ask for multiple instances - beanFactory.getBean("trusted-spring-factory"); - beanFactory.getBean("trusted-spring-factory"); - beanFactory.getBean("trusted-spring-factory"); - - beanFactory.getBean("trusted-factory-bean"); - beanFactory.getBean("trusted-static-factory-method"); - beanFactory.getBean("trusted-factory-method"); - beanFactory.getBean("trusted-property-injection"); - beanFactory.getBean("trusted-working-property-injection"); - - beanFactory.destroySingletons(); - assertThat(NonPrivilegedBean.destroyed).isEqualTo(true); - return null; - } - }, provider.getAccessControlContext()); - } - - private Consumer mostSpecificCauseOf(Class type) { - return ex -> assertThat(ex.getMostSpecificCause()).isInstanceOf(type); - - } - -} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/ConstructorBean.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/ConstructorBean.java deleted file mode 100644 index fc60fc3db145..000000000000 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/ConstructorBean.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2002-2013 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.support.security.support; - -/** - * @author Costin Leau - */ -public class ConstructorBean { - - public ConstructorBean() { - System.getProperties(); - } - - public ConstructorBean(Object obj) { - } -} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomCallbackBean.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomCallbackBean.java deleted file mode 100644 index 4874306e6e12..000000000000 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomCallbackBean.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.support.security.support; - -/** - * @author Costin Leau - */ -public class CustomCallbackBean { - - public void init() { - System.getProperties(); - } - - public void destroy() { - System.setProperty("security.destroy", "true"); - } -} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomFactoryBean.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomFactoryBean.java deleted file mode 100644 index 4ec3d7131bf9..000000000000 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomFactoryBean.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.support.security.support; - -import java.util.Properties; - -import org.springframework.beans.factory.FactoryBean; - -/** - * @author Costin Leau - */ -public class CustomFactoryBean implements FactoryBean { - - @Override - public Properties getObject() throws Exception { - return System.getProperties(); - } - - @Override - public Class getObjectType() { - System.setProperty("factory.object.type", "true"); - return Properties.class; - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/DestroyBean.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/DestroyBean.java deleted file mode 100644 index 67005abf7836..000000000000 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/DestroyBean.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.support.security.support; - -import org.springframework.beans.factory.DisposableBean; - -/** - * @author Costin Leau - */ -public class DestroyBean implements DisposableBean { - - @Override - public void destroy() throws Exception { - System.setProperty("security.destroy", "true"); - } -} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/FactoryBean.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/FactoryBean.java deleted file mode 100644 index 4f7fb62e5be2..000000000000 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/FactoryBean.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.support.security.support; - -/** - * @author Costin Leau - */ -public class FactoryBean { - - public static Object makeStaticInstance() { - System.getProperties(); - return new Object(); - } - - protected static Object protectedStaticInstance() { - return "protectedStaticInstance"; - } - - public Object makeInstance() { - System.getProperties(); - return new Object(); - } -} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/InitBean.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/InitBean.java deleted file mode 100644 index 3693bb9d749e..000000000000 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/InitBean.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.support.security.support; - -import org.springframework.beans.factory.InitializingBean; - -/** - * @author Costin Leau - */ -public class InitBean implements InitializingBean { - - @Override - public void afterPropertiesSet() throws Exception { - System.getProperties(); - } -} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/PropertyBean.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/PropertyBean.java deleted file mode 100644 index 51933137f0da..000000000000 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/PropertyBean.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.support.security.support; - -/** - * @author Costin Leau - */ -public class PropertyBean { - - public void setSecurityProperty(Object property) { - System.getProperties(); - } - - public void setProperty(Object property) { - - } -} diff --git a/spring-beans/src/test/java/org/springframework/beans/propertyeditors/CustomEditorTests.java b/spring-beans/src/test/java/org/springframework/beans/propertyeditors/CustomEditorTests.java index e3dddf62db2e..8962008451ce 100644 --- a/spring-beans/src/test/java/org/springframework/beans/propertyeditors/CustomEditorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/propertyeditors/CustomEditorTests.java @@ -502,7 +502,7 @@ void testCharacterEditor() { CharBean cb = new CharBean(); BeanWrapper bw = new BeanWrapperImpl(cb); - bw.setPropertyValue("myChar", new Character('c')); + bw.setPropertyValue("myChar", Character.valueOf('c')); assertThat(cb.getMyChar()).isEqualTo('c'); bw.setPropertyValue("myChar", "c"); diff --git a/spring-context/src/main/java/org/springframework/context/support/ApplicationContextAwareProcessor.java b/spring-context/src/main/java/org/springframework/context/support/ApplicationContextAwareProcessor.java index a58bb6303470..60b1c3b58af1 100644 --- a/spring-context/src/main/java/org/springframework/context/support/ApplicationContextAwareProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/support/ApplicationContextAwareProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,6 @@ package org.springframework.context.support; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; - import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.EmbeddedValueResolver; @@ -86,22 +82,7 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro return bean; } - AccessControlContext acc = null; - - if (System.getSecurityManager() != null) { - acc = this.applicationContext.getBeanFactory().getAccessControlContext(); - } - - if (acc != null) { - AccessController.doPrivileged((PrivilegedAction) () -> { - invokeAwareInterfaces(bean); - return null; - }, acc); - } - else { - invokeAwareInterfaces(bean); - } - + invokeAwareInterfaces(bean); return bean; } diff --git a/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java b/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java index f78120b8fead..012237889a49 100644 --- a/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java +++ b/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,9 +22,6 @@ import java.io.Reader; import java.net.URL; import java.net.URLConnection; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.text.MessageFormat; import java.util.Locale; import java.util.Map; @@ -400,28 +397,19 @@ public ResourceBundle newBundle(String baseName, Locale locale, String format, C final String resourceName = toResourceName(bundleName, "properties"); final ClassLoader classLoader = loader; final boolean reloadFlag = reload; - InputStream inputStream; - try { - inputStream = AccessController.doPrivileged((PrivilegedExceptionAction) () -> { - InputStream is = null; - if (reloadFlag) { - URL url = classLoader.getResource(resourceName); - if (url != null) { - URLConnection connection = url.openConnection(); - if (connection != null) { - connection.setUseCaches(false); - is = connection.getInputStream(); - } - } + InputStream inputStream = null; + if (reloadFlag) { + URL url = classLoader.getResource(resourceName); + if (url != null) { + URLConnection connection = url.openConnection(); + if (connection != null) { + connection.setUseCaches(false); + inputStream = connection.getInputStream(); } - else { - is = classLoader.getResourceAsStream(resourceName); - } - return is; - }); + } } - catch (PrivilegedActionException ex) { - throw (IOException) ex.getException(); + else { + inputStream = classLoader.getResourceAsStream(resourceName); } if (inputStream != null) { String encoding = getDefaultEncoding(); diff --git a/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java b/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java index 657597bc23f9..827f5f5b0929 100644 --- a/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java +++ b/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java @@ -23,8 +23,6 @@ import java.io.Serializable; import java.net.URI; import java.net.URL; -import java.security.AccessControlException; -import java.security.Permission; import java.util.Optional; import java.util.Properties; @@ -237,43 +235,6 @@ void prototypeCreationReevaluatesExpressions() { } } - @Test - void systemPropertiesSecurityManager() { - AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); - - GenericBeanDefinition bd = new GenericBeanDefinition(); - bd.setBeanClass(TestBean.class); - bd.getPropertyValues().add("country", "#{systemProperties.country}"); - ac.registerBeanDefinition("tb", bd); - - SecurityManager oldSecurityManager = System.getSecurityManager(); - try { - System.setProperty("country", "NL"); - - SecurityManager securityManager = new SecurityManager() { - @Override - public void checkPropertiesAccess() { - throw new AccessControlException("Not Allowed"); - } - @Override - public void checkPermission(Permission perm) { - // allow everything else - } - }; - System.setSecurityManager(securityManager); - ac.refresh(); - - TestBean tb = ac.getBean("tb", TestBean.class); - assertThat(tb.getCountry()).isEqualTo("NL"); - - } - finally { - System.setSecurityManager(oldSecurityManager); - System.getProperties().remove("country"); - } - ac.close(); - } - @Test void stringConcatenationWithDebugLogging() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); diff --git a/spring-context/src/test/java/org/springframework/context/support/EnvironmentSecurityManagerIntegrationTests.java b/spring-context/src/test/java/org/springframework/context/support/EnvironmentSecurityManagerIntegrationTests.java deleted file mode 100644 index 968aba7f695f..000000000000 --- a/spring-context/src/test/java/org/springframework/context/support/EnvironmentSecurityManagerIntegrationTests.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.support; - -import java.security.AccessControlException; -import java.security.Permission; -import java.util.Map; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; -import org.springframework.context.annotation.Profile; -import org.springframework.core.env.AbstractEnvironment; -import org.springframework.core.testfixture.env.EnvironmentTestUtils; -import org.springframework.stereotype.Component; - -import static java.lang.String.format; -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests integration between Environment and SecurityManagers. See SPR-9970. - * - * @author Chris Beams - */ -public class EnvironmentSecurityManagerIntegrationTests { - - private SecurityManager originalSecurityManager; - - private Map env; - - - @BeforeEach - public void setUp() { - originalSecurityManager = System.getSecurityManager(); - env = EnvironmentTestUtils.getModifiableSystemEnvironment(); - env.put(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "p1"); - } - - @AfterEach - public void tearDown() { - env.remove(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME); - System.setSecurityManager(originalSecurityManager); - } - - - @Test - public void securityManagerDisallowsAccessToSystemEnvironmentButAllowsAccessToIndividualKeys() { - SecurityManager securityManager = new SecurityManager() { - @Override - public void checkPermission(Permission perm) { - // Disallowing access to System#getenv means that our - // ReadOnlySystemAttributesMap will come into play. - if ("getenv.*".equals(perm.getName())) { - throw new AccessControlException("Accessing the system environment is disallowed"); - } - } - }; - System.setSecurityManager(securityManager); - - DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); - AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(bf); - reader.register(C1.class); - assertThat(bf.containsBean("c1")).isTrue(); - } - - @Test - public void securityManagerDisallowsAccessToSystemEnvironmentAndDisallowsAccessToIndividualKey() { - SecurityManager securityManager = new SecurityManager() { - @Override - public void checkPermission(Permission perm) { - // Disallowing access to System#getenv means that our - // ReadOnlySystemAttributesMap will come into play. - if ("getenv.*".equals(perm.getName())) { - throw new AccessControlException("Accessing the system environment is disallowed"); - } - // Disallowing access to the spring.profiles.active property means that - // the BeanDefinitionReader won't be able to determine which profiles are - // active. We should see an INFO-level message in the console about this - // and as a result, any components marked with a non-default profile will - // be ignored. - if (("getenv." + AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME).equals(perm.getName())) { - throw new AccessControlException( - format("Accessing system environment variable [%s] is disallowed", - AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME)); - } - } - }; - System.setSecurityManager(securityManager); - - DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); - AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(bf); - reader.register(C1.class); - assertThat(bf.containsBean("c1")).isFalse(); - } - - - @Component("c1") - @Profile("p1") - static class C1 { - } - -} diff --git a/spring-context/src/test/java/org/springframework/jmx/support/JmxUtilsTests.java b/spring-context/src/test/java/org/springframework/jmx/support/JmxUtilsTests.java index f8ef4348bc00..eba01bd4fe6b 100644 --- a/spring-context/src/test/java/org/springframework/jmx/support/JmxUtilsTests.java +++ b/spring-context/src/test/java/org/springframework/jmx/support/JmxUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,6 @@ import java.beans.PropertyDescriptor; import javax.management.DynamicMBean; -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; import javax.management.MalformedObjectNameException; import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; @@ -57,42 +55,42 @@ void isMBean() { } @Test - void isMBeanWithDynamicMBean() throws Exception { + void isMBeanWithDynamicMBean() { DynamicMBean mbean = new TestDynamicMBean(); assertThat(JmxUtils.isMBean(mbean.getClass())).as("Dynamic MBean not detected correctly").isTrue(); } @Test - void isMBeanWithStandardMBeanWrapper() throws Exception { + void isMBeanWithStandardMBeanWrapper() throws NotCompliantMBeanException { StandardMBean mbean = new StandardMBean(new JmxTestBean(), IJmxTestBean.class); assertThat(JmxUtils.isMBean(mbean.getClass())).as("Standard MBean not detected correctly").isTrue(); } @Test - void isMBeanWithStandardMBeanInherited() throws Exception { + void isMBeanWithStandardMBeanInherited() throws NotCompliantMBeanException { StandardMBean mbean = new StandardMBeanImpl(); assertThat(JmxUtils.isMBean(mbean.getClass())).as("Standard MBean not detected correctly").isTrue(); } @Test - void notAnMBean() throws Exception { + void notAnMBean() { assertThat(JmxUtils.isMBean(Object.class)).as("Object incorrectly identified as an MBean").isFalse(); } @Test - void simpleMBean() throws Exception { + void simpleMBean() { Foo foo = new Foo(); assertThat(JmxUtils.isMBean(foo.getClass())).as("Simple MBean not detected correctly").isTrue(); } @Test - void simpleMXBean() throws Exception { + void simpleMXBean() { FooX foo = new FooX(); assertThat(JmxUtils.isMBean(foo.getClass())).as("Simple MXBean not detected correctly").isTrue(); } @Test - void simpleMBeanThroughInheritance() throws Exception { + void simpleMBeanThroughInheritance() { Bar bar = new Bar(); Abc abc = new Abc(); assertThat(JmxUtils.isMBean(bar.getClass())).as("Simple MBean (through inheritance) not detected correctly").isTrue(); @@ -126,19 +124,6 @@ void appendIdentityToObjectName() throws MalformedObjectNameException { assertThat(uniqueName.getKeyProperty(JmxUtils.IDENTITY_OBJECT_NAME_KEY)).as("Identity key is incorrect").isEqualTo(ObjectUtils.getIdentityHexString(managedResource)); } - @Test - void locatePlatformMBeanServer() { - MBeanServer server = null; - try { - server = JmxUtils.locateMBeanServer(); - } - finally { - if (server != null) { - MBeanServerFactory.releaseMBeanServer(server); - } - } - } - public static class AttributeTestBean { diff --git a/spring-context/src/test/java/org/springframework/jmx/support/MBeanServerFactoryBeanTests.java b/spring-context/src/test/java/org/springframework/jmx/support/MBeanServerFactoryBeanTests.java index 02a24b48fdca..a0092708c58e 100644 --- a/spring-context/src/test/java/org/springframework/jmx/support/MBeanServerFactoryBeanTests.java +++ b/spring-context/src/test/java/org/springframework/jmx/support/MBeanServerFactoryBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,7 +47,7 @@ void resetMBeanServers() throws Exception { } @Test - void defaultValues() throws Exception { + void defaultValues() { MBeanServerFactoryBean bean = new MBeanServerFactoryBean(); bean.afterPropertiesSet(); try { @@ -60,7 +60,7 @@ void defaultValues() throws Exception { } @Test - void defaultDomain() throws Exception { + void defaultDomain() { MBeanServerFactoryBean bean = new MBeanServerFactoryBean(); bean.setDefaultDomain("foo"); bean.afterPropertiesSet(); @@ -129,7 +129,8 @@ void newMBeanServer() throws Exception { assertCreation(false, "The server should not be available in the list"); } - private void assertCreation(boolean referenceShouldExist, String failMsg) throws Exception { + + private void assertCreation(boolean referenceShouldExist, String failMsg) { MBeanServerFactoryBean bean = new MBeanServerFactoryBean(); bean.setRegisterWithFactory(referenceShouldExist); bean.afterPropertiesSet(); diff --git a/spring-context/src/test/java/org/springframework/jndi/JndiLocatorDelegateTests.java b/spring-context/src/test/java/org/springframework/jndi/JndiLocatorDelegateTests.java deleted file mode 100644 index c3601d3b1a26..000000000000 --- a/spring-context/src/test/java/org/springframework/jndi/JndiLocatorDelegateTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jndi; - -import java.lang.reflect.Field; - -import javax.naming.spi.NamingManager; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - - - -/** - * Tests for {@link JndiLocatorDelegate}. - * - * @author Phillip Webb - * @author Juergen Hoeller - */ -public class JndiLocatorDelegateTests { - - @Test - public void isDefaultJndiEnvironmentAvailableFalse() throws Exception { - Field builderField = NamingManager.class.getDeclaredField("initctx_factory_builder"); - builderField.setAccessible(true); - Object oldBuilder = builderField.get(null); - builderField.set(null, null); - - try { - assertThat(JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()).isEqualTo(false); - } - finally { - builderField.set(null, oldBuilder); - } - } - -} diff --git a/spring-context/src/test/java/org/springframework/util/MBeanTestUtils.java b/spring-context/src/test/java/org/springframework/util/MBeanTestUtils.java index b96c56053c49..6b214a7f3360 100644 --- a/spring-context/src/test/java/org/springframework/util/MBeanTestUtils.java +++ b/spring-context/src/test/java/org/springframework/util/MBeanTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,6 @@ package org.springframework.util; -import java.lang.management.ManagementFactory; -import java.lang.reflect.Field; - import javax.management.MBeanServer; import javax.management.MBeanServerFactory; @@ -45,10 +42,6 @@ public static synchronized void resetMBeanServers() throws Exception { } } } - - Field field = ManagementFactory.class.getDeclaredField("platformMBeanServer"); - field.setAccessible(true); - field.set(null, null); } } diff --git a/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java b/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java index 4420c50c9ee1..76e3ebf7cba0 100644 --- a/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java +++ b/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java @@ -26,9 +26,6 @@ import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.Arrays; @@ -56,11 +53,6 @@ private ReflectUtils() { private static final ClassLoader defaultLoader = ReflectUtils.class.getClassLoader(); - // SPRING PATCH BEGIN - private static final Method privateLookupInMethod; - - private static final Method lookupDefineClassMethod; - private static final Method classLoaderDefineClassMethod; private static final ProtectionDomain PROTECTION_DOMAIN; @@ -69,63 +61,28 @@ private ReflectUtils() { private static final List OBJECT_METHODS = new ArrayList(); + // SPRING PATCH BEGIN static { - Method privateLookupIn; - Method lookupDefineClass; Method classLoaderDefineClass; ProtectionDomain protectionDomain; Throwable throwable = null; try { - privateLookupIn = (Method) AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - try { - return MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class); - } - catch (NoSuchMethodException ex) { - return null; - } - } - }); - lookupDefineClass = (Method) AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - try { - return MethodHandles.Lookup.class.getMethod("defineClass", byte[].class); - } - catch (NoSuchMethodException ex) { - return null; - } - } - }); - classLoaderDefineClass = (Method) AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - return ClassLoader.class.getDeclaredMethod("defineClass", + classLoaderDefineClass = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, Integer.TYPE, Integer.TYPE, ProtectionDomain.class); - } - }); protectionDomain = getProtectionDomain(ReflectUtils.class); - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - Method[] methods = Object.class.getDeclaredMethods(); - for (Method method : methods) { - if ("finalize".equals(method.getName()) - || (method.getModifiers() & (Modifier.FINAL | Modifier.STATIC)) > 0) { - continue; - } - OBJECT_METHODS.add(method); - } - return null; + for (Method method : Object.class.getDeclaredMethods()) { + if ("finalize".equals(method.getName()) + || (method.getModifiers() & (Modifier.FINAL | Modifier.STATIC)) > 0) { + continue; } - }); + OBJECT_METHODS.add(method); + } } catch (Throwable t) { - privateLookupIn = null; - lookupDefineClass = null; classLoaderDefineClass = null; protectionDomain = null; throwable = t; } - privateLookupInMethod = privateLookupIn; - lookupDefineClassMethod = lookupDefineClass; classLoaderDefineClassMethod = classLoaderDefineClass; PROTECTION_DOMAIN = protectionDomain; THROWABLE = throwable; @@ -160,11 +117,7 @@ public static ProtectionDomain getProtectionDomain(final Class source) { if (source == null) { return null; } - return (ProtectionDomain) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return source.getProtectionDomain(); - } - }); + return source.getProtectionDomain(); } public static Type[] getExceptionTypes(Member member) { @@ -336,15 +289,7 @@ public static Object newInstance(final Constructor cstruct, final Object[] args) public static Constructor getConstructor(Class type, Class[] parameterTypes) { try { Constructor constructor = type.getDeclaredConstructor(parameterTypes); - if (System.getSecurityManager() != null) { - AccessController.doPrivileged((PrivilegedAction) () -> { - constructor.setAccessible(true); - return null; - }); - } - else { - constructor.setAccessible(true); - } + constructor.setAccessible(true); return constructor; } catch (NoSuchMethodException e) { @@ -501,18 +446,12 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader, Class c = null; // Preferred option: JDK 9+ Lookup.defineClass API if ClassLoader matches - if (contextClass != null && contextClass.getClassLoader() == loader && - privateLookupInMethod != null && lookupDefineClassMethod != null) { + if (contextClass != null && contextClass.getClassLoader() == loader) { try { - MethodHandles.Lookup lookup = (MethodHandles.Lookup) - privateLookupInMethod.invoke(null, contextClass, MethodHandles.lookup()); - c = (Class) lookupDefineClassMethod.invoke(lookup, b); + MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(contextClass, MethodHandles.lookup()); + c = lookup.defineClass(b); } - catch (InvocationTargetException ex) { - Throwable target = ex.getTargetException(); - if (target.getClass() != LinkageError.class && target.getClass() != IllegalArgumentException.class) { - throw new CodeGenerationException(target); - } + catch (LinkageError | IllegalArgumentException ex) { // in case of plain LinkageError (class already defined) // or IllegalArgumentException (class in different package): // fall through to traditional ClassLoader.defineClass below @@ -567,15 +506,10 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader, } // Fallback option: JDK 9+ Lookup.defineClass API even if ClassLoader does not match - if (c == null && contextClass != null && contextClass.getClassLoader() != loader && - privateLookupInMethod != null && lookupDefineClassMethod != null) { + if (c == null && contextClass != null && contextClass.getClassLoader() != loader) { try { - MethodHandles.Lookup lookup = (MethodHandles.Lookup) - privateLookupInMethod.invoke(null, contextClass, MethodHandles.lookup()); - c = (Class) lookupDefineClassMethod.invoke(lookup, b); - } - catch (InvocationTargetException ex) { - throw new CodeGenerationException(ex.getTargetException()); + MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(contextClass, MethodHandles.lookup()); + c = lookup.defineClass(b); } catch (Throwable ex) { throw new CodeGenerationException(ex); diff --git a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java index 5fa9aa45d2c8..7f983189d6d1 100644 --- a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java +++ b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java @@ -16,7 +16,6 @@ package org.springframework.core.env; -import java.security.AccessControlException; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashSet; @@ -60,8 +59,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { *

    The default is "false", falling back to system environment variable checks if a * Spring environment property (e.g. a placeholder in a configuration String) isn't * resolvable otherwise. Consider switching this flag to "true" if you experience - * log warnings from {@code getenv} calls coming from Spring, e.g. on WebSphere - * with strict SecurityManager settings and AccessControlExceptions warnings. + * log warnings from {@code getenv} calls coming from Spring. * @see #suppressGetenvAccess() */ public static final String IGNORE_GETENV_PROPERTY_NAME = "spring.getenv.ignore"; @@ -438,27 +436,7 @@ public MutablePropertySources getPropertySources() { @Override @SuppressWarnings({"rawtypes", "unchecked"}) public Map getSystemProperties() { - try { - return (Map) System.getProperties(); - } - catch (AccessControlException ex) { - return (Map) new ReadOnlySystemAttributesMap() { - @Override - @Nullable - protected String getSystemAttribute(String attributeName) { - try { - return System.getProperty(attributeName); - } - catch (AccessControlException ex) { - if (logger.isInfoEnabled()) { - logger.info("Caught AccessControlException when accessing system property '" + - attributeName + "'; its value will be returned [null]. Reason: " + ex.getMessage()); - } - return null; - } - } - }; - } + return (Map) System.getProperties(); } @Override @@ -467,27 +445,7 @@ public Map getSystemEnvironment() { if (suppressGetenvAccess()) { return Collections.emptyMap(); } - try { - return (Map) System.getenv(); - } - catch (AccessControlException ex) { - return (Map) new ReadOnlySystemAttributesMap() { - @Override - @Nullable - protected String getSystemAttribute(String attributeName) { - try { - return System.getenv(attributeName); - } - catch (AccessControlException ex) { - if (logger.isInfoEnabled()) { - logger.info("Caught AccessControlException when accessing system environment variable '" + - attributeName + "'; its value will be returned [null]. Reason: " + ex.getMessage()); - } - return null; - } - } - }; - } + return (Map) System.getenv(); } /** diff --git a/spring-core/src/main/java/org/springframework/core/env/ConfigurableEnvironment.java b/spring-core/src/main/java/org/springframework/core/env/ConfigurableEnvironment.java index b174ca00cf87..507fbdb8c483 100644 --- a/spring-core/src/main/java/org/springframework/core/env/ConfigurableEnvironment.java +++ b/spring-core/src/main/java/org/springframework/core/env/ConfigurableEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,32 +119,20 @@ public interface ConfigurableEnvironment extends Environment, ConfigurableProper MutablePropertySources getPropertySources(); /** - * Return the value of {@link System#getProperties()} if allowed by the current - * {@link SecurityManager}, otherwise return a map implementation that will attempt - * to access individual keys using calls to {@link System#getProperty(String)}. + * Return the value of {@link System#getProperties()}. *

    Note that most {@code Environment} implementations will include this system * properties map as a default {@link PropertySource} to be searched. Therefore, it is * recommended that this method not be used directly unless bypassing other property * sources is expressly intended. - *

    Calls to {@link Map#get(Object)} on the Map returned will never throw - * {@link IllegalAccessException}; in cases where the SecurityManager forbids access - * to a property, {@code null} will be returned and an INFO-level log message will be - * issued noting the exception. */ Map getSystemProperties(); /** - * Return the value of {@link System#getenv()} if allowed by the current - * {@link SecurityManager}, otherwise return a map implementation that will attempt - * to access individual keys using calls to {@link System#getenv(String)}. + * Return the value of {@link System#getenv()}. *

    Note that most {@link Environment} implementations will include this system * environment map as a default {@link PropertySource} to be searched. Therefore, it * is recommended that this method not be used directly unless bypassing other * property sources is expressly intended. - *

    Calls to {@link Map#get(Object)} on the Map returned will never throw - * {@link IllegalAccessException}; in cases where the SecurityManager forbids access - * to a property, {@code null} will be returned and an INFO-level log message will be - * issued noting the exception. */ Map getSystemEnvironment(); diff --git a/spring-core/src/main/java/org/springframework/core/env/ReadOnlySystemAttributesMap.java b/spring-core/src/main/java/org/springframework/core/env/ReadOnlySystemAttributesMap.java deleted file mode 100644 index 37867bd1d4bf..000000000000 --- a/spring-core/src/main/java/org/springframework/core/env/ReadOnlySystemAttributesMap.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.env; - -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -import org.springframework.lang.Nullable; - -/** - * Read-only {@code Map} implementation that is backed by system - * properties or environment variables. - * - *

    Used by {@link AbstractEnvironment} when a {@link SecurityManager} prohibits - * access to {@link System#getProperties()} or {@link System#getenv()}. It is for this - * reason that the implementations of {@link #keySet()}, {@link #entrySet()}, and - * {@link #values()} always return empty even though {@link #get(Object)} may in fact - * return non-null if the current security manager allows access to individual keys. - * - * @author Arjen Poutsma - * @author Chris Beams - * @since 3.0 - */ -abstract class ReadOnlySystemAttributesMap implements Map { - - @Override - public boolean containsKey(Object key) { - return (get(key) != null); - } - - /** - * Returns the value to which the specified key is mapped, or {@code null} if this map - * contains no mapping for the key. - * @param key the name of the system attribute to retrieve - * @throws IllegalArgumentException if given key is non-String - */ - @Override - @Nullable - public String get(Object key) { - if (!(key instanceof String)) { - throw new IllegalArgumentException( - "Type of key [" + key.getClass().getName() + "] must be java.lang.String"); - } - return getSystemAttribute((String) key); - } - - @Override - public boolean isEmpty() { - return false; - } - - /** - * Template method that returns the underlying system attribute. - *

    Implementations typically call {@link System#getProperty(String)} or {@link System#getenv(String)} here. - */ - @Nullable - protected abstract String getSystemAttribute(String attributeName); - - - // Unsupported - - @Override - public int size() { - throw new UnsupportedOperationException(); - } - - @Override - public String put(String key, String value) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean containsValue(Object value) { - throw new UnsupportedOperationException(); - } - - @Override - public String remove(Object key) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public Set keySet() { - return Collections.emptySet(); - } - - @Override - public void putAll(Map map) { - throw new UnsupportedOperationException(); - } - - @Override - public Collection values() { - return Collections.emptySet(); - } - - @Override - public Set> entrySet() { - return Collections.emptySet(); - } - -} diff --git a/spring-core/src/main/java/org/springframework/core/env/SystemEnvironmentPropertySource.java b/spring-core/src/main/java/org/springframework/core/env/SystemEnvironmentPropertySource.java index 06dd2b7a63b3..6b5f2fa36ac5 100644 --- a/spring-core/src/main/java/org/springframework/core/env/SystemEnvironmentPropertySource.java +++ b/spring-core/src/main/java/org/springframework/core/env/SystemEnvironmentPropertySource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -122,34 +122,26 @@ protected final String resolvePropertyName(String name) { @Nullable private String checkPropertyName(String name) { // Check name as-is - if (containsKey(name)) { + if (this.source.containsKey(name)) { return name; } // Check name with just dots replaced String noDotName = name.replace('.', '_'); - if (!name.equals(noDotName) && containsKey(noDotName)) { + if (!name.equals(noDotName) && this.source.containsKey(noDotName)) { return noDotName; } // Check name with just hyphens replaced String noHyphenName = name.replace('-', '_'); - if (!name.equals(noHyphenName) && containsKey(noHyphenName)) { + if (!name.equals(noHyphenName) && this.source.containsKey(noHyphenName)) { return noHyphenName; } // Check name with dots and hyphens replaced String noDotNoHyphenName = noDotName.replace('-', '_'); - if (!noDotName.equals(noDotNoHyphenName) && containsKey(noDotNoHyphenName)) { + if (!noDotName.equals(noDotNoHyphenName) && this.source.containsKey(noDotNoHyphenName)) { return noDotNoHyphenName; } // Give up return null; } - private boolean containsKey(String name) { - return (isSecurityManagerPresent() ? this.source.keySet().contains(name) : this.source.containsKey(name)); - } - - protected boolean isSecurityManagerPresent() { - return (System.getSecurityManager() != null); - } - } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AbstractRecursiveAnnotationVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AbstractRecursiveAnnotationVisitor.java index fa23cebbc2bc..356ab5b46159 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AbstractRecursiveAnnotationVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/AbstractRecursiveAnnotationVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package org.springframework.core.type.classreading; import java.lang.reflect.Field; -import java.security.AccessControlException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -97,7 +96,7 @@ protected Object getEnumValue(String asmTypeDescriptor, String attributeValue) { catch (ClassNotFoundException | NoClassDefFoundError ex) { logger.debug("Failed to classload enum type while reading annotation metadata", ex); } - catch (IllegalAccessException | AccessControlException ex) { + catch (IllegalAccessException ex) { logger.debug("Could not access enum value while reading annotation metadata", ex); } return valueToUse; diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java index e9f1a15f38d0..ba1bfe06cfee 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java @@ -107,9 +107,7 @@ private void recursivelyCollectMetaAnnotations(Set visited, Annotati String annotationName = annotationType.getName(); if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationName) && visited.add(annotation)) { try { - // Only do attribute scanning for public annotations; we'd run into - // IllegalAccessExceptions otherwise, and we don't want to mess with - // accessibility in a SecurityManager environment. + // Only do attribute scanning for public annotations. if (Modifier.isPublic(annotationType.getModifiers())) { this.attributesMap.add(annotationName, AnnotationUtils.getAnnotationAttributes(annotation, false, true)); diff --git a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java index 2177481f0d30..aa4e79316288 100644 --- a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java @@ -190,8 +190,7 @@ public static Constructor accessibleConstructor(Class clazz, Class. /** * Make the given constructor accessible, explicitly setting it accessible * if necessary. The {@code setAccessible(true)} method is only called - * when actually necessary, to avoid unnecessary conflicts with a JVM - * SecurityManager (if active). + * when actually necessary, to avoid unnecessary conflicts. * @param ctor the constructor to make accessible * @see java.lang.reflect.Constructor#setAccessible */ @@ -441,10 +440,9 @@ public static Method[] getUniqueDeclaredMethods(Class leafClass, @Nullable Me /** * Variant of {@link Class#getDeclaredMethods()} that uses a local cache in - * order to avoid the JVM's SecurityManager check and new Method instances. - * In addition, it also includes Java 8 default methods from locally - * implemented interfaces, since those are effectively to be treated just - * like declared methods. + * order to avoid new Method instances. In addition, it also includes Java 8 + * default methods from locally implemented interfaces, since those are + * effectively to be treated just like declared methods. * @param clazz the class to introspect * @return the cached array of methods * @throws IllegalStateException if introspection fails @@ -561,8 +559,7 @@ public static boolean isCglibRenamedMethod(Method renamedMethod) { /** * Make the given method accessible, explicitly setting it accessible if * necessary. The {@code setAccessible(true)} method is only called - * when actually necessary, to avoid unnecessary conflicts with a JVM - * SecurityManager (if active). + * when actually necessary, to avoid unnecessary conflicts. * @param method the method to make accessible * @see java.lang.reflect.Method#setAccessible */ @@ -720,7 +717,7 @@ public static void doWithFields(Class clazz, FieldCallback fc, @Nullable Fiel /** * This variant retrieves {@link Class#getDeclaredFields()} from a local cache - * in order to avoid the JVM's SecurityManager check and defensive array copying. + * in order to avoid defensive array copying. * @param clazz the class to introspect * @return the cached array of fields * @throws IllegalStateException if introspection fails @@ -774,8 +771,7 @@ public static boolean isPublicStaticFinal(Field field) { /** * Make the given field accessible, explicitly setting it accessible if * necessary. The {@code setAccessible(true)} method is only called - * when actually necessary, to avoid unnecessary conflicts with a JVM - * SecurityManager (if active). + * when actually necessary, to avoid unnecessary conflicts. * @param field the field to make accessible * @see java.lang.reflect.Field#setAccessible */ diff --git a/spring-core/src/test/java/org/springframework/core/env/StandardEnvironmentTests.java b/spring-core/src/test/java/org/springframework/core/env/StandardEnvironmentTests.java index acd6d84acabb..5716a8065025 100644 --- a/spring-core/src/test/java/org/springframework/core/env/StandardEnvironmentTests.java +++ b/spring-core/src/test/java/org/springframework/core/env/StandardEnvironmentTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,15 +16,12 @@ package org.springframework.core.env; -import java.security.AccessControlException; -import java.security.Permission; import java.util.Arrays; import java.util.Map; import org.junit.jupiter.api.Test; import org.springframework.core.SpringProperties; -import org.springframework.core.testfixture.env.EnvironmentTestUtils; import org.springframework.core.testfixture.env.MockPropertySource; import static org.assertj.core.api.Assertions.assertThat; @@ -381,72 +378,22 @@ void suppressGetenvAccessThroughSpringFlag() { } @Test - void getSystemProperties_withAndWithoutSecurityManager() { + void getSystemProperties() { System.setProperty(ALLOWED_PROPERTY_NAME, ALLOWED_PROPERTY_VALUE); System.setProperty(DISALLOWED_PROPERTY_NAME, DISALLOWED_PROPERTY_VALUE); System.getProperties().put(STRING_PROPERTY_NAME, NON_STRING_PROPERTY_VALUE); System.getProperties().put(NON_STRING_PROPERTY_NAME, STRING_PROPERTY_VALUE); - { + try { Map systemProperties = environment.getSystemProperties(); assertThat(systemProperties).isNotNull(); assertThat(System.getProperties()).isSameAs(systemProperties); assertThat(systemProperties.get(ALLOWED_PROPERTY_NAME)).isEqualTo(ALLOWED_PROPERTY_VALUE); assertThat(systemProperties.get(DISALLOWED_PROPERTY_NAME)).isEqualTo(DISALLOWED_PROPERTY_VALUE); - - // non-string keys and values work fine... until the security manager is introduced below assertThat(systemProperties.get(STRING_PROPERTY_NAME)).isEqualTo(NON_STRING_PROPERTY_VALUE); assertThat(systemProperties.get(NON_STRING_PROPERTY_NAME)).isEqualTo(STRING_PROPERTY_VALUE); } - - SecurityManager oldSecurityManager = System.getSecurityManager(); - SecurityManager securityManager = new SecurityManager() { - @Override - public void checkPropertiesAccess() { - // see https://download.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#getProperties() - throw new AccessControlException("Accessing the system properties is disallowed"); - } - @Override - public void checkPropertyAccess(String key) { - // see https://download.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#getProperty(java.lang.String) - if (DISALLOWED_PROPERTY_NAME.equals(key)) { - throw new AccessControlException( - String.format("Accessing the system property [%s] is disallowed", DISALLOWED_PROPERTY_NAME)); - } - } - @Override - public void checkPermission(Permission perm) { - // allow everything else - } - }; - - try { - System.setSecurityManager(securityManager); - - { - Map systemProperties = environment.getSystemProperties(); - assertThat(systemProperties).isNotNull(); - assertThat(systemProperties).isInstanceOf(ReadOnlySystemAttributesMap.class); - assertThat((String)systemProperties.get(ALLOWED_PROPERTY_NAME)).isEqualTo(ALLOWED_PROPERTY_VALUE); - assertThat(systemProperties.get(DISALLOWED_PROPERTY_NAME)).isNull(); - - // nothing we can do here in terms of warning the user that there was - // actually a (non-string) value available. By this point, we only - // have access to calling System.getProperty(), which itself returns null - // if the value is non-string. So we're stuck with returning a potentially - // misleading null. - assertThat(systemProperties.get(STRING_PROPERTY_NAME)).isNull(); - - // in the case of a non-string *key*, however, we can do better. Alert - // the user that under these very special conditions (non-object key + - // SecurityManager that disallows access to system properties), they - // cannot do what they're attempting. - assertThatIllegalArgumentException().as("searching with non-string key against ReadOnlySystemAttributesMap").isThrownBy(() -> - systemProperties.get(NON_STRING_PROPERTY_NAME)); - } - } finally { - System.setSecurityManager(oldSecurityManager); System.clearProperty(ALLOWED_PROPERTY_NAME); System.clearProperty(DISALLOWED_PROPERTY_NAME); System.getProperties().remove(STRING_PROPERTY_NAME); @@ -455,48 +402,10 @@ public void checkPermission(Permission perm) { } @Test - void getSystemEnvironment_withAndWithoutSecurityManager() { - EnvironmentTestUtils.getModifiableSystemEnvironment().put(ALLOWED_PROPERTY_NAME, ALLOWED_PROPERTY_VALUE); - EnvironmentTestUtils.getModifiableSystemEnvironment().put(DISALLOWED_PROPERTY_NAME, DISALLOWED_PROPERTY_VALUE); - - { - Map systemEnvironment = environment.getSystemEnvironment(); - assertThat(systemEnvironment).isNotNull(); - assertThat(System.getenv()).isSameAs(systemEnvironment); - } - - SecurityManager oldSecurityManager = System.getSecurityManager(); - SecurityManager securityManager = new SecurityManager() { - @Override - public void checkPermission(Permission perm) { - //see https://download.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#getenv() - if ("getenv.*".equals(perm.getName())) { - throw new AccessControlException("Accessing the system environment is disallowed"); - } - //see https://download.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#getenv(java.lang.String) - if (("getenv."+DISALLOWED_PROPERTY_NAME).equals(perm.getName())) { - throw new AccessControlException( - String.format("Accessing the system environment variable [%s] is disallowed", DISALLOWED_PROPERTY_NAME)); - } - } - }; - - try { - System.setSecurityManager(securityManager); - { - Map systemEnvironment = environment.getSystemEnvironment(); - assertThat(systemEnvironment).isNotNull(); - assertThat(systemEnvironment).isInstanceOf(ReadOnlySystemAttributesMap.class); - assertThat(systemEnvironment.get(ALLOWED_PROPERTY_NAME)).isEqualTo(ALLOWED_PROPERTY_VALUE); - assertThat(systemEnvironment.get(DISALLOWED_PROPERTY_NAME)).isNull(); - } - } - finally { - System.setSecurityManager(oldSecurityManager); - } - - EnvironmentTestUtils.getModifiableSystemEnvironment().remove(ALLOWED_PROPERTY_NAME); - EnvironmentTestUtils.getModifiableSystemEnvironment().remove(DISALLOWED_PROPERTY_NAME); + void getSystemEnvironment() { + Map systemEnvironment = environment.getSystemEnvironment(); + assertThat(systemEnvironment).isNotNull(); + assertThat(System.getenv()).isSameAs(systemEnvironment); } } diff --git a/spring-core/src/test/java/org/springframework/core/env/SystemEnvironmentPropertySourceTests.java b/spring-core/src/test/java/org/springframework/core/env/SystemEnvironmentPropertySourceTests.java index daca3a701318..ca52768f9002 100644 --- a/spring-core/src/test/java/org/springframework/core/env/SystemEnvironmentPropertySourceTests.java +++ b/spring-core/src/test/java/org/springframework/core/env/SystemEnvironmentPropertySourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,13 @@ package org.springframework.core.env; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; - /** * Unit tests for {@link SystemEnvironmentPropertySource}. * @@ -148,30 +145,4 @@ void withUppercase() { assertThat(ps.getProperty("A.hyphen-KEY")).isEqualTo("a_hyphen_value"); } - @Test - @SuppressWarnings("serial") - void withSecurityConstraints() throws Exception { - envMap = new HashMap() { - @Override - public boolean containsKey(Object key) { - throw new UnsupportedOperationException(); - } - @Override - public Set keySet() { - return new HashSet<>(super.keySet()); - } - }; - envMap.put("A_KEY", "a_value"); - - ps = new SystemEnvironmentPropertySource("sysEnv", envMap) { - @Override - protected boolean isSecurityManagerPresent() { - return true; - } - }; - - assertThat(ps.containsProperty("A_KEY")).isEqualTo(true); - assertThat(ps.getProperty("A_KEY")).isEqualTo("a_value"); - } - } diff --git a/spring-core/src/test/java/org/springframework/util/StreamUtilsTests.java b/spring-core/src/test/java/org/springframework/util/StreamUtilsTests.java index 21f0829457b3..fad81878e7ed 100644 --- a/spring-core/src/test/java/org/springframework/util/StreamUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/StreamUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,8 +33,6 @@ import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; /** * Tests for {@link StreamUtils}. @@ -57,53 +55,47 @@ void setup() { @Test void copyToByteArray() throws Exception { - InputStream inputStream = spy(new ByteArrayInputStream(bytes)); + InputStream inputStream = new ByteArrayInputStream(bytes); byte[] actual = StreamUtils.copyToByteArray(inputStream); assertThat(actual).isEqualTo(bytes); - verify(inputStream, never()).close(); } @Test void copyToString() throws Exception { Charset charset = Charset.defaultCharset(); - InputStream inputStream = spy(new ByteArrayInputStream(string.getBytes(charset))); + InputStream inputStream = new ByteArrayInputStream(string.getBytes(charset)); String actual = StreamUtils.copyToString(inputStream, charset); assertThat(actual).isEqualTo(string); - verify(inputStream, never()).close(); } @Test void copyBytes() throws Exception { - ByteArrayOutputStream out = spy(new ByteArrayOutputStream()); + ByteArrayOutputStream out = new ByteArrayOutputStream(); StreamUtils.copy(bytes, out); assertThat(out.toByteArray()).isEqualTo(bytes); - verify(out, never()).close(); } @Test void copyString() throws Exception { Charset charset = Charset.defaultCharset(); - ByteArrayOutputStream out = spy(new ByteArrayOutputStream()); + ByteArrayOutputStream out = new ByteArrayOutputStream(); StreamUtils.copy(string, charset, out); assertThat(out.toByteArray()).isEqualTo(string.getBytes(charset)); - verify(out, never()).close(); } @Test void copyStream() throws Exception { - ByteArrayOutputStream out = spy(new ByteArrayOutputStream()); + ByteArrayOutputStream out = new ByteArrayOutputStream(); StreamUtils.copy(new ByteArrayInputStream(bytes), out); assertThat(out.toByteArray()).isEqualTo(bytes); - verify(out, never()).close(); } @Test void copyRange() throws Exception { - ByteArrayOutputStream out = spy(new ByteArrayOutputStream()); + ByteArrayOutputStream out = new ByteArrayOutputStream(); StreamUtils.copyRange(new ByteArrayInputStream(bytes), out, 0, 100); byte[] range = Arrays.copyOfRange(bytes, 0, 101); assertThat(out.toByteArray()).isEqualTo(range); - verify(out, never()).close(); } @Test diff --git a/spring-core/src/testFixtures/java/org/springframework/core/testfixture/env/EnvironmentTestUtils.java b/spring-core/src/testFixtures/java/org/springframework/core/testfixture/env/EnvironmentTestUtils.java deleted file mode 100644 index 8606c47be386..000000000000 --- a/spring-core/src/testFixtures/java/org/springframework/core/testfixture/env/EnvironmentTestUtils.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.testfixture.env; - -import java.lang.reflect.Field; -import java.util.Collections; -import java.util.Map; - -import org.springframework.core.env.StandardEnvironment; - -/** - * Test utilities for {@link StandardEnvironment}. - * - * @author Chris Beams - * @author Juergen Hoeller - */ -public class EnvironmentTestUtils { - - @SuppressWarnings("unchecked") - public static Map getModifiableSystemEnvironment() { - // for os x / linux - Class[] classes = Collections.class.getDeclaredClasses(); - Map env = System.getenv(); - for (Class cl : classes) { - if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) { - try { - Field field = cl.getDeclaredField("m"); - field.setAccessible(true); - Object obj = field.get(env); - if (obj != null && obj.getClass().getName().equals("java.lang.ProcessEnvironment$StringEnvironment")) { - return (Map) obj; - } - } - catch (Exception ex) { - throw new RuntimeException(ex); - } - } - } - - // for windows - Class processEnvironmentClass; - try { - processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment"); - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - - try { - Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment"); - theCaseInsensitiveEnvironmentField.setAccessible(true); - Object obj = theCaseInsensitiveEnvironmentField.get(null); - return (Map) obj; - } - catch (NoSuchFieldException ex) { - // do nothing - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - - try { - Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment"); - theEnvironmentField.setAccessible(true); - Object obj = theEnvironmentField.get(null); - return (Map) obj; - } - catch (NoSuchFieldException ex) { - // do nothing - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - - throw new IllegalStateException(); - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/MockHttpOutputMessage.java b/spring-web/src/test/java/org/springframework/http/MockHttpOutputMessage.java index 3d2d5bb2a336..c11c36db71cb 100644 --- a/spring-web/src/test/java/org/springframework/http/MockHttpOutputMessage.java +++ b/spring-web/src/test/java/org/springframework/http/MockHttpOutputMessage.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,6 @@ import java.io.OutputStream; import java.nio.charset.Charset; -import static org.mockito.Mockito.spy; - /** * @author Arjen Poutsma * @author Rossen Stoyanchev @@ -31,7 +29,7 @@ public class MockHttpOutputMessage implements HttpOutputMessage { private final HttpHeaders headers = new HttpHeaders(); - private final ByteArrayOutputStream body = spy(new ByteArrayOutputStream()); + private final ByteArrayOutputStream body = new ByteArrayOutputStream(); private boolean headersWritten = false; 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 05669acc9962..43bfe0552098 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,8 +48,6 @@ import org.springframework.util.MultiValueMap; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED; import static org.springframework.http.MediaType.MULTIPART_FORM_DATA; import static org.springframework.http.MediaType.MULTIPART_MIXED; @@ -226,10 +224,9 @@ public String getFilename() { item = items.get(5); assertThat(item.getFieldName()).isEqualTo("xml"); assertThat(item.getContentType()).isEqualTo("text/xml"); - verify(outputMessage.getBody(), never()).close(); } - @Test // SPR-13309 + @Test // SPR-13309 public void writeMultipartOrder() throws Exception { MyBean myBean = new MyBean(); myBean.setString("foo"); diff --git a/spring-web/src/test/java/org/springframework/http/converter/StringHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/StringHttpMessageConverterTests.java index 3323dbdb3502..4be55e2b821a 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/StringHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/StringHttpMessageConverterTests.java @@ -102,7 +102,7 @@ public void writeDefaultCharset() throws IOException { assertThat(headers.getAcceptCharset().isEmpty()).isTrue(); } - @Test // gh-24123 + @Test // gh-24123 public void writeJson() throws IOException { String body = "{\"føø\":\"bår\"}"; this.converter.write(body, MediaType.APPLICATION_JSON, this.outputMessage); @@ -114,7 +114,7 @@ public void writeJson() throws IOException { assertThat(headers.getAcceptCharset().isEmpty()).isTrue(); } - @Test // gh-25328 + @Test // gh-25328 public void writeJsonApi() throws IOException { String body = "{\"føø\":\"bår\"}"; MediaType contentType = new MediaType("application", "vnd.api.v1+json"); diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java index cea6e8c7cf76..cef67ddb80ce 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,8 +47,6 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.entry; import static org.assertj.core.api.Assertions.within; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; /** * Jackson 2.x converter tests. @@ -188,7 +186,6 @@ public void write() throws IOException { assertThat(result.contains("\"bool\":true")).isTrue(); assertThat(result.contains("\"bytes\":\"AQI=\"")).isTrue(); assertThat(outputMessage.getHeaders().getContentType()).as("Invalid content-type").isEqualTo(MediaType.APPLICATION_JSON); - verify(outputMessage.getBody(), never()).close(); } @Test diff --git a/spring-web/src/test/java/org/springframework/web/context/request/ServletRequestAttributesTests.java b/spring-web/src/test/java/org/springframework/web/context/request/ServletRequestAttributesTests.java index b24979a9548e..d71be10683a0 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/ServletRequestAttributesTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/ServletRequestAttributesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,13 +51,13 @@ public class ServletRequestAttributesTests { @Test - public void ctorRejectsNullArg() throws Exception { + public void ctorRejectsNullArg() { assertThatIllegalArgumentException().isThrownBy(() -> new ServletRequestAttributes(null)); } @Test - public void setRequestScopedAttribute() throws Exception { + public void setRequestScopedAttribute() { MockHttpServletRequest request = new MockHttpServletRequest(); ServletRequestAttributes attrs = new ServletRequestAttributes(request); attrs.setAttribute(KEY, VALUE, RequestAttributes.SCOPE_REQUEST); @@ -66,7 +66,7 @@ public void setRequestScopedAttribute() throws Exception { } @Test - public void setRequestScopedAttributeAfterCompletion() throws Exception { + public void setRequestScopedAttributeAfterCompletion() { MockHttpServletRequest request = new MockHttpServletRequest(); ServletRequestAttributes attrs = new ServletRequestAttributes(request); request.close(); @@ -75,7 +75,7 @@ public void setRequestScopedAttributeAfterCompletion() throws Exception { } @Test - public void setSessionScopedAttribute() throws Exception { + public void setSessionScopedAttribute() { MockHttpSession session = new MockHttpSession(); session.setAttribute(KEY, VALUE); MockHttpServletRequest request = new MockHttpServletRequest(); @@ -86,7 +86,7 @@ public void setSessionScopedAttribute() throws Exception { } @Test - public void setSessionScopedAttributeAfterCompletion() throws Exception { + public void setSessionScopedAttributeAfterCompletion() { MockHttpSession session = new MockHttpSession(); session.setAttribute(KEY, VALUE); MockHttpServletRequest request = new MockHttpServletRequest(); @@ -100,7 +100,7 @@ public void setSessionScopedAttributeAfterCompletion() throws Exception { } @Test - public void getSessionScopedAttributeDoesNotForceCreationOfSession() throws Exception { + public void getSessionScopedAttributeDoesNotForceCreationOfSession() { HttpServletRequest request = mock(HttpServletRequest.class); ServletRequestAttributes attrs = new ServletRequestAttributes(request); @@ -110,7 +110,7 @@ public void getSessionScopedAttributeDoesNotForceCreationOfSession() throws Exce } @Test - public void removeSessionScopedAttribute() throws Exception { + public void removeSessionScopedAttribute() { MockHttpSession session = new MockHttpSession(); session.setAttribute(KEY, VALUE); MockHttpServletRequest request = new MockHttpServletRequest(); @@ -122,7 +122,7 @@ public void removeSessionScopedAttribute() throws Exception { } @Test - public void removeSessionScopedAttributeDoesNotForceCreationOfSession() throws Exception { + public void removeSessionScopedAttributeDoesNotForceCreationOfSession() { HttpServletRequest request = mock(HttpServletRequest.class); ServletRequestAttributes attrs = new ServletRequestAttributes(request); @@ -131,7 +131,7 @@ public void removeSessionScopedAttributeDoesNotForceCreationOfSession() throws E } @Test - public void updateAccessedAttributes() throws Exception { + public void updateAccessedAttributes() { HttpServletRequest request = mock(HttpServletRequest.class); HttpSession session = mock(HttpSession.class); given(request.getSession(anyBoolean())).willReturn(session); @@ -153,7 +153,7 @@ public void skipImmutableString() { @Test public void skipImmutableCharacter() { - doSkipImmutableValue(new Character('x')); + doSkipImmutableValue(Character.valueOf('x')); } @Test From 4e3d1fa4e9da90b21c2e19c29037f0d687ee4f3e Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 15 Sep 2021 16:20:48 +0200 Subject: [PATCH 102/735] Temporarily downgrade Java compat level for AspectJ classes AspectJ doesn't support JDK17 language level (yet). For the time being, this commit is downgrading the language level for the aspectJ generated classes to 1.8. See gh-27416 --- build.gradle | 2 +- spring-aspects/spring-aspects.gradle | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3cb2fa7f94c7..54b192d25bcd 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { id 'org.asciidoctor.jvm.convert' version '3.3.2' id 'org.asciidoctor.jvm.pdf' version '3.3.2' id 'de.undercouch.download' version '4.1.2' - id "io.freefair.aspectj" version '6.1.0' apply false + id "io.freefair.aspectj" version '6.2.0' apply false id "com.github.ben-manes.versions" version '0.39.0' id "com.github.johnrengelman.shadow" version '7.0.0' apply false id "me.champeau.jmh" version "0.6.6" apply false diff --git a/spring-aspects/spring-aspects.gradle b/spring-aspects/spring-aspects.gradle index 4ee0ef3fda68..85c84bfd4670 100644 --- a/spring-aspects/spring-aspects.gradle +++ b/spring-aspects/spring-aspects.gradle @@ -10,6 +10,15 @@ sourceSets.test.java.srcDirs = files() aspectj.version = dependencyManagement.managedVersions['org.aspectj:aspectjweaver'] +compileAspectj { + sourceCompatibility "1.8" + targetCompatibility "1.8" +} +compileTestAspectj { + sourceCompatibility "1.8" + targetCompatibility "1.8" +} + dependencies { api("org.aspectj:aspectjweaver") compileOnly("org.aspectj:aspectjrt") From 33cddef026ad7a8c86eac0195377d67f00b37674 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 15 Sep 2021 18:45:15 +0200 Subject: [PATCH 103/735] Upgrade Javadoc URLs for JDK 17 based build Prior to this commit, the Javadoc task would fail on `spring-context-indexer` and `spring-instrumentation`. It seems that missing remote docs or HTTP redirects were failing the process. This commit removes the missing published Javadocs and updates the version for the JDK API. See gh-17778 --- build.gradle | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 54b192d25bcd..255ecde3a6df 100644 --- a/build.gradle +++ b/build.gradle @@ -365,11 +365,10 @@ configure([rootProject] + javaProjects) { project -> } ext.javadocLinks = [ - "https://docs.oracle.com/javase/8/docs/api/", - "https://docs.oracle.com/javaee/7/api/", + "https://docs.oracle.com/en/java/javase/17/docs/api/", + "https://javaee.github.io/javaee-spec/javadocs/", "https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ "https://www.ibm.com/docs/api/v1/content/SSEQTP_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/", - "https://glassfish.java.net/nonav/docs/v3/api/", "https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/", "https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/", "https://tiles.apache.org/tiles-request/apidocs/", From 008aa48d5c97b5f5969662f9cab5b0b7594cf1b5 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 16 Sep 2021 14:10:54 +0200 Subject: [PATCH 104/735] Fix formatting for SQL `IN` clause example in ref docs See gh-27388 --- src/docs/asciidoc/data-access.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/docs/asciidoc/data-access.adoc b/src/docs/asciidoc/data-access.adoc index fa0ccbe73f4a..edf4ccbe5636 100644 --- a/src/docs/asciidoc/data-access.adoc +++ b/src/docs/asciidoc/data-access.adoc @@ -6027,8 +6027,8 @@ limit is 1000. In addition to the primitive values in the value list, you can create a `java.util.List` of object arrays. This list can support multiple expressions being defined for the `in` -clause, such as `select * from T_ACTOR where (id, last_name) in ((1, 'Johnson'), (2, -'Harrop'))`. This, of course, requires that your database supports this syntax. +clause, such as `+++select * from T_ACTOR where (id, last_name) in ((1, 'Johnson'), (2, +'Harrop'))+++`. This, of course, requires that your database supports this syntax. [[jdbc-complex-types]] From b74e93807e0443d30cd1a7c5a8671ceae27e3178 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 17 Sep 2021 08:58:19 +0200 Subject: [PATCH 105/735] Remove JDK 9 workarounds etc See gh-17778 --- .../aop/framework/AopProxyUtils.java | 8 +---- .../cglib/core/ReflectUtils.java | 4 +-- .../cglib/core/package-info.java | 2 +- .../cglib/proxy/package-info.java | 2 +- .../core/ReactiveAdapterRegistry.java | 32 +++++-------------- .../convert/support/ByteBufferConverter.java | 8 ++--- .../core/io/buffer/DefaultDataBuffer.java | 18 +++-------- .../org/springframework/util/ClassUtils.java | 2 +- .../springframework/util/ReflectionUtils.java | 6 ++-- .../util/ObjectUtilsTests.java | 2 +- .../apache/commons/logging/LogAdapter.java | 2 +- .../messaging/simp/stomp/StompDecoder.java | 14 +++----- .../oxm/support/AbstractMarshaller.java | 4 +-- .../http/codec/xml/XmlEventDecoder.java | 5 ++- .../xml/SourceHttpMessageConverter.java | 4 +-- 15 files changed, 36 insertions(+), 77 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java b/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java index 12ce1ce86cdc..47bf3deed53c 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java @@ -33,7 +33,6 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; /** * Utility methods for AOP proxy factories. @@ -48,11 +47,6 @@ */ public abstract class AopProxyUtils { - // JDK 17 Class.isSealed() method available? - @Nullable - private static final Method isSealedMethod = ClassUtils.getMethodIfAvailable(Class.class, "isSealed"); - - /** * Obtain the singleton target object behind the given proxy, if any. * @param candidate the (potential) proxy to check @@ -142,7 +136,7 @@ else if (Proxy.isProxyClass(targetClass)) { List> proxiedInterfaces = new ArrayList<>(specifiedInterfaces.length + 3); for (Class ifc : specifiedInterfaces) { // Only non-sealed interfaces are actually eligible for JDK proxying (on JDK 17) - if (isSealedMethod == null || Boolean.FALSE.equals(ReflectionUtils.invokeMethod(isSealedMethod, ifc))) { + if (!ifc.isSealed()) { proxiedInterfaces.add(ifc); } } diff --git a/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java b/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java index 76e3ebf7cba0..d6c0aa2a391b 100644 --- a/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java +++ b/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java @@ -260,7 +260,7 @@ public static Object newInstance(Class type, Class[] parameterTypes, Object[] ar return newInstance(getConstructor(type, parameterTypes), args); } - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") public static Object newInstance(final Constructor cstruct, final Object[] args) { boolean flag = cstruct.isAccessible(); try { @@ -439,7 +439,7 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader, return defineClass(className, b, loader, protectionDomain, null); } - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") public static Class defineClass(String className, byte[] b, ClassLoader loader, ProtectionDomain protectionDomain, Class contextClass) throws Exception { diff --git a/spring-core/src/main/java/org/springframework/cglib/core/package-info.java b/spring-core/src/main/java/org/springframework/cglib/core/package-info.java index a2ed94ff2ead..6d43d8c8bcc2 100644 --- a/spring-core/src/main/java/org/springframework/cglib/core/package-info.java +++ b/spring-core/src/main/java/org/springframework/cglib/core/package-info.java @@ -5,6 +5,6 @@ * *

    As this repackaging happens at the class file level, sources * and javadocs are not available here... except for a few files - * that have been patched for Spring's purposes on JDK 9/10/11. + * that have been patched for Spring's purposes on JDK 9-17. */ package org.springframework.cglib.core; diff --git a/spring-core/src/main/java/org/springframework/cglib/proxy/package-info.java b/spring-core/src/main/java/org/springframework/cglib/proxy/package-info.java index 0d651c8f0464..9f8cfe268e57 100644 --- a/spring-core/src/main/java/org/springframework/cglib/proxy/package-info.java +++ b/spring-core/src/main/java/org/springframework/cglib/proxy/package-info.java @@ -5,6 +5,6 @@ * *

    As this repackaging happens at the class file level, sources * and javadocs are not available here... except for a few files - * that have been patched for Spring's purposes on JDK 9/10/11. + * that have been patched for Spring's purposes on JDK 9-17. */ package org.springframework.cglib.proxy; diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java index cfeaffcaf734..5010538b6f67 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -16,17 +16,18 @@ package org.springframework.core; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import java.util.concurrent.Flow; import java.util.function.Function; import kotlinx.coroutines.CompletableDeferredKt; import kotlinx.coroutines.Deferred; import org.reactivestreams.Publisher; +import reactor.adapter.JdkFlowAdapter; import reactor.blockhound.BlockHound; import reactor.blockhound.integration.BlockHoundIntegration; import reactor.core.publisher.Flux; @@ -36,7 +37,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import org.springframework.util.ConcurrentReferenceHashMap; -import org.springframework.util.ReflectionUtils; /** * A registry of adapters to adapt Reactive Streams {@link Publisher} to/from @@ -350,28 +350,12 @@ void registerAdapters(ReactiveAdapterRegistry registry) { private static class ReactorJdkFlowAdapterRegistrar { void registerAdapter(ReactiveAdapterRegistry registry) { - // TODO: remove reflection when build requires JDK 9+ - - try { - String publisherName = "java.util.concurrent.Flow.Publisher"; - Class publisherClass = ClassUtils.forName(publisherName, getClass().getClassLoader()); - - String adapterName = "reactor.adapter.JdkFlowAdapter"; - Class flowAdapterClass = ClassUtils.forName(adapterName, getClass().getClassLoader()); - - Method toFluxMethod = flowAdapterClass.getMethod("flowPublisherToFlux", publisherClass); - Method toFlowMethod = flowAdapterClass.getMethod("publisherToFlowPublisher", Publisher.class); - Object emptyFlow = ReflectionUtils.invokeMethod(toFlowMethod, null, Flux.empty()); - - registry.registerReactiveType( - ReactiveTypeDescriptor.multiValue(publisherClass, () -> emptyFlow), - source -> (Publisher) ReflectionUtils.invokeMethod(toFluxMethod, null, source), - publisher -> ReflectionUtils.invokeMethod(toFlowMethod, null, publisher) - ); - } - catch (Throwable ex) { - // Ignore - } + Flow.Publisher emptyFlow = JdkFlowAdapter.publisherToFlowPublisher(Flux.empty()); + registry.registerReactiveType( + ReactiveTypeDescriptor.multiValue(Flow.Publisher.class, () -> emptyFlow), + source -> JdkFlowAdapter.flowPublisherToFlux((Flow.Publisher) source), + JdkFlowAdapter::publisherToFlowPublisher + ); } } diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java index 55a1c077474b..0a230ef076c7 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.core.convert.support; -import java.nio.Buffer; import java.nio.ByteBuffer; import java.util.Collections; import java.util.HashSet; @@ -122,10 +121,7 @@ private Object convertToByteBuffer(@Nullable Object source, TypeDescriptor sourc ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length); byteBuffer.put(bytes); - // Extra cast necessary for compiling on JDK 9 plus running on JDK 8, since - // otherwise the overridden ByteBuffer-returning rewind method would be chosen - // which isn't available on JDK 8. - return ((Buffer) byteBuffer).rewind(); + return byteBuffer.rewind(); } } diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java index be2155f34332..ab6c80a25f45 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.Arrays; @@ -333,18 +332,14 @@ private void write(ByteBuffer source) { public DefaultDataBuffer slice(int index, int length) { checkIndex(index, length); int oldPosition = this.byteBuffer.position(); - // Explicit access via Buffer base type for compatibility - // with covariant return type on JDK 9's ByteBuffer... - Buffer buffer = this.byteBuffer; try { - buffer.position(index); + this.byteBuffer.position(index); ByteBuffer slice = this.byteBuffer.slice(); - // Explicit cast for compatibility with covariant return type on JDK 9's ByteBuffer slice.limit(length); return new SlicedDefaultDataBuffer(slice, this.dataBufferFactory, length); } finally { - buffer.position(oldPosition); + this.byteBuffer.position(oldPosition); } } @@ -358,11 +353,8 @@ public ByteBuffer asByteBuffer(int index, int length) { checkIndex(index, length); ByteBuffer duplicate = this.byteBuffer.duplicate(); - // Explicit access via Buffer base type for compatibility - // with covariant return type on JDK 9's ByteBuffer... - Buffer buffer = duplicate; - buffer.position(index); - buffer.limit(index + length); + duplicate.position(index); + duplicate.limit(index + length); return duplicate.slice(); } diff --git a/spring-core/src/main/java/org/springframework/util/ClassUtils.java b/spring-core/src/main/java/org/springframework/util/ClassUtils.java index c9fa24824afb..5bee704483af 100644 --- a/spring-core/src/main/java/org/springframework/util/ClassUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ClassUtils.java @@ -778,7 +778,7 @@ public static Set> getAllInterfacesForClassAsSet(Class clazz, @Nulla * conflicting method signatures (or a similar constraint is violated) * @see java.lang.reflect.Proxy#getProxyClass */ - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") public static Class createCompositeInterface(Class[] interfaces, @Nullable ClassLoader classLoader) { Assert.notEmpty(interfaces, "Interface array must not be empty"); return Proxy.getProxyClass(classLoader, interfaces); diff --git a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java index aa4e79316288..e35836f1f5a8 100644 --- a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java @@ -194,7 +194,7 @@ public static Constructor accessibleConstructor(Class clazz, Class. * @param ctor the constructor to make accessible * @see java.lang.reflect.Constructor#setAccessible */ - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") public static void makeAccessible(Constructor ctor) { if ((!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor.getDeclaringClass().getModifiers())) && !ctor.isAccessible()) { @@ -563,7 +563,7 @@ public static boolean isCglibRenamedMethod(Method renamedMethod) { * @param method the method to make accessible * @see java.lang.reflect.Method#setAccessible */ - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") public static void makeAccessible(Method method) { if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) && !method.isAccessible()) { @@ -775,7 +775,7 @@ public static boolean isPublicStaticFinal(Field field) { * @param field the field to make accessible * @see java.lang.reflect.Field#setAccessible */ - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") public static void makeAccessible(Field field) { if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || diff --git a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java index b18710a1bfde..c89286af88d0 100644 --- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java @@ -251,7 +251,7 @@ void hashCodeWithBooleanTrue() { @Deprecated void hashCodeWithDouble() { double dbl = 9830.43; - int expected = (new Double(dbl)).hashCode(); + int expected = Double.valueOf(dbl).hashCode(); assertThat(ObjectUtils.hashCode(dbl)).isEqualTo(expected); } diff --git a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java index c918ee7c2df0..c308340714d0 100644 --- a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java +++ b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java @@ -681,7 +681,7 @@ else if (found) { setSourceMethodName(sourceMethodName); } - @SuppressWarnings("deprecation") // setMillis is deprecated in JDK 9 + @SuppressWarnings("deprecation") protected Object writeReplace() { LogRecord serialized = new LogRecord(getLevel(), getMessage()); serialized.setLoggerName(getLoggerName()); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java index d71f78752ccb..70b2c0b2e545 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package org.springframework.messaging.simp.stomp; import java.io.ByteArrayOutputStream; -import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -134,11 +133,7 @@ public List> decode(ByteBuffer byteBuffer, private Message decodeMessage(ByteBuffer byteBuffer, @Nullable MultiValueMap headers) { Message decodedMessage = null; skipEol(byteBuffer); - - // Explicit mark/reset access via Buffer base type for compatibility - // with covariant return type on JDK 9's ByteBuffer... - Buffer buffer = byteBuffer; - buffer.mark(); + byteBuffer.mark(); String command = readCommand(byteBuffer); if (command.length() > 0) { @@ -176,7 +171,7 @@ private Message decodeMessage(ByteBuffer byteBuffer, @Nullable MultiValu headers.putAll(map); } } - buffer.reset(); + byteBuffer.reset(); } } else { @@ -357,8 +352,7 @@ else if (b == '\r') { throw new StompConversionException("'\\r' must be followed by '\\n'"); } } - // Explicit cast for compatibility with covariant return type on JDK 9's ByteBuffer - ((Buffer) byteBuffer).position(byteBuffer.position() - 1); + byteBuffer.position(byteBuffer.position() - 1); } return false; } diff --git a/spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java index f492caf38cab..4803cfada497 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -189,7 +189,7 @@ protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory) * @return the XMLReader * @throws SAXException if thrown by JAXP methods */ - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") protected XMLReader createXmlReader() throws SAXException { XMLReader xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd()); diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java index dac546303944..7ee5253fd8e1 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -122,7 +122,6 @@ public int getMaxInMemorySize() { @Override - @SuppressWarnings({"rawtypes", "unchecked", "cast"}) // XMLEventReader is Iterator on JDK 9 public Flux decode(Publisher input, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map hints) { @@ -137,7 +136,7 @@ public Flux decode(Publisher input, ResolvableType element .flatMapIterable(buffer -> { try { InputStream is = buffer.asInputStream(); - Iterator eventReader = inputFactory.createXMLEventReader(is); + Iterator eventReader = inputFactory.createXMLEventReader(is); List result = new ArrayList<>(); eventReader.forEachRemaining(event -> result.add((XMLEvent) event)); return result; diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java index 63c70e30c643..94d4b0d75117 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -197,7 +197,7 @@ private DOMSource readDOMSource(InputStream body, HttpInputMessage inputMessage) } } - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") private SAXSource readSAXSource(InputStream body, HttpInputMessage inputMessage) throws IOException { try { XMLReader xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); From b7b078d26e4eea472f753b3027d86ddba183b3b9 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 17 Sep 2021 08:58:40 +0200 Subject: [PATCH 106/735] Remove Joda-Time support Closes gh-27426 --- .../format/annotation/DateTimeFormat.java | 1 - .../datetime/DateFormatterRegistrar.java | 3 +- ...eTimeFormatAnnotationFormatterFactory.java | 1 - .../joda/DateTimeFormatterFactory.java | 169 ---- .../joda/DateTimeFormatterFactoryBean.java | 67 -- .../format/datetime/joda/DateTimeParser.java | 54 -- .../datetime/joda/DurationFormatter.java | 46 -- ...eTimeFormatAnnotationFormatterFactory.java | 133 --- .../format/datetime/joda/JodaTimeContext.java | 113 --- .../datetime/joda/JodaTimeContextHolder.java | 91 --- .../datetime/joda/JodaTimeConverters.java | 219 ----- .../joda/JodaTimeFormatterRegistrar.java | 236 ------ .../format/datetime/joda/LocalDateParser.java | 55 -- .../datetime/joda/LocalDateTimeParser.java | 55 -- .../format/datetime/joda/LocalTimeParser.java | 55 -- .../joda/MillisecondInstantPrinter.java | 52 -- .../datetime/joda/MonthDayFormatter.java | 46 -- .../format/datetime/joda/PeriodFormatter.java | 46 -- .../datetime/joda/ReadableInstantPrinter.java | 53 -- .../datetime/joda/ReadablePartialPrinter.java | 53 -- .../datetime/joda/YearMonthFormatter.java | 46 -- .../format/datetime/joda/package-info.java | 9 - .../standard/DateTimeFormatterRegistrar.java | 1 - .../DefaultFormattingConversionService.java | 16 +- .../format/datetime/DateFormatterTests.java | 42 +- .../DateTimeFormatterFactoryBeanTests.java | 63 -- .../joda/DateTimeFormatterFactoryTests.java | 104 --- .../joda/JodaTimeFormattingTests.java | 770 ------------------ .../FormattingConversionServiceTests.java | 193 +---- .../scheduling/support/CronTriggerTests.java | 235 +++--- .../json/Jackson2ObjectMapperBuilder.java | 15 - .../json/Jackson2ObjectMapperFactoryBean.java | 4 +- .../Jackson2ObjectMapperBuilderTests.java | 43 +- .../Jackson2ObjectMapperFactoryBeanTests.java | 40 +- 34 files changed, 126 insertions(+), 3003 deletions(-) delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeFormatterFactory.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryBean.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeParser.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/DurationFormatter.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/JodaDateTimeFormatAnnotationFormatterFactory.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeContext.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeContextHolder.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeConverters.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeFormatterRegistrar.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateParser.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateTimeParser.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/LocalTimeParser.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/MillisecondInstantPrinter.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/MonthDayFormatter.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/PeriodFormatter.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/ReadableInstantPrinter.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/ReadablePartialPrinter.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/YearMonthFormatter.java delete mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/package-info.java delete mode 100644 spring-context/src/test/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryBeanTests.java delete mode 100644 spring-context/src/test/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryTests.java delete mode 100644 spring-context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java diff --git a/spring-context/src/main/java/org/springframework/format/annotation/DateTimeFormat.java b/spring-context/src/main/java/org/springframework/format/annotation/DateTimeFormat.java index 612728c5ad11..435ad2b7ec24 100644 --- a/spring-context/src/main/java/org/springframework/format/annotation/DateTimeFormat.java +++ b/spring-context/src/main/java/org/springframework/format/annotation/DateTimeFormat.java @@ -66,7 +66,6 @@ * @author Sam Brannen * @since 3.0 * @see java.time.format.DateTimeFormatter - * @see org.joda.time.format.DateTimeFormat */ @Documented @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-context/src/main/java/org/springframework/format/datetime/DateFormatterRegistrar.java b/spring-context/src/main/java/org/springframework/format/datetime/DateFormatterRegistrar.java index 3e7a01b24018..35f361fe6547 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/DateFormatterRegistrar.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/DateFormatterRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,6 @@ * @author Phillip Webb * @since 3.2 * @see org.springframework.format.datetime.standard.DateTimeFormatterRegistrar - * @see org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar * @see FormatterRegistrar#registerFormatters */ public class DateFormatterRegistrar implements FormatterRegistrar { diff --git a/spring-context/src/main/java/org/springframework/format/datetime/DateTimeFormatAnnotationFormatterFactory.java b/spring-context/src/main/java/org/springframework/format/datetime/DateTimeFormatAnnotationFormatterFactory.java index 4c46cd8d0bd0..f9fa9c3a99d7 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/DateTimeFormatAnnotationFormatterFactory.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/DateTimeFormatAnnotationFormatterFactory.java @@ -38,7 +38,6 @@ * @author Phillip Webb * @author Sam Brannen * @since 3.2 - * @see org.springframework.format.datetime.joda.JodaDateTimeFormatAnnotationFormatterFactory */ public class DateTimeFormatAnnotationFormatterFactory extends EmbeddedValueResolutionSupport implements AnnotationFormatterFactory { diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeFormatterFactory.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeFormatterFactory.java deleted file mode 100644 index e276fd278cb4..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeFormatterFactory.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.util.TimeZone; - -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; -import org.joda.time.format.ISODateTimeFormat; - -import org.springframework.format.annotation.DateTimeFormat.ISO; -import org.springframework.lang.Nullable; -import org.springframework.util.StringUtils; - -/** - * Factory that creates a Joda-Time {@link DateTimeFormatter}. - * - *

    Formatters will be created using the defined {@link #setPattern pattern}, - * {@link #setIso ISO}, and {@link #setStyle style} methods (considered in that order). - * - * @author Phillip Webb - * @author Sam Brannen - * @since 3.2 - * @see #createDateTimeFormatter() - * @see #createDateTimeFormatter(DateTimeFormatter) - * @see #setPattern - * @see #setStyle - * @see #setIso - * @see DateTimeFormatterFactoryBean - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public class DateTimeFormatterFactory { - - @Nullable - private String pattern; - - @Nullable - private ISO iso; - - @Nullable - private String style; - - @Nullable - private TimeZone timeZone; - - - /** - * Create a new {@code DateTimeFormatterFactory} instance. - */ - public DateTimeFormatterFactory() { - } - - /** - * Create a new {@code DateTimeFormatterFactory} instance. - * @param pattern the pattern to use to format date values - */ - public DateTimeFormatterFactory(String pattern) { - this.pattern = pattern; - } - - - /** - * Set the pattern to use to format date values. - * @param pattern the format pattern - */ - public void setPattern(String pattern) { - this.pattern = pattern; - } - - /** - * Set the ISO format used to format date values. - * @param iso the ISO format - */ - public void setIso(ISO iso) { - this.iso = iso; - } - - /** - * Set the two characters to use to format date values, in Joda-Time style. - *

    The first character is used for the date style; the second is for - * the time style. Supported characters are: - *

      - *
    • 'S' = Small
    • - *
    • 'M' = Medium
    • - *
    • 'L' = Long
    • - *
    • 'F' = Full
    • - *
    • '-' = Omitted
    • - *
    - * @param style two characters from the set {"S", "M", "L", "F", "-"} - */ - public void setStyle(String style) { - this.style = style; - } - - /** - * Set the {@code TimeZone} to normalize the date values into, if any. - * @param timeZone the time zone - */ - public void setTimeZone(TimeZone timeZone) { - this.timeZone = timeZone; - } - - - /** - * Create a new {@code DateTimeFormatter} using this factory. - *

    If no specific pattern or style has been defined, - * {@link DateTimeFormat#mediumDateTime() medium date time format} will be used. - * @return a new date time formatter - * @see #createDateTimeFormatter(DateTimeFormatter) - */ - public DateTimeFormatter createDateTimeFormatter() { - return createDateTimeFormatter(DateTimeFormat.mediumDateTime()); - } - - /** - * Create a new {@code DateTimeFormatter} using this factory. - *

    If no specific pattern or style has been defined, - * the supplied {@code fallbackFormatter} will be used. - * @param fallbackFormatter the fall-back formatter to use - * when no specific factory properties have been set - * @return a new date time formatter - */ - public DateTimeFormatter createDateTimeFormatter(DateTimeFormatter fallbackFormatter) { - DateTimeFormatter dateTimeFormatter = null; - if (StringUtils.hasLength(this.pattern)) { - dateTimeFormatter = DateTimeFormat.forPattern(this.pattern); - } - else if (this.iso != null && this.iso != ISO.NONE) { - switch (this.iso) { - case DATE: - dateTimeFormatter = ISODateTimeFormat.date(); - break; - case TIME: - dateTimeFormatter = ISODateTimeFormat.time(); - break; - case DATE_TIME: - dateTimeFormatter = ISODateTimeFormat.dateTime(); - break; - default: - throw new IllegalStateException("Unsupported ISO format: " + this.iso); - } - } - else if (StringUtils.hasLength(this.style)) { - dateTimeFormatter = DateTimeFormat.forStyle(this.style); - } - - if (dateTimeFormatter != null && this.timeZone != null) { - dateTimeFormatter = dateTimeFormatter.withZone(DateTimeZone.forTimeZone(this.timeZone)); - } - return (dateTimeFormatter != null ? dateTimeFormatter : fallbackFormatter); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryBean.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryBean.java deleted file mode 100644 index d7a0aa3a8f47..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryBean.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import org.joda.time.format.DateTimeFormatter; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; - -/** - * {@link FactoryBean} that creates a Joda-Time {@link DateTimeFormatter}. - * See the {@link DateTimeFormatterFactory base class} for configuration details. - * - * @author Phillip Webb - * @author Sam Brannen - * @since 3.2 - * @see #setPattern - * @see #setIso - * @see #setStyle - * @see DateTimeFormatterFactory - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public class DateTimeFormatterFactoryBean extends DateTimeFormatterFactory - implements FactoryBean, InitializingBean { - - @Nullable - private DateTimeFormatter dateTimeFormatter; - - - @Override - public void afterPropertiesSet() { - this.dateTimeFormatter = createDateTimeFormatter(); - } - - @Override - @Nullable - public DateTimeFormatter getObject() { - return this.dateTimeFormatter; - } - - @Override - public Class getObjectType() { - return DateTimeFormatter.class; - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeParser.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeParser.java deleted file mode 100644 index 99cc1e595324..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeParser.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2002-2013 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.text.ParseException; -import java.util.Locale; - -import org.joda.time.DateTime; -import org.joda.time.format.DateTimeFormatter; - -import org.springframework.format.Parser; - -/** - * Parses Joda {@link DateTime} instances using a {@link DateTimeFormatter}. - * - * @author Keith Donald - * @since 3.0 - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public final class DateTimeParser implements Parser { - - private final DateTimeFormatter formatter; - - - /** - * Create a new DateTimeParser. - * @param formatter the Joda DateTimeFormatter instance - */ - public DateTimeParser(DateTimeFormatter formatter) { - this.formatter = formatter; - } - - - @Override - public DateTime parse(String text, Locale locale) throws ParseException { - return JodaTimeContextHolder.getFormatter(this.formatter, locale).parseDateTime(text); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/DurationFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/DurationFormatter.java deleted file mode 100644 index fe30ac4c017a..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/DurationFormatter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.text.ParseException; -import java.util.Locale; - -import org.joda.time.Duration; - -import org.springframework.format.Formatter; - -/** - * {@link Formatter} implementation for a Joda-Time {@link Duration}, - * following Joda-Time's parsing rules for a Duration. - * - * @author Juergen Hoeller - * @since 4.2.4 - * @see Duration#parse - */ -class DurationFormatter implements Formatter { - - @Override - public Duration parse(String text, Locale locale) throws ParseException { - return Duration.parse(text); - } - - @Override - public String print(Duration object, Locale locale) { - return object.toString(); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaDateTimeFormatAnnotationFormatterFactory.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaDateTimeFormatAnnotationFormatterFactory.java deleted file mode 100644 index 3d5d541cf50f..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaDateTimeFormatAnnotationFormatterFactory.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.util.Calendar; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.Set; - -import org.joda.time.LocalDate; -import org.joda.time.LocalDateTime; -import org.joda.time.LocalTime; -import org.joda.time.ReadableInstant; -import org.joda.time.ReadablePartial; -import org.joda.time.format.DateTimeFormatter; - -import org.springframework.context.support.EmbeddedValueResolutionSupport; -import org.springframework.format.AnnotationFormatterFactory; -import org.springframework.format.Parser; -import org.springframework.format.Printer; -import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.util.StringUtils; - -/** - * Formats fields annotated with the {@link DateTimeFormat} annotation using Joda-Time. - * - *

    NOTE: Spring's Joda-Time support requires Joda-Time 2.x, as of Spring 4.0. - * - * @author Keith Donald - * @author Juergen Hoeller - * @since 3.0 - * @see DateTimeFormat - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public class JodaDateTimeFormatAnnotationFormatterFactory extends EmbeddedValueResolutionSupport - implements AnnotationFormatterFactory { - - private static final Set> FIELD_TYPES; - - static { - // Create the set of field types that may be annotated with @DateTimeFormat. - // Note: the 3 ReadablePartial concrete types are registered explicitly since - // addFormatterForFieldType rules exist for each of these types - // (if we did not do this, the default byType rules for LocalDate, LocalTime, - // and LocalDateTime would take precedence over the annotation rule, which - // is not what we want) - Set> fieldTypes = new HashSet<>(8); - fieldTypes.add(ReadableInstant.class); - fieldTypes.add(LocalDate.class); - fieldTypes.add(LocalTime.class); - fieldTypes.add(LocalDateTime.class); - fieldTypes.add(Date.class); - fieldTypes.add(Calendar.class); - fieldTypes.add(Long.class); - FIELD_TYPES = Collections.unmodifiableSet(fieldTypes); - } - - - @Override - public final Set> getFieldTypes() { - return FIELD_TYPES; - } - - @Override - public Printer getPrinter(DateTimeFormat annotation, Class fieldType) { - DateTimeFormatter formatter = getFormatter(annotation, fieldType); - if (ReadablePartial.class.isAssignableFrom(fieldType)) { - return new ReadablePartialPrinter(formatter); - } - else if (ReadableInstant.class.isAssignableFrom(fieldType) || Calendar.class.isAssignableFrom(fieldType)) { - // assumes Calendar->ReadableInstant converter is registered - return new ReadableInstantPrinter(formatter); - } - else { - // assumes Date->Long converter is registered - return new MillisecondInstantPrinter(formatter); - } - } - - @Override - public Parser getParser(DateTimeFormat annotation, Class fieldType) { - if (LocalDate.class == fieldType) { - return new LocalDateParser(getFormatter(annotation, fieldType)); - } - else if (LocalTime.class == fieldType) { - return new LocalTimeParser(getFormatter(annotation, fieldType)); - } - else if (LocalDateTime.class == fieldType) { - return new LocalDateTimeParser(getFormatter(annotation, fieldType)); - } - else { - return new DateTimeParser(getFormatter(annotation, fieldType)); - } - } - - /** - * Factory method used to create a {@link DateTimeFormatter}. - * @param annotation the format annotation for the field - * @param fieldType the type of field - * @return a {@link DateTimeFormatter} instance - * @since 3.2 - */ - protected DateTimeFormatter getFormatter(DateTimeFormat annotation, Class fieldType) { - DateTimeFormatterFactory factory = new DateTimeFormatterFactory(); - String style = resolveEmbeddedValue(annotation.style()); - if (StringUtils.hasLength(style)) { - factory.setStyle(style); - } - factory.setIso(annotation.iso()); - String pattern = resolveEmbeddedValue(annotation.pattern()); - if (StringUtils.hasLength(pattern)) { - factory.setPattern(pattern); - } - return factory.createDateTimeFormatter(); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeContext.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeContext.java deleted file mode 100644 index c544497d0fb1..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeContext.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.util.TimeZone; - -import org.joda.time.Chronology; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormatter; - -import org.springframework.context.i18n.LocaleContext; -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.context.i18n.TimeZoneAwareLocaleContext; -import org.springframework.lang.Nullable; - -/** - * A context that holds user-specific Joda-Time settings such as the user's - * Chronology (calendar system) and time zone. - * - *

    A {@code null} property value indicate the user has not specified a setting. - * - * @author Keith Donald - * @since 3.0 - * @see JodaTimeContextHolder - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public class JodaTimeContext { - - @Nullable - private Chronology chronology; - - @Nullable - private DateTimeZone timeZone; - - - /** - * Set the user's chronology (calendar system). - */ - public void setChronology(@Nullable Chronology chronology) { - this.chronology = chronology; - } - - /** - * Return the user's chronology (calendar system), if any. - */ - @Nullable - public Chronology getChronology() { - return this.chronology; - } - - /** - * Set the user's time zone. - *

    Alternatively, set a {@link TimeZoneAwareLocaleContext} on - * {@link LocaleContextHolder}. This context class will fall back to - * checking the locale context if no setting has been provided here. - * @see org.springframework.context.i18n.LocaleContextHolder#getTimeZone() - * @see org.springframework.context.i18n.LocaleContextHolder#setLocaleContext - */ - public void setTimeZone(@Nullable DateTimeZone timeZone) { - this.timeZone = timeZone; - } - - /** - * Return the user's time zone, if any. - */ - @Nullable - public DateTimeZone getTimeZone() { - return this.timeZone; - } - - - /** - * Get the DateTimeFormatter with the this context's settings - * applied to the base {@code formatter}. - * @param formatter the base formatter that establishes default - * formatting rules, generally context-independent - * @return the contextual DateTimeFormatter - */ - public DateTimeFormatter getFormatter(DateTimeFormatter formatter) { - if (this.chronology != null) { - formatter = formatter.withChronology(this.chronology); - } - if (this.timeZone != null) { - formatter = formatter.withZone(this.timeZone); - } - else { - LocaleContext localeContext = LocaleContextHolder.getLocaleContext(); - if (localeContext instanceof TimeZoneAwareLocaleContext) { - TimeZone timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone(); - if (timeZone != null) { - formatter = formatter.withZone(DateTimeZone.forTimeZone(timeZone)); - } - } - } - return formatter; - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeContextHolder.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeContextHolder.java deleted file mode 100644 index 44cd2e93911c..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeContextHolder.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.util.Locale; - -import org.joda.time.format.DateTimeFormatter; - -import org.springframework.core.NamedThreadLocal; -import org.springframework.lang.Nullable; - -/** - * A holder for a thread-local {@link JodaTimeContext} - * with user-specific Joda-Time settings. - * - * @author Keith Donald - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.context.i18n.LocaleContextHolder - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public final class JodaTimeContextHolder { - - private static final ThreadLocal jodaTimeContextHolder = - new NamedThreadLocal<>("JodaTimeContext"); - - - private JodaTimeContextHolder() { - } - - - /** - * Reset the JodaTimeContext for the current thread. - */ - public static void resetJodaTimeContext() { - jodaTimeContextHolder.remove(); - } - - /** - * Associate the given JodaTimeContext with the current thread. - * @param jodaTimeContext the current JodaTimeContext, - * or {@code null} to reset the thread-bound context - */ - public static void setJodaTimeContext(@Nullable JodaTimeContext jodaTimeContext) { - if (jodaTimeContext == null) { - resetJodaTimeContext(); - } - else { - jodaTimeContextHolder.set(jodaTimeContext); - } - } - - /** - * Return the JodaTimeContext associated with the current thread, if any. - * @return the current JodaTimeContext, or {@code null} if none - */ - @Nullable - public static JodaTimeContext getJodaTimeContext() { - return jodaTimeContextHolder.get(); - } - - - /** - * Obtain a DateTimeFormatter with user-specific settings applied to the given base Formatter. - * @param formatter the base formatter that establishes default formatting rules - * (generally user independent) - * @param locale the current user locale (may be {@code null} if not known) - * @return the user-specific DateTimeFormatter - */ - public static DateTimeFormatter getFormatter(DateTimeFormatter formatter, @Nullable Locale locale) { - DateTimeFormatter formatterToUse = (locale != null ? formatter.withLocale(locale) : formatter); - JodaTimeContext context = getJodaTimeContext(); - return (context != null ? context.getFormatter(formatterToUse) : formatterToUse); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeConverters.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeConverters.java deleted file mode 100644 index 84ba3d035c72..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeConverters.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.util.Calendar; -import java.util.Date; - -import org.joda.time.DateTime; -import org.joda.time.Instant; -import org.joda.time.LocalDate; -import org.joda.time.LocalDateTime; -import org.joda.time.LocalTime; -import org.joda.time.MutableDateTime; -import org.joda.time.ReadableInstant; - -import org.springframework.core.convert.converter.Converter; -import org.springframework.core.convert.converter.ConverterRegistry; -import org.springframework.format.datetime.DateFormatterRegistrar; - -/** - * Installs lower-level type converters required to integrate - * Joda-Time support into Spring's field formatting system. - * - *

    Note: {@link JodaTimeFormatterRegistrar} installs these converters - * and relies on several of them for its formatters. Some additional - * converters are just being registered for custom conversion scenarios. - * - * @author Keith Donald - * @author Phillip Webb - * @author Juergen Hoeller - * @since 3.0 - */ -final class JodaTimeConverters { - - private JodaTimeConverters() { - } - - - /** - * Install the converters into the converter registry. - * @param registry the converter registry - */ - @SuppressWarnings("deprecation") - public static void registerConverters(ConverterRegistry registry) { - DateFormatterRegistrar.addDateConverters(registry); - - registry.addConverter(new DateTimeToLocalDateConverter()); - registry.addConverter(new DateTimeToLocalTimeConverter()); - registry.addConverter(new DateTimeToLocalDateTimeConverter()); - registry.addConverter(new DateTimeToDateMidnightConverter()); - registry.addConverter(new DateTimeToMutableDateTimeConverter()); - registry.addConverter(new DateTimeToInstantConverter()); - registry.addConverter(new DateTimeToDateConverter()); - registry.addConverter(new DateTimeToCalendarConverter()); - registry.addConverter(new DateTimeToLongConverter()); - registry.addConverter(new DateToReadableInstantConverter()); - registry.addConverter(new CalendarToReadableInstantConverter()); - registry.addConverter(new LongToReadableInstantConverter()); - registry.addConverter(new LocalDateTimeToLocalDateConverter()); - registry.addConverter(new LocalDateTimeToLocalTimeConverter()); - } - - - private static class DateTimeToLocalDateConverter implements Converter { - - @Override - public LocalDate convert(DateTime source) { - return source.toLocalDate(); - } - } - - - private static class DateTimeToLocalTimeConverter implements Converter { - - @Override - public LocalTime convert(DateTime source) { - return source.toLocalTime(); - } - } - - - private static class DateTimeToLocalDateTimeConverter implements Converter { - - @Override - public LocalDateTime convert(DateTime source) { - return source.toLocalDateTime(); - } - } - - - @Deprecated - private static class DateTimeToDateMidnightConverter implements Converter { - - @Override - public org.joda.time.DateMidnight convert(DateTime source) { - return source.toDateMidnight(); - } - } - - - private static class DateTimeToMutableDateTimeConverter implements Converter { - - @Override - public MutableDateTime convert(DateTime source) { - return source.toMutableDateTime(); - } - } - - - private static class DateTimeToInstantConverter implements Converter { - - @Override - public Instant convert(DateTime source) { - return source.toInstant(); - } - } - - - private static class DateTimeToDateConverter implements Converter { - - @Override - public Date convert(DateTime source) { - return source.toDate(); - } - } - - - private static class DateTimeToCalendarConverter implements Converter { - - @Override - public Calendar convert(DateTime source) { - return source.toGregorianCalendar(); - } - } - - - private static class DateTimeToLongConverter implements Converter { - - @Override - public Long convert(DateTime source) { - return source.getMillis(); - } - } - - - /** - * Used when printing a {@code java.util.Date} field with a ReadableInstantPrinter. - * @see MillisecondInstantPrinter - * @see JodaDateTimeFormatAnnotationFormatterFactory - */ - private static class DateToReadableInstantConverter implements Converter { - - @Override - public ReadableInstant convert(Date source) { - return new DateTime(source); - } - } - - - /** - * Used when printing a {@code java.util.Calendar} field with a ReadableInstantPrinter. - * @see MillisecondInstantPrinter - * @see JodaDateTimeFormatAnnotationFormatterFactory - */ - private static class CalendarToReadableInstantConverter implements Converter { - - @Override - public ReadableInstant convert(Calendar source) { - return new DateTime(source); - } - } - - - /** - * Used when printing a Long field with a ReadableInstantPrinter. - * @see MillisecondInstantPrinter - * @see JodaDateTimeFormatAnnotationFormatterFactory - */ - private static class LongToReadableInstantConverter implements Converter { - - @Override - public ReadableInstant convert(Long source) { - return new DateTime(source.longValue()); - } - } - - - private static class LocalDateTimeToLocalDateConverter implements Converter { - - @Override - public LocalDate convert(LocalDateTime source) { - return source.toLocalDate(); - } - } - - - private static class LocalDateTimeToLocalTimeConverter implements Converter { - - @Override - public LocalTime convert(LocalDateTime source) { - return source.toLocalTime(); - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeFormatterRegistrar.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeFormatterRegistrar.java deleted file mode 100644 index 19835bbc5177..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeFormatterRegistrar.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.util.Calendar; -import java.util.Date; -import java.util.EnumMap; -import java.util.Map; - -import org.joda.time.DateTime; -import org.joda.time.Duration; -import org.joda.time.LocalDate; -import org.joda.time.LocalDateTime; -import org.joda.time.LocalTime; -import org.joda.time.MonthDay; -import org.joda.time.Period; -import org.joda.time.ReadableInstant; -import org.joda.time.YearMonth; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; - -import org.springframework.format.FormatterRegistrar; -import org.springframework.format.FormatterRegistry; -import org.springframework.format.Parser; -import org.springframework.format.Printer; -import org.springframework.format.annotation.DateTimeFormat.ISO; - -/** - * Configures Joda-Time's formatting system for use with Spring. - * - *

    NOTE: Spring's Joda-Time support requires Joda-Time 2.x, as of Spring 4.0. - * - * @author Keith Donald - * @author Juergen Hoeller - * @author Phillip Webb - * @since 3.1 - * @see #setDateStyle - * @see #setTimeStyle - * @see #setDateTimeStyle - * @see #setUseIsoFormat - * @see FormatterRegistrar#registerFormatters - * @see org.springframework.format.datetime.DateFormatterRegistrar - * @see DateTimeFormatterFactoryBean - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public class JodaTimeFormatterRegistrar implements FormatterRegistrar { - - private enum Type {DATE, TIME, DATE_TIME} - - - /** - * User defined formatters. - */ - private final Map formatters = new EnumMap<>(Type.class); - - /** - * Factories used when specific formatters have not been specified. - */ - private final Map factories; - - - public JodaTimeFormatterRegistrar() { - this.factories = new EnumMap<>(Type.class); - for (Type type : Type.values()) { - this.factories.put(type, new DateTimeFormatterFactory()); - } - } - - - /** - * Set whether standard ISO formatting should be applied to all date/time types. - * Default is "false" (no). - *

    If set to "true", the "dateStyle", "timeStyle" and "dateTimeStyle" - * properties are effectively ignored. - */ - public void setUseIsoFormat(boolean useIsoFormat) { - this.factories.get(Type.DATE).setIso(useIsoFormat ? ISO.DATE : ISO.NONE); - this.factories.get(Type.TIME).setIso(useIsoFormat ? ISO.TIME : ISO.NONE); - this.factories.get(Type.DATE_TIME).setIso(useIsoFormat ? ISO.DATE_TIME : ISO.NONE); - } - - /** - * Set the default format style of Joda {@link LocalDate} objects. - * Default is {@link DateTimeFormat#shortDate()}. - */ - public void setDateStyle(String dateStyle) { - this.factories.get(Type.DATE).setStyle(dateStyle + "-"); - } - - /** - * Set the default format style of Joda {@link LocalTime} objects. - * Default is {@link DateTimeFormat#shortTime()}. - */ - public void setTimeStyle(String timeStyle) { - this.factories.get(Type.TIME).setStyle("-" + timeStyle); - } - - /** - * Set the default format style of Joda {@link LocalDateTime} and {@link DateTime} objects, - * as well as JDK {@link Date} and {@link Calendar} objects. - * Default is {@link DateTimeFormat#shortDateTime()}. - */ - public void setDateTimeStyle(String dateTimeStyle) { - this.factories.get(Type.DATE_TIME).setStyle(dateTimeStyle); - } - - /** - * Set the formatter that will be used for objects representing date values. - *

    This formatter will be used for the {@link LocalDate} type. When specified - * the {@link #setDateStyle(String) dateStyle} and - * {@link #setUseIsoFormat(boolean) useIsoFormat} properties will be ignored. - * @param formatter the formatter to use - * @since 3.2 - * @see #setTimeFormatter - * @see #setDateTimeFormatter - */ - public void setDateFormatter(DateTimeFormatter formatter) { - this.formatters.put(Type.DATE, formatter); - } - - /** - * Set the formatter that will be used for objects representing time values. - *

    This formatter will be used for the {@link LocalTime} type. When specified - * the {@link #setTimeStyle(String) timeStyle} and - * {@link #setUseIsoFormat(boolean) useIsoFormat} properties will be ignored. - * @param formatter the formatter to use - * @since 3.2 - * @see #setDateFormatter - * @see #setDateTimeFormatter - */ - public void setTimeFormatter(DateTimeFormatter formatter) { - this.formatters.put(Type.TIME, formatter); - } - - /** - * Set the formatter that will be used for objects representing date and time values. - *

    This formatter will be used for {@link LocalDateTime}, {@link ReadableInstant}, - * {@link Date} and {@link Calendar} types. When specified - * the {@link #setDateTimeStyle(String) dateTimeStyle} and - * {@link #setUseIsoFormat(boolean) useIsoFormat} properties will be ignored. - * @param formatter the formatter to use - * @since 3.2 - * @see #setDateFormatter - * @see #setTimeFormatter - */ - public void setDateTimeFormatter(DateTimeFormatter formatter) { - this.formatters.put(Type.DATE_TIME, formatter); - } - - - @Override - public void registerFormatters(FormatterRegistry registry) { - JodaTimeConverters.registerConverters(registry); - - DateTimeFormatter dateFormatter = getFormatter(Type.DATE); - DateTimeFormatter timeFormatter = getFormatter(Type.TIME); - DateTimeFormatter dateTimeFormatter = getFormatter(Type.DATE_TIME); - - addFormatterForFields(registry, - new ReadablePartialPrinter(dateFormatter), - new LocalDateParser(dateFormatter), - LocalDate.class); - - addFormatterForFields(registry, - new ReadablePartialPrinter(timeFormatter), - new LocalTimeParser(timeFormatter), - LocalTime.class); - - addFormatterForFields(registry, - new ReadablePartialPrinter(dateTimeFormatter), - new LocalDateTimeParser(dateTimeFormatter), - LocalDateTime.class); - - addFormatterForFields(registry, - new ReadableInstantPrinter(dateTimeFormatter), - new DateTimeParser(dateTimeFormatter), - ReadableInstant.class); - - // In order to retain backwards compatibility we only register Date/Calendar - // types when a user defined formatter is specified (see SPR-10105) - if (this.formatters.containsKey(Type.DATE_TIME)) { - addFormatterForFields(registry, - new ReadableInstantPrinter(dateTimeFormatter), - new DateTimeParser(dateTimeFormatter), - Date.class, Calendar.class); - } - - registry.addFormatterForFieldType(Period.class, new PeriodFormatter()); - registry.addFormatterForFieldType(Duration.class, new DurationFormatter()); - registry.addFormatterForFieldType(YearMonth.class, new YearMonthFormatter()); - registry.addFormatterForFieldType(MonthDay.class, new MonthDayFormatter()); - - registry.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory()); - } - - private DateTimeFormatter getFormatter(Type type) { - DateTimeFormatter formatter = this.formatters.get(type); - if (formatter != null) { - return formatter; - } - DateTimeFormatter fallbackFormatter = getFallbackFormatter(type); - return this.factories.get(type).createDateTimeFormatter(fallbackFormatter); - } - - private DateTimeFormatter getFallbackFormatter(Type type) { - switch (type) { - case DATE: return DateTimeFormat.shortDate(); - case TIME: return DateTimeFormat.shortTime(); - default: return DateTimeFormat.shortDateTime(); - } - } - - private void addFormatterForFields(FormatterRegistry registry, Printer printer, - Parser parser, Class... fieldTypes) { - - for (Class fieldType : fieldTypes) { - registry.addFormatterForFieldType(fieldType, printer, parser); - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateParser.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateParser.java deleted file mode 100644 index 189f6ea5f43c..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateParser.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2002-2013 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.text.ParseException; -import java.util.Locale; - -import org.joda.time.LocalDate; -import org.joda.time.format.DateTimeFormatter; - -import org.springframework.format.Parser; - -/** - * Parses Joda {@link org.joda.time.LocalDate} instances using a - * {@link org.joda.time.format.DateTimeFormatter}. - * - * @author Juergen Hoeller - * @since 4.0 - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public final class LocalDateParser implements Parser { - - private final DateTimeFormatter formatter; - - - /** - * Create a new DateTimeParser. - * @param formatter the Joda DateTimeFormatter instance - */ - public LocalDateParser(DateTimeFormatter formatter) { - this.formatter = formatter; - } - - - @Override - public LocalDate parse(String text, Locale locale) throws ParseException { - return JodaTimeContextHolder.getFormatter(this.formatter, locale).parseLocalDate(text); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateTimeParser.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateTimeParser.java deleted file mode 100644 index 9a2d6ec86688..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateTimeParser.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2002-2013 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.text.ParseException; -import java.util.Locale; - -import org.joda.time.LocalDateTime; -import org.joda.time.format.DateTimeFormatter; - -import org.springframework.format.Parser; - -/** - * Parses Joda {@link org.joda.time.LocalDateTime} instances using a - * {@link org.joda.time.format.DateTimeFormatter}. - * - * @author Juergen Hoeller - * @since 4.0 - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public final class LocalDateTimeParser implements Parser { - - private final DateTimeFormatter formatter; - - - /** - * Create a new DateTimeParser. - * @param formatter the Joda DateTimeFormatter instance - */ - public LocalDateTimeParser(DateTimeFormatter formatter) { - this.formatter = formatter; - } - - - @Override - public LocalDateTime parse(String text, Locale locale) throws ParseException { - return JodaTimeContextHolder.getFormatter(this.formatter, locale).parseLocalDateTime(text); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalTimeParser.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalTimeParser.java deleted file mode 100644 index 0d68e82fd2f5..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalTimeParser.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2002-2013 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.text.ParseException; -import java.util.Locale; - -import org.joda.time.LocalTime; -import org.joda.time.format.DateTimeFormatter; - -import org.springframework.format.Parser; - -/** - * Parses Joda {@link org.joda.time.LocalTime} instances using a - * {@link org.joda.time.format.DateTimeFormatter}. - * - * @author Juergen Hoeller - * @since 4.0 - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public final class LocalTimeParser implements Parser { - - private final DateTimeFormatter formatter; - - - /** - * Create a new DateTimeParser. - * @param formatter the Joda DateTimeFormatter instance - */ - public LocalTimeParser(DateTimeFormatter formatter) { - this.formatter = formatter; - } - - - @Override - public LocalTime parse(String text, Locale locale) throws ParseException { - return JodaTimeContextHolder.getFormatter(this.formatter, locale).parseLocalTime(text); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/MillisecondInstantPrinter.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/MillisecondInstantPrinter.java deleted file mode 100644 index 75cd6baa68ed..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/MillisecondInstantPrinter.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2002-2013 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.util.Locale; - -import org.joda.time.format.DateTimeFormatter; - -import org.springframework.format.Printer; - -/** - * Prints Long instances using a Joda {@link DateTimeFormatter}. - * - * @author Keith Donald - * @since 3.0 - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public final class MillisecondInstantPrinter implements Printer { - - private final DateTimeFormatter formatter; - - - /** - * Create a new ReadableInstantPrinter. - * @param formatter the Joda DateTimeFormatter instance - */ - public MillisecondInstantPrinter(DateTimeFormatter formatter) { - this.formatter = formatter; - } - - - @Override - public String print(Long instant, Locale locale) { - return JodaTimeContextHolder.getFormatter(this.formatter, locale).print(instant); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/MonthDayFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/MonthDayFormatter.java deleted file mode 100644 index 1cb12cef3bd1..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/MonthDayFormatter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.text.ParseException; -import java.util.Locale; - -import org.joda.time.MonthDay; - -import org.springframework.format.Formatter; - -/** - * {@link Formatter} implementation for a Joda-Time {@link MonthDay}, - * following Joda-Time's parsing rules for a MonthDay. - * - * @author Juergen Hoeller - * @since 4.2.4 - * @see MonthDay#parse - */ -class MonthDayFormatter implements Formatter { - - @Override - public MonthDay parse(String text, Locale locale) throws ParseException { - return MonthDay.parse(text); - } - - @Override - public String print(MonthDay object, Locale locale) { - return object.toString(); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/PeriodFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/PeriodFormatter.java deleted file mode 100644 index 28133f72344f..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/PeriodFormatter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.text.ParseException; -import java.util.Locale; - -import org.joda.time.Period; - -import org.springframework.format.Formatter; - -/** - * {@link Formatter} implementation for a Joda-Time {@link Period}, - * following Joda-Time's parsing rules for a Period. - * - * @author Juergen Hoeller - * @since 4.2.4 - * @see Period#parse - */ -class PeriodFormatter implements Formatter { - - @Override - public Period parse(String text, Locale locale) throws ParseException { - return Period.parse(text); - } - - @Override - public String print(Period object, Locale locale) { - return object.toString(); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/ReadableInstantPrinter.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/ReadableInstantPrinter.java deleted file mode 100644 index 995075be0ee6..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/ReadableInstantPrinter.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2002-2013 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.util.Locale; - -import org.joda.time.ReadableInstant; -import org.joda.time.format.DateTimeFormatter; - -import org.springframework.format.Printer; - -/** - * Prints Joda-Time {@link ReadableInstant} instances using a {@link DateTimeFormatter}. - * - * @author Keith Donald - * @since 3.0 - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public final class ReadableInstantPrinter implements Printer { - - private final DateTimeFormatter formatter; - - - /** - * Create a new ReadableInstantPrinter. - * @param formatter the Joda DateTimeFormatter instance - */ - public ReadableInstantPrinter(DateTimeFormatter formatter) { - this.formatter = formatter; - } - - - @Override - public String print(ReadableInstant instant, Locale locale) { - return JodaTimeContextHolder.getFormatter(this.formatter, locale).print(instant); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/ReadablePartialPrinter.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/ReadablePartialPrinter.java deleted file mode 100644 index 85d4e3d556a0..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/ReadablePartialPrinter.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2002-2013 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.util.Locale; - -import org.joda.time.ReadablePartial; -import org.joda.time.format.DateTimeFormatter; - -import org.springframework.format.Printer; - -/** - * Prints Joda-Time {@link ReadablePartial} instances using a {@link DateTimeFormatter}. - * - * @author Keith Donald - * @since 3.0 - * @deprecated as of 5.3, in favor of standard JSR-310 support - */ -@Deprecated -public final class ReadablePartialPrinter implements Printer { - - private final DateTimeFormatter formatter; - - - /** - * Create a new ReadableInstantPrinter. - * @param formatter the Joda DateTimeFormatter instance - */ - public ReadablePartialPrinter(DateTimeFormatter formatter) { - this.formatter = formatter; - } - - - @Override - public String print(ReadablePartial partial, Locale locale) { - return JodaTimeContextHolder.getFormatter(this.formatter, locale).print(partial); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/YearMonthFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/YearMonthFormatter.java deleted file mode 100644 index 1ac44b4af0c5..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/YearMonthFormatter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.text.ParseException; -import java.util.Locale; - -import org.joda.time.YearMonth; - -import org.springframework.format.Formatter; - -/** - * {@link Formatter} implementation for a Joda-Time {@link YearMonth}, - * following Joda-Time's parsing rules for a YearMonth. - * - * @author Juergen Hoeller - * @since 4.2.4 - * @see YearMonth#parse - */ -class YearMonthFormatter implements Formatter { - - @Override - public YearMonth parse(String text, Locale locale) throws ParseException { - return YearMonth.parse(text); - } - - @Override - public String print(YearMonth object, Locale locale) { - return object.toString(); - } - -} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/package-info.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/package-info.java deleted file mode 100644 index a8a190bd3a1d..000000000000 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Integration with Joda-Time for formatting Joda date and time types as well as standard JDK Date types. - */ -@NonNullApi -@NonNullFields -package org.springframework.format.datetime.joda; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java index 96b4a793453c..ec4964b0e149 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java @@ -50,7 +50,6 @@ * @see #setUseIsoFormat * @see org.springframework.format.FormatterRegistrar#registerFormatters * @see org.springframework.format.datetime.DateFormatterRegistrar - * @see org.springframework.format.datetime.joda.DateTimeFormatterFactoryBean */ public class DateTimeFormatterRegistrar implements FormatterRegistrar { diff --git a/spring-context/src/main/java/org/springframework/format/support/DefaultFormattingConversionService.java b/spring-context/src/main/java/org/springframework/format/support/DefaultFormattingConversionService.java index 805a9828c4c5..190c1f656504 100644 --- a/spring-context/src/main/java/org/springframework/format/support/DefaultFormattingConversionService.java +++ b/spring-context/src/main/java/org/springframework/format/support/DefaultFormattingConversionService.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,12 +48,9 @@ public class DefaultFormattingConversionService extends FormattingConversionServ private static final boolean jsr354Present; - private static final boolean jodaTimePresent; - static { ClassLoader classLoader = DefaultFormattingConversionService.class.getClassLoader(); jsr354Present = ClassUtils.isPresent("javax.money.MonetaryAmount", classLoader); - jodaTimePresent = ClassUtils.isPresent("org.joda.time.YearMonth", classLoader); } /** @@ -104,7 +101,6 @@ public DefaultFormattingConversionService( * depending on the presence of the corresponding API on the classpath. * @param formatterRegistry the service to register default formatters with */ - @SuppressWarnings("deprecation") public static void addDefaultFormatters(FormatterRegistry formatterRegistry) { // Default handling of number values formatterRegistry.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory()); @@ -121,14 +117,8 @@ public static void addDefaultFormatters(FormatterRegistry formatterRegistry) { // just handling JSR-310 specific date and time types new DateTimeFormatterRegistrar().registerFormatters(formatterRegistry); - if (jodaTimePresent) { - // handles Joda-specific types as well as Date, Calendar, Long - new org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar().registerFormatters(formatterRegistry); - } - else { - // regular DateFormat-based Date, Calendar, Long converters - new DateFormatterRegistrar().registerFormatters(formatterRegistry); - } + // regular DateFormat-based Date, Calendar, Long converters + new DateFormatterRegistrar().registerFormatters(formatterRegistry); } } diff --git a/spring-context/src/test/java/org/springframework/format/datetime/DateFormatterTests.java b/spring-context/src/test/java/org/springframework/format/datetime/DateFormatterTests.java index 7737902082a9..d085e4d622fa 100644 --- a/spring-context/src/test/java/org/springframework/format/datetime/DateFormatterTests.java +++ b/spring-context/src/test/java/org/springframework/format/datetime/DateFormatterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,9 +23,6 @@ import java.util.Locale; import java.util.TimeZone; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; import org.junit.jupiter.api.Test; import org.springframework.format.annotation.DateTimeFormat.ISO; @@ -33,9 +30,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - - - /** * Tests for {@link DateFormatter}. * @@ -137,40 +131,6 @@ public void shouldPrintAndParseISODateTime() throws Exception { assertThat(formatter.parse("2009-06-01T14:23:05.003Z", Locale.US)).isEqualTo(date); } - @Test - public void shouldSupportJodaStylePatterns() throws Exception { - String[] chars = { "S", "M", "-" }; - for (String d : chars) { - for (String t : chars) { - String style = d + t; - if (!style.equals("--")) { - Date date = getDate(2009, Calendar.JUNE, 10, 14, 23, 0, 0); - if (t.equals("-")) { - date = getDate(2009, Calendar.JUNE, 10); - } - else if (d.equals("-")) { - date = getDate(1970, Calendar.JANUARY, 1, 14, 23, 0, 0); - } - testJodaStylePatterns(style, Locale.US, date); - } - } - } - } - - private void testJodaStylePatterns(String style, Locale locale, Date date) throws Exception { - DateFormatter formatter = new DateFormatter(); - formatter.setTimeZone(UTC); - formatter.setStylePattern(style); - DateTimeFormatter jodaFormatter = DateTimeFormat.forStyle(style).withLocale(locale).withZone(DateTimeZone.UTC); - String jodaPrinted = jodaFormatter.print(date.getTime()); - assertThat(formatter.print(date, locale)) - .as("Unable to print style pattern " + style) - .isEqualTo(jodaPrinted); - assertThat(formatter.parse(jodaPrinted, locale)) - .as("Unable to parse style pattern " + style) - .isEqualTo(date); - } - @Test public void shouldThrowOnUnsupportedStylePattern() throws Exception { DateFormatter formatter = new DateFormatter(); diff --git a/spring-context/src/test/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryBeanTests.java b/spring-context/src/test/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryBeanTests.java deleted file mode 100644 index 4472cb321e1e..000000000000 --- a/spring-context/src/test/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryBeanTests.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - - - - - -/** - * @author Phillip Webb - * @author Sam Brannen - */ -public class DateTimeFormatterFactoryBeanTests { - - private final DateTimeFormatterFactoryBean factory = new DateTimeFormatterFactoryBean(); - - - @Test - public void isSingleton() { - assertThat(factory.isSingleton()).isTrue(); - } - - @Test - public void getObjectType() { - assertThat(factory.getObjectType()).isEqualTo(DateTimeFormatter.class); - } - - @Test - public void getObject() { - factory.afterPropertiesSet(); - assertThat(factory.getObject()).isEqualTo(DateTimeFormat.mediumDateTime()); - } - - @Test - public void getObjectIsAlwaysSingleton() { - factory.afterPropertiesSet(); - DateTimeFormatter formatter = factory.getObject(); - assertThat(formatter).isEqualTo(DateTimeFormat.mediumDateTime()); - factory.setStyle("LL"); - assertThat(factory.getObject()).isSameAs(formatter); - } - -} diff --git a/spring-context/src/test/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryTests.java b/spring-context/src/test/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryTests.java deleted file mode 100644 index d76302fe109f..000000000000 --- a/spring-context/src/test/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryTests.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.util.Locale; -import java.util.TimeZone; - -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; -import org.junit.jupiter.api.Test; - -import org.springframework.format.annotation.DateTimeFormat.ISO; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Phillip Webb - * @author Sam Brannen - */ -public class DateTimeFormatterFactoryTests { - - // Potential test timezone, both have daylight savings on October 21st - private static final TimeZone ZURICH = TimeZone.getTimeZone("Europe/Zurich"); - private static final TimeZone NEW_YORK = TimeZone.getTimeZone("America/New_York"); - - // Ensure that we are testing against a timezone other than the default. - private static final TimeZone TEST_TIMEZONE = ZURICH.equals(TimeZone.getDefault()) ? NEW_YORK : ZURICH; - - - private DateTimeFormatterFactory factory = new DateTimeFormatterFactory(); - - private DateTime dateTime = new DateTime(2009, 10, 21, 12, 10, 00, 00); - - - @Test - public void createDateTimeFormatter() { - assertThat(factory.createDateTimeFormatter()).isEqualTo(DateTimeFormat.mediumDateTime()); - } - - @Test - public void createDateTimeFormatterWithPattern() { - factory = new DateTimeFormatterFactory("yyyyMMddHHmmss"); - DateTimeFormatter formatter = factory.createDateTimeFormatter(); - assertThat(formatter.print(dateTime)).isEqualTo("20091021121000"); - } - - @Test - public void createDateTimeFormatterWithNullFallback() { - DateTimeFormatter formatter = factory.createDateTimeFormatter(null); - assertThat(formatter).isNull(); - } - - @Test - public void createDateTimeFormatterWithFallback() { - DateTimeFormatter fallback = DateTimeFormat.forStyle("LL"); - DateTimeFormatter formatter = factory.createDateTimeFormatter(fallback); - assertThat(formatter).isSameAs(fallback); - } - - @Test - public void createDateTimeFormatterInOrderOfPropertyPriority() { - factory.setStyle("SS"); - String value = applyLocale(factory.createDateTimeFormatter()).print(dateTime); - assertThat(value.startsWith("10/21/09")).isTrue(); - assertThat(value.endsWith("12:10 PM")).isTrue(); - - factory.setIso(ISO.DATE); - assertThat(applyLocale(factory.createDateTimeFormatter()).print(dateTime)).isEqualTo("2009-10-21"); - - factory.setPattern("yyyyMMddHHmmss"); - assertThat(factory.createDateTimeFormatter().print(dateTime)).isEqualTo("20091021121000"); - } - - @Test - public void createDateTimeFormatterWithTimeZone() { - factory.setPattern("yyyyMMddHHmmss Z"); - factory.setTimeZone(TEST_TIMEZONE); - DateTimeZone dateTimeZone = DateTimeZone.forTimeZone(TEST_TIMEZONE); - DateTime dateTime = new DateTime(2009, 10, 21, 12, 10, 00, 00, dateTimeZone); - String offset = (TEST_TIMEZONE.equals(NEW_YORK) ? "-0400" : "+0200"); - assertThat(factory.createDateTimeFormatter().print(dateTime)).isEqualTo("20091021121000 " + offset); - } - - private DateTimeFormatter applyLocale(DateTimeFormatter dateTimeFormatter) { - return dateTimeFormatter.withLocale(Locale.US); - } - -} diff --git a/spring-context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java b/spring-context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java deleted file mode 100644 index 63a241f504d5..000000000000 --- a/spring-context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java +++ /dev/null @@ -1,770 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.datetime.joda; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Locale; - -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.Duration; -import org.joda.time.Instant; -import org.joda.time.LocalDate; -import org.joda.time.LocalDateTime; -import org.joda.time.LocalTime; -import org.joda.time.MonthDay; -import org.joda.time.Period; -import org.joda.time.YearMonth; -import org.joda.time.chrono.ISOChronology; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.MutablePropertyValues; -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.core.convert.support.DefaultConversionService; -import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.format.annotation.DateTimeFormat.ISO; -import org.springframework.format.support.FormattingConversionService; -import org.springframework.validation.DataBinder; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Keith Donald - * @author Juergen Hoeller - * @author Phillip Webb - */ -public class JodaTimeFormattingTests { - - private FormattingConversionService conversionService; - - private DataBinder binder; - - - @BeforeEach - public void setup() { - JodaTimeFormatterRegistrar registrar = new JodaTimeFormatterRegistrar(); - setup(registrar); - } - - private void setup(JodaTimeFormatterRegistrar registrar) { - conversionService = new FormattingConversionService(); - DefaultConversionService.addDefaultConverters(conversionService); - registrar.registerFormatters(conversionService); - - JodaTimeBean bean = new JodaTimeBean(); - bean.getChildren().add(new JodaTimeBean()); - binder = new DataBinder(bean); - binder.setConversionService(conversionService); - - LocaleContextHolder.setLocale(Locale.US); - JodaTimeContext context = new JodaTimeContext(); - context.setTimeZone(DateTimeZone.forID("-05:00")); - JodaTimeContextHolder.setJodaTimeContext(context); - } - - @AfterEach - public void cleanup() { - LocaleContextHolder.setLocale(null); - JodaTimeContextHolder.setJodaTimeContext(null); - } - - - @Test - public void testJodaTimePatternsForStyle() { - System.out.println(org.joda.time.format.DateTimeFormat.patternForStyle("SS", LocaleContextHolder.getLocale())); - System.out.println(org.joda.time.format.DateTimeFormat.patternForStyle("MM", LocaleContextHolder.getLocale())); - System.out.println(org.joda.time.format.DateTimeFormat.patternForStyle("LL", LocaleContextHolder.getLocale())); - System.out.println(org.joda.time.format.DateTimeFormat.patternForStyle("FF", LocaleContextHolder.getLocale())); - } - - @Test - public void testBindLocalDate() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDate", "10/31/09"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("localDate")).isEqualTo("10/31/09"); - } - - @Test - public void testBindLocalDateWithSpecificStyle() { - JodaTimeFormatterRegistrar registrar = new JodaTimeFormatterRegistrar(); - registrar.setDateStyle("L"); - setup(registrar); - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDate", "October 31, 2009"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("localDate")).isEqualTo("October 31, 2009"); - } - - @Test - public void testBindLocalDateWithSpecificFormatter() { - JodaTimeFormatterRegistrar registrar = new JodaTimeFormatterRegistrar(); - registrar.setDateFormatter(org.joda.time.format.DateTimeFormat.forPattern("yyyyMMdd")); - setup(registrar); - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDate", "20091031"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("localDate")).isEqualTo("20091031"); - } - - @Test - public void testBindLocalDateArray() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDate", new String[]{"10/31/09"}); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - } - - @Test - public void testBindLocalDateAnnotated() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDateAnnotated", "Oct 31, 2009"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("localDateAnnotated")).isEqualTo("Oct 31, 2009"); - } - - @Test - public void testBindLocalDateAnnotatedWithError() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDateAnnotated", "Oct 031, 2009"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getFieldErrorCount("localDateAnnotated")).isEqualTo(1); - assertThat(binder.getBindingResult().getFieldValue("localDateAnnotated")).isEqualTo("Oct 031, 2009"); - } - - @Test - public void testBindNestedLocalDateAnnotated() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("children[0].localDateAnnotated", "Oct 31, 2009"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("children[0].localDateAnnotated")).isEqualTo("Oct 31, 2009"); - } - - @Test - public void testBindLocalDateAnnotatedWithDirectFieldAccess() { - binder.initDirectFieldAccess(); - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDateAnnotated", "Oct 31, 2009"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("localDateAnnotated")).isEqualTo("Oct 31, 2009"); - } - - @Test - public void testBindLocalDateAnnotatedWithDirectFieldAccessAndError() { - binder.initDirectFieldAccess(); - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDateAnnotated", "Oct 031, 2009"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getFieldErrorCount("localDateAnnotated")).isEqualTo(1); - assertThat(binder.getBindingResult().getFieldValue("localDateAnnotated")).isEqualTo("Oct 031, 2009"); - } - - @Test - public void testBindLocalTime() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localTime", "12:00 PM"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("localTime")).isEqualTo("12:00 PM"); - } - - @Test - public void testBindLocalTimeWithSpecificStyle() { - JodaTimeFormatterRegistrar registrar = new JodaTimeFormatterRegistrar(); - registrar.setTimeStyle("M"); - setup(registrar); - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localTime", "12:00:00 PM"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("localTime")).isEqualTo("12:00:00 PM"); - } - - @Test - public void testBindLocalTimeWithSpecificFormatter() { - JodaTimeFormatterRegistrar registrar = new JodaTimeFormatterRegistrar(); - registrar.setTimeFormatter(org.joda.time.format.DateTimeFormat.forPattern("HHmmss")); - setup(registrar); - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localTime", "130000"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("localTime")).isEqualTo("130000"); - } - - @Test - public void testBindLocalTimeAnnotated() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localTimeAnnotated", "12:00:00 PM"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("localTimeAnnotated")).isEqualTo("12:00:00 PM"); - } - - @Test - public void testBindLocalDateTime() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDateTime", new LocalDateTime(2009, 10, 31, 12, 0)); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - String value = binder.getBindingResult().getFieldValue("localDateTime").toString(); - assertThat(value.startsWith("10/31/09")).isTrue(); - assertThat(value.endsWith("12:00 PM")).isTrue(); - } - - @Test - public void testBindLocalDateTimeAnnotated() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDateTimeAnnotated", new LocalDateTime(2009, 10, 31, 12, 0)); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - String value = binder.getBindingResult().getFieldValue("localDateTimeAnnotated").toString(); - assertThat(value.startsWith("Oct 31, 2009")).isTrue(); - assertThat(value.endsWith("12:00 PM")).isTrue(); - } - - @Test - public void testBindDateTime() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("dateTime", new DateTime(2009, 10, 31, 12, 0, ISOChronology.getInstanceUTC())); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - String value = binder.getBindingResult().getFieldValue("dateTime").toString(); - assertThat(value.startsWith("10/31/09")).isTrue(); - } - - @Test - public void testBindDateTimeWithSpecificStyle() { - JodaTimeFormatterRegistrar registrar = new JodaTimeFormatterRegistrar(); - registrar.setDateTimeStyle("MM"); - setup(registrar); - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDateTime", new LocalDateTime(2009, 10, 31, 12, 0)); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - String value = binder.getBindingResult().getFieldValue("localDateTime").toString(); - assertThat(value.startsWith("Oct 31, 2009")).isTrue(); - assertThat(value.endsWith("12:00:00 PM")).isTrue(); - } - - @Test - public void testBindDateTimeISO() { - JodaTimeFormatterRegistrar registrar = new JodaTimeFormatterRegistrar(); - registrar.setUseIsoFormat(true); - setup(registrar); - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("dateTime", "2009-10-31T12:00:00.000Z"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("dateTime")).isEqualTo("2009-10-31T07:00:00.000-05:00"); - } - - @Test - public void testBindDateTimeWithSpecificFormatter() { - JodaTimeFormatterRegistrar registrar = new JodaTimeFormatterRegistrar(); - registrar.setDateTimeFormatter(org.joda.time.format.DateTimeFormat.forPattern("yyyyMMddHHmmss")); - setup(registrar); - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("dateTime", "20091031130000"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("dateTime")).isEqualTo("20091031130000"); - } - - @Test - public void testBindDateTimeAnnotated() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("dateTimeAnnotated", new DateTime(2009, 10, 31, 12, 0, ISOChronology.getInstanceUTC())); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - String value = binder.getBindingResult().getFieldValue("dateTimeAnnotated").toString(); - assertThat(value.startsWith("Oct 31, 2009")).isTrue(); - } - - @Test - public void testBindDateTimeAnnotatedPattern() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("dateTimeAnnotatedPattern", "10/31/09 12:00 PM"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("dateTimeAnnotatedPattern")).isEqualTo("10/31/09 12:00 PM"); - } - - @Test - public void testBindDateTimeOverflow() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("dateTimeAnnotatedPattern", "02/29/09 12:00 PM"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(1); - } - - @Test - public void testBindDateTimeAnnotatedDefault() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("dateTimeAnnotatedDefault", new DateTime(2009, 10, 31, 12, 0, ISOChronology.getInstanceUTC())); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - String value = binder.getBindingResult().getFieldValue("dateTimeAnnotatedDefault").toString(); - assertThat(value.startsWith("10/31/09")).isTrue(); - } - - @Test - public void testBindDateWithErrorAvoidingDateConstructor() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("date", "Sat, 12 Aug 1995 13:30:00 GMT"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(1); - assertThat(binder.getBindingResult().getFieldValue("date")).isEqualTo("Sat, 12 Aug 1995 13:30:00 GMT"); - } - - @Test - public void testBindDateWithoutErrorFallingBackToDateConstructor() { - DataBinder binder = new DataBinder(new JodaTimeBean()); - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("date", "Sat, 12 Aug 1995 13:30:00 GMT"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - } - - @Test - public void testBindDateAnnotated() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("dateAnnotated", "10/31/09"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("dateAnnotated")).isEqualTo("10/31/09"); - } - - @Test - public void testBindCalendarAnnotated() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("calendarAnnotated", "10/31/09"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("calendarAnnotated")).isEqualTo("10/31/09"); - } - - @Test - public void testBindLong() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("millis", "1256961600"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("millis")).isEqualTo("1256961600"); - } - - @Test - public void testBindLongAnnotated() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("millisAnnotated", "10/31/09"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("millisAnnotated")).isEqualTo("10/31/09"); - } - - @Test - public void testBindISODate() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("isoDate", "2009-10-31"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("isoDate")).isEqualTo("2009-10-31"); - } - - @Test - public void testBindISOTime() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("isoTime", "12:00:00.000-05:00"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("isoTime")).isEqualTo("12:00:00.000"); - } - - @Test - public void testBindISODateTime() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("isoDateTime", "2009-10-31T12:00:00.000Z"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("isoDateTime")).isEqualTo("2009-10-31T07:00:00.000-05:00"); - } - - @Test - public void testBindInstantAnnotated() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("instantAnnotated", "2009-10-31T12:00:00.000Z"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("instantAnnotated")).isEqualTo("2009-10-31T07:00:00.000-05:00"); - } - - @Test - public void testBindMutableDateTimeAnnotated() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("mutableDateTimeAnnotated", "2009-10-31T12:00:00.000Z"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("mutableDateTimeAnnotated")).isEqualTo("2009-10-31T07:00:00.000-05:00"); - } - - @Test - public void dateToStringWithFormat() { - JodaTimeFormatterRegistrar registrar = new JodaTimeFormatterRegistrar(); - registrar.setDateTimeFormatter(org.joda.time.format.DateTimeFormat.shortDateTime()); - setup(registrar); - Date date = new Date(); - Object actual = this.conversionService.convert(date, TypeDescriptor.valueOf(Date.class), TypeDescriptor.valueOf(String.class)); - String expected = JodaTimeContextHolder.getFormatter(org.joda.time.format.DateTimeFormat.shortDateTime(), Locale.US).print(new DateTime(date)); - assertThat(actual).isEqualTo(expected); - } - - @Test // SPR-10105 - @SuppressWarnings("deprecation") - public void stringToDateWithoutGlobalFormat() { - String string = "Sat, 12 Aug 1995 13:30:00 GM"; - Date date = this.conversionService.convert(string, Date.class); - assertThat(date).isEqualTo(new Date(string)); - } - - @Test // SPR-10105 - public void stringToDateWithGlobalFormat() { - JodaTimeFormatterRegistrar registrar = new JodaTimeFormatterRegistrar(); - DateTimeFormatterFactory factory = new DateTimeFormatterFactory(); - factory.setIso(ISO.DATE_TIME); - registrar.setDateTimeFormatter(factory.createDateTimeFormatter()); - setup(registrar); - // This is a format that cannot be parsed by new Date(String) - String string = "2009-10-31T07:00:00.000-05:00"; - Date date = this.conversionService.convert(string, Date.class); - assertThat(date).isNotNull(); - } - - @Test - public void testBindPeriod() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("period", "P6Y3M1D"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("period").toString().equals("P6Y3M1D")).isTrue(); - } - - @Test - public void testBindDuration() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("duration", "PT72.345S"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("duration").toString().equals("PT72.345S")).isTrue(); - } - - @Test - public void testBindYearMonth() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("yearMonth", "2007-12"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("yearMonth").toString().equals("2007-12")).isTrue(); - } - - @Test - public void testBindMonthDay() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("monthDay", "--12-03"); - binder.bind(propertyValues); - assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); - assertThat(binder.getBindingResult().getFieldValue("monthDay").toString().equals("--12-03")).isTrue(); - } - - - @SuppressWarnings("unused") - private static class JodaTimeBean { - - private LocalDate localDate; - - @DateTimeFormat(style="M-") - private LocalDate localDateAnnotated; - - private LocalTime localTime; - - @DateTimeFormat(style="-M") - private LocalTime localTimeAnnotated; - - private LocalDateTime localDateTime; - - @DateTimeFormat(style="MS") - private LocalDateTime localDateTimeAnnotated; - - private DateTime dateTime; - - @DateTimeFormat(style="MS") - private DateTime dateTimeAnnotated; - - @DateTimeFormat - private Date date; - - @DateTimeFormat(style="S-") - private Date dateAnnotated; - - @DateTimeFormat(style="S-") - private Calendar calendarAnnotated; - - private Long millis; - - @DateTimeFormat - private DateTime dateTimeAnnotatedDefault; - - private Long millisAnnotated; - - @DateTimeFormat(pattern="M/d/yy h:mm a") - private DateTime dateTimeAnnotatedPattern; - - @DateTimeFormat(iso=ISO.DATE) - private LocalDate isoDate; - - @DateTimeFormat(iso=ISO.TIME) - private LocalTime isoTime; - - @DateTimeFormat(iso=ISO.DATE_TIME) - private DateTime isoDateTime; - - @DateTimeFormat(iso=ISO.DATE_TIME) - private Instant instantAnnotated; - - @DateTimeFormat(iso=ISO.DATE_TIME) - private Instant mutableDateTimeAnnotated; - - private Period period; - - private Duration duration; - - private YearMonth yearMonth; - - private MonthDay monthDay; - - private final List children = new ArrayList<>(); - - public LocalDate getLocalDate() { - return localDate; - } - - public void setLocalDate(LocalDate localDate) { - this.localDate = localDate; - } - - public LocalDate getLocalDateAnnotated() { - return localDateAnnotated; - } - - public void setLocalDateAnnotated(LocalDate localDateAnnotated) { - this.localDateAnnotated = localDateAnnotated; - } - - public LocalTime getLocalTime() { - return localTime; - } - - public void setLocalTime(LocalTime localTime) { - this.localTime = localTime; - } - - public LocalTime getLocalTimeAnnotated() { - return localTimeAnnotated; - } - - public void setLocalTimeAnnotated(LocalTime localTimeAnnotated) { - this.localTimeAnnotated = localTimeAnnotated; - } - - public LocalDateTime getLocalDateTime() { - return localDateTime; - } - - public void setLocalDateTime(LocalDateTime localDateTime) { - this.localDateTime = localDateTime; - } - - public LocalDateTime getLocalDateTimeAnnotated() { - return localDateTimeAnnotated; - } - - public void setLocalDateTimeAnnotated(LocalDateTime localDateTimeAnnotated) { - this.localDateTimeAnnotated = localDateTimeAnnotated; - } - - public DateTime getDateTime() { - return dateTime; - } - - public void setDateTime(DateTime dateTime) { - this.dateTime = dateTime; - } - - public DateTime getDateTimeAnnotated() { - return dateTimeAnnotated; - } - - public void setDateTimeAnnotated(DateTime dateTimeAnnotated) { - this.dateTimeAnnotated = dateTimeAnnotated; - } - - public DateTime getDateTimeAnnotatedPattern() { - return dateTimeAnnotatedPattern; - } - - public void setDateTimeAnnotatedPattern(DateTime dateTimeAnnotatedPattern) { - this.dateTimeAnnotatedPattern = dateTimeAnnotatedPattern; - } - - public DateTime getDateTimeAnnotatedDefault() { - return dateTimeAnnotatedDefault; - } - - public void setDateTimeAnnotatedDefault(DateTime dateTimeAnnotatedDefault) { - this.dateTimeAnnotatedDefault = dateTimeAnnotatedDefault; - } - - public Date getDate() { - return date; - } - - public void setDate(Date date) { - this.date = date; - } - - public Date getDateAnnotated() { - return dateAnnotated; - } - - public void setDateAnnotated(Date dateAnnotated) { - this.dateAnnotated = dateAnnotated; - } - - public Calendar getCalendarAnnotated() { - return calendarAnnotated; - } - - public void setCalendarAnnotated(Calendar calendarAnnotated) { - this.calendarAnnotated = calendarAnnotated; - } - - public Long getMillis() { - return millis; - } - - public void setMillis(Long millis) { - this.millis = millis; - } - - @DateTimeFormat(style="S-") - public Long getMillisAnnotated() { - return millisAnnotated; - } - - public void setMillisAnnotated(@DateTimeFormat(style="S-") Long millisAnnotated) { - this.millisAnnotated = millisAnnotated; - } - - public LocalDate getIsoDate() { - return isoDate; - } - - public void setIsoDate(LocalDate isoDate) { - this.isoDate = isoDate; - } - - public LocalTime getIsoTime() { - return isoTime; - } - - public void setIsoTime(LocalTime isoTime) { - this.isoTime = isoTime; - } - - public DateTime getIsoDateTime() { - return isoDateTime; - } - - public void setIsoDateTime(DateTime isoDateTime) { - this.isoDateTime = isoDateTime; - } - - public Instant getInstantAnnotated() { - return instantAnnotated; - } - - public void setInstantAnnotated(Instant instantAnnotated) { - this.instantAnnotated = instantAnnotated; - } - - public Instant getMutableDateTimeAnnotated() { - return mutableDateTimeAnnotated; - } - - public void setMutableDateTimeAnnotated(Instant mutableDateTimeAnnotated) { - this.mutableDateTimeAnnotated = mutableDateTimeAnnotated; - } - - public Period getPeriod() { - return period; - } - - public void setPeriod(Period period) { - this.period = period; - } - - public Duration getDuration() { - return duration; - } - - public void setDuration(Duration duration) { - this.duration = duration; - } - - public YearMonth getYearMonth() { - return yearMonth; - } - - public void setYearMonth(YearMonth yearMonth) { - this.yearMonth = yearMonth; - } - - public MonthDay getMonthDay() { - return monthDay; - } - - public void setMonthDay(MonthDay monthDay) { - this.monthDay = monthDay; - } - - public List getChildren() { - return children; - } - } - -} diff --git a/spring-context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java b/spring-context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java index eeb6895eddea..494594df8cd6 100644 --- a/spring-context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java +++ b/spring-context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,40 +18,24 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; -import java.util.Properties; -import org.joda.time.DateTime; -import org.joda.time.LocalDate; -import org.joda.time.format.DateTimeFormat; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.ConfigurablePropertyAccessor; -import org.springframework.beans.PropertyAccessorFactory; import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.format.Formatter; -import org.springframework.format.Printer; import org.springframework.format.annotation.NumberFormat; -import org.springframework.format.datetime.joda.DateTimeParser; -import org.springframework.format.datetime.joda.JodaDateTimeFormatAnnotationFormatterFactory; -import org.springframework.format.datetime.joda.ReadablePartialPrinter; import org.springframework.format.number.NumberStyleFormatter; import static org.assertj.core.api.Assertions.assertThat; @@ -90,155 +74,6 @@ public void formatFieldForTypeWithFormatter() { assertThat(i).isEqualTo(3); } - @Test - public void formatFieldForTypeWithPrinterParserWithCoercion() { - formattingService.addConverter(new Converter() { - @Override - public LocalDate convert(DateTime source) { - return source.toLocalDate(); - } - }); - formattingService.addFormatterForFieldType(LocalDate.class, new ReadablePartialPrinter(DateTimeFormat - .shortDate()), new DateTimeParser(DateTimeFormat.shortDate())); - String formatted = formattingService.convert(new LocalDate(2009, 10, 31), String.class); - assertThat(formatted).isEqualTo("10/31/09"); - LocalDate date = formattingService.convert("10/31/09", LocalDate.class); - assertThat(date).isEqualTo(new LocalDate(2009, 10, 31)); - } - - @Test - @SuppressWarnings("resource") - public void formatFieldForValueInjection() { - AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); - ac.registerBeanDefinition("valueBean", new RootBeanDefinition(ValueBean.class)); - ac.registerBeanDefinition("conversionService", new RootBeanDefinition(FormattingConversionServiceFactoryBean.class)); - ac.refresh(); - ValueBean valueBean = ac.getBean(ValueBean.class); - assertThat(new LocalDate(valueBean.date)).isEqualTo(new LocalDate(2009, 10, 31)); - } - - @Test - @SuppressWarnings("resource") - public void formatFieldForValueInjectionUsingMetaAnnotations() { - AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); - RootBeanDefinition bd = new RootBeanDefinition(MetaValueBean.class); - bd.setScope(BeanDefinition.SCOPE_PROTOTYPE); - ac.registerBeanDefinition("valueBean", bd); - ac.registerBeanDefinition("conversionService", new RootBeanDefinition(FormattingConversionServiceFactoryBean.class)); - ac.registerBeanDefinition("ppc", new RootBeanDefinition(PropertyPlaceholderConfigurer.class)); - ac.refresh(); - System.setProperty("myDate", "10-31-09"); - System.setProperty("myNumber", "99.99%"); - try { - MetaValueBean valueBean = ac.getBean(MetaValueBean.class); - assertThat(new LocalDate(valueBean.date)).isEqualTo(new LocalDate(2009, 10, 31)); - assertThat(valueBean.number).isEqualTo(Double.valueOf(0.9999)); - } - finally { - System.clearProperty("myDate"); - System.clearProperty("myNumber"); - } - } - - @Test - public void formatFieldForAnnotation() throws Exception { - formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory()); - doTestFormatFieldForAnnotation(Model.class, false); - } - - @Test - public void formatFieldForAnnotationWithDirectFieldAccess() throws Exception { - formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory()); - doTestFormatFieldForAnnotation(Model.class, true); - } - - @Test - @SuppressWarnings("resource") - public void formatFieldForAnnotationWithPlaceholders() throws Exception { - GenericApplicationContext context = new GenericApplicationContext(); - PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); - Properties props = new Properties(); - props.setProperty("dateStyle", "S-"); - props.setProperty("datePattern", "M-d-yy"); - ppc.setProperties(props); - context.getBeanFactory().registerSingleton("ppc", ppc); - context.refresh(); - context.getBeanFactory().initializeBean(formattingService, "formattingService"); - formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory()); - doTestFormatFieldForAnnotation(ModelWithPlaceholders.class, false); - } - - @Test - @SuppressWarnings("resource") - public void formatFieldForAnnotationWithPlaceholdersAndFactoryBean() throws Exception { - GenericApplicationContext context = new GenericApplicationContext(); - PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); - Properties props = new Properties(); - props.setProperty("dateStyle", "S-"); - props.setProperty("datePattern", "M-d-yy"); - ppc.setProperties(props); - context.registerBeanDefinition("formattingService", new RootBeanDefinition(FormattingConversionServiceFactoryBean.class)); - context.getBeanFactory().registerSingleton("ppc", ppc); - context.refresh(); - formattingService = context.getBean("formattingService", FormattingConversionService.class); - doTestFormatFieldForAnnotation(ModelWithPlaceholders.class, false); - } - - @SuppressWarnings("unchecked") - private void doTestFormatFieldForAnnotation(Class modelClass, boolean directFieldAccess) throws Exception { - formattingService.addConverter(new Converter() { - @Override - public Long convert(Date source) { - return source.getTime(); - } - }); - formattingService.addConverter(new Converter() { - @Override - public Date convert(DateTime source) { - return source.toDate(); - } - }); - - String formatted = (String) formattingService.convert(new LocalDate(2009, 10, 31).toDateTimeAtCurrentTime() - .toDate(), new TypeDescriptor(modelClass.getField("date")), TypeDescriptor.valueOf(String.class)); - assertThat(formatted).isEqualTo("10/31/09"); - LocalDate date = new LocalDate(formattingService.convert("10/31/09", TypeDescriptor.valueOf(String.class), - new TypeDescriptor(modelClass.getField("date")))); - assertThat(date).isEqualTo(new LocalDate(2009, 10, 31)); - - List dates = new ArrayList<>(); - dates.add(new LocalDate(2009, 10, 31).toDateTimeAtCurrentTime().toDate()); - dates.add(new LocalDate(2009, 11, 1).toDateTimeAtCurrentTime().toDate()); - dates.add(new LocalDate(2009, 11, 2).toDateTimeAtCurrentTime().toDate()); - formatted = (String) formattingService.convert(dates, - new TypeDescriptor(modelClass.getField("dates")), TypeDescriptor.valueOf(String.class)); - assertThat(formatted).isEqualTo("10-31-09,11-1-09,11-2-09"); - dates = (List) formattingService.convert("10-31-09,11-1-09,11-2-09", - TypeDescriptor.valueOf(String.class), new TypeDescriptor(modelClass.getField("dates"))); - assertThat(new LocalDate(dates.get(0))).isEqualTo(new LocalDate(2009, 10, 31)); - assertThat(new LocalDate(dates.get(1))).isEqualTo(new LocalDate(2009, 11, 1)); - assertThat(new LocalDate(dates.get(2))).isEqualTo(new LocalDate(2009, 11, 2)); - - Object model = modelClass.newInstance(); - ConfigurablePropertyAccessor accessor = directFieldAccess ? PropertyAccessorFactory.forDirectFieldAccess(model) : - PropertyAccessorFactory.forBeanPropertyAccess(model); - accessor.setConversionService(formattingService); - accessor.setPropertyValue("dates", "10-31-09,11-1-09,11-2-09"); - dates = (List) accessor.getPropertyValue("dates"); - assertThat(new LocalDate(dates.get(0))).isEqualTo(new LocalDate(2009, 10, 31)); - assertThat(new LocalDate(dates.get(1))).isEqualTo(new LocalDate(2009, 11, 1)); - assertThat(new LocalDate(dates.get(2))).isEqualTo(new LocalDate(2009, 11, 2)); - if (!directFieldAccess) { - accessor.setPropertyValue("dates[0]", "10-30-09"); - accessor.setPropertyValue("dates[1]", "10-1-09"); - accessor.setPropertyValue("dates[2]", "10-2-09"); - dates = (List) accessor.getPropertyValue("dates"); - assertThat(new LocalDate(dates.get(0))).isEqualTo(new LocalDate(2009, 10, 30)); - assertThat(new LocalDate(dates.get(1))).isEqualTo(new LocalDate(2009, 10, 1)); - assertThat(new LocalDate(dates.get(2))).isEqualTo(new LocalDate(2009, 10, 2)); - } - } - @Test public void printNull() { formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter()); @@ -295,32 +130,6 @@ public void parseEmptyStringDefault() { assertThat(formattingService.convert("", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class))).isNull(); } - @Test - public void formatFieldForAnnotationWithSubclassAsFieldType() throws Exception { - formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory() { - @Override - public Printer getPrinter(org.springframework.format.annotation.DateTimeFormat annotation, Class fieldType) { - assertThat(fieldType).isEqualTo(MyDate.class); - return super.getPrinter(annotation, fieldType); - } - }); - formattingService.addConverter(new Converter() { - @Override - public Long convert(MyDate source) { - return source.getTime(); - } - }); - formattingService.addConverter(new Converter() { - @Override - public Date convert(MyDate source) { - return source; - } - }); - - formattingService.convert(new MyDate(), new TypeDescriptor(ModelWithSubclassField.class.getField("date")), - TypeDescriptor.valueOf(String.class)); - } - @Test public void registerDefaultValueViaFormatter() { registerDefaultValue(Date.class, new Date()); diff --git a/spring-context/src/test/java/org/springframework/scheduling/support/CronTriggerTests.java b/spring-context/src/test/java/org/springframework/scheduling/support/CronTriggerTests.java index 1fe501b1301d..df7fc852b8b3 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/support/CronTriggerTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/support/CronTriggerTests.java @@ -26,7 +26,6 @@ import java.util.TimeZone; import java.util.stream.Stream; -import org.joda.time.LocalDateTime; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -49,25 +48,25 @@ class CronTriggerTests { private final Calendar calendar = new GregorianCalendar(); - private void setUp(LocalDateTime localDateTime, TimeZone timeZone) { + private void setup(Date localDateTime, TimeZone timeZone) { + this.calendar.setTime(localDateTime); this.calendar.setTimeZone(timeZone); - this.calendar.setTime(localDateTime.toDate()); roundup(this.calendar); } @ParameterizedCronTriggerTest - void matchAll(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void matchAll(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("* * * * * *", timeZone); - TriggerContext context = getTriggerContext(localDateTime.toDate()); + TriggerContext context = getTriggerContext(localDateTime); assertThat(trigger.nextExecutionTime(context)).isEqualTo(this.calendar.getTime()); } @ParameterizedCronTriggerTest - void matchLastSecond(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void matchLastSecond(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("* * * * * *", timeZone); GregorianCalendar calendar = new GregorianCalendar(); @@ -76,8 +75,8 @@ void matchLastSecond(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void matchSpecificSecond(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void matchSpecificSecond(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("10 * * * * *", timeZone); GregorianCalendar calendar = new GregorianCalendar(); @@ -86,8 +85,8 @@ void matchSpecificSecond(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void incrementSecondByOne(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementSecondByOne(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("11 * * * * *", timeZone); this.calendar.set(Calendar.SECOND, 10); @@ -98,8 +97,8 @@ void incrementSecondByOne(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void incrementSecondWithPreviousExecutionTooEarly(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementSecondWithPreviousExecutionTooEarly(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("11 * * * * *", timeZone); this.calendar.set(Calendar.SECOND, 11); @@ -111,8 +110,8 @@ void incrementSecondWithPreviousExecutionTooEarly(LocalDateTime localDateTime, T } @ParameterizedCronTriggerTest - void incrementSecondAndRollover(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementSecondAndRollover(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("10 * * * * *", timeZone); this.calendar.set(Calendar.SECOND, 11); @@ -123,8 +122,8 @@ void incrementSecondAndRollover(LocalDateTime localDateTime, TimeZone timeZone) } @ParameterizedCronTriggerTest - void secondRange(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void secondRange(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("10-15 * * * * *", timeZone); this.calendar.set(Calendar.SECOND, 9); @@ -134,8 +133,8 @@ void secondRange(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void incrementMinute(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementMinute(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 * * * * *", timeZone); this.calendar.set(Calendar.MINUTE, 10); @@ -152,8 +151,8 @@ void incrementMinute(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void incrementMinuteByOne(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementMinuteByOne(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 11 * * * *", timeZone); this.calendar.set(Calendar.MINUTE, 10); @@ -164,8 +163,8 @@ void incrementMinuteByOne(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void incrementMinuteAndRollover(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementMinuteAndRollover(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 10 * * * *", timeZone); this.calendar.set(Calendar.MINUTE, 11); @@ -177,8 +176,8 @@ void incrementMinuteAndRollover(LocalDateTime localDateTime, TimeZone timeZone) } @ParameterizedCronTriggerTest - void incrementHour(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementHour(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 0 * * * *", timeZone); this.calendar.set(Calendar.MONTH, 9); @@ -198,8 +197,8 @@ void incrementHour(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void incrementHourAndRollover(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementHourAndRollover(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 0 * * * *", timeZone); this.calendar.set(Calendar.MONTH, 9); @@ -220,8 +219,8 @@ void incrementHourAndRollover(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void incrementDayOfMonth(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementDayOfMonth(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 0 0 * * *", timeZone); this.calendar.set(Calendar.DAY_OF_MONTH, 1); @@ -242,8 +241,8 @@ void incrementDayOfMonth(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void incrementDayOfMonthByOne(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementDayOfMonthByOne(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("* * * 10 * *", timeZone); this.calendar.set(Calendar.DAY_OF_MONTH, 9); @@ -257,8 +256,8 @@ void incrementDayOfMonthByOne(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void incrementDayOfMonthAndRollover(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementDayOfMonthAndRollover(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("* * * 10 * *", timeZone); this.calendar.set(Calendar.DAY_OF_MONTH, 11); @@ -273,8 +272,8 @@ void incrementDayOfMonthAndRollover(LocalDateTime localDateTime, TimeZone timeZo } @ParameterizedCronTriggerTest - void dailyTriggerInShortMonth(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void dailyTriggerInShortMonth(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 0 0 * * *", timeZone); this.calendar.set(Calendar.MONTH, 8); // September: 30 days @@ -294,8 +293,8 @@ void dailyTriggerInShortMonth(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void dailyTriggerInLongMonth(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void dailyTriggerInLongMonth(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 0 0 * * *", timeZone); this.calendar.set(Calendar.MONTH, 7); // August: 31 days and not a daylight saving boundary @@ -315,8 +314,8 @@ void dailyTriggerInLongMonth(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void dailyTriggerOnDaylightSavingBoundary(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void dailyTriggerOnDaylightSavingBoundary(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 0 0 * * *", timeZone); this.calendar.set(Calendar.MONTH, 9); // October: 31 days and a daylight saving boundary in CET @@ -336,8 +335,8 @@ void dailyTriggerOnDaylightSavingBoundary(LocalDateTime localDateTime, TimeZone } @ParameterizedCronTriggerTest - void incrementMonth(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementMonth(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 0 0 1 * *", timeZone); this.calendar.set(Calendar.MONTH, 9); @@ -357,8 +356,8 @@ void incrementMonth(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void incrementMonthAndRollover(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementMonthAndRollover(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 0 0 1 * *", timeZone); this.calendar.set(Calendar.MONTH, 11); @@ -380,8 +379,8 @@ void incrementMonthAndRollover(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void monthlyTriggerInLongMonth(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void monthlyTriggerInLongMonth(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 0 0 31 * *", timeZone); this.calendar.set(Calendar.MONTH, 9); @@ -396,8 +395,8 @@ void monthlyTriggerInLongMonth(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void monthlyTriggerInShortMonth(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void monthlyTriggerInShortMonth(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 0 0 1 * *", timeZone); this.calendar.set(Calendar.MONTH, 9); @@ -413,8 +412,8 @@ void monthlyTriggerInShortMonth(LocalDateTime localDateTime, TimeZone timeZone) } @ParameterizedCronTriggerTest - void incrementDayOfWeekByOne(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementDayOfWeekByOne(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("* * * * * 2", timeZone); this.calendar.set(Calendar.DAY_OF_WEEK, 2); @@ -429,8 +428,8 @@ void incrementDayOfWeekByOne(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void incrementDayOfWeekAndRollover(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void incrementDayOfWeekAndRollover(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("* * * * * 2", timeZone); this.calendar.set(Calendar.DAY_OF_WEEK, 4); @@ -445,8 +444,8 @@ void incrementDayOfWeekAndRollover(LocalDateTime localDateTime, TimeZone timeZon } @ParameterizedCronTriggerTest - void specificMinuteSecond(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void specificMinuteSecond(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("55 5 * * * *", timeZone); this.calendar.set(Calendar.MINUTE, 4); @@ -464,8 +463,8 @@ void specificMinuteSecond(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void specificHourSecond(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void specificHourSecond(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("55 * 10 * * *", timeZone); this.calendar.set(Calendar.HOUR_OF_DAY, 9); @@ -484,8 +483,8 @@ void specificHourSecond(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void specificMinuteHour(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void specificMinuteHour(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("* 5 10 * * *", timeZone); this.calendar.set(Calendar.MINUTE, 4); @@ -505,8 +504,8 @@ void specificMinuteHour(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void specificDayOfMonthSecond(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void specificDayOfMonthSecond(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("55 * * 3 * *", timeZone); this.calendar.set(Calendar.DAY_OF_MONTH, 2); @@ -526,8 +525,8 @@ void specificDayOfMonthSecond(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void specificDate(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void specificDate(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("* * * 3 11 *", timeZone); this.calendar.set(Calendar.DAY_OF_MONTH, 2); @@ -548,8 +547,8 @@ void specificDate(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void nonExistentSpecificDate(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void nonExistentSpecificDate(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); // TODO: maybe try and detect this as a special case in parser? CronTrigger trigger = new CronTrigger("0 0 0 31 6 *", timeZone); @@ -561,8 +560,8 @@ void nonExistentSpecificDate(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void leapYearSpecificDate(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void leapYearSpecificDate(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 0 0 29 2 *", timeZone); this.calendar.set(Calendar.YEAR, 2007); @@ -584,8 +583,8 @@ void leapYearSpecificDate(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void weekDaySequence(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void weekDaySequence(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 0 7 ? * MON-FRI", timeZone); // This is a Saturday @@ -612,8 +611,8 @@ void weekDaySequence(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void dayOfWeekIndifferent(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void dayOfWeekIndifferent(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger1 = new CronTrigger("* * * 2 * *", timeZone); CronTrigger trigger2 = new CronTrigger("* * * 2 * ?", timeZone); @@ -621,8 +620,8 @@ void dayOfWeekIndifferent(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void secondIncrementer(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void secondIncrementer(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger1 = new CronTrigger("57,59 * * * * *", timeZone); CronTrigger trigger2 = new CronTrigger("57/2 * * * * *", timeZone); @@ -630,8 +629,8 @@ void secondIncrementer(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void secondIncrementerWithRange(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void secondIncrementerWithRange(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger1 = new CronTrigger("1,3,5 * * * * *", timeZone); CronTrigger trigger2 = new CronTrigger("1-6/2 * * * * *", timeZone); @@ -639,8 +638,8 @@ void secondIncrementerWithRange(LocalDateTime localDateTime, TimeZone timeZone) } @ParameterizedCronTriggerTest - void hourIncrementer(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void hourIncrementer(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger1 = new CronTrigger("* * 4,8,12,16,20 * * *", timeZone); CronTrigger trigger2 = new CronTrigger("* * 4/4 * * *", timeZone); @@ -648,8 +647,8 @@ void hourIncrementer(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void dayNames(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void dayNames(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger1 = new CronTrigger("* * * * * 0-6", timeZone); CronTrigger trigger2 = new CronTrigger("* * * * * TUE,WED,THU,FRI,SAT,SUN,MON", timeZone); @@ -657,8 +656,8 @@ void dayNames(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void sundayIsZero(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void sundayIsZero(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger1 = new CronTrigger("* * * * * 0", timeZone); CronTrigger trigger2 = new CronTrigger("* * * * * SUN", timeZone); @@ -666,8 +665,8 @@ void sundayIsZero(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void sundaySynonym(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void sundaySynonym(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger1 = new CronTrigger("* * * * * 0", timeZone); CronTrigger trigger2 = new CronTrigger("* * * * * 7", timeZone); @@ -675,8 +674,8 @@ void sundaySynonym(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void monthNames(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void monthNames(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger1 = new CronTrigger("* * * * 1-12 *", timeZone); CronTrigger trigger2 = new CronTrigger("* * * * FEB,JAN,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC *", timeZone); @@ -684,8 +683,8 @@ void monthNames(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void monthNamesMixedCase(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void monthNamesMixedCase(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger1 = new CronTrigger("* * * * 2 *", timeZone); CronTrigger trigger2 = new CronTrigger("* * * * Feb *", timeZone); @@ -693,92 +692,92 @@ void monthNamesMixedCase(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void secondInvalid(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void secondInvalid(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); assertThatIllegalArgumentException().isThrownBy(() -> new CronTrigger("77 * * * * *", timeZone)); } @ParameterizedCronTriggerTest - void secondRangeInvalid(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void secondRangeInvalid(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); assertThatIllegalArgumentException().isThrownBy(() -> new CronTrigger("44-77 * * * * *", timeZone)); } @ParameterizedCronTriggerTest - void minuteInvalid(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void minuteInvalid(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); assertThatIllegalArgumentException().isThrownBy(() -> new CronTrigger("* 77 * * * *", timeZone)); } @ParameterizedCronTriggerTest - void minuteRangeInvalid(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void minuteRangeInvalid(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); assertThatIllegalArgumentException().isThrownBy(() -> new CronTrigger("* 44-77 * * * *", timeZone)); } @ParameterizedCronTriggerTest - void hourInvalid(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void hourInvalid(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); assertThatIllegalArgumentException().isThrownBy(() -> new CronTrigger("* * 27 * * *", timeZone)); } @ParameterizedCronTriggerTest - void hourRangeInvalid(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void hourRangeInvalid(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); assertThatIllegalArgumentException().isThrownBy(() -> new CronTrigger("* * 23-28 * * *", timeZone)); } @ParameterizedCronTriggerTest - void dayInvalid(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void dayInvalid(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); assertThatIllegalArgumentException().isThrownBy(() -> new CronTrigger("* * * 45 * *", timeZone)); } @ParameterizedCronTriggerTest - void dayRangeInvalid(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void dayRangeInvalid(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); assertThatIllegalArgumentException().isThrownBy(() -> new CronTrigger("* * * 28-45 * *", timeZone)); } @ParameterizedCronTriggerTest - void monthInvalid(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void monthInvalid(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); assertThatIllegalArgumentException().isThrownBy(() -> new CronTrigger("0 0 0 25 13 ?", timeZone)); } @ParameterizedCronTriggerTest - void monthInvalidTooSmall(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void monthInvalidTooSmall(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); assertThatIllegalArgumentException().isThrownBy(() -> new CronTrigger("0 0 0 25 0 ?", timeZone)); } @ParameterizedCronTriggerTest - void dayOfMonthInvalid(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void dayOfMonthInvalid(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); assertThatIllegalArgumentException().isThrownBy(() -> new CronTrigger("0 0 0 32 12 ?", timeZone)); } @ParameterizedCronTriggerTest - void monthRangeInvalid(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void monthRangeInvalid(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); assertThatIllegalArgumentException().isThrownBy(() -> new CronTrigger("* * * * 11-13 *", timeZone)); } @ParameterizedCronTriggerTest - void whitespace(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void whitespace(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger1 = new CronTrigger("* * * * 1 *", timeZone); CronTrigger trigger2 = new CronTrigger("* * * * 1 *", timeZone); @@ -786,8 +785,8 @@ void whitespace(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void monthSequence(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void monthSequence(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); CronTrigger trigger = new CronTrigger("0 30 23 30 1/3 ?", timeZone); this.calendar.set(2010, 11, 30); @@ -813,8 +812,8 @@ void monthSequence(LocalDateTime localDateTime, TimeZone timeZone) { } @ParameterizedCronTriggerTest - void daylightSavingMissingHour(LocalDateTime localDateTime, TimeZone timeZone) { - setUp(localDateTime, timeZone); + void daylightSavingMissingHour(Date localDateTime, TimeZone timeZone) { + setup(localDateTime, timeZone); // This trigger has to be somewhere between 2:00 AM and 3:00 AM, so we // use a cron expression for 2:10 AM every day. @@ -876,8 +875,8 @@ private static TriggerContext getTriggerContext(Date lastCompletionTime) { static Stream parameters() { return Stream.of( - arguments(LocalDateTime.now(), TimeZone.getTimeZone("PST")), - arguments(LocalDateTime.now(), TimeZone.getTimeZone("CET")) + arguments(new Date(), TimeZone.getTimeZone("PST")), + arguments(new Date(), TimeZone.getTimeZone("CET")) ); } diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java index 415113ff0596..03bc16cc5104 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java @@ -84,8 +84,6 @@ * support for other Java 8 types like {@link java.util.Optional} *

  • jackson-datatype-jsr310: * support for Java 8 Date & Time API types
  • - *
  • jackson-datatype-joda: - * support for Joda-Time types
  • *
  • jackson-module-kotlin: * support for Kotlin classes and data classes
  • * @@ -836,19 +834,6 @@ private void registerWellKnownModulesIfAvailable(MultiValueMap m // jackson-datatype-jsr310 not available } - // Joda-Time 2.x present? - if (ClassUtils.isPresent("org.joda.time.YearMonth", this.moduleClassLoader)) { - try { - Class jodaModuleClass = (Class) - ClassUtils.forName("com.fasterxml.jackson.datatype.joda.JodaModule", this.moduleClassLoader); - Module jodaModule = BeanUtils.instantiateClass(jodaModuleClass); - modulesToRegister.set(jodaModule.getTypeId(), jodaModule); - } - catch (ClassNotFoundException ex) { - // jackson-datatype-joda not available - } - } - // Kotlin present? if (KotlinDetector.isKotlinPresent()) { try { diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java index 57d3e63e184f..a2c8e5beebdc 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -120,8 +120,6 @@ * support for other Java 8 types like {@link java.util.Optional} *
  • jackson-datatype-jsr310: * support for Java 8 Date & Time API types
  • - *
  • jackson-datatype-joda: - * support for Joda-Time types
  • *
  • jackson-module-kotlin: * support for Kotlin classes and data classes
  • * diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java index 32a93851ba46..eb4c321a1edf 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,8 +79,6 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import kotlin.ranges.IntRange; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.junit.jupiter.api.Test; import org.springframework.beans.FatalBeanException; @@ -263,10 +261,6 @@ void modulesToInstallByInstance() { void wellKnownModules() throws JsonProcessingException, UnsupportedEncodingException { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); - Long timestamp = 1322903730000L; - DateTime dateTime = new DateTime(timestamp, DateTimeZone.UTC); - assertThat(new String(objectMapper.writeValueAsBytes(dateTime), "UTF-8")).isEqualTo(timestamp.toString()); - Path file = Paths.get("foo"); assertThat(new String(objectMapper.writeValueAsBytes(file), "UTF-8").endsWith("foo\"")).isTrue(); @@ -278,41 +272,6 @@ void wellKnownModules() throws JsonProcessingException, UnsupportedEncodingExcep assertThat(new String(objectMapper.writeValueAsBytes(range), "UTF-8")).isEqualTo("{\"start\":1,\"end\":3}"); } - @Test // SPR-12634 - void customizeWellKnownModulesWithModule() - throws JsonProcessingException, UnsupportedEncodingException { - - ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() - .modulesToInstall(new CustomIntegerModule()) - .build(); - DateTime dateTime = new DateTime(1322903730000L, DateTimeZone.UTC); - assertThat(new String(objectMapper.writeValueAsBytes(dateTime), "UTF-8")).isEqualTo("1322903730000"); - assertThat(new String(objectMapper.writeValueAsBytes(4), "UTF-8")).contains("customid"); - } - - @Test // SPR-12634 - void customizeWellKnownModulesWithModuleClass() - throws JsonProcessingException, UnsupportedEncodingException { - - ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() - .modulesToInstall(CustomIntegerModule.class) - .build(); - DateTime dateTime = new DateTime(1322903730000L, DateTimeZone.UTC); - assertThat(new String(objectMapper.writeValueAsBytes(dateTime), "UTF-8")).isEqualTo("1322903730000"); - assertThat(new String(objectMapper.writeValueAsBytes(4), "UTF-8")).contains("customid"); - } - - @Test // SPR-12634 - void customizeWellKnownModulesWithSerializer() - throws JsonProcessingException, UnsupportedEncodingException { - - ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() - .serializerByType(Integer.class, new CustomIntegerSerializer()).build(); - DateTime dateTime = new DateTime(1322903730000L, DateTimeZone.UTC); - assertThat(new String(objectMapper.writeValueAsBytes(dateTime), "UTF-8")).isEqualTo("1322903730000"); - assertThat(new String(objectMapper.writeValueAsBytes(4), "UTF-8")).contains("customid"); - } - @Test // gh-22576 void overrideWellKnownModuleWithModule() throws IOException { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBeanTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBeanTests.java index 716abf906f06..d7a49c18eeb9 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBeanTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package org.springframework.http.converter.json; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; @@ -58,8 +57,6 @@ import com.fasterxml.jackson.databind.type.SimpleType; import com.fasterxml.jackson.dataformat.smile.SmileFactory; import com.fasterxml.jackson.dataformat.xml.XmlMapper; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.junit.jupiter.api.Test; import org.springframework.beans.FatalBeanException; @@ -202,41 +199,6 @@ public void setModules() { assertThat(serializers.findSerializer(null, SimpleType.construct(Integer.class), null)).isSameAs(serializer); } - @Test - public void defaultModules() throws JsonProcessingException, UnsupportedEncodingException { - this.factory.afterPropertiesSet(); - ObjectMapper objectMapper = this.factory.getObject(); - - Long timestamp = 1322903730000L; - DateTime dateTime = new DateTime(timestamp, DateTimeZone.UTC); - assertThat(new String(objectMapper.writeValueAsBytes(dateTime), "UTF-8")).isEqualTo(timestamp.toString()); - } - - @Test // SPR-12634 - public void customizeDefaultModulesWithModuleClass() throws JsonProcessingException, UnsupportedEncodingException { - this.factory.setModulesToInstall(CustomIntegerModule.class); - this.factory.afterPropertiesSet(); - ObjectMapper objectMapper = this.factory.getObject(); - - DateTime dateTime = new DateTime(1322903730000L, DateTimeZone.UTC); - assertThat(new String(objectMapper.writeValueAsBytes(dateTime), "UTF-8")).isEqualTo("1322903730000"); - assertThat(new String(objectMapper.writeValueAsBytes(4), "UTF-8")).contains("customid"); - } - - @Test // SPR-12634 - public void customizeDefaultModulesWithSerializer() throws JsonProcessingException, UnsupportedEncodingException { - Map, JsonSerializer> serializers = new HashMap<>(); - serializers.put(Integer.class, new CustomIntegerSerializer()); - - this.factory.setSerializersByType(serializers); - this.factory.afterPropertiesSet(); - ObjectMapper objectMapper = this.factory.getObject(); - - DateTime dateTime = new DateTime(1322903730000L, DateTimeZone.UTC); - assertThat(new String(objectMapper.writeValueAsBytes(dateTime), "UTF-8")).isEqualTo("1322903730000"); - assertThat(new String(objectMapper.writeValueAsBytes(4), "UTF-8")).contains("customid"); - } - @Test public void simpleSetup() { this.factory.afterPropertiesSet(); From 3c8724ba3d0375e4a50354c15383972fee788e9c Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 17 Sep 2021 08:58:52 +0200 Subject: [PATCH 107/735] Remove JiBX support Closes gh-27425 --- .../JibxMarshallerBeanDefinitionParser.java | 38 -- .../oxm/config/OxmNamespaceHandler.java | 4 +- .../oxm/jibx/JibxMarshaller.java | 502 ------------------ .../oxm/jibx/package-info.java | 10 - .../springframework/oxm/jibx/FlightType.java | 40 -- .../org/springframework/oxm/jibx/Flights.java | 36 -- .../oxm/jibx/JibxMarshallerTests.java | 105 ---- .../oxm/jibx/JibxUnmarshallerTests.java | 90 ---- 8 files changed, 1 insertion(+), 824 deletions(-) delete mode 100644 spring-oxm/src/main/java/org/springframework/oxm/config/JibxMarshallerBeanDefinitionParser.java delete mode 100644 spring-oxm/src/main/java/org/springframework/oxm/jibx/JibxMarshaller.java delete mode 100644 spring-oxm/src/main/java/org/springframework/oxm/jibx/package-info.java delete mode 100644 spring-oxm/src/test/java/org/springframework/oxm/jibx/FlightType.java delete mode 100644 spring-oxm/src/test/java/org/springframework/oxm/jibx/Flights.java delete mode 100644 spring-oxm/src/test/java/org/springframework/oxm/jibx/JibxMarshallerTests.java delete mode 100644 spring-oxm/src/test/java/org/springframework/oxm/jibx/JibxUnmarshallerTests.java diff --git a/spring-oxm/src/main/java/org/springframework/oxm/config/JibxMarshallerBeanDefinitionParser.java b/spring-oxm/src/main/java/org/springframework/oxm/config/JibxMarshallerBeanDefinitionParser.java deleted file mode 100644 index c14452eb56fc..000000000000 --- a/spring-oxm/src/main/java/org/springframework/oxm/config/JibxMarshallerBeanDefinitionParser.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.oxm.config; - -import org.w3c.dom.Element; - -import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser; - -/** - * Parser for the {@code } element. - * - * @author Arjen Poutsma - * @since 3.0 - * @deprecated as of Spring Framework 5.1.5, due to the lack of activity on the JiBX project - */ -@Deprecated -class JibxMarshallerBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser { - - @Override - protected String getBeanClassName(Element element) { - return "org.springframework.oxm.jibx.JibxMarshaller"; - } - -} diff --git a/spring-oxm/src/main/java/org/springframework/oxm/config/OxmNamespaceHandler.java b/spring-oxm/src/main/java/org/springframework/oxm/config/OxmNamespaceHandler.java index ecb7b64012ef..c57540c4edde 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/config/OxmNamespaceHandler.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/config/OxmNamespaceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,10 +28,8 @@ public class OxmNamespaceHandler extends NamespaceHandlerSupport { @Override - @SuppressWarnings("deprecation") public void init() { registerBeanDefinitionParser("jaxb2-marshaller", new Jaxb2MarshallerBeanDefinitionParser()); - registerBeanDefinitionParser("jibx-marshaller", new JibxMarshallerBeanDefinitionParser()); } } diff --git a/spring-oxm/src/main/java/org/springframework/oxm/jibx/JibxMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/jibx/JibxMarshaller.java deleted file mode 100644 index 174c973c6377..000000000000 --- a/spring-oxm/src/main/java/org/springframework/oxm/jibx/JibxMarshaller.java +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.oxm.jibx; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.Writer; - -import javax.xml.stream.XMLEventReader; -import javax.xml.stream.XMLEventWriter; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; -import javax.xml.stream.XMLStreamWriter; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMResult; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.sax.SAXSource; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; - -import org.jibx.runtime.BindingDirectory; -import org.jibx.runtime.IBindingFactory; -import org.jibx.runtime.IMarshallingContext; -import org.jibx.runtime.IUnmarshallingContext; -import org.jibx.runtime.IXMLReader; -import org.jibx.runtime.IXMLWriter; -import org.jibx.runtime.JiBXException; -import org.jibx.runtime.ValidationException; -import org.jibx.runtime.impl.MarshallingContext; -import org.jibx.runtime.impl.StAXReaderWrapper; -import org.jibx.runtime.impl.StAXWriter; -import org.jibx.runtime.impl.UnmarshallingContext; -import org.w3c.dom.Node; -import org.xml.sax.ContentHandler; -import org.xml.sax.InputSource; -import org.xml.sax.XMLReader; -import org.xml.sax.ext.LexicalHandler; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; -import org.springframework.oxm.MarshallingFailureException; -import org.springframework.oxm.UnmarshallingFailureException; -import org.springframework.oxm.ValidationFailureException; -import org.springframework.oxm.XmlMappingException; -import org.springframework.oxm.support.AbstractMarshaller; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; -import org.springframework.util.xml.StaxUtils; - -/** - * Implementation of the {@code Marshaller} and {@code Unmarshaller} interfaces for JiBX. - * - *

    The typical usage will be to set the {@code targetClass} and optionally the - * {@code bindingName} property on this bean. - * - * @author Arjen Poutsma - * @since 3.0 - * @see org.jibx.runtime.IMarshallingContext - * @see org.jibx.runtime.IUnmarshallingContext - * @deprecated as of Spring Framework 5.1.5, due to the lack of activity on the JiBX project - */ -@Deprecated -public class JibxMarshaller extends AbstractMarshaller implements InitializingBean { - - private static final String DEFAULT_BINDING_NAME = "binding"; - - - @Nullable - private Class targetClass; - - @Nullable - private String targetPackage; - - @Nullable - private String bindingName; - - private int indent = -1; - - private String encoding = "UTF-8"; - - @Nullable - private Boolean standalone; - - @Nullable - private String docTypeRootElementName; - - @Nullable - private String docTypeSystemId; - - @Nullable - private String docTypePublicId; - - @Nullable - private String docTypeInternalSubset; - - @Nullable - private IBindingFactory bindingFactory; - - private final TransformerFactory transformerFactory = TransformerFactory.newInstance(); - - - /** - * Set the target class for this instance. Setting either this property or the - * {@link #setTargetPackage(String) targetPackage} property is required. - *

    If this property is set, {@link #setTargetPackage(String) targetPackage} is ignored. - */ - public void setTargetClass(Class targetClass) { - this.targetClass = targetClass; - } - - /** - * Set the target package for this instance. Setting either this property or the - * {@link #setTargetClass(Class) targetClass} property is required. - *

    If {@link #setTargetClass(Class) targetClass} is set, this property is ignored. - */ - public void setTargetPackage(String targetPackage) { - this.targetPackage = targetPackage; - } - - /** - * Set the optional binding name for this instance. - */ - public void setBindingName(String bindingName) { - this.bindingName = bindingName; - } - - /** - * Set the number of nesting indent spaces. Default is {@code -1}, i.e. no indentation. - */ - public void setIndent(int indent) { - this.indent = indent; - } - - /** - * Set the document encoding using for marshalling. Default is UTF-8. - */ - public void setEncoding(String encoding) { - this.encoding = encoding; - } - - @Override - protected String getDefaultEncoding() { - return this.encoding; - } - - /** - * Set the document standalone flag for marshalling. By default, this flag is not present. - */ - public void setStandalone(Boolean standalone) { - this.standalone = standalone; - } - - /** - * Set the root element name for the DTD declaration written when marshalling. - * By default, this is {@code null} (i.e. no DTD declaration is written). - *

    If set to a value, the system ID or public ID also need to be set. - * @see #setDocTypeSystemId(String) - * @see #setDocTypePublicId(String) - */ - public void setDocTypeRootElementName(String docTypeRootElementName) { - this.docTypeRootElementName = docTypeRootElementName; - } - - /** - * Set the system id for the DTD declaration written when marshalling. - * By default, this is {@code null}. Only used when the root element also has been set. - *

    Set either this property or {@code docTypePublicId}, not both. - * @see #setDocTypeRootElementName(String) - */ - public void setDocTypeSystemId(String docTypeSystemId) { - this.docTypeSystemId = docTypeSystemId; - } - - /** - * Set the public id for the DTD declaration written when marshalling. - * By default, this is {@code null}. Only used when the root element also has been set. - *

    Set either this property or {@code docTypeSystemId}, not both. - * @see #setDocTypeRootElementName(String) - */ - public void setDocTypePublicId(String docTypePublicId) { - this.docTypePublicId = docTypePublicId; - } - - /** - * Set the internal subset Id for the DTD declaration written when marshalling. - * By default, this is {@code null}. Only used when the root element also has been set. - * @see #setDocTypeRootElementName(String) - */ - public void setDocTypeInternalSubset(String docTypeInternalSubset) { - this.docTypeInternalSubset = docTypeInternalSubset; - } - - - @Override - public void afterPropertiesSet() throws JiBXException { - if (this.targetClass != null) { - if (StringUtils.hasLength(this.bindingName)) { - if (logger.isDebugEnabled()) { - logger.debug("Configured for target class [" + this.targetClass + - "] using binding [" + this.bindingName + "]"); - } - this.bindingFactory = BindingDirectory.getFactory(this.bindingName, this.targetClass); - } - else { - if (logger.isDebugEnabled()) { - logger.debug("Configured for target class [" + this.targetClass + "]"); - } - this.bindingFactory = BindingDirectory.getFactory(this.targetClass); - } - } - else if (this.targetPackage != null) { - if (!StringUtils.hasLength(this.bindingName)) { - this.bindingName = DEFAULT_BINDING_NAME; - } - if (logger.isDebugEnabled()) { - logger.debug("Configured for target package [" + this.targetPackage + - "] using binding [" + this.bindingName + "]"); - } - this.bindingFactory = BindingDirectory.getFactory(this.bindingName, this.targetPackage); - } - else { - throw new IllegalArgumentException("Either 'targetClass' or 'targetPackage' is required"); - } - } - - - @Override - public boolean supports(Class clazz) { - Assert.notNull(clazz, "Class must not be null"); - if (this.targetClass != null) { - return (this.targetClass == clazz); - } - Assert.state(this.bindingFactory != null, "JibxMarshaller not initialized"); - String[] mappedClasses = this.bindingFactory.getMappedClasses(); - String className = clazz.getName(); - for (String mappedClass : mappedClasses) { - if (className.equals(mappedClass)) { - return true; - } - } - return false; - } - - - // Supported marshalling - - @Override - protected void marshalOutputStream(Object graph, OutputStream outputStream) - throws XmlMappingException, IOException { - try { - IMarshallingContext marshallingContext = createMarshallingContext(); - marshallingContext.startDocument(this.encoding, this.standalone, outputStream); - marshalDocument(marshallingContext, graph); - } - catch (JiBXException ex) { - throw convertJibxException(ex, true); - } - } - - @Override - protected void marshalWriter(Object graph, Writer writer) throws XmlMappingException, IOException { - try { - IMarshallingContext marshallingContext = createMarshallingContext(); - marshallingContext.startDocument(this.encoding, this.standalone, writer); - marshalDocument(marshallingContext, graph); - } - catch (JiBXException ex) { - throw convertJibxException(ex, true); - } - } - - private void marshalDocument(IMarshallingContext marshallingContext, Object graph) throws IOException, JiBXException { - if (StringUtils.hasLength(this.docTypeRootElementName)) { - IXMLWriter xmlWriter = marshallingContext.getXmlWriter(); - xmlWriter.writeDocType(this.docTypeRootElementName, this.docTypeSystemId, - this.docTypePublicId, this.docTypeInternalSubset); - } - marshallingContext.marshalDocument(graph); - } - - - // Unsupported marshalling - - @Override - protected void marshalDomNode(Object graph, Node node) throws XmlMappingException { - try { - // JiBX does not support DOM natively, so we write to a buffer first, and transform that to the Node - Result result = new DOMResult(node); - transformAndMarshal(graph, result); - } - catch (IOException ex) { - throw new MarshallingFailureException("JiBX marshalling exception", ex); - } - } - - @Override - protected void marshalXmlEventWriter(Object graph, XMLEventWriter eventWriter) { - XMLStreamWriter streamWriter = StaxUtils.createEventStreamWriter(eventWriter); - marshalXmlStreamWriter(graph, streamWriter); - } - - @Override - protected void marshalXmlStreamWriter(Object graph, XMLStreamWriter streamWriter) throws XmlMappingException { - try { - MarshallingContext marshallingContext = (MarshallingContext) createMarshallingContext(); - IXMLWriter xmlWriter = new StAXWriter(marshallingContext.getNamespaces(), streamWriter); - marshallingContext.setXmlWriter(xmlWriter); - marshallingContext.marshalDocument(graph); - } - catch (JiBXException ex) { - throw convertJibxException(ex, false); - } - } - - @Override - protected void marshalSaxHandlers(Object graph, ContentHandler contentHandler, @Nullable LexicalHandler lexicalHandler) - throws XmlMappingException { - try { - // JiBX does not support SAX natively, so we write to a buffer first, and transform that to the handlers - SAXResult saxResult = new SAXResult(contentHandler); - saxResult.setLexicalHandler(lexicalHandler); - transformAndMarshal(graph, saxResult); - } - catch (IOException ex) { - throw new MarshallingFailureException("JiBX marshalling exception", ex); - } - } - - private void transformAndMarshal(Object graph, Result result) throws IOException { - try { - ByteArrayOutputStream os = new ByteArrayOutputStream(1024); - marshalOutputStream(graph, os); - ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); - Transformer transformer = this.transformerFactory.newTransformer(); - transformer.transform(new StreamSource(is), result); - } - catch (TransformerException ex) { - throw new MarshallingFailureException( - "Could not transform to [" + ClassUtils.getShortName(result.getClass()) + "]", ex); - } - - } - - - // Unmarshalling - - @Override - protected Object unmarshalXmlEventReader(XMLEventReader eventReader) { - try { - XMLStreamReader streamReader = StaxUtils.createEventStreamReader(eventReader); - return unmarshalXmlStreamReader(streamReader); - } - catch (XMLStreamException ex) { - return new UnmarshallingFailureException("JiBX unmarshalling exception", ex); - } - } - - @Override - protected Object unmarshalXmlStreamReader(XMLStreamReader streamReader) { - try { - UnmarshallingContext unmarshallingContext = (UnmarshallingContext) createUnmarshallingContext(); - IXMLReader xmlReader = new StAXReaderWrapper(streamReader, null, true); - unmarshallingContext.setDocument(xmlReader); - return unmarshallingContext.unmarshalElement(); - } - catch (JiBXException ex) { - throw convertJibxException(ex, false); - } - } - - @Override - protected Object unmarshalInputStream(InputStream inputStream) throws XmlMappingException, IOException { - try { - IUnmarshallingContext unmarshallingContext = createUnmarshallingContext(); - return unmarshallingContext.unmarshalDocument(inputStream, this.encoding); - } - catch (JiBXException ex) { - throw convertJibxException(ex, false); - } - } - - @Override - protected Object unmarshalReader(Reader reader) throws XmlMappingException, IOException { - try { - IUnmarshallingContext unmarshallingContext = createUnmarshallingContext(); - return unmarshallingContext.unmarshalDocument(reader); - } - catch (JiBXException ex) { - throw convertJibxException(ex, false); - } - } - - - // Unsupported Unmarshalling - - @Override - protected Object unmarshalDomNode(Node node) throws XmlMappingException { - try { - return transformAndUnmarshal(new DOMSource(node), null); - } - catch (IOException ex) { - throw new UnmarshallingFailureException("JiBX unmarshalling exception", ex); - } - } - - @Override - protected Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource) - throws XmlMappingException, IOException { - - return transformAndUnmarshal(new SAXSource(xmlReader, inputSource), inputSource.getEncoding()); - } - - private Object transformAndUnmarshal(Source source, @Nullable String encoding) throws IOException { - try { - Transformer transformer = this.transformerFactory.newTransformer(); - if (encoding != null) { - transformer.setOutputProperty(OutputKeys.ENCODING, encoding); - } - ByteArrayOutputStream os = new ByteArrayOutputStream(1024); - transformer.transform(source, new StreamResult(os)); - ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); - return unmarshalInputStream(is); - } - catch (TransformerException ex) { - throw new MarshallingFailureException( - "Could not transform from [" + ClassUtils.getShortName(source.getClass()) + "]", ex); - } - } - - - /** - * Create a new {@code IMarshallingContext}, configured with the correct indentation. - * @return the created marshalling context - * @throws JiBXException in case of errors - */ - protected IMarshallingContext createMarshallingContext() throws JiBXException { - Assert.state(this.bindingFactory != null, "JibxMarshaller not initialized"); - IMarshallingContext marshallingContext = this.bindingFactory.createMarshallingContext(); - marshallingContext.setIndent(this.indent); - return marshallingContext; - } - - /** - * Create a new {@code IUnmarshallingContext}. - * @return the created unmarshalling context - * @throws JiBXException in case of errors - */ - protected IUnmarshallingContext createUnmarshallingContext() throws JiBXException { - Assert.state(this.bindingFactory != null, "JibxMarshaller not initialized"); - return this.bindingFactory.createUnmarshallingContext(); - } - - /** - * Convert the given {@code JiBXException} to an appropriate exception from the - * {@code org.springframework.oxm} hierarchy. - *

    A boolean flag is used to indicate whether this exception occurs during marshalling or - * unmarshalling, since JiBX itself does not make this distinction in its exception hierarchy. - * @param ex {@code JiBXException} that occurred - * @param marshalling indicates whether the exception occurs during marshalling ({@code true}), - * or unmarshalling ({@code false}) - * @return the corresponding {@code XmlMappingException} - */ - public XmlMappingException convertJibxException(JiBXException ex, boolean marshalling) { - if (ex instanceof ValidationException) { - return new ValidationFailureException("JiBX validation exception", ex); - } - else { - if (marshalling) { - return new MarshallingFailureException("JiBX marshalling exception", ex); - } - else { - return new UnmarshallingFailureException("JiBX unmarshalling exception", ex); - } - } - } - -} diff --git a/spring-oxm/src/main/java/org/springframework/oxm/jibx/package-info.java b/spring-oxm/src/main/java/org/springframework/oxm/jibx/package-info.java deleted file mode 100644 index 8f6b47b98ce5..000000000000 --- a/spring-oxm/src/main/java/org/springframework/oxm/jibx/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Package providing integration of JiBX - * with Spring's O/X Mapping support. - */ -@NonNullApi -@NonNullFields -package org.springframework.oxm.jibx; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jibx/FlightType.java b/spring-oxm/src/test/java/org/springframework/oxm/jibx/FlightType.java deleted file mode 100644 index d47f26ab78cc..000000000000 --- a/spring-oxm/src/test/java/org/springframework/oxm/jibx/FlightType.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2006-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.oxm.jibx; - -public class FlightType { - - protected String airline; - - protected long number; - - public String getAirline() { - return this.airline; - } - - public void setAirline(String airline) { - this.airline = airline; - } - - public long getNumber() { - return this.number; - } - - public void setNumber(long number) { - this.number = number; - } -} diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jibx/Flights.java b/spring-oxm/src/test/java/org/springframework/oxm/jibx/Flights.java deleted file mode 100644 index e50359bade48..000000000000 --- a/spring-oxm/src/test/java/org/springframework/oxm/jibx/Flights.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.oxm.jibx; - -import java.util.ArrayList; - -public class Flights { - - protected ArrayList flightList = new ArrayList<>(); - - public void addFlight(FlightType flight) { - flightList.add(flight); - } - - public FlightType getFlight(int index) { - return flightList.get(index); - } - - public int sizeFlightList() { - return flightList.size(); - } -} diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jibx/JibxMarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/jibx/JibxMarshallerTests.java deleted file mode 100644 index 6ed3d7102d5c..000000000000 --- a/spring-oxm/src/test/java/org/springframework/oxm/jibx/JibxMarshallerTests.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.oxm.jibx; - -import java.io.StringWriter; - -import javax.xml.transform.stream.StreamResult; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledOnJre; - -import org.springframework.core.testfixture.xml.XmlContent; -import org.springframework.oxm.AbstractMarshallerTests; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.junit.jupiter.api.condition.JRE.JAVA_8; - -/** - * NOTE: These tests fail under Eclipse/IDEA because JiBX binding does not occur by - * default. The Gradle build should succeed, however. - * - * @author Arjen Poutsma - * @author Sam Brannen - */ -@Deprecated -@EnabledOnJre(JAVA_8) // JiBX compiler is currently not compatible with JDK 9 -public class JibxMarshallerTests extends AbstractMarshallerTests { - - @Override - protected JibxMarshaller createMarshaller() throws Exception { - JibxMarshaller marshaller = new JibxMarshaller(); - marshaller.setTargetPackage("org.springframework.oxm.jibx"); - marshaller.afterPropertiesSet(); - return marshaller; - } - - @Override - protected Object createFlights() { - Flights flights = new Flights(); - FlightType flight = new FlightType(); - flight.setNumber(42L); - flights.addFlight(flight); - return flights; - } - - - @Test - public void afterPropertiesSetNoContextPath() throws Exception { - JibxMarshaller marshaller = new JibxMarshaller(); - assertThatIllegalArgumentException().isThrownBy( - marshaller::afterPropertiesSet); - } - - @Test - public void indentation() throws Exception { - marshaller.setIndent(4); - StringWriter writer = new StringWriter(); - marshaller.marshal(flights, new StreamResult(writer)); - String expected = - "\n" + "\n" + - " \n" + " 42\n" + " \n" + ""; - assertThat(XmlContent.from(writer)).isSimilarToIgnoringWhitespace(expected); - } - - @Test - public void encodingAndStandalone() throws Exception { - marshaller.setEncoding("ISO-8859-1"); - marshaller.setStandalone(Boolean.TRUE); - StringWriter writer = new StringWriter(); - marshaller.marshal(flights, new StreamResult(writer)); - assertThat(writer.toString().startsWith("")).as("Encoding and standalone not set").isTrue(); - } - - @Test - public void dtd() throws Exception { - marshaller.setDocTypeRootElementName("flights"); - marshaller.setDocTypeSystemId("flights.dtd"); - StringWriter writer = new StringWriter(); - marshaller.marshal(flights, new StreamResult(writer)); - assertThat(writer.toString().contains("")).as("doc type not written").isTrue(); - } - - @Test - public void supports() throws Exception { - assertThat(marshaller.supports(Flights.class)).as("JibxMarshaller does not support Flights").isTrue(); - assertThat(marshaller.supports(FlightType.class)).as("JibxMarshaller does not support FlightType").isTrue(); - assertThat(marshaller.supports(getClass())).as("JibxMarshaller supports illegal type").isFalse(); - } - -} diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jibx/JibxUnmarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/jibx/JibxUnmarshallerTests.java deleted file mode 100644 index 0dcf21172551..000000000000 --- a/spring-oxm/src/test/java/org/springframework/oxm/jibx/JibxUnmarshallerTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.oxm.jibx; - -import java.io.ByteArrayInputStream; - -import javax.xml.transform.stream.StreamSource; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledOnJre; - -import org.springframework.oxm.AbstractUnmarshallerTests; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.condition.JRE.JAVA_8; - -/** - * NOTE: These tests fail under Eclipse/IDEA because JiBX binding does - * not occur by default. The Gradle build should succeed, however. - * - * @author Arjen Poutsma - * @author Sam Brannen - */ -@Deprecated -@EnabledOnJre(JAVA_8) // JiBX compiler is currently not compatible with JDK 9 -public class JibxUnmarshallerTests extends AbstractUnmarshallerTests { - - protected static final String INPUT_STRING_WITH_SPECIAL_CHARACTERS = - "" + - "Air Libert\u00e942"; - - - @Override - protected JibxMarshaller createUnmarshaller() throws Exception { - JibxMarshaller unmarshaller = new JibxMarshaller(); - unmarshaller.setTargetClass(Flights.class); - unmarshaller.afterPropertiesSet(); - return unmarshaller; - } - - @Override - protected void testFlights(Object o) { - Flights flights = (Flights) o; - assertThat(flights).as("Flights is null").isNotNull(); - assertThat(flights.sizeFlightList()).as("Invalid amount of flight elements").isEqualTo(1); - testFlight(flights.getFlight(0)); - } - - @Override - protected void testFlight(Object o) { - FlightType flight = (FlightType) o; - assertThat(flight).as("Flight is null").isNotNull(); - assertThat(flight.getNumber()).as("Number is invalid").isEqualTo(42L); - } - - - @Test - @Override - public void unmarshalPartialStaxSourceXmlStreamReader() throws Exception { - // JiBX does not support reading XML fragments, hence the override here - } - - @Test - public void unmarshalStreamSourceInputStreamUsingNonDefaultEncoding() throws Exception { - String encoding = "ISO-8859-1"; - unmarshaller.setEncoding(encoding); - - StreamSource source = new StreamSource(new ByteArrayInputStream(INPUT_STRING_WITH_SPECIAL_CHARACTERS.getBytes(encoding))); - Object flights = unmarshaller.unmarshal(source); - testFlights(flights); - - FlightType flight = ((Flights)flights).getFlight(0); - assertThat(flight.getAirline()).as("Airline is invalid").isEqualTo("Air Libert\u00e9"); - } - -} From 5822f1bf85b94fd15f9829914b065b1c61910c7d Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 17 Sep 2021 08:59:58 +0200 Subject: [PATCH 108/735] Drop RPC-style remoting Closes gh-27422 --- .../remoting/RemoteAccessException.java | 73 --- .../RemoteConnectFailureException.java | 38 -- .../RemoteInvocationFailureException.java | 40 -- .../RemoteLookupFailureException.java | 46 -- .../remoting/RemoteProxyFailureException.java | 40 -- .../remoting/RemoteTimeoutException.java | 45 -- .../remoting/package-info.java | 10 - .../rmi/CodebaseAwareObjectInputStream.java | 122 ---- .../rmi/JndiRmiClientInterceptor.java | 452 -------------- .../remoting/rmi/JndiRmiProxyFactoryBean.java | 104 ---- .../remoting/rmi/JndiRmiServiceExporter.java | 194 ------ .../RemoteInvocationSerializingExporter.java | 183 ------ .../remoting/rmi/RmiBasedExporter.java | 78 --- .../remoting/rmi/RmiClientInterceptor.java | 424 ------------- .../rmi/RmiClientInterceptorUtils.java | 176 ------ .../remoting/rmi/RmiInvocationHandler.java | 64 -- .../remoting/rmi/RmiInvocationWrapper.java | 81 --- .../remoting/rmi/RmiProxyFactoryBean.java | 92 --- .../remoting/rmi/RmiRegistryFactoryBean.java | 317 ---------- .../remoting/rmi/RmiServiceExporter.java | 464 --------------- .../remoting/rmi/package-info.java | 6 - .../remoting/soap/SoapFaultException.java | 65 -- .../remoting/soap/package-info.java | 4 - .../DefaultRemoteInvocationExecutor.java | 42 -- .../DefaultRemoteInvocationFactory.java | 35 -- .../remoting/support/RemoteAccessor.java | 63 -- .../remoting/support/RemoteExporter.java | 186 ------ .../remoting/support/RemoteInvocation.java | 225 ------- .../RemoteInvocationBasedAccessor.java | 91 --- .../RemoteInvocationBasedExporter.java | 122 ---- .../support/RemoteInvocationExecutor.java | 49 -- .../support/RemoteInvocationFactory.java | 46 -- .../support/RemoteInvocationResult.java | 164 ----- .../RemoteInvocationTraceInterceptor.java | 104 ---- .../support/RemoteInvocationUtils.java | 60 -- .../remoting/support/RemotingSupport.java | 77 --- .../support/SimpleHttpServerFactoryBean.java | 194 ------ .../support/UrlBasedRemoteAccessor.java | 56 -- .../remoting/support/package-info.java | 5 - .../remoting/rmi/RmiSupportTests.java | 445 -------------- .../support/RemoteInvocationUtilsTests.java | 46 -- .../remoting/JmsInvokerClientInterceptor.java | 437 -------------- .../remoting/JmsInvokerProxyFactoryBean.java | 101 ---- .../remoting/JmsInvokerServiceExporter.java | 199 ------- .../jms/remoting/package-info.java | 13 - .../jms/remoting/JmsInvokerTests.java | 511 ---------------- .../caucho/HessianClientInterceptor.java | 302 ---------- .../remoting/caucho/HessianExporter.java | 254 -------- .../caucho/HessianProxyFactoryBean.java | 75 --- .../caucho/HessianServiceExporter.java | 73 --- .../caucho/SimpleHessianServiceExporter.java | 77 --- .../remoting/caucho/package-info.java | 15 - .../AbstractHttpInvokerRequestExecutor.java | 295 --------- ...pComponentsHttpInvokerRequestExecutor.java | 370 ------------ .../HttpInvokerClientConfiguration.java | 47 -- .../HttpInvokerClientInterceptor.java | 241 -------- .../HttpInvokerProxyFactoryBean.java | 90 --- .../HttpInvokerRequestExecutor.java | 62 -- .../HttpInvokerServiceExporter.java | 215 ------- .../SimpleHttpInvokerRequestExecutor.java | 233 -------- .../SimpleHttpInvokerServiceExporter.java | 182 ------ .../remoting/httpinvoker/package-info.java | 16 - .../jaxws/AbstractJaxWsServiceExporter.java | 214 ------- .../jaxws/JaxWsPortClientInterceptor.java | 561 ------------------ .../jaxws/JaxWsPortProxyFactoryBean.java | 74 --- .../jaxws/JaxWsSoapFaultException.java | 71 --- .../jaxws/LocalJaxWsServiceFactory.java | 192 ------ .../jaxws/LocalJaxWsServiceFactoryBean.java | 67 --- .../SimpleHttpServerJaxWsServiceExporter.java | 228 ------- .../jaxws/SimpleJaxWsServiceExporter.java | 89 --- .../remoting/jaxws/package-info.java | 11 - .../remoting/caucho/CauchoRemotingTests.java | 163 ----- ...onentsHttpInvokerRequestExecutorTests.java | 169 ------ ...ttpInvokerFactoryBeanIntegrationTests.java | 145 ----- .../httpinvoker/HttpInvokerTests.java | 453 -------------- .../remoting/jaxws/JaxWsSupportTests.java | 161 ----- .../jaxws/OrderNotFoundException.java | 44 -- .../remoting/jaxws/OrderService.java | 31 - .../remoting/jaxws/OrderServiceImpl.java | 44 -- 79 files changed, 11653 deletions(-) delete mode 100644 spring-context/src/main/java/org/springframework/remoting/RemoteAccessException.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/RemoteConnectFailureException.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/RemoteInvocationFailureException.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/RemoteLookupFailureException.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/RemoteProxyFailureException.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/RemoteTimeoutException.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/package-info.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/CodebaseAwareObjectInputStream.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiClientInterceptor.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiProxyFactoryBean.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiServiceExporter.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/RemoteInvocationSerializingExporter.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/RmiBasedExporter.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptor.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptorUtils.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationHandler.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationWrapper.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/RmiProxyFactoryBean.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/RmiRegistryFactoryBean.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/RmiServiceExporter.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/rmi/package-info.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/soap/SoapFaultException.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/soap/package-info.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationExecutor.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationFactory.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/RemoteAccessor.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/RemoteExporter.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocation.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedAccessor.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedExporter.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationExecutor.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationFactory.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationResult.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationTraceInterceptor.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationUtils.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/RemotingSupport.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/SimpleHttpServerFactoryBean.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/UrlBasedRemoteAccessor.java delete mode 100644 spring-context/src/main/java/org/springframework/remoting/support/package-info.java delete mode 100644 spring-context/src/test/java/org/springframework/remoting/rmi/RmiSupportTests.java delete mode 100644 spring-context/src/test/java/org/springframework/remoting/support/RemoteInvocationUtilsTests.java delete mode 100644 spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerClientInterceptor.java delete mode 100644 spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerProxyFactoryBean.java delete mode 100644 spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerServiceExporter.java delete mode 100644 spring-jms/src/main/java/org/springframework/jms/remoting/package-info.java delete mode 100644 spring-jms/src/test/java/org/springframework/jms/remoting/JmsInvokerTests.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/caucho/HessianClientInterceptor.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/caucho/HessianExporter.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/caucho/HessianProxyFactoryBean.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/caucho/HessianServiceExporter.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/caucho/SimpleHessianServiceExporter.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/caucho/package-info.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutor.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientConfiguration.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientInterceptor.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerRequestExecutor.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerRequestExecutor.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerServiceExporter.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/httpinvoker/package-info.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/jaxws/AbstractJaxWsServiceExporter.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortClientInterceptor.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortProxyFactoryBean.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsSoapFaultException.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactory.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactoryBean.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleHttpServerJaxWsServiceExporter.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleJaxWsServiceExporter.java delete mode 100644 spring-web/src/main/java/org/springframework/remoting/jaxws/package-info.java delete mode 100644 spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java delete mode 100644 spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutorTests.java delete mode 100644 spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerFactoryBeanIntegrationTests.java delete mode 100644 spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerTests.java delete mode 100644 spring-web/src/test/java/org/springframework/remoting/jaxws/JaxWsSupportTests.java delete mode 100644 spring-web/src/test/java/org/springframework/remoting/jaxws/OrderNotFoundException.java delete mode 100644 spring-web/src/test/java/org/springframework/remoting/jaxws/OrderService.java delete mode 100644 spring-web/src/test/java/org/springframework/remoting/jaxws/OrderServiceImpl.java diff --git a/spring-context/src/main/java/org/springframework/remoting/RemoteAccessException.java b/spring-context/src/main/java/org/springframework/remoting/RemoteAccessException.java deleted file mode 100644 index 0d6cde82e519..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/RemoteAccessException.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting; - -import org.springframework.core.NestedRuntimeException; - -/** - * Generic remote access exception. A service proxy for any remoting - * protocol should throw this exception or subclasses of it, in order - * to transparently expose a plain Java business interface. - * - *

    When using conforming proxies, switching the actual remoting protocol - * e.g. from Hessian does not affect client code. Clients work with a plain - * natural Java business interface that the service exposes. A client object - * simply receives an implementation for the interface that it needs via a - * bean reference, like it does for a local bean as well. - * - *

    A client may catch RemoteAccessException if it wants to, but as - * remote access errors are typically unrecoverable, it will probably let - * such exceptions propagate to a higher level that handles them generically. - * In this case, the client code doesn't show any signs of being involved in - * remote access, as there aren't any remoting-specific dependencies. - * - *

    Even when switching from a remote service proxy to a local implementation - * of the same interface, this amounts to just a matter of configuration. Obviously, - * the client code should be somewhat aware that it might be working - * against a remote service, for example in terms of repeated method calls that - * cause unnecessary roundtrips etc. However, it doesn't have to be aware whether - * it is actually working against a remote service or a local implementation, - * or with which remoting protocol it is working under the hood. - * - * @author Juergen Hoeller - * @since 14.05.2003 - */ -public class RemoteAccessException extends NestedRuntimeException { - - /** Use serialVersionUID from Spring 1.2 for interoperability. */ - private static final long serialVersionUID = -4906825139312227864L; - - - /** - * Constructor for RemoteAccessException. - * @param msg the detail message - */ - public RemoteAccessException(String msg) { - super(msg); - } - - /** - * Constructor for RemoteAccessException. - * @param msg the detail message - * @param cause the root cause (usually from using an underlying - * remoting API such as RMI) - */ - public RemoteAccessException(String msg, Throwable cause) { - super(msg, cause); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/RemoteConnectFailureException.java b/spring-context/src/main/java/org/springframework/remoting/RemoteConnectFailureException.java deleted file mode 100644 index 99857c3694ec..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/RemoteConnectFailureException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting; - -/** - * RemoteAccessException subclass to be thrown when no connection - * could be established with a remote service. - * - * @author Juergen Hoeller - * @since 1.1 - */ -@SuppressWarnings("serial") -public class RemoteConnectFailureException extends RemoteAccessException { - - /** - * Constructor for RemoteConnectFailureException. - * @param msg the detail message - * @param cause the root cause from the remoting API in use - */ - public RemoteConnectFailureException(String msg, Throwable cause) { - super(msg, cause); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/RemoteInvocationFailureException.java b/spring-context/src/main/java/org/springframework/remoting/RemoteInvocationFailureException.java deleted file mode 100644 index 40e95213991d..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/RemoteInvocationFailureException.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting; - -/** - * RemoteAccessException subclass to be thrown when the execution - * of the target method failed on the server side, for example - * when a method was not found on the target object. - * - * @author Juergen Hoeller - * @since 2.5 - * @see RemoteProxyFailureException - */ -@SuppressWarnings("serial") -public class RemoteInvocationFailureException extends RemoteAccessException { - - /** - * Constructor for RemoteInvocationFailureException. - * @param msg the detail message - * @param cause the root cause from the remoting API in use - */ - public RemoteInvocationFailureException(String msg, Throwable cause) { - super(msg, cause); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/RemoteLookupFailureException.java b/spring-context/src/main/java/org/springframework/remoting/RemoteLookupFailureException.java deleted file mode 100644 index ee0e9fa0429b..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/RemoteLookupFailureException.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting; - -/** - * RemoteAccessException subclass to be thrown in case of a lookup failure, - * typically if the lookup happens on demand for each method invocation. - * - * @author Juergen Hoeller - * @since 1.1 - */ -@SuppressWarnings("serial") -public class RemoteLookupFailureException extends RemoteAccessException { - - /** - * Constructor for RemoteLookupFailureException. - * @param msg the detail message - */ - public RemoteLookupFailureException(String msg) { - super(msg); - } - - /** - * Constructor for RemoteLookupFailureException. - * @param msg message - * @param cause the root cause from the remoting API in use - */ - public RemoteLookupFailureException(String msg, Throwable cause) { - super(msg, cause); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/RemoteProxyFailureException.java b/spring-context/src/main/java/org/springframework/remoting/RemoteProxyFailureException.java deleted file mode 100644 index ce36152f4c04..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/RemoteProxyFailureException.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting; - -/** - * RemoteAccessException subclass to be thrown in case of a failure - * within the client-side proxy for a remote service, for example - * when a method was not found on the underlying RMI stub. - * - * @author Juergen Hoeller - * @since 1.2.8 - * @see RemoteInvocationFailureException - */ -@SuppressWarnings("serial") -public class RemoteProxyFailureException extends RemoteAccessException { - - /** - * Constructor for RemoteProxyFailureException. - * @param msg the detail message - * @param cause the root cause from the remoting API in use - */ - public RemoteProxyFailureException(String msg, Throwable cause) { - super(msg, cause); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/RemoteTimeoutException.java b/spring-context/src/main/java/org/springframework/remoting/RemoteTimeoutException.java deleted file mode 100644 index 8dbff587c6f1..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/RemoteTimeoutException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting; - -/** - * RemoteAccessException subclass to be thrown when the execution - * of the target method did not complete before a configurable - * timeout, for example when a reply message was not received. - * @author Stephane Nicoll - * @since 4.2 - */ -@SuppressWarnings("serial") -public class RemoteTimeoutException extends RemoteAccessException { - - /** - * Constructor for RemoteTimeoutException. - * @param msg the detail message - */ - public RemoteTimeoutException(String msg) { - super(msg); - } - - /** - * Constructor for RemoteTimeoutException. - * @param msg the detail message - * @param cause the root cause from the remoting API in use - */ - public RemoteTimeoutException(String msg, Throwable cause) { - super(msg, cause); - } -} diff --git a/spring-context/src/main/java/org/springframework/remoting/package-info.java b/spring-context/src/main/java/org/springframework/remoting/package-info.java deleted file mode 100644 index a4b3e95f5dba..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Exception hierarchy for Spring's remoting infrastructure, - * independent of any specific remote method invocation system. - */ -@NonNullApi -@NonNullFields -package org.springframework.remoting; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/CodebaseAwareObjectInputStream.java b/spring-context/src/main/java/org/springframework/remoting/rmi/CodebaseAwareObjectInputStream.java deleted file mode 100644 index 9c897b8a7641..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/CodebaseAwareObjectInputStream.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import java.io.IOException; -import java.io.InputStream; -import java.rmi.server.RMIClassLoader; - -import org.springframework.core.ConfigurableObjectInputStream; -import org.springframework.lang.Nullable; - -/** - * Special ObjectInputStream subclass that falls back to a specified codebase - * to load classes from if not found locally. In contrast to standard RMI - * conventions for dynamic class download, it is the client that determines - * the codebase URL here, rather than the "java.rmi.server.codebase" system - * property on the server. - * - *

    Uses the JDK's RMIClassLoader to load classes from the specified codebase. - * The codebase can consist of multiple URLs, separated by spaces. - * Note that RMIClassLoader requires a SecurityManager to be set, like when - * using dynamic class download with standard RMI! (See the RMI documentation - * for details.) - * - *

    Despite residing in the RMI package, this class is not used for - * RmiClientInterceptor, which uses the standard RMI infrastructure instead - * and thus is only able to rely on RMI's standard dynamic class download via - * "java.rmi.server.codebase". CodebaseAwareObjectInputStream is used by - * HttpInvokerClientInterceptor (see the "codebaseUrl" property there). - * - *

    Thanks to Lionel Mestre for suggesting the option and providing - * a prototype! - * - * @author Juergen Hoeller - * @since 1.1.3 - * @see java.rmi.server.RMIClassLoader - * @see RemoteInvocationSerializingExporter#createObjectInputStream - * @see org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor#setCodebaseUrl - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class CodebaseAwareObjectInputStream extends ConfigurableObjectInputStream { - - private final String codebaseUrl; - - - /** - * Create a new CodebaseAwareObjectInputStream for the given InputStream and codebase. - * @param in the InputStream to read from - * @param codebaseUrl the codebase URL to load classes from if not found locally - * (can consist of multiple URLs, separated by spaces) - * @see java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream) - */ - public CodebaseAwareObjectInputStream(InputStream in, String codebaseUrl) throws IOException { - this(in, null, codebaseUrl); - } - - /** - * Create a new CodebaseAwareObjectInputStream for the given InputStream and codebase. - * @param in the InputStream to read from - * @param classLoader the ClassLoader to use for loading local classes - * (may be {@code null} to indicate RMI's default ClassLoader) - * @param codebaseUrl the codebase URL to load classes from if not found locally - * (can consist of multiple URLs, separated by spaces) - * @see java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream) - */ - public CodebaseAwareObjectInputStream( - InputStream in, @Nullable ClassLoader classLoader, String codebaseUrl) throws IOException { - - super(in, classLoader); - this.codebaseUrl = codebaseUrl; - } - - /** - * Create a new CodebaseAwareObjectInputStream for the given InputStream and codebase. - * @param in the InputStream to read from - * @param classLoader the ClassLoader to use for loading local classes - * (may be {@code null} to indicate RMI's default ClassLoader) - * @param acceptProxyClasses whether to accept deserialization of proxy classes - * (may be deactivated as a security measure) - * @see java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream) - */ - public CodebaseAwareObjectInputStream( - InputStream in, @Nullable ClassLoader classLoader, boolean acceptProxyClasses) throws IOException { - - super(in, classLoader, acceptProxyClasses); - this.codebaseUrl = null; - } - - - @Override - protected Class resolveFallbackIfPossible(String className, ClassNotFoundException ex) - throws IOException, ClassNotFoundException { - - // If codebaseUrl is set, try to load the class with the RMIClassLoader. - // Else, propagate the ClassNotFoundException. - if (this.codebaseUrl == null) { - throw ex; - } - return RMIClassLoader.loadClass(this.codebaseUrl, className); - } - - @Override - protected ClassLoader getFallbackClassLoader() throws IOException { - return RMIClassLoader.getClassLoader(this.codebaseUrl); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiClientInterceptor.java b/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiClientInterceptor.java deleted file mode 100644 index d90dd6a1a347..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiClientInterceptor.java +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.rmi.RemoteException; - -import javax.naming.Context; -import javax.naming.NamingException; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.aop.support.AopUtils; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.jndi.JndiObjectLocator; -import org.springframework.lang.Nullable; -import org.springframework.remoting.RemoteConnectFailureException; -import org.springframework.remoting.RemoteInvocationFailureException; -import org.springframework.remoting.RemoteLookupFailureException; -import org.springframework.remoting.support.DefaultRemoteInvocationFactory; -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.remoting.support.RemoteInvocationFactory; -import org.springframework.util.Assert; - -/** - * {@link org.aopalliance.intercept.MethodInterceptor} for accessing RMI services - * from JNDI. Typically used for RMI-IIOP but can also be used for EJB home objects - * (for example, a Stateful Session Bean home). In contrast to a plain JNDI lookup, - * this accessor also performs narrowing through PortableRemoteObject. - * - *

    With conventional RMI services, this invoker is typically used with the RMI - * service interface. Alternatively, this invoker can also proxy a remote RMI service - * with a matching non-RMI business interface, i.e. an interface that mirrors the RMI - * service methods but does not declare RemoteExceptions. In the latter case, - * RemoteExceptions thrown by the RMI stub will automatically get converted to - * Spring's unchecked RemoteAccessException. - * - *

    The JNDI environment can be specified as "jndiEnvironment" property, - * or be configured in a {@code jndi.properties} file or as system properties. - * For example: - * - *

    <property name="jndiEnvironment">
    - * 	 <props>
    - *		 <prop key="java.naming.factory.initial">com.sun.jndi.cosnaming.CNCtxFactory</prop>
    - *		 <prop key="java.naming.provider.url">iiop://localhost:1050</prop>
    - *	 </props>
    - * </property>
    - * - * @author Juergen Hoeller - * @since 1.1 - * @see #setJndiTemplate - * @see #setJndiEnvironment - * @see #setJndiName - * @see JndiRmiServiceExporter - * @see JndiRmiProxyFactoryBean - * @see org.springframework.remoting.RemoteAccessException - * @see java.rmi.RemoteException - * @see java.rmi.Remote - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class JndiRmiClientInterceptor extends JndiObjectLocator implements MethodInterceptor, InitializingBean { - - private Class serviceInterface; - - private RemoteInvocationFactory remoteInvocationFactory = new DefaultRemoteInvocationFactory(); - - private boolean lookupStubOnStartup = true; - - private boolean cacheStub = true; - - private boolean refreshStubOnConnectFailure = false; - - private boolean exposeAccessContext = false; - - private Object cachedStub; - - private final Object stubMonitor = new Object(); - - - /** - * Set the interface of the service to access. - * The interface must be suitable for the particular service and remoting tool. - *

    Typically required to be able to create a suitable service proxy, - * but can also be optional if the lookup returns a typed stub. - */ - public void setServiceInterface(Class serviceInterface) { - Assert.notNull(serviceInterface, "'serviceInterface' must not be null"); - Assert.isTrue(serviceInterface.isInterface(), "'serviceInterface' must be an interface"); - this.serviceInterface = serviceInterface; - } - - /** - * Return the interface of the service to access. - */ - public Class getServiceInterface() { - return this.serviceInterface; - } - - /** - * Set the RemoteInvocationFactory to use for this accessor. - * Default is a {@link DefaultRemoteInvocationFactory}. - *

    A custom invocation factory can add further context information - * to the invocation, for example user credentials. - */ - public void setRemoteInvocationFactory(RemoteInvocationFactory remoteInvocationFactory) { - this.remoteInvocationFactory = remoteInvocationFactory; - } - - /** - * Return the RemoteInvocationFactory used by this accessor. - */ - public RemoteInvocationFactory getRemoteInvocationFactory() { - return this.remoteInvocationFactory; - } - - /** - * Set whether to look up the RMI stub on startup. Default is "true". - *

    Can be turned off to allow for late start of the RMI server. - * In this case, the RMI stub will be fetched on first access. - * @see #setCacheStub - */ - public void setLookupStubOnStartup(boolean lookupStubOnStartup) { - this.lookupStubOnStartup = lookupStubOnStartup; - } - - /** - * Set whether to cache the RMI stub once it has been located. - * Default is "true". - *

    Can be turned off to allow for hot restart of the RMI server. - * In this case, the RMI stub will be fetched for each invocation. - * @see #setLookupStubOnStartup - */ - public void setCacheStub(boolean cacheStub) { - this.cacheStub = cacheStub; - } - - /** - * Set whether to refresh the RMI stub on connect failure. - * Default is "false". - *

    Can be turned on to allow for hot restart of the RMI server. - * If a cached RMI stub throws an RMI exception that indicates a - * remote connect failure, a fresh proxy will be fetched and the - * invocation will be retried. - * @see java.rmi.ConnectException - * @see java.rmi.ConnectIOException - * @see java.rmi.NoSuchObjectException - */ - public void setRefreshStubOnConnectFailure(boolean refreshStubOnConnectFailure) { - this.refreshStubOnConnectFailure = refreshStubOnConnectFailure; - } - - /** - * Set whether to expose the JNDI environment context for all access to the target - * RMI stub, i.e. for all method invocations on the exposed object reference. - *

    Default is "false", i.e. to only expose the JNDI context for object lookup. - * Switch this flag to "true" in order to expose the JNDI environment (including - * the authorization context) for each RMI invocation, as needed by WebLogic - * for RMI stubs with authorization requirements. - */ - public void setExposeAccessContext(boolean exposeAccessContext) { - this.exposeAccessContext = exposeAccessContext; - } - - - @Override - public void afterPropertiesSet() throws NamingException { - super.afterPropertiesSet(); - prepare(); - } - - /** - * Fetches the RMI stub on startup, if necessary. - * @throws RemoteLookupFailureException if RMI stub creation failed - * @see #setLookupStubOnStartup - * @see #lookupStub - */ - public void prepare() throws RemoteLookupFailureException { - // Cache RMI stub on initialization? - if (this.lookupStubOnStartup) { - Object remoteObj = lookupStub(); - if (logger.isDebugEnabled()) { - if (remoteObj instanceof RmiInvocationHandler) { - logger.debug("JNDI RMI object [" + getJndiName() + "] is an RMI invoker"); - } - else if (getServiceInterface() != null) { - boolean isImpl = getServiceInterface().isInstance(remoteObj); - logger.debug("Using service interface [" + getServiceInterface().getName() + - "] for JNDI RMI object [" + getJndiName() + "] - " + - (!isImpl ? "not " : "") + "directly implemented"); - } - } - if (this.cacheStub) { - this.cachedStub = remoteObj; - } - } - } - - /** - * Create the RMI stub, typically by looking it up. - *

    Called on interceptor initialization if "cacheStub" is "true"; - * else called for each invocation by {@link #getStub()}. - *

    The default implementation retrieves the service from the - * JNDI environment. This can be overridden in subclasses. - * @return the RMI stub to store in this interceptor - * @throws RemoteLookupFailureException if RMI stub creation failed - * @see #setCacheStub - * @see #lookup - */ - protected Object lookupStub() throws RemoteLookupFailureException { - try { - return lookup(); - } - catch (NamingException ex) { - throw new RemoteLookupFailureException("JNDI lookup for RMI service [" + getJndiName() + "] failed", ex); - } - } - - /** - * Return the RMI stub to use. Called for each invocation. - *

    The default implementation returns the stub created on initialization, - * if any. Else, it invokes {@link #lookupStub} to get a new stub for - * each invocation. This can be overridden in subclasses, for example in - * order to cache a stub for a given amount of time before recreating it, - * or to test the stub whether it is still alive. - * @return the RMI stub to use for an invocation - * @throws NamingException if stub creation failed - * @throws RemoteLookupFailureException if RMI stub creation failed - */ - protected Object getStub() throws NamingException, RemoteLookupFailureException { - if (!this.cacheStub || (this.lookupStubOnStartup && !this.refreshStubOnConnectFailure)) { - return (this.cachedStub != null ? this.cachedStub : lookupStub()); - } - else { - synchronized (this.stubMonitor) { - if (this.cachedStub == null) { - this.cachedStub = lookupStub(); - } - return this.cachedStub; - } - } - } - - - /** - * Fetches an RMI stub and delegates to {@link #doInvoke}. - * If configured to refresh on connect failure, it will call - * {@link #refreshAndRetry} on corresponding RMI exceptions. - * @see #getStub - * @see #doInvoke - * @see #refreshAndRetry - * @see java.rmi.ConnectException - * @see java.rmi.ConnectIOException - * @see java.rmi.NoSuchObjectException - */ - @Override - @Nullable - public Object invoke(MethodInvocation invocation) throws Throwable { - Object stub; - try { - stub = getStub(); - } - catch (NamingException ex) { - throw new RemoteLookupFailureException("JNDI lookup for RMI service [" + getJndiName() + "] failed", ex); - } - - Context ctx = (this.exposeAccessContext ? getJndiTemplate().getContext() : null); - try { - return doInvoke(invocation, stub); - } - catch (RemoteConnectFailureException ex) { - return handleRemoteConnectFailure(invocation, ex); - } - catch (RemoteException ex) { - if (isConnectFailure(ex)) { - return handleRemoteConnectFailure(invocation, ex); - } - else { - throw ex; - } - } - finally { - getJndiTemplate().releaseContext(ctx); - } - } - - /** - * Determine whether the given RMI exception indicates a connect failure. - *

    The default implementation delegates to - * {@link RmiClientInterceptorUtils#isConnectFailure}. - * @param ex the RMI exception to check - * @return whether the exception should be treated as connect failure - */ - protected boolean isConnectFailure(RemoteException ex) { - return RmiClientInterceptorUtils.isConnectFailure(ex); - } - - /** - * Refresh the stub and retry the remote invocation if necessary. - *

    If not configured to refresh on connect failure, this method - * simply rethrows the original exception. - * @param invocation the invocation that failed - * @param ex the exception raised on remote invocation - * @return the result value of the new invocation, if succeeded - * @throws Throwable an exception raised by the new invocation, if failed too. - */ - private Object handleRemoteConnectFailure(MethodInvocation invocation, Exception ex) throws Throwable { - if (this.refreshStubOnConnectFailure) { - if (logger.isDebugEnabled()) { - logger.debug("Could not connect to RMI service [" + getJndiName() + "] - retrying", ex); - } - else if (logger.isInfoEnabled()) { - logger.info("Could not connect to RMI service [" + getJndiName() + "] - retrying"); - } - return refreshAndRetry(invocation); - } - else { - throw ex; - } - } - - /** - * Refresh the RMI stub and retry the given invocation. - * Called by invoke on connect failure. - * @param invocation the AOP method invocation - * @return the invocation result, if any - * @throws Throwable in case of invocation failure - * @see #invoke - */ - @Nullable - protected Object refreshAndRetry(MethodInvocation invocation) throws Throwable { - Object freshStub; - synchronized (this.stubMonitor) { - this.cachedStub = null; - freshStub = lookupStub(); - if (this.cacheStub) { - this.cachedStub = freshStub; - } - } - return doInvoke(invocation, freshStub); - } - - - /** - * Perform the given invocation on the given RMI stub. - * @param invocation the AOP method invocation - * @param stub the RMI stub to invoke - * @return the invocation result, if any - * @throws Throwable in case of invocation failure - */ - @Nullable - protected Object doInvoke(MethodInvocation invocation, Object stub) throws Throwable { - if (stub instanceof RmiInvocationHandler) { - // RMI invoker - try { - return doInvoke(invocation, (RmiInvocationHandler) stub); - } - catch (RemoteException ex) { - throw convertRmiAccessException(ex, invocation.getMethod()); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - catch (Throwable ex) { - throw new RemoteInvocationFailureException("Invocation of method [" + invocation.getMethod() + - "] failed in RMI service [" + getJndiName() + "]", ex); - } - } - else { - // traditional RMI stub - try { - return RmiClientInterceptorUtils.invokeRemoteMethod(invocation, stub); - } - catch (InvocationTargetException ex) { - Throwable targetEx = ex.getTargetException(); - if (targetEx instanceof RemoteException) { - throw convertRmiAccessException((RemoteException) targetEx, invocation.getMethod()); - } - else { - throw targetEx; - } - } - } - } - - /** - * Apply the given AOP method invocation to the given {@link RmiInvocationHandler}. - *

    The default implementation delegates to {@link #createRemoteInvocation}. - * @param methodInvocation the current AOP method invocation - * @param invocationHandler the RmiInvocationHandler to apply the invocation to - * @return the invocation result - * @throws RemoteException in case of communication errors - * @throws NoSuchMethodException if the method name could not be resolved - * @throws IllegalAccessException if the method could not be accessed - * @throws InvocationTargetException if the method invocation resulted in an exception - * @see org.springframework.remoting.support.RemoteInvocation - */ - protected Object doInvoke(MethodInvocation methodInvocation, RmiInvocationHandler invocationHandler) - throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { - - if (AopUtils.isToStringMethod(methodInvocation.getMethod())) { - return "RMI invoker proxy for service URL [" + getJndiName() + "]"; - } - - return invocationHandler.invoke(createRemoteInvocation(methodInvocation)); - } - - /** - * Create a new RemoteInvocation object for the given AOP method invocation. - *

    The default implementation delegates to the configured - * {@link #setRemoteInvocationFactory RemoteInvocationFactory}. - * This can be overridden in subclasses in order to provide custom RemoteInvocation - * subclasses, containing additional invocation parameters (e.g. user credentials). - *

    Note that it is preferable to build a custom RemoteInvocationFactory - * as a reusable strategy, instead of overriding this method. - * @param methodInvocation the current AOP method invocation - * @return the RemoteInvocation object - * @see RemoteInvocationFactory#createRemoteInvocation - */ - protected RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) { - return getRemoteInvocationFactory().createRemoteInvocation(methodInvocation); - } - - /** - * Convert the given RMI RemoteException that happened during remote access - * to Spring's RemoteAccessException if the method signature does not declare - * RemoteException. Else, return the original RemoteException. - * @param method the invoked method - * @param ex the RemoteException that happened - * @return the exception to be thrown to the caller - */ - private Exception convertRmiAccessException(RemoteException ex, Method method) { - return RmiClientInterceptorUtils.convertRmiAccessException(method, ex, isConnectFailure(ex), getJndiName()); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiProxyFactoryBean.java b/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiProxyFactoryBean.java deleted file mode 100644 index a9d33d8973b6..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiProxyFactoryBean.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import javax.naming.NamingException; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * {@link FactoryBean} for RMI proxies from JNDI. - * - *

    Typically used for RMI-IIOP (CORBA), but can also be used for EJB home objects - * (for example, a Stateful Session Bean home). In contrast to a plain JNDI lookup, - * this accessor also performs narrowing through {@link javax.rmi.PortableRemoteObject}. - * - *

    With conventional RMI services, this invoker is typically used with the RMI - * service interface. Alternatively, this invoker can also proxy a remote RMI service - * with a matching non-RMI business interface, i.e. an interface that mirrors the RMI - * service methods but does not declare RemoteExceptions. In the latter case, - * RemoteExceptions thrown by the RMI stub will automatically get converted to - * Spring's unchecked RemoteAccessException. - * - *

    The JNDI environment can be specified as "jndiEnvironment" property, - * or be configured in a {@code jndi.properties} file or as system properties. - * For example: - * - *

    <property name="jndiEnvironment">
    - * 	 <props>
    - *		 <prop key="java.naming.factory.initial">com.sun.jndi.cosnaming.CNCtxFactory</prop>
    - *		 <prop key="java.naming.provider.url">iiop://localhost:1050</prop>
    - *	 </props>
    - * </property>
    - * - * @author Juergen Hoeller - * @since 1.1 - * @see #setServiceInterface - * @see #setJndiName - * @see #setJndiTemplate - * @see #setJndiEnvironment - * @see #setJndiName - * @see JndiRmiServiceExporter - * @see org.springframework.remoting.RemoteAccessException - * @see java.rmi.RemoteException - * @see java.rmi.Remote - * @see javax.rmi.PortableRemoteObject#narrow - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class JndiRmiProxyFactoryBean extends JndiRmiClientInterceptor - implements FactoryBean, BeanClassLoaderAware { - - private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); - - private Object serviceProxy; - - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } - - @Override - public void afterPropertiesSet() throws NamingException { - super.afterPropertiesSet(); - Class ifc = getServiceInterface(); - Assert.notNull(ifc, "Property 'serviceInterface' is required"); - this.serviceProxy = new ProxyFactory(ifc, this).getProxy(this.beanClassLoader); - } - - - @Override - public Object getObject() { - return this.serviceProxy; - } - - @Override - public Class getObjectType() { - return getServiceInterface(); - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiServiceExporter.java b/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiServiceExporter.java deleted file mode 100644 index 49b2db295ae8..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiServiceExporter.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.rmi.Remote; -import java.rmi.RemoteException; -import java.util.Properties; - -import javax.naming.NamingException; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.jndi.JndiTemplate; -import org.springframework.lang.Nullable; -import org.springframework.util.ReflectionUtils; - -/** - * Service exporter which binds RMI services to JNDI. - * Typically used for RMI-IIOP (CORBA). - * - *

    Exports services via the {@link javax.rmi.PortableRemoteObject} class. - * You need to run "rmic" with the "-iiop" option to generate corresponding - * stubs and skeletons for each exported service. - * - *

    Also supports exposing any non-RMI service via RMI invokers, to be accessed - * via {@link JndiRmiClientInterceptor} / {@link JndiRmiProxyFactoryBean}'s - * automatic detection of such invokers. - * - *

    With an RMI invoker, RMI communication works on the {@link RmiInvocationHandler} - * level, needing only one stub for any service. Service interfaces do not have to - * extend {@code java.rmi.Remote} or throw {@code java.rmi.RemoteException} - * on all methods, but in and out parameters have to be serializable. - * - *

    The JNDI environment can be specified as "jndiEnvironment" bean property, - * or be configured in a {@code jndi.properties} file or as system properties. - * For example: - * - *

    <property name="jndiEnvironment">
    - * 	 <props>
    - *		 <prop key="java.naming.factory.initial">com.sun.jndi.cosnaming.CNCtxFactory</prop>
    - *		 <prop key="java.naming.provider.url">iiop://localhost:1050</prop>
    - *	 </props>
    - * </property>
    - * - * @author Juergen Hoeller - * @since 1.1 - * @see #setService - * @see #setJndiTemplate - * @see #setJndiEnvironment - * @see #setJndiName - * @see JndiRmiClientInterceptor - * @see JndiRmiProxyFactoryBean - * @see javax.rmi.PortableRemoteObject#exportObject - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class JndiRmiServiceExporter extends RmiBasedExporter implements InitializingBean, DisposableBean { - - @Nullable - private static Method exportObject; - - @Nullable - private static Method unexportObject; - - static { - try { - Class portableRemoteObject = - JndiRmiServiceExporter.class.getClassLoader().loadClass("javax.rmi.PortableRemoteObject"); - exportObject = portableRemoteObject.getMethod("exportObject", Remote.class); - unexportObject = portableRemoteObject.getMethod("unexportObject", Remote.class); - } - catch (Throwable ex) { - // java.corba module not available on JDK 9+ - exportObject = null; - unexportObject = null; - } - } - - - private JndiTemplate jndiTemplate = new JndiTemplate(); - - private String jndiName; - - private Remote exportedObject; - - - /** - * Set the JNDI template to use for JNDI lookups. - * You can also specify JNDI environment settings via "jndiEnvironment". - * @see #setJndiEnvironment - */ - public void setJndiTemplate(JndiTemplate jndiTemplate) { - this.jndiTemplate = (jndiTemplate != null ? jndiTemplate : new JndiTemplate()); - } - - /** - * Set the JNDI environment to use for JNDI lookups. - * Creates a JndiTemplate with the given environment settings. - * @see #setJndiTemplate - */ - public void setJndiEnvironment(Properties jndiEnvironment) { - this.jndiTemplate = new JndiTemplate(jndiEnvironment); - } - - /** - * Set the JNDI name of the exported RMI service. - */ - public void setJndiName(String jndiName) { - this.jndiName = jndiName; - } - - - @Override - public void afterPropertiesSet() throws NamingException, RemoteException { - prepare(); - } - - /** - * Initialize this service exporter, binding the specified service to JNDI. - * @throws NamingException if service binding failed - * @throws RemoteException if service export failed - */ - public void prepare() throws NamingException, RemoteException { - if (this.jndiName == null) { - throw new IllegalArgumentException("Property 'jndiName' is required"); - } - - // Initialize and cache exported object. - this.exportedObject = getObjectToExport(); - invokePortableRemoteObject(exportObject); - - rebind(); - } - - /** - * Rebind the specified service to JNDI, for recovering in case - * of the target registry having been restarted. - * @throws NamingException if service binding failed - */ - public void rebind() throws NamingException { - if (logger.isDebugEnabled()) { - logger.debug("Binding RMI service to JNDI location [" + this.jndiName + "]"); - } - this.jndiTemplate.rebind(this.jndiName, this.exportedObject); - } - - /** - * Unbind the RMI service from JNDI on bean factory shutdown. - */ - @Override - public void destroy() throws NamingException, RemoteException { - if (logger.isDebugEnabled()) { - logger.debug("Unbinding RMI service from JNDI location [" + this.jndiName + "]"); - } - this.jndiTemplate.unbind(this.jndiName); - invokePortableRemoteObject(unexportObject); - } - - - private void invokePortableRemoteObject(@Nullable Method method) throws RemoteException { - if (method != null) { - try { - method.invoke(null, this.exportedObject); - } - catch (InvocationTargetException ex) { - Throwable targetEx = ex.getTargetException(); - if (targetEx instanceof RemoteException) { - throw (RemoteException) targetEx; - } - ReflectionUtils.rethrowRuntimeException(targetEx); - } - catch (Throwable ex) { - throw new IllegalStateException("PortableRemoteObject invocation failed", ex); - } - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RemoteInvocationSerializingExporter.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RemoteInvocationSerializingExporter.java deleted file mode 100644 index 99e81a4e27cf..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/RemoteInvocationSerializingExporter.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.rmi.RemoteException; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.remoting.support.RemoteInvocationBasedExporter; -import org.springframework.remoting.support.RemoteInvocationResult; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * Abstract base class for remote service exporters that explicitly deserialize - * {@link org.springframework.remoting.support.RemoteInvocation} objects and serialize - * {@link org.springframework.remoting.support.RemoteInvocationResult} objects, - * for example Spring's HTTP invoker. - * - *

    Provides template methods for {@code ObjectInputStream} and - * {@code ObjectOutputStream} handling. - * - * @author Juergen Hoeller - * @since 2.5.1 - * @see java.io.ObjectInputStream - * @see java.io.ObjectOutputStream - * @see #doReadRemoteInvocation - * @see #doWriteRemoteInvocationResult - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public abstract class RemoteInvocationSerializingExporter extends RemoteInvocationBasedExporter - implements InitializingBean { - - /** - * Default content type: "application/x-java-serialized-object". - */ - public static final String CONTENT_TYPE_SERIALIZED_OBJECT = "application/x-java-serialized-object"; - - - private String contentType = CONTENT_TYPE_SERIALIZED_OBJECT; - - private boolean acceptProxyClasses = true; - - private Object proxy; - - - /** - * Specify the content type to use for sending remote invocation responses. - *

    Default is "application/x-java-serialized-object". - */ - public void setContentType(String contentType) { - Assert.notNull(contentType, "'contentType' must not be null"); - this.contentType = contentType; - } - - /** - * Return the content type to use for sending remote invocation responses. - */ - public String getContentType() { - return this.contentType; - } - - /** - * Set whether to accept deserialization of proxy classes. - *

    Default is "true". May be deactivated as a security measure. - */ - public void setAcceptProxyClasses(boolean acceptProxyClasses) { - this.acceptProxyClasses = acceptProxyClasses; - } - - /** - * Return whether to accept deserialization of proxy classes. - */ - public boolean isAcceptProxyClasses() { - return this.acceptProxyClasses; - } - - - @Override - public void afterPropertiesSet() { - prepare(); - } - - /** - * Initialize this service exporter. - */ - public void prepare() { - this.proxy = getProxyForService(); - } - - protected final Object getProxy() { - if (this.proxy == null) { - throw new IllegalStateException(ClassUtils.getShortName(getClass()) + " has not been initialized"); - } - return this.proxy; - } - - - /** - * Create an ObjectInputStream for the given InputStream. - *

    The default implementation creates a Spring {@link CodebaseAwareObjectInputStream}. - * @param is the InputStream to read from - * @return the new ObjectInputStream instance to use - * @throws java.io.IOException if creation of the ObjectInputStream failed - */ - protected ObjectInputStream createObjectInputStream(InputStream is) throws IOException { - return new CodebaseAwareObjectInputStream(is, getBeanClassLoader(), isAcceptProxyClasses()); - } - - /** - * Perform the actual reading of an invocation result object from the - * given ObjectInputStream. - *

    The default implementation simply calls - * {@link java.io.ObjectInputStream#readObject()}. - * Can be overridden for deserialization of a custom wrapper object rather - * than the plain invocation, for example an encryption-aware holder. - * @param ois the ObjectInputStream to read from - * @return the RemoteInvocationResult object - * @throws java.io.IOException in case of I/O failure - * @throws ClassNotFoundException if case of a transferred class not - * being found in the local ClassLoader - */ - protected RemoteInvocation doReadRemoteInvocation(ObjectInputStream ois) - throws IOException, ClassNotFoundException { - - Object obj = ois.readObject(); - if (!(obj instanceof RemoteInvocation)) { - throw new RemoteException("Deserialized object needs to be assignable to type [" + - RemoteInvocation.class.getName() + "]: " + ClassUtils.getDescriptiveType(obj)); - } - return (RemoteInvocation) obj; - } - - /** - * Create an ObjectOutputStream for the given OutputStream. - *

    The default implementation creates a plain - * {@link java.io.ObjectOutputStream}. - * @param os the OutputStream to write to - * @return the new ObjectOutputStream instance to use - * @throws java.io.IOException if creation of the ObjectOutputStream failed - */ - protected ObjectOutputStream createObjectOutputStream(OutputStream os) throws IOException { - return new ObjectOutputStream(os); - } - - /** - * Perform the actual writing of the given invocation result object - * to the given ObjectOutputStream. - *

    The default implementation simply calls - * {@link java.io.ObjectOutputStream#writeObject}. - * Can be overridden for serialization of a custom wrapper object rather - * than the plain invocation, for example an encryption-aware holder. - * @param result the RemoteInvocationResult object - * @param oos the ObjectOutputStream to write to - * @throws java.io.IOException if thrown by I/O methods - */ - protected void doWriteRemoteInvocationResult(RemoteInvocationResult result, ObjectOutputStream oos) - throws IOException { - - oos.writeObject(result); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiBasedExporter.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiBasedExporter.java deleted file mode 100644 index e6ae6529afb6..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiBasedExporter.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import java.lang.reflect.InvocationTargetException; -import java.rmi.Remote; - -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.remoting.support.RemoteInvocationBasedExporter; - -/** - * Convenient superclass for RMI-based remote exporters. Provides a facility - * to automatically wrap a given plain Java service object with an - * RmiInvocationWrapper, exposing the {@link RmiInvocationHandler} remote interface. - * - *

    Using the RMI invoker mechanism, RMI communication operates at the {@link RmiInvocationHandler} - * level, sharing a common invoker stub for any number of services. Service interfaces are not - * required to extend {@code java.rmi.Remote} or declare {@code java.rmi.RemoteException} - * on all service methods. However, in and out parameters still have to be serializable. - * - * @author Juergen Hoeller - * @since 1.2.5 - * @see RmiServiceExporter - * @see JndiRmiServiceExporter - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public abstract class RmiBasedExporter extends RemoteInvocationBasedExporter { - - /** - * Determine the object to export: either the service object itself - * or a RmiInvocationWrapper in case of a non-RMI service object. - * @return the RMI object to export - * @see #setService - * @see #setServiceInterface - */ - protected Remote getObjectToExport() { - // determine remote object - if (getService() instanceof Remote && - (getServiceInterface() == null || Remote.class.isAssignableFrom(getServiceInterface()))) { - // conventional RMI service - return (Remote) getService(); - } - else { - // RMI invoker - if (logger.isDebugEnabled()) { - logger.debug("RMI service [" + getService() + "] is an RMI invoker"); - } - return new RmiInvocationWrapper(getProxyForService(), this); - } - } - - /** - * Redefined here to be visible to RmiInvocationWrapper. - * Simply delegates to the corresponding superclass method. - */ - @Override - protected Object invoke(RemoteInvocation invocation, Object targetObject) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - - return super.invoke(invocation, targetObject); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptor.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptor.java deleted file mode 100644 index 8d8569a8f1dd..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptor.java +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLStreamHandler; -import java.rmi.Naming; -import java.rmi.NotBoundException; -import java.rmi.Remote; -import java.rmi.RemoteException; -import java.rmi.registry.LocateRegistry; -import java.rmi.registry.Registry; -import java.rmi.server.RMIClientSocketFactory; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.aop.support.AopUtils; -import org.springframework.lang.Nullable; -import org.springframework.remoting.RemoteConnectFailureException; -import org.springframework.remoting.RemoteInvocationFailureException; -import org.springframework.remoting.RemoteLookupFailureException; -import org.springframework.remoting.support.RemoteInvocationBasedAccessor; -import org.springframework.remoting.support.RemoteInvocationUtils; - -/** - * {@link org.aopalliance.intercept.MethodInterceptor} for accessing conventional - * RMI services or RMI invokers. The service URL must be a valid RMI URL - * (e.g. "rmi://localhost:1099/myservice"). - * - *

    RMI invokers work at the RmiInvocationHandler level, needing only one stub for - * any service. Service interfaces do not have to extend {@code java.rmi.Remote} - * or throw {@code java.rmi.RemoteException}. Spring's unchecked - * RemoteAccessException will be thrown on remote invocation failure. - * Of course, in and out parameters have to be serializable. - * - *

    With conventional RMI services, this invoker is typically used with the RMI - * service interface. Alternatively, this invoker can also proxy a remote RMI service - * with a matching non-RMI business interface, i.e. an interface that mirrors the RMI - * service methods but does not declare RemoteExceptions. In the latter case, - * RemoteExceptions thrown by the RMI stub will automatically get converted to - * Spring's unchecked RemoteAccessException. - * - * @author Juergen Hoeller - * @since 29.09.2003 - * @see RmiServiceExporter - * @see RmiProxyFactoryBean - * @see RmiInvocationHandler - * @see org.springframework.remoting.RemoteAccessException - * @see java.rmi.RemoteException - * @see java.rmi.Remote - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class RmiClientInterceptor extends RemoteInvocationBasedAccessor - implements MethodInterceptor { - - private boolean lookupStubOnStartup = true; - - private boolean cacheStub = true; - - private boolean refreshStubOnConnectFailure = false; - - private RMIClientSocketFactory registryClientSocketFactory; - - private Remote cachedStub; - - private final Object stubMonitor = new Object(); - - - /** - * Set whether to look up the RMI stub on startup. Default is "true". - *

    Can be turned off to allow for late start of the RMI server. - * In this case, the RMI stub will be fetched on first access. - * @see #setCacheStub - */ - public void setLookupStubOnStartup(boolean lookupStubOnStartup) { - this.lookupStubOnStartup = lookupStubOnStartup; - } - - /** - * Set whether to cache the RMI stub once it has been located. - * Default is "true". - *

    Can be turned off to allow for hot restart of the RMI server. - * In this case, the RMI stub will be fetched for each invocation. - * @see #setLookupStubOnStartup - */ - public void setCacheStub(boolean cacheStub) { - this.cacheStub = cacheStub; - } - - /** - * Set whether to refresh the RMI stub on connect failure. - * Default is "false". - *

    Can be turned on to allow for hot restart of the RMI server. - * If a cached RMI stub throws an RMI exception that indicates a - * remote connect failure, a fresh proxy will be fetched and the - * invocation will be retried. - * @see java.rmi.ConnectException - * @see java.rmi.ConnectIOException - * @see java.rmi.NoSuchObjectException - */ - public void setRefreshStubOnConnectFailure(boolean refreshStubOnConnectFailure) { - this.refreshStubOnConnectFailure = refreshStubOnConnectFailure; - } - - /** - * Set a custom RMI client socket factory to use for accessing the RMI registry. - * @see java.rmi.server.RMIClientSocketFactory - * @see java.rmi.registry.LocateRegistry#getRegistry(String, int, RMIClientSocketFactory) - */ - public void setRegistryClientSocketFactory(RMIClientSocketFactory registryClientSocketFactory) { - this.registryClientSocketFactory = registryClientSocketFactory; - } - - - @Override - public void afterPropertiesSet() { - super.afterPropertiesSet(); - prepare(); - } - - /** - * Fetches RMI stub on startup, if necessary. - * @throws RemoteLookupFailureException if RMI stub creation failed - * @see #setLookupStubOnStartup - * @see #lookupStub - */ - public void prepare() throws RemoteLookupFailureException { - // Cache RMI stub on initialization? - if (this.lookupStubOnStartup) { - Remote remoteObj = lookupStub(); - if (logger.isDebugEnabled()) { - if (remoteObj instanceof RmiInvocationHandler) { - logger.debug("RMI stub [" + getServiceUrl() + "] is an RMI invoker"); - } - else if (getServiceInterface() != null) { - boolean isImpl = getServiceInterface().isInstance(remoteObj); - logger.debug("Using service interface [" + getServiceInterface().getName() + - "] for RMI stub [" + getServiceUrl() + "] - " + - (!isImpl ? "not " : "") + "directly implemented"); - } - } - if (this.cacheStub) { - this.cachedStub = remoteObj; - } - } - } - - /** - * Create the RMI stub, typically by looking it up. - *

    Called on interceptor initialization if "cacheStub" is "true"; - * else called for each invocation by {@link #getStub()}. - *

    The default implementation looks up the service URL via - * {@code java.rmi.Naming}. This can be overridden in subclasses. - * @return the RMI stub to store in this interceptor - * @throws RemoteLookupFailureException if RMI stub creation failed - * @see #setCacheStub - * @see java.rmi.Naming#lookup - */ - protected Remote lookupStub() throws RemoteLookupFailureException { - try { - Remote stub = null; - if (this.registryClientSocketFactory != null) { - // RMIClientSocketFactory specified for registry access. - // Unfortunately, due to RMI API limitations, this means - // that we need to parse the RMI URL ourselves and perform - // straight LocateRegistry.getRegistry/Registry.lookup calls. - URL url = new URL(null, getServiceUrl(), new DummyURLStreamHandler()); - String protocol = url.getProtocol(); - if (protocol != null && !"rmi".equals(protocol)) { - throw new MalformedURLException("Invalid URL scheme '" + protocol + "'"); - } - String host = url.getHost(); - int port = url.getPort(); - String name = url.getPath(); - if (name != null && name.startsWith("/")) { - name = name.substring(1); - } - Registry registry = LocateRegistry.getRegistry(host, port, this.registryClientSocketFactory); - stub = registry.lookup(name); - } - else { - // Can proceed with standard RMI lookup API... - stub = Naming.lookup(getServiceUrl()); - } - if (logger.isDebugEnabled()) { - logger.debug("Located RMI stub with URL [" + getServiceUrl() + "]"); - } - return stub; - } - catch (MalformedURLException ex) { - throw new RemoteLookupFailureException("Service URL [" + getServiceUrl() + "] is invalid", ex); - } - catch (NotBoundException ex) { - throw new RemoteLookupFailureException( - "Could not find RMI service [" + getServiceUrl() + "] in RMI registry", ex); - } - catch (RemoteException ex) { - throw new RemoteLookupFailureException("Lookup of RMI stub failed", ex); - } - } - - /** - * Return the RMI stub to use. Called for each invocation. - *

    The default implementation returns the stub created on initialization, - * if any. Else, it invokes {@link #lookupStub} to get a new stub for - * each invocation. This can be overridden in subclasses, for example in - * order to cache a stub for a given amount of time before recreating it, - * or to test the stub whether it is still alive. - * @return the RMI stub to use for an invocation - * @throws RemoteLookupFailureException if RMI stub creation failed - * @see #lookupStub - */ - protected Remote getStub() throws RemoteLookupFailureException { - if (!this.cacheStub || (this.lookupStubOnStartup && !this.refreshStubOnConnectFailure)) { - return (this.cachedStub != null ? this.cachedStub : lookupStub()); - } - else { - synchronized (this.stubMonitor) { - if (this.cachedStub == null) { - this.cachedStub = lookupStub(); - } - return this.cachedStub; - } - } - } - - - /** - * Fetches an RMI stub and delegates to {@code doInvoke}. - * If configured to refresh on connect failure, it will call - * {@link #refreshAndRetry} on corresponding RMI exceptions. - * @see #getStub - * @see #doInvoke(MethodInvocation, Remote) - * @see #refreshAndRetry - * @see java.rmi.ConnectException - * @see java.rmi.ConnectIOException - * @see java.rmi.NoSuchObjectException - */ - @Override - @Nullable - public Object invoke(MethodInvocation invocation) throws Throwable { - Remote stub = getStub(); - try { - return doInvoke(invocation, stub); - } - catch (RemoteConnectFailureException ex) { - return handleRemoteConnectFailure(invocation, ex); - } - catch (RemoteException ex) { - if (isConnectFailure(ex)) { - return handleRemoteConnectFailure(invocation, ex); - } - else { - throw ex; - } - } - } - - /** - * Determine whether the given RMI exception indicates a connect failure. - *

    The default implementation delegates to - * {@link RmiClientInterceptorUtils#isConnectFailure}. - * @param ex the RMI exception to check - * @return whether the exception should be treated as connect failure - */ - protected boolean isConnectFailure(RemoteException ex) { - return RmiClientInterceptorUtils.isConnectFailure(ex); - } - - /** - * Refresh the stub and retry the remote invocation if necessary. - *

    If not configured to refresh on connect failure, this method - * simply rethrows the original exception. - * @param invocation the invocation that failed - * @param ex the exception raised on remote invocation - * @return the result value of the new invocation, if succeeded - * @throws Throwable an exception raised by the new invocation, - * if it failed as well - * @see #setRefreshStubOnConnectFailure - * @see #doInvoke - */ - @Nullable - private Object handleRemoteConnectFailure(MethodInvocation invocation, Exception ex) throws Throwable { - if (this.refreshStubOnConnectFailure) { - String msg = "Could not connect to RMI service [" + getServiceUrl() + "] - retrying"; - if (logger.isDebugEnabled()) { - logger.warn(msg, ex); - } - else if (logger.isWarnEnabled()) { - logger.warn(msg); - } - return refreshAndRetry(invocation); - } - else { - throw ex; - } - } - - /** - * Refresh the RMI stub and retry the given invocation. - * Called by invoke on connect failure. - * @param invocation the AOP method invocation - * @return the invocation result, if any - * @throws Throwable in case of invocation failure - * @see #invoke - */ - @Nullable - protected Object refreshAndRetry(MethodInvocation invocation) throws Throwable { - Remote freshStub = null; - synchronized (this.stubMonitor) { - this.cachedStub = null; - freshStub = lookupStub(); - if (this.cacheStub) { - this.cachedStub = freshStub; - } - } - return doInvoke(invocation, freshStub); - } - - /** - * Perform the given invocation on the given RMI stub. - * @param invocation the AOP method invocation - * @param stub the RMI stub to invoke - * @return the invocation result, if any - * @throws Throwable in case of invocation failure - */ - @Nullable - protected Object doInvoke(MethodInvocation invocation, Remote stub) throws Throwable { - if (stub instanceof RmiInvocationHandler) { - // RMI invoker - try { - return doInvoke(invocation, (RmiInvocationHandler) stub); - } - catch (RemoteException ex) { - throw RmiClientInterceptorUtils.convertRmiAccessException( - invocation.getMethod(), ex, isConnectFailure(ex), getServiceUrl()); - } - catch (InvocationTargetException ex) { - Throwable exToThrow = ex.getTargetException(); - RemoteInvocationUtils.fillInClientStackTraceIfPossible(exToThrow); - throw exToThrow; - } - catch (Throwable ex) { - throw new RemoteInvocationFailureException("Invocation of method [" + invocation.getMethod() + - "] failed in RMI service [" + getServiceUrl() + "]", ex); - } - } - else { - // traditional RMI stub - try { - return RmiClientInterceptorUtils.invokeRemoteMethod(invocation, stub); - } - catch (InvocationTargetException ex) { - Throwable targetEx = ex.getTargetException(); - if (targetEx instanceof RemoteException) { - RemoteException rex = (RemoteException) targetEx; - throw RmiClientInterceptorUtils.convertRmiAccessException( - invocation.getMethod(), rex, isConnectFailure(rex), getServiceUrl()); - } - else { - throw targetEx; - } - } - } - } - - /** - * Apply the given AOP method invocation to the given {@link RmiInvocationHandler}. - *

    The default implementation delegates to {@link #createRemoteInvocation}. - * @param methodInvocation the current AOP method invocation - * @param invocationHandler the RmiInvocationHandler to apply the invocation to - * @return the invocation result - * @throws RemoteException in case of communication errors - * @throws NoSuchMethodException if the method name could not be resolved - * @throws IllegalAccessException if the method could not be accessed - * @throws InvocationTargetException if the method invocation resulted in an exception - * @see org.springframework.remoting.support.RemoteInvocation - */ - @Nullable - protected Object doInvoke(MethodInvocation methodInvocation, RmiInvocationHandler invocationHandler) - throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { - - if (AopUtils.isToStringMethod(methodInvocation.getMethod())) { - return "RMI invoker proxy for service URL [" + getServiceUrl() + "]"; - } - - return invocationHandler.invoke(createRemoteInvocation(methodInvocation)); - } - - - /** - * Dummy URLStreamHandler that's just specified to suppress the standard - * {@code java.net.URL} URLStreamHandler lookup, to be able to - * use the standard URL class for parsing "rmi:..." URLs. - */ - private static class DummyURLStreamHandler extends URLStreamHandler { - - @Override - protected URLConnection openConnection(URL url) throws IOException { - throw new UnsupportedOperationException(); - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptorUtils.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptorUtils.java deleted file mode 100644 index 2842e061433a..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptorUtils.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.SocketException; -import java.rmi.ConnectException; -import java.rmi.ConnectIOException; -import java.rmi.NoSuchObjectException; -import java.rmi.RemoteException; -import java.rmi.StubNotFoundException; -import java.rmi.UnknownHostException; - -import org.aopalliance.intercept.MethodInvocation; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.lang.Nullable; -import org.springframework.remoting.RemoteAccessException; -import org.springframework.remoting.RemoteConnectFailureException; -import org.springframework.remoting.RemoteProxyFailureException; -import org.springframework.util.ReflectionUtils; - -/** - * Factored-out methods for performing invocations within an RMI client. - * Can handle both RMI and non-RMI service interfaces working on an RMI stub. - * - *

    Note: This is an SPI class, not intended to be used by applications. - * - * @author Juergen Hoeller - * @since 1.1 - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public abstract class RmiClientInterceptorUtils { - - private static final Log logger = LogFactory.getLog(RmiClientInterceptorUtils.class); - - - /** - * Perform a raw method invocation on the given RMI stub, - * letting reflection exceptions through as-is. - * @param invocation the AOP MethodInvocation - * @param stub the RMI stub - * @return the invocation result, if any - * @throws InvocationTargetException if thrown by reflection - */ - @Nullable - public static Object invokeRemoteMethod(MethodInvocation invocation, Object stub) - throws InvocationTargetException { - - Method method = invocation.getMethod(); - try { - if (method.getDeclaringClass().isInstance(stub)) { - // directly implemented - return method.invoke(stub, invocation.getArguments()); - } - else { - // not directly implemented - Method stubMethod = stub.getClass().getMethod(method.getName(), method.getParameterTypes()); - return stubMethod.invoke(stub, invocation.getArguments()); - } - } - catch (InvocationTargetException ex) { - throw ex; - } - catch (NoSuchMethodException ex) { - throw new RemoteProxyFailureException("No matching RMI stub method found for: " + method, ex); - } - catch (Throwable ex) { - throw new RemoteProxyFailureException("Invocation of RMI stub method failed: " + method, ex); - } - } - - /** - * Wrap the given arbitrary exception that happened during remote access - * in either a RemoteException or a Spring RemoteAccessException (if the - * method signature does not support RemoteException). - *

    Only call this for remote access exceptions, not for exceptions - * thrown by the target service itself! - * @param method the invoked method - * @param ex the exception that happened, to be used as cause for the - * RemoteAccessException or RemoteException - * @param message the message for the RemoteAccessException respectively - * RemoteException - * @return the exception to be thrown to the caller - */ - public static Exception convertRmiAccessException(Method method, Throwable ex, String message) { - if (logger.isDebugEnabled()) { - logger.debug(message, ex); - } - if (ReflectionUtils.declaresException(method, RemoteException.class)) { - return new RemoteException(message, ex); - } - else { - return new RemoteAccessException(message, ex); - } - } - - /** - * Convert the given RemoteException that happened during remote access - * to Spring's RemoteAccessException if the method signature does not - * support RemoteException. Else, return the original RemoteException. - * @param method the invoked method - * @param ex the RemoteException that happened - * @param serviceName the name of the service (for debugging purposes) - * @return the exception to be thrown to the caller - */ - public static Exception convertRmiAccessException(Method method, RemoteException ex, String serviceName) { - return convertRmiAccessException(method, ex, isConnectFailure(ex), serviceName); - } - - /** - * Convert the given RemoteException that happened during remote access - * to Spring's RemoteAccessException if the method signature does not - * support RemoteException. Else, return the original RemoteException. - * @param method the invoked method - * @param ex the RemoteException that happened - * @param isConnectFailure whether the given exception should be considered - * a connect failure - * @param serviceName the name of the service (for debugging purposes) - * @return the exception to be thrown to the caller - */ - public static Exception convertRmiAccessException( - Method method, RemoteException ex, boolean isConnectFailure, String serviceName) { - - if (logger.isDebugEnabled()) { - logger.debug("Remote service [" + serviceName + "] threw exception", ex); - } - if (ReflectionUtils.declaresException(method, ex.getClass())) { - return ex; - } - else { - if (isConnectFailure) { - return new RemoteConnectFailureException("Could not connect to remote service [" + serviceName + "]", ex); - } - else { - return new RemoteAccessException("Could not access remote service [" + serviceName + "]", ex); - } - } - } - - /** - * Determine whether the given RMI exception indicates a connect failure. - *

    Treats RMI's ConnectException, ConnectIOException, UnknownHostException, - * NoSuchObjectException and StubNotFoundException as connect failure. - * @param ex the RMI exception to check - * @return whether the exception should be treated as connect failure - * @see java.rmi.ConnectException - * @see java.rmi.ConnectIOException - * @see java.rmi.UnknownHostException - * @see java.rmi.NoSuchObjectException - * @see java.rmi.StubNotFoundException - */ - public static boolean isConnectFailure(RemoteException ex) { - return (ex instanceof ConnectException || ex instanceof ConnectIOException || - ex instanceof UnknownHostException || ex instanceof NoSuchObjectException || - ex instanceof StubNotFoundException || ex.getCause() instanceof SocketException); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationHandler.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationHandler.java deleted file mode 100644 index fb26b071f51b..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationHandler.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import java.lang.reflect.InvocationTargetException; -import java.rmi.Remote; -import java.rmi.RemoteException; - -import org.springframework.lang.Nullable; -import org.springframework.remoting.support.RemoteInvocation; - -/** - * Interface for RMI invocation handlers instances on the server, - * wrapping exported services. A client uses a stub implementing - * this interface to access such a service. - * - *

    This is an SPI interface, not to be used directly by applications. - * - * @author Juergen Hoeller - * @since 14.05.2003 - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public interface RmiInvocationHandler extends Remote { - - /** - * Return the name of the target interface that this invoker operates on. - * @return the name of the target interface, or {@code null} if none - * @throws RemoteException in case of communication errors - * @see RmiServiceExporter#getServiceInterface() - */ - @Nullable - public String getTargetInterfaceName() throws RemoteException; - - /** - * Apply the given invocation to the target object. - *

    Called by - * {@link RmiClientInterceptor#doInvoke(org.aopalliance.intercept.MethodInvocation, RmiInvocationHandler)}. - * @param invocation object that encapsulates invocation parameters - * @return the object returned from the invoked method, if any - * @throws RemoteException in case of communication errors - * @throws NoSuchMethodException if the method name could not be resolved - * @throws IllegalAccessException if the method could not be accessed - * @throws InvocationTargetException if the method invocation resulted in an exception - */ - @Nullable - public Object invoke(RemoteInvocation invocation) - throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException; - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationWrapper.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationWrapper.java deleted file mode 100644 index 1f030b327cf5..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationWrapper.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import java.lang.reflect.InvocationTargetException; -import java.rmi.RemoteException; - -import org.springframework.lang.Nullable; -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.util.Assert; - -/** - * Server-side implementation of {@link RmiInvocationHandler}. An instance - * of this class exists for each remote object. Automatically created - * by {@link RmiServiceExporter} for non-RMI service implementations. - * - *

    This is an SPI class, not to be used directly by applications. - * - * @author Juergen Hoeller - * @since 14.05.2003 - * @see RmiServiceExporter - */ -@Deprecated -class RmiInvocationWrapper implements RmiInvocationHandler { - - private final Object wrappedObject; - - private final RmiBasedExporter rmiExporter; - - - /** - * Create a new RmiInvocationWrapper for the given object. - * @param wrappedObject the object to wrap with an RmiInvocationHandler - * @param rmiExporter the RMI exporter to handle the actual invocation - */ - public RmiInvocationWrapper(Object wrappedObject, RmiBasedExporter rmiExporter) { - Assert.notNull(wrappedObject, "Object to wrap is required"); - Assert.notNull(rmiExporter, "RMI exporter is required"); - this.wrappedObject = wrappedObject; - this.rmiExporter = rmiExporter; - } - - - /** - * Exposes the exporter's service interface, if any, as target interface. - * @see RmiBasedExporter#getServiceInterface() - */ - @Override - @Nullable - public String getTargetInterfaceName() { - Class ifc = this.rmiExporter.getServiceInterface(); - return (ifc != null ? ifc.getName() : null); - } - - /** - * Delegates the actual invocation handling to the RMI exporter. - * @see RmiBasedExporter#invoke(org.springframework.remoting.support.RemoteInvocation, Object) - */ - @Override - @Nullable - public Object invoke(RemoteInvocation invocation) - throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { - - return this.rmiExporter.invoke(invocation, this.wrappedObject); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiProxyFactoryBean.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiProxyFactoryBean.java deleted file mode 100644 index 142640926dc5..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiProxyFactoryBean.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.util.Assert; - -/** - * {@link FactoryBean} for RMI proxies, supporting both conventional RMI services - * and RMI invokers. Exposes the proxied service for use as a bean reference, - * using the specified service interface. Proxies will throw Spring's unchecked - * RemoteAccessException on remote invocation failure instead of RMI's RemoteException. - * - *

    The service URL must be a valid RMI URL like "rmi://localhost:1099/myservice". - * RMI invokers work at the RmiInvocationHandler level, using the same invoker stub - * for any service. Service interfaces do not have to extend {@code java.rmi.Remote} - * or throw {@code java.rmi.RemoteException}. Of course, in and out parameters - * have to be serializable. - * - *

    With conventional RMI services, this proxy factory is typically used with the - * RMI service interface. Alternatively, this factory can also proxy a remote RMI - * service with a matching non-RMI business interface, i.e. an interface that mirrors - * the RMI service methods but does not declare RemoteExceptions. In the latter case, - * RemoteExceptions thrown by the RMI stub will automatically get converted to - * Spring's unchecked RemoteAccessException. - * - *

    The major advantage of RMI, compared to Hessian, is serialization. - * Effectively, any serializable Java object can be transported without hassle. - * Hessian has its own (de-)serialization mechanisms, but is HTTP-based and thus - * much easier to setup than RMI. Alternatively, consider Spring's HTTP invoker - * to combine Java serialization with HTTP-based transport. - * - * @author Juergen Hoeller - * @since 13.05.2003 - * @see #setServiceInterface - * @see #setServiceUrl - * @see RmiClientInterceptor - * @see RmiServiceExporter - * @see java.rmi.Remote - * @see java.rmi.RemoteException - * @see org.springframework.remoting.RemoteAccessException - * @see org.springframework.remoting.caucho.HessianProxyFactoryBean - * @see org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class RmiProxyFactoryBean extends RmiClientInterceptor implements FactoryBean, BeanClassLoaderAware { - - private Object serviceProxy; - - - @Override - public void afterPropertiesSet() { - super.afterPropertiesSet(); - Class ifc = getServiceInterface(); - Assert.notNull(ifc, "Property 'serviceInterface' is required"); - this.serviceProxy = new ProxyFactory(ifc, this).getProxy(getBeanClassLoader()); - } - - - @Override - public Object getObject() { - return this.serviceProxy; - } - - @Override - public Class getObjectType() { - return getServiceInterface(); - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiRegistryFactoryBean.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiRegistryFactoryBean.java deleted file mode 100644 index e0b9cf601528..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiRegistryFactoryBean.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import java.rmi.RemoteException; -import java.rmi.registry.LocateRegistry; -import java.rmi.registry.Registry; -import java.rmi.server.RMIClientSocketFactory; -import java.rmi.server.RMIServerSocketFactory; -import java.rmi.server.UnicastRemoteObject; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; - -/** - * {@link FactoryBean} that locates a {@link java.rmi.registry.Registry} and - * exposes it for bean references. Can also create a local RMI registry - * on the fly if none exists already. - * - *

    Can be used to set up and pass around the actual Registry object to - * applications objects that need to work with RMI. One example for such an - * object that needs to work with RMI is Spring's {@link RmiServiceExporter}, - * which either works with a passed-in Registry reference or falls back to - * the registry as specified by its local properties and defaults. - * - *

    Also useful to enforce creation of a local RMI registry at a given port, - * for example for a JMX connector. If used in conjunction with - * {@link org.springframework.jmx.support.ConnectorServerFactoryBean}, - * it is recommended to mark the connector definition (ConnectorServerFactoryBean) - * as "depends-on" the registry definition (RmiRegistryFactoryBean), - * to guarantee starting up the registry first. - * - *

    Note: The implementation of this class mirrors the corresponding logic - * in {@link RmiServiceExporter}, and also offers the same customization hooks. - * RmiServiceExporter implements its own registry lookup as a convenience: - * It is very common to simply rely on the registry defaults. - * - * @author Juergen Hoeller - * @since 1.2.3 - * @see RmiServiceExporter#setRegistry - * @see org.springframework.jmx.support.ConnectorServerFactoryBean - * @see java.rmi.registry.Registry - * @see java.rmi.registry.LocateRegistry - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class RmiRegistryFactoryBean implements FactoryBean, InitializingBean, DisposableBean { - - protected final Log logger = LogFactory.getLog(getClass()); - - private String host; - - private int port = Registry.REGISTRY_PORT; - - private RMIClientSocketFactory clientSocketFactory; - - private RMIServerSocketFactory serverSocketFactory; - - private Registry registry; - - private boolean alwaysCreate = false; - - private boolean created = false; - - - /** - * Set the host of the registry for the exported RMI service, - * i.e. {@code rmi://HOST:port/name} - *

    Default is localhost. - */ - public void setHost(String host) { - this.host = host; - } - - /** - * Return the host of the registry for the exported RMI service. - */ - public String getHost() { - return this.host; - } - - /** - * Set the port of the registry for the exported RMI service, - * i.e. {@code rmi://host:PORT/name} - *

    Default is {@code Registry.REGISTRY_PORT} (1099). - */ - public void setPort(int port) { - this.port = port; - } - - /** - * Return the port of the registry for the exported RMI service. - */ - public int getPort() { - return this.port; - } - - /** - * Set a custom RMI client socket factory to use for the RMI registry. - *

    If the given object also implements {@code java.rmi.server.RMIServerSocketFactory}, - * it will automatically be registered as server socket factory too. - * @see #setServerSocketFactory - * @see java.rmi.server.RMIClientSocketFactory - * @see java.rmi.server.RMIServerSocketFactory - * @see java.rmi.registry.LocateRegistry#getRegistry(String, int, java.rmi.server.RMIClientSocketFactory) - */ - public void setClientSocketFactory(RMIClientSocketFactory clientSocketFactory) { - this.clientSocketFactory = clientSocketFactory; - } - - /** - * Set a custom RMI server socket factory to use for the RMI registry. - *

    Only needs to be specified when the client socket factory does not - * implement {@code java.rmi.server.RMIServerSocketFactory} already. - * @see #setClientSocketFactory - * @see java.rmi.server.RMIClientSocketFactory - * @see java.rmi.server.RMIServerSocketFactory - * @see java.rmi.registry.LocateRegistry#createRegistry(int, RMIClientSocketFactory, java.rmi.server.RMIServerSocketFactory) - */ - public void setServerSocketFactory(RMIServerSocketFactory serverSocketFactory) { - this.serverSocketFactory = serverSocketFactory; - } - - /** - * Set whether to always create the registry in-process, - * not attempting to locate an existing registry at the specified port. - *

    Default is "false". Switch this flag to "true" in order to avoid - * the overhead of locating an existing registry when you always - * intend to create a new registry in any case. - */ - public void setAlwaysCreate(boolean alwaysCreate) { - this.alwaysCreate = alwaysCreate; - } - - - @Override - public void afterPropertiesSet() throws Exception { - // Check socket factories for registry. - if (this.clientSocketFactory instanceof RMIServerSocketFactory) { - this.serverSocketFactory = (RMIServerSocketFactory) this.clientSocketFactory; - } - if ((this.clientSocketFactory != null && this.serverSocketFactory == null) || - (this.clientSocketFactory == null && this.serverSocketFactory != null)) { - throw new IllegalArgumentException( - "Both RMIClientSocketFactory and RMIServerSocketFactory or none required"); - } - - // Fetch RMI registry to expose. - this.registry = getRegistry(this.host, this.port, this.clientSocketFactory, this.serverSocketFactory); - } - - - /** - * Locate or create the RMI registry. - * @param registryHost the registry host to use (if this is specified, - * no implicit creation of a RMI registry will happen) - * @param registryPort the registry port to use - * @param clientSocketFactory the RMI client socket factory for the registry (if any) - * @param serverSocketFactory the RMI server socket factory for the registry (if any) - * @return the RMI registry - * @throws java.rmi.RemoteException if the registry couldn't be located or created - */ - protected Registry getRegistry(String registryHost, int registryPort, - @Nullable RMIClientSocketFactory clientSocketFactory, @Nullable RMIServerSocketFactory serverSocketFactory) - throws RemoteException { - - if (registryHost != null) { - // Host explicitly specified: only lookup possible. - if (logger.isDebugEnabled()) { - logger.debug("Looking for RMI registry at port '" + registryPort + "' of host [" + registryHost + "]"); - } - Registry reg = LocateRegistry.getRegistry(registryHost, registryPort, clientSocketFactory); - testRegistry(reg); - return reg; - } - - else { - return getRegistry(registryPort, clientSocketFactory, serverSocketFactory); - } - } - - /** - * Locate or create the RMI registry. - * @param registryPort the registry port to use - * @param clientSocketFactory the RMI client socket factory for the registry (if any) - * @param serverSocketFactory the RMI server socket factory for the registry (if any) - * @return the RMI registry - * @throws RemoteException if the registry couldn't be located or created - */ - protected Registry getRegistry(int registryPort, - @Nullable RMIClientSocketFactory clientSocketFactory, @Nullable RMIServerSocketFactory serverSocketFactory) - throws RemoteException { - - if (clientSocketFactory != null) { - if (this.alwaysCreate) { - logger.debug("Creating new RMI registry"); - this.created = true; - return LocateRegistry.createRegistry(registryPort, clientSocketFactory, serverSocketFactory); - } - if (logger.isDebugEnabled()) { - logger.debug("Looking for RMI registry at port '" + registryPort + "', using custom socket factory"); - } - synchronized (LocateRegistry.class) { - try { - // Retrieve existing registry. - Registry reg = LocateRegistry.getRegistry(null, registryPort, clientSocketFactory); - testRegistry(reg); - return reg; - } - catch (RemoteException ex) { - logger.trace("RMI registry access threw exception", ex); - logger.debug("Could not detect RMI registry - creating new one"); - // Assume no registry found -> create new one. - this.created = true; - return LocateRegistry.createRegistry(registryPort, clientSocketFactory, serverSocketFactory); - } - } - } - - else { - return getRegistry(registryPort); - } - } - - /** - * Locate or create the RMI registry. - * @param registryPort the registry port to use - * @return the RMI registry - * @throws RemoteException if the registry couldn't be located or created - */ - protected Registry getRegistry(int registryPort) throws RemoteException { - if (this.alwaysCreate) { - logger.debug("Creating new RMI registry"); - this.created = true; - return LocateRegistry.createRegistry(registryPort); - } - if (logger.isDebugEnabled()) { - logger.debug("Looking for RMI registry at port '" + registryPort + "'"); - } - synchronized (LocateRegistry.class) { - try { - // Retrieve existing registry. - Registry reg = LocateRegistry.getRegistry(registryPort); - testRegistry(reg); - return reg; - } - catch (RemoteException ex) { - logger.trace("RMI registry access threw exception", ex); - logger.debug("Could not detect RMI registry - creating new one"); - // Assume no registry found -> create new one. - this.created = true; - return LocateRegistry.createRegistry(registryPort); - } - } - } - - /** - * Test the given RMI registry, calling some operation on it to - * check whether it is still active. - *

    Default implementation calls {@code Registry.list()}. - * @param registry the RMI registry to test - * @throws RemoteException if thrown by registry methods - * @see java.rmi.registry.Registry#list() - */ - protected void testRegistry(Registry registry) throws RemoteException { - registry.list(); - } - - - @Override - public Registry getObject() throws Exception { - return this.registry; - } - - @Override - public Class getObjectType() { - return (this.registry != null ? this.registry.getClass() : Registry.class); - } - - @Override - public boolean isSingleton() { - return true; - } - - - /** - * Unexport the RMI registry on bean factory shutdown, - * provided that this bean actually created a registry. - */ - @Override - public void destroy() throws RemoteException { - if (this.created) { - logger.debug("Unexporting RMI registry"); - UnicastRemoteObject.unexportObject(this.registry, true); - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiServiceExporter.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiServiceExporter.java deleted file mode 100644 index 9ee3a6c112bf..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiServiceExporter.java +++ /dev/null @@ -1,464 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import java.rmi.AlreadyBoundException; -import java.rmi.NoSuchObjectException; -import java.rmi.NotBoundException; -import java.rmi.Remote; -import java.rmi.RemoteException; -import java.rmi.registry.LocateRegistry; -import java.rmi.registry.Registry; -import java.rmi.server.RMIClientSocketFactory; -import java.rmi.server.RMIServerSocketFactory; -import java.rmi.server.UnicastRemoteObject; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; - -/** - * RMI exporter that exposes the specified service as RMI object with the specified name. - * Such services can be accessed via plain RMI or via {@link RmiProxyFactoryBean}. - * Also supports exposing any non-RMI service via RMI invokers, to be accessed via - * {@link RmiClientInterceptor} / {@link RmiProxyFactoryBean}'s automatic detection - * of such invokers. - * - *

    With an RMI invoker, RMI communication works on the {@link RmiInvocationHandler} - * level, needing only one stub for any service. Service interfaces do not have to - * extend {@code java.rmi.Remote} or throw {@code java.rmi.RemoteException} - * on all methods, but in and out parameters have to be serializable. - * - *

    The major advantage of RMI, compared to Hessian, is serialization. - * Effectively, any serializable Java object can be transported without hassle. - * Hessian has its own (de-)serialization mechanisms, but is HTTP-based and thus - * much easier to setup than RMI. Alternatively, consider Spring's HTTP invoker - * to combine Java serialization with HTTP-based transport. - * - *

    Note: RMI makes a best-effort attempt to obtain the fully qualified host name. - * If one cannot be determined, it will fall back and use the IP address. Depending - * on your network configuration, in some cases it will resolve the IP to the loopback - * address. To ensure that RMI will use the host name bound to the correct network - * interface, you should pass the {@code java.rmi.server.hostname} property to the - * JVM that will export the registry and/or the service using the "-D" JVM argument. - * For example: {@code -Djava.rmi.server.hostname=myserver.com} - * - * @author Juergen Hoeller - * @since 13.05.2003 - * @see RmiClientInterceptor - * @see RmiProxyFactoryBean - * @see java.rmi.Remote - * @see java.rmi.RemoteException - * @see org.springframework.remoting.caucho.HessianServiceExporter - * @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class RmiServiceExporter extends RmiBasedExporter implements InitializingBean, DisposableBean { - - private String serviceName; - - private int servicePort = 0; // anonymous port - - private RMIClientSocketFactory clientSocketFactory; - - private RMIServerSocketFactory serverSocketFactory; - - private Registry registry; - - private String registryHost; - - private int registryPort = Registry.REGISTRY_PORT; - - private RMIClientSocketFactory registryClientSocketFactory; - - private RMIServerSocketFactory registryServerSocketFactory; - - private boolean alwaysCreateRegistry = false; - - private boolean replaceExistingBinding = true; - - private Remote exportedObject; - - private boolean createdRegistry = false; - - - /** - * Set the name of the exported RMI service, - * i.e. {@code rmi://host:port/NAME} - */ - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - /** - * Set the port that the exported RMI service will use. - *

    Default is 0 (anonymous port). - */ - public void setServicePort(int servicePort) { - this.servicePort = servicePort; - } - - /** - * Set a custom RMI client socket factory to use for exporting the service. - *

    If the given object also implements {@code java.rmi.server.RMIServerSocketFactory}, - * it will automatically be registered as server socket factory too. - * @see #setServerSocketFactory - * @see java.rmi.server.RMIClientSocketFactory - * @see java.rmi.server.RMIServerSocketFactory - * @see UnicastRemoteObject#exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory) - */ - public void setClientSocketFactory(RMIClientSocketFactory clientSocketFactory) { - this.clientSocketFactory = clientSocketFactory; - } - - /** - * Set a custom RMI server socket factory to use for exporting the service. - *

    Only needs to be specified when the client socket factory does not - * implement {@code java.rmi.server.RMIServerSocketFactory} already. - * @see #setClientSocketFactory - * @see java.rmi.server.RMIClientSocketFactory - * @see java.rmi.server.RMIServerSocketFactory - * @see UnicastRemoteObject#exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory) - */ - public void setServerSocketFactory(RMIServerSocketFactory serverSocketFactory) { - this.serverSocketFactory = serverSocketFactory; - } - - /** - * Specify the RMI registry to register the exported service with. - * Typically used in combination with RmiRegistryFactoryBean. - *

    Alternatively, you can specify all registry properties locally. - * This exporter will then try to locate the specified registry, - * automatically creating a new local one if appropriate. - *

    Default is a local registry at the default port (1099), - * created on the fly if necessary. - * @see RmiRegistryFactoryBean - * @see #setRegistryHost - * @see #setRegistryPort - * @see #setRegistryClientSocketFactory - * @see #setRegistryServerSocketFactory - */ - public void setRegistry(Registry registry) { - this.registry = registry; - } - - /** - * Set the host of the registry for the exported RMI service, - * i.e. {@code rmi://HOST:port/name} - *

    Default is localhost. - */ - public void setRegistryHost(String registryHost) { - this.registryHost = registryHost; - } - - /** - * Set the port of the registry for the exported RMI service, - * i.e. {@code rmi://host:PORT/name} - *

    Default is {@code Registry.REGISTRY_PORT} (1099). - * @see java.rmi.registry.Registry#REGISTRY_PORT - */ - public void setRegistryPort(int registryPort) { - this.registryPort = registryPort; - } - - /** - * Set a custom RMI client socket factory to use for the RMI registry. - *

    If the given object also implements {@code java.rmi.server.RMIServerSocketFactory}, - * it will automatically be registered as server socket factory too. - * @see #setRegistryServerSocketFactory - * @see java.rmi.server.RMIClientSocketFactory - * @see java.rmi.server.RMIServerSocketFactory - * @see LocateRegistry#getRegistry(String, int, RMIClientSocketFactory) - */ - public void setRegistryClientSocketFactory(RMIClientSocketFactory registryClientSocketFactory) { - this.registryClientSocketFactory = registryClientSocketFactory; - } - - /** - * Set a custom RMI server socket factory to use for the RMI registry. - *

    Only needs to be specified when the client socket factory does not - * implement {@code java.rmi.server.RMIServerSocketFactory} already. - * @see #setRegistryClientSocketFactory - * @see java.rmi.server.RMIClientSocketFactory - * @see java.rmi.server.RMIServerSocketFactory - * @see LocateRegistry#createRegistry(int, RMIClientSocketFactory, RMIServerSocketFactory) - */ - public void setRegistryServerSocketFactory(RMIServerSocketFactory registryServerSocketFactory) { - this.registryServerSocketFactory = registryServerSocketFactory; - } - - /** - * Set whether to always create the registry in-process, - * not attempting to locate an existing registry at the specified port. - *

    Default is "false". Switch this flag to "true" in order to avoid - * the overhead of locating an existing registry when you always - * intend to create a new registry in any case. - */ - public void setAlwaysCreateRegistry(boolean alwaysCreateRegistry) { - this.alwaysCreateRegistry = alwaysCreateRegistry; - } - - /** - * Set whether to replace an existing binding in the RMI registry, - * that is, whether to simply override an existing binding with the - * specified service in case of a naming conflict in the registry. - *

    Default is "true", assuming that an existing binding for this - * exporter's service name is an accidental leftover from a previous - * execution. Switch this to "false" to make the exporter fail in such - * a scenario, indicating that there was already an RMI object bound. - */ - public void setReplaceExistingBinding(boolean replaceExistingBinding) { - this.replaceExistingBinding = replaceExistingBinding; - } - - - @Override - public void afterPropertiesSet() throws RemoteException { - prepare(); - } - - /** - * Initialize this service exporter, registering the service as RMI object. - *

    Creates an RMI registry on the specified port if none exists. - * @throws RemoteException if service registration failed - */ - public void prepare() throws RemoteException { - checkService(); - - if (this.serviceName == null) { - throw new IllegalArgumentException("Property 'serviceName' is required"); - } - - // Check socket factories for exported object. - if (this.clientSocketFactory instanceof RMIServerSocketFactory) { - this.serverSocketFactory = (RMIServerSocketFactory) this.clientSocketFactory; - } - if ((this.clientSocketFactory != null && this.serverSocketFactory == null) || - (this.clientSocketFactory == null && this.serverSocketFactory != null)) { - throw new IllegalArgumentException( - "Both RMIClientSocketFactory and RMIServerSocketFactory or none required"); - } - - // Check socket factories for RMI registry. - if (this.registryClientSocketFactory instanceof RMIServerSocketFactory) { - this.registryServerSocketFactory = (RMIServerSocketFactory) this.registryClientSocketFactory; - } - if (this.registryClientSocketFactory == null && this.registryServerSocketFactory != null) { - throw new IllegalArgumentException( - "RMIServerSocketFactory without RMIClientSocketFactory for registry not supported"); - } - - this.createdRegistry = false; - - // Determine RMI registry to use. - if (this.registry == null) { - this.registry = getRegistry(this.registryHost, this.registryPort, - this.registryClientSocketFactory, this.registryServerSocketFactory); - this.createdRegistry = true; - } - - // Initialize and cache exported object. - this.exportedObject = getObjectToExport(); - - if (logger.isDebugEnabled()) { - logger.debug("Binding service '" + this.serviceName + "' to RMI registry: " + this.registry); - } - - // Export RMI object. - if (this.clientSocketFactory != null) { - UnicastRemoteObject.exportObject( - this.exportedObject, this.servicePort, this.clientSocketFactory, this.serverSocketFactory); - } - else { - UnicastRemoteObject.exportObject(this.exportedObject, this.servicePort); - } - - // Bind RMI object to registry. - try { - if (this.replaceExistingBinding) { - this.registry.rebind(this.serviceName, this.exportedObject); - } - else { - this.registry.bind(this.serviceName, this.exportedObject); - } - } - catch (AlreadyBoundException ex) { - // Already an RMI object bound for the specified service name... - unexportObjectSilently(); - throw new IllegalStateException( - "Already an RMI object bound for name '" + this.serviceName + "': " + ex.toString()); - } - catch (RemoteException ex) { - // Registry binding failed: let's unexport the RMI object as well. - unexportObjectSilently(); - throw ex; - } - } - - - /** - * Locate or create the RMI registry for this exporter. - * @param registryHost the registry host to use (if this is specified, - * no implicit creation of a RMI registry will happen) - * @param registryPort the registry port to use - * @param clientSocketFactory the RMI client socket factory for the registry (if any) - * @param serverSocketFactory the RMI server socket factory for the registry (if any) - * @return the RMI registry - * @throws RemoteException if the registry couldn't be located or created - */ - protected Registry getRegistry(String registryHost, int registryPort, - @Nullable RMIClientSocketFactory clientSocketFactory, @Nullable RMIServerSocketFactory serverSocketFactory) - throws RemoteException { - - if (registryHost != null) { - // Host explicitly specified: only lookup possible. - if (logger.isDebugEnabled()) { - logger.debug("Looking for RMI registry at port '" + registryPort + "' of host [" + registryHost + "]"); - } - Registry reg = LocateRegistry.getRegistry(registryHost, registryPort, clientSocketFactory); - testRegistry(reg); - return reg; - } - - else { - return getRegistry(registryPort, clientSocketFactory, serverSocketFactory); - } - } - - /** - * Locate or create the RMI registry for this exporter. - * @param registryPort the registry port to use - * @param clientSocketFactory the RMI client socket factory for the registry (if any) - * @param serverSocketFactory the RMI server socket factory for the registry (if any) - * @return the RMI registry - * @throws RemoteException if the registry couldn't be located or created - */ - protected Registry getRegistry(int registryPort, - @Nullable RMIClientSocketFactory clientSocketFactory, @Nullable RMIServerSocketFactory serverSocketFactory) - throws RemoteException { - - if (clientSocketFactory != null) { - if (this.alwaysCreateRegistry) { - logger.debug("Creating new RMI registry"); - return LocateRegistry.createRegistry(registryPort, clientSocketFactory, serverSocketFactory); - } - if (logger.isDebugEnabled()) { - logger.debug("Looking for RMI registry at port '" + registryPort + "', using custom socket factory"); - } - synchronized (LocateRegistry.class) { - try { - // Retrieve existing registry. - Registry reg = LocateRegistry.getRegistry(null, registryPort, clientSocketFactory); - testRegistry(reg); - return reg; - } - catch (RemoteException ex) { - logger.trace("RMI registry access threw exception", ex); - logger.debug("Could not detect RMI registry - creating new one"); - // Assume no registry found -> create new one. - return LocateRegistry.createRegistry(registryPort, clientSocketFactory, serverSocketFactory); - } - } - } - - else { - return getRegistry(registryPort); - } - } - - /** - * Locate or create the RMI registry for this exporter. - * @param registryPort the registry port to use - * @return the RMI registry - * @throws RemoteException if the registry couldn't be located or created - */ - protected Registry getRegistry(int registryPort) throws RemoteException { - if (this.alwaysCreateRegistry) { - logger.debug("Creating new RMI registry"); - return LocateRegistry.createRegistry(registryPort); - } - if (logger.isDebugEnabled()) { - logger.debug("Looking for RMI registry at port '" + registryPort + "'"); - } - synchronized (LocateRegistry.class) { - try { - // Retrieve existing registry. - Registry reg = LocateRegistry.getRegistry(registryPort); - testRegistry(reg); - return reg; - } - catch (RemoteException ex) { - logger.trace("RMI registry access threw exception", ex); - logger.debug("Could not detect RMI registry - creating new one"); - // Assume no registry found -> create new one. - return LocateRegistry.createRegistry(registryPort); - } - } - } - - /** - * Test the given RMI registry, calling some operation on it to - * check whether it is still active. - *

    Default implementation calls {@code Registry.list()}. - * @param registry the RMI registry to test - * @throws RemoteException if thrown by registry methods - * @see java.rmi.registry.Registry#list() - */ - protected void testRegistry(Registry registry) throws RemoteException { - registry.list(); - } - - - /** - * Unbind the RMI service from the registry on bean factory shutdown. - */ - @Override - public void destroy() throws RemoteException { - if (logger.isDebugEnabled()) { - logger.debug("Unbinding RMI service '" + this.serviceName + - "' from registry" + (this.createdRegistry ? (" at port '" + this.registryPort + "'") : "")); - } - try { - this.registry.unbind(this.serviceName); - } - catch (NotBoundException ex) { - if (logger.isInfoEnabled()) { - logger.info("RMI service '" + this.serviceName + "' is not bound to registry" + - (this.createdRegistry ? (" at port '" + this.registryPort + "' anymore") : ""), ex); - } - } - finally { - unexportObjectSilently(); - } - } - - /** - * Unexport the registered RMI object, logging any exception that arises. - */ - private void unexportObjectSilently() { - try { - UnicastRemoteObject.unexportObject(this.exportedObject, true); - } - catch (NoSuchObjectException ex) { - if (logger.isInfoEnabled()) { - logger.info("RMI object for service '" + this.serviceName + "' is not exported anymore", ex); - } - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/package-info.java b/spring-context/src/main/java/org/springframework/remoting/rmi/package-info.java deleted file mode 100644 index 8296464c341f..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Remoting classes for conventional RMI and transparent remoting via - * RMI invokers. Provides a proxy factory for accessing RMI services, - * and an exporter for making beans available to RMI clients. - */ -package org.springframework.remoting.rmi; diff --git a/spring-context/src/main/java/org/springframework/remoting/soap/SoapFaultException.java b/spring-context/src/main/java/org/springframework/remoting/soap/SoapFaultException.java deleted file mode 100644 index 175c351cf34b..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/soap/SoapFaultException.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.soap; - -import javax.xml.namespace.QName; - -import org.springframework.remoting.RemoteInvocationFailureException; - -/** - * RemoteInvocationFailureException subclass that provides the details - * of a SOAP fault. - * - * @author Juergen Hoeller - * @since 2.5 - * @see javax.xml.rpc.soap.SOAPFaultException - * @see javax.xml.ws.soap.SOAPFaultException - */ -@SuppressWarnings("serial") -public abstract class SoapFaultException extends RemoteInvocationFailureException { - - /** - * Constructor for SoapFaultException. - * @param msg the detail message - * @param cause the root cause from the SOAP API in use - */ - protected SoapFaultException(String msg, Throwable cause) { - super(msg, cause); - } - - - /** - * Return the SOAP fault code. - */ - public abstract String getFaultCode(); - - /** - * Return the SOAP fault code as a {@code QName} object. - */ - public abstract QName getFaultCodeAsQName(); - - /** - * Return the descriptive SOAP fault string. - */ - public abstract String getFaultString(); - - /** - * Return the actor that caused this fault. - */ - public abstract String getFaultActor(); - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/soap/package-info.java b/spring-context/src/main/java/org/springframework/remoting/soap/package-info.java deleted file mode 100644 index e1e110740973..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/soap/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * SOAP-specific exceptions and support classes for Spring's remoting subsystem. - */ -package org.springframework.remoting.soap; diff --git a/spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationExecutor.java b/spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationExecutor.java deleted file mode 100644 index 870fe87ff177..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationExecutor.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import java.lang.reflect.InvocationTargetException; - -import org.springframework.util.Assert; - -/** - * Default implementation of the {@link RemoteInvocationExecutor} interface. - * Simply delegates to {@link RemoteInvocation}'s invoke method. - * - * @author Juergen Hoeller - * @since 1.1 - * @see RemoteInvocation#invoke - */ -public class DefaultRemoteInvocationExecutor implements RemoteInvocationExecutor { - - @Override - public Object invoke(RemoteInvocation invocation, Object targetObject) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException{ - - Assert.notNull(invocation, "RemoteInvocation must not be null"); - Assert.notNull(targetObject, "Target object must not be null"); - return invocation.invoke(targetObject); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationFactory.java b/spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationFactory.java deleted file mode 100644 index 10f3ab184a4f..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import org.aopalliance.intercept.MethodInvocation; - -/** - * Default implementation of the {@link RemoteInvocationFactory} interface. - * Simply creates a new standard {@link RemoteInvocation} object. - * - * @author Juergen Hoeller - * @since 1.1 - */ -public class DefaultRemoteInvocationFactory implements RemoteInvocationFactory { - - @Override - public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) { - return new RemoteInvocation(methodInvocation); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteAccessor.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteAccessor.java deleted file mode 100644 index f26ca9a84931..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteAccessor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import org.springframework.util.Assert; - -/** - * Abstract base class for classes that access a remote service. - * Provides a "serviceInterface" bean property. - * - *

    Note that the service interface being used will show some signs of - * remotability, like the granularity of method calls that it offers. - * Furthermore, it has to have serializable arguments etc. - * - *

    Accessors are supposed to throw Spring's generic - * {@link org.springframework.remoting.RemoteAccessException} in case - * of remote invocation failure, provided that the service interface - * does not declare {@code java.rmi.RemoteException}. - * - * @author Juergen Hoeller - * @since 13.05.2003 - * @see org.springframework.remoting.RemoteAccessException - * @see java.rmi.RemoteException - */ -public abstract class RemoteAccessor extends RemotingSupport { - - private Class serviceInterface; - - - /** - * Set the interface of the service to access. - * The interface must be suitable for the particular service and remoting strategy. - *

    Typically required to be able to create a suitable service proxy, - * but can also be optional if the lookup returns a typed proxy. - */ - public void setServiceInterface(Class serviceInterface) { - Assert.notNull(serviceInterface, "'serviceInterface' must not be null"); - Assert.isTrue(serviceInterface.isInterface(), "'serviceInterface' must be an interface"); - this.serviceInterface = serviceInterface; - } - - /** - * Return the interface of the service to access. - */ - public Class getServiceInterface() { - return this.serviceInterface; - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteExporter.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteExporter.java deleted file mode 100644 index 2c590ff5480c..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteExporter.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry; -import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * Abstract base class for classes that export a remote service. - * Provides "service" and "serviceInterface" bean properties. - * - *

    Note that the service interface being used will show some signs of - * remotability, like the granularity of method calls that it offers. - * Furthermore, it has to have serializable arguments etc. - * - * @author Juergen Hoeller - * @since 26.12.2003 - */ -public abstract class RemoteExporter extends RemotingSupport { - - private Object service; - - private Class serviceInterface; - - private Boolean registerTraceInterceptor; - - private Object[] interceptors; - - - /** - * Set the service to export. - * Typically populated via a bean reference. - */ - public void setService(Object service) { - this.service = service; - } - - /** - * Return the service to export. - */ - public Object getService() { - return this.service; - } - - /** - * Set the interface of the service to export. - * The interface must be suitable for the particular service and remoting strategy. - */ - public void setServiceInterface(Class serviceInterface) { - Assert.notNull(serviceInterface, "'serviceInterface' must not be null"); - Assert.isTrue(serviceInterface.isInterface(), "'serviceInterface' must be an interface"); - this.serviceInterface = serviceInterface; - } - - /** - * Return the interface of the service to export. - */ - public Class getServiceInterface() { - return this.serviceInterface; - } - - /** - * Set whether to register a RemoteInvocationTraceInterceptor for exported - * services. Only applied when a subclass uses {@code getProxyForService} - * for creating the proxy to expose. - *

    Default is "true". RemoteInvocationTraceInterceptor's most important value - * is that it logs exception stacktraces on the server, before propagating an - * exception to the client. Note that RemoteInvocationTraceInterceptor will not - * be registered by default if the "interceptors" property has been specified. - * @see #setInterceptors - * @see #getProxyForService - * @see RemoteInvocationTraceInterceptor - */ - public void setRegisterTraceInterceptor(boolean registerTraceInterceptor) { - this.registerTraceInterceptor = registerTraceInterceptor; - } - - /** - * Set additional interceptors (or advisors) to be applied before the - * remote endpoint, e.g. a PerformanceMonitorInterceptor. - *

    You may specify any AOP Alliance MethodInterceptors or other - * Spring AOP Advices, as well as Spring AOP Advisors. - * @see #getProxyForService - * @see org.springframework.aop.interceptor.PerformanceMonitorInterceptor - */ - public void setInterceptors(Object[] interceptors) { - this.interceptors = interceptors; - } - - - /** - * Check whether the service reference has been set. - * @see #setService - */ - protected void checkService() throws IllegalArgumentException { - Assert.notNull(getService(), "Property 'service' is required"); - } - - /** - * Check whether a service reference has been set, - * and whether it matches the specified service. - * @see #setServiceInterface - * @see #setService - */ - protected void checkServiceInterface() throws IllegalArgumentException { - Class serviceInterface = getServiceInterface(); - Assert.notNull(serviceInterface, "Property 'serviceInterface' is required"); - - Object service = getService(); - if (service instanceof String) { - throw new IllegalArgumentException("Service [" + service + "] is a String " + - "rather than an actual service reference: Have you accidentally specified " + - "the service bean name as value instead of as reference?"); - } - if (!serviceInterface.isInstance(service)) { - throw new IllegalArgumentException("Service interface [" + serviceInterface.getName() + - "] needs to be implemented by service [" + service + "] of class [" + - service.getClass().getName() + "]"); - } - } - - /** - * Get a proxy for the given service object, implementing the specified - * service interface. - *

    Used to export a proxy that does not expose any internals but just - * a specific interface intended for remote access. Furthermore, a - * {@link RemoteInvocationTraceInterceptor} will be registered (by default). - * @return the proxy - * @see #setServiceInterface - * @see #setRegisterTraceInterceptor - * @see RemoteInvocationTraceInterceptor - */ - protected Object getProxyForService() { - checkService(); - checkServiceInterface(); - - ProxyFactory proxyFactory = new ProxyFactory(); - proxyFactory.addInterface(getServiceInterface()); - - if (this.registerTraceInterceptor != null ? this.registerTraceInterceptor : this.interceptors == null) { - proxyFactory.addAdvice(new RemoteInvocationTraceInterceptor(getExporterName())); - } - if (this.interceptors != null) { - AdvisorAdapterRegistry adapterRegistry = GlobalAdvisorAdapterRegistry.getInstance(); - for (Object interceptor : this.interceptors) { - proxyFactory.addAdvisor(adapterRegistry.wrap(interceptor)); - } - } - - proxyFactory.setTarget(getService()); - proxyFactory.setOpaque(true); - - return proxyFactory.getProxy(getBeanClassLoader()); - } - - /** - * Return a short name for this exporter. - * Used for tracing of remote invocations. - *

    Default is the unqualified class name (without package). - * Can be overridden in subclasses. - * @see #getProxyForService - * @see RemoteInvocationTraceInterceptor - * @see org.springframework.util.ClassUtils#getShortName - */ - protected String getExporterName() { - return ClassUtils.getShortName(getClass()); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocation.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocation.java deleted file mode 100644 index fec43c6bb209..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocation.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; - -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.lang.Nullable; -import org.springframework.util.ClassUtils; - -/** - * Encapsulates a remote invocation, providing core method invocation properties - * in a serializable fashion. Used for RMI and HTTP-based serialization invokers. - * - *

    This is an SPI class, typically not used directly by applications. - * Can be subclassed for additional invocation parameters. - * - *

    Both {@link RemoteInvocation} and {@link RemoteInvocationResult} are designed - * for use with standard Java serialization as well as JavaBean-style serialization. - * - * @author Juergen Hoeller - * @since 25.02.2004 - * @see RemoteInvocationResult - * @see RemoteInvocationFactory - * @see RemoteInvocationExecutor - * @see org.springframework.remoting.rmi.RmiProxyFactoryBean - * @see org.springframework.remoting.rmi.RmiServiceExporter - * @see org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean - * @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter - */ -public class RemoteInvocation implements Serializable { - - /** use serialVersionUID from Spring 1.1 for interoperability. */ - private static final long serialVersionUID = 6876024250231820554L; - - - private String methodName; - - private Class[] parameterTypes; - - private Object[] arguments; - - private Map attributes; - - - /** - * Create a new RemoteInvocation for the given AOP method invocation. - * @param methodInvocation the AOP invocation to convert - */ - public RemoteInvocation(MethodInvocation methodInvocation) { - this.methodName = methodInvocation.getMethod().getName(); - this.parameterTypes = methodInvocation.getMethod().getParameterTypes(); - this.arguments = methodInvocation.getArguments(); - } - - /** - * Create a new RemoteInvocation for the given parameters. - * @param methodName the name of the method to invoke - * @param parameterTypes the parameter types of the method - * @param arguments the arguments for the invocation - */ - public RemoteInvocation(String methodName, Class[] parameterTypes, Object[] arguments) { - this.methodName = methodName; - this.parameterTypes = parameterTypes; - this.arguments = arguments; - } - - /** - * Create a new RemoteInvocation for JavaBean-style deserialization - * (e.g. with Jackson). - */ - public RemoteInvocation() { - } - - - /** - * Set the name of the target method. - *

    This setter is intended for JavaBean-style deserialization. - */ - public void setMethodName(String methodName) { - this.methodName = methodName; - } - - /** - * Return the name of the target method. - */ - public String getMethodName() { - return this.methodName; - } - - /** - * Set the parameter types of the target method. - *

    This setter is intended for JavaBean-style deserialization. - */ - public void setParameterTypes(Class[] parameterTypes) { - this.parameterTypes = parameterTypes; - } - - /** - * Return the parameter types of the target method. - */ - public Class[] getParameterTypes() { - return this.parameterTypes; - } - - /** - * Set the arguments for the target method call. - *

    This setter is intended for JavaBean-style deserialization. - */ - public void setArguments(Object[] arguments) { - this.arguments = arguments; - } - - /** - * Return the arguments for the target method call. - */ - public Object[] getArguments() { - return this.arguments; - } - - - /** - * Add an additional invocation attribute. Useful to add additional - * invocation context without having to subclass RemoteInvocation. - *

    Attribute keys have to be unique, and no overriding of existing - * attributes is allowed. - *

    The implementation avoids to unnecessarily create the attributes - * Map, to minimize serialization size. - * @param key the attribute key - * @param value the attribute value - * @throws IllegalStateException if the key is already bound - */ - public void addAttribute(String key, Serializable value) throws IllegalStateException { - if (this.attributes == null) { - this.attributes = new HashMap<>(); - } - if (this.attributes.containsKey(key)) { - throw new IllegalStateException("There is already an attribute with key '" + key + "' bound"); - } - this.attributes.put(key, value); - } - - /** - * Retrieve the attribute for the given key, if any. - *

    The implementation avoids to unnecessarily create the attributes - * Map, to minimize serialization size. - * @param key the attribute key - * @return the attribute value, or {@code null} if not defined - */ - @Nullable - public Serializable getAttribute(String key) { - if (this.attributes == null) { - return null; - } - return this.attributes.get(key); - } - - /** - * Set the attributes Map. Only here for special purposes: - * Preferably, use {@link #addAttribute} and {@link #getAttribute}. - * @param attributes the attributes Map - * @see #addAttribute - * @see #getAttribute - */ - public void setAttributes(@Nullable Map attributes) { - this.attributes = attributes; - } - - /** - * Return the attributes Map. Mainly here for debugging purposes: - * Preferably, use {@link #addAttribute} and {@link #getAttribute}. - * @return the attributes Map, or {@code null} if none created - * @see #addAttribute - * @see #getAttribute - */ - @Nullable - public Map getAttributes() { - return this.attributes; - } - - - /** - * Perform this invocation on the given target object. - * Typically called when a RemoteInvocation is received on the server. - * @param targetObject the target object to apply the invocation to - * @return the invocation result - * @throws NoSuchMethodException if the method name could not be resolved - * @throws IllegalAccessException if the method could not be accessed - * @throws InvocationTargetException if the method invocation resulted in an exception - * @see java.lang.reflect.Method#invoke - */ - public Object invoke(Object targetObject) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - - Method method = targetObject.getClass().getMethod(this.methodName, this.parameterTypes); - return method.invoke(targetObject, this.arguments); - } - - - @Override - public String toString() { - return "RemoteInvocation: method name '" + this.methodName + "'; parameter types " + - ClassUtils.classNamesToString(this.parameterTypes); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedAccessor.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedAccessor.java deleted file mode 100644 index c7f58152c0c2..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedAccessor.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.lang.Nullable; - -/** - * Abstract base class for remote service accessors that are based - * on serialization of {@link RemoteInvocation} objects. - * - * Provides a "remoteInvocationFactory" property, with a - * {@link DefaultRemoteInvocationFactory} as default strategy. - * - * @author Juergen Hoeller - * @since 1.1 - * @see #setRemoteInvocationFactory - * @see RemoteInvocation - * @see RemoteInvocationFactory - * @see DefaultRemoteInvocationFactory - */ -public abstract class RemoteInvocationBasedAccessor extends UrlBasedRemoteAccessor { - - private RemoteInvocationFactory remoteInvocationFactory = new DefaultRemoteInvocationFactory(); - - - /** - * Set the RemoteInvocationFactory to use for this accessor. - * Default is a {@link DefaultRemoteInvocationFactory}. - *

    A custom invocation factory can add further context information - * to the invocation, for example user credentials. - */ - public void setRemoteInvocationFactory(RemoteInvocationFactory remoteInvocationFactory) { - this.remoteInvocationFactory = - (remoteInvocationFactory != null ? remoteInvocationFactory : new DefaultRemoteInvocationFactory()); - } - - /** - * Return the RemoteInvocationFactory used by this accessor. - */ - public RemoteInvocationFactory getRemoteInvocationFactory() { - return this.remoteInvocationFactory; - } - - /** - * Create a new RemoteInvocation object for the given AOP method invocation. - *

    The default implementation delegates to the configured - * {@link #setRemoteInvocationFactory RemoteInvocationFactory}. - * This can be overridden in subclasses in order to provide custom RemoteInvocation - * subclasses, containing additional invocation parameters (e.g. user credentials). - *

    Note that it is preferable to build a custom RemoteInvocationFactory - * as a reusable strategy, instead of overriding this method. - * @param methodInvocation the current AOP method invocation - * @return the RemoteInvocation object - * @see RemoteInvocationFactory#createRemoteInvocation - */ - protected RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) { - return getRemoteInvocationFactory().createRemoteInvocation(methodInvocation); - } - - /** - * Recreate the invocation result contained in the given RemoteInvocationResult object. - *

    The default implementation calls the default {@code recreate()} method. - * This can be overridden in subclass to provide custom recreation, potentially - * processing the returned result object. - * @param result the RemoteInvocationResult to recreate - * @return a return value if the invocation result is a successful return - * @throws Throwable if the invocation result is an exception - * @see RemoteInvocationResult#recreate() - */ - @Nullable - protected Object recreateRemoteInvocationResult(RemoteInvocationResult result) throws Throwable { - return result.recreate(); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedExporter.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedExporter.java deleted file mode 100644 index a25aae4a7480..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedExporter.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import java.lang.reflect.InvocationTargetException; - -/** - * Abstract base class for remote service exporters that are based - * on deserialization of {@link RemoteInvocation} objects. - * - *

    Provides a "remoteInvocationExecutor" property, with a - * {@link DefaultRemoteInvocationExecutor} as default strategy. - * - * @author Juergen Hoeller - * @since 1.1 - * @see RemoteInvocationExecutor - * @see DefaultRemoteInvocationExecutor - */ -public abstract class RemoteInvocationBasedExporter extends RemoteExporter { - - private RemoteInvocationExecutor remoteInvocationExecutor = new DefaultRemoteInvocationExecutor(); - - - /** - * Set the RemoteInvocationExecutor to use for this exporter. - * Default is a DefaultRemoteInvocationExecutor. - *

    A custom invocation executor can extract further context information - * from the invocation, for example user credentials. - */ - public void setRemoteInvocationExecutor(RemoteInvocationExecutor remoteInvocationExecutor) { - this.remoteInvocationExecutor = remoteInvocationExecutor; - } - - /** - * Return the RemoteInvocationExecutor used by this exporter. - */ - public RemoteInvocationExecutor getRemoteInvocationExecutor() { - return this.remoteInvocationExecutor; - } - - - /** - * Apply the given remote invocation to the given target object. - * The default implementation delegates to the RemoteInvocationExecutor. - *

    Can be overridden in subclasses for custom invocation behavior, - * possibly for applying additional invocation parameters from a - * custom RemoteInvocation subclass. Note that it is preferable to use - * a custom RemoteInvocationExecutor which is a reusable strategy. - * @param invocation the remote invocation - * @param targetObject the target object to apply the invocation to - * @return the invocation result - * @throws NoSuchMethodException if the method name could not be resolved - * @throws IllegalAccessException if the method could not be accessed - * @throws InvocationTargetException if the method invocation resulted in an exception - * @see RemoteInvocationExecutor#invoke - */ - protected Object invoke(RemoteInvocation invocation, Object targetObject) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - - if (logger.isTraceEnabled()) { - logger.trace("Executing " + invocation); - } - try { - return getRemoteInvocationExecutor().invoke(invocation, targetObject); - } - catch (NoSuchMethodException ex) { - if (logger.isDebugEnabled()) { - logger.debug("Could not find target method for " + invocation, ex); - } - throw ex; - } - catch (IllegalAccessException ex) { - if (logger.isDebugEnabled()) { - logger.debug("Could not access target method for " + invocation, ex); - } - throw ex; - } - catch (InvocationTargetException ex) { - if (logger.isDebugEnabled()) { - logger.debug("Target method failed for " + invocation, ex.getTargetException()); - } - throw ex; - } - } - - /** - * Apply the given remote invocation to the given target object, wrapping - * the invocation result in a serializable RemoteInvocationResult object. - * The default implementation creates a plain RemoteInvocationResult. - *

    Can be overridden in subclasses for custom invocation behavior, - * for example to return additional context information. Note that this - * is not covered by the RemoteInvocationExecutor strategy! - * @param invocation the remote invocation - * @param targetObject the target object to apply the invocation to - * @return the invocation result - * @see #invoke - */ - protected RemoteInvocationResult invokeAndCreateResult(RemoteInvocation invocation, Object targetObject) { - try { - Object value = invoke(invocation, targetObject); - return new RemoteInvocationResult(value); - } - catch (Throwable ex) { - return new RemoteInvocationResult(ex); - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationExecutor.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationExecutor.java deleted file mode 100644 index 02d456b3a4be..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationExecutor.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2002-2007 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import java.lang.reflect.InvocationTargetException; - -/** - * Strategy interface for executing a {@link RemoteInvocation} on a target object. - * - *

    Used by {@link org.springframework.remoting.rmi.RmiServiceExporter} (for RMI invokers) - * and by {@link org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter}. - * - * @author Juergen Hoeller - * @since 1.1 - * @see DefaultRemoteInvocationFactory - * @see org.springframework.remoting.rmi.RmiServiceExporter#setRemoteInvocationExecutor - * @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter#setRemoteInvocationExecutor - */ -public interface RemoteInvocationExecutor { - - /** - * Perform this invocation on the given target object. - * Typically called when a RemoteInvocation is received on the server. - * @param invocation the RemoteInvocation - * @param targetObject the target object to apply the invocation to - * @return the invocation result - * @throws NoSuchMethodException if the method name could not be resolved - * @throws IllegalAccessException if the method could not be accessed - * @throws InvocationTargetException if the method invocation resulted in an exception - * @see java.lang.reflect.Method#invoke - */ - Object invoke(RemoteInvocation invocation, Object targetObject) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException; - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationFactory.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationFactory.java deleted file mode 100644 index 5fba21f81b6d..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationFactory.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-2007 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import org.aopalliance.intercept.MethodInvocation; - -/** - * Strategy interface for creating a {@link RemoteInvocation} from an AOP Alliance - * {@link org.aopalliance.intercept.MethodInvocation}. - * - *

    Used by {@link org.springframework.remoting.rmi.RmiClientInterceptor} (for RMI invokers) - * and by {@link org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor}. - * - * @author Juergen Hoeller - * @since 1.1 - * @see DefaultRemoteInvocationFactory - * @see org.springframework.remoting.rmi.RmiClientInterceptor#setRemoteInvocationFactory - * @see org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor#setRemoteInvocationFactory - */ -public interface RemoteInvocationFactory { - - /** - * Create a serializable RemoteInvocation object from the given AOP - * MethodInvocation. - *

    Can be implemented to add custom context information to the - * remote invocation, for example user credentials. - * @param methodInvocation the original AOP MethodInvocation object - * @return the RemoteInvocation object - */ - RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation); - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationResult.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationResult.java deleted file mode 100644 index 76de6b8b4a05..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationResult.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; - -import org.springframework.lang.Nullable; - -/** - * Encapsulates a remote invocation result, holding a result value or an exception. - * Used for HTTP-based serialization invokers. - * - *

    This is an SPI class, typically not used directly by applications. - * Can be subclassed for additional invocation parameters. - * - *

    Both {@link RemoteInvocation} and {@link RemoteInvocationResult} are designed - * for use with standard Java serialization as well as JavaBean-style serialization. - * - * @author Juergen Hoeller - * @since 1.1 - * @see RemoteInvocation - */ -public class RemoteInvocationResult implements Serializable { - - /** Use serialVersionUID from Spring 1.1 for interoperability. */ - private static final long serialVersionUID = 2138555143707773549L; - - - @Nullable - private Object value; - - @Nullable - private Throwable exception; - - - /** - * Create a new RemoteInvocationResult for the given result value. - * @param value the result value returned by a successful invocation - * of the target method - */ - public RemoteInvocationResult(@Nullable Object value) { - this.value = value; - } - - /** - * Create a new RemoteInvocationResult for the given exception. - * @param exception the exception thrown by an unsuccessful invocation - * of the target method - */ - public RemoteInvocationResult(@Nullable Throwable exception) { - this.exception = exception; - } - - /** - * Create a new RemoteInvocationResult for JavaBean-style deserialization - * (e.g. with Jackson). - * @see #setValue - * @see #setException - */ - public RemoteInvocationResult() { - } - - - /** - * Set the result value returned by a successful invocation of the - * target method, if any. - *

    This setter is intended for JavaBean-style deserialization. - * Use {@link #RemoteInvocationResult(Object)} otherwise. - * @see #RemoteInvocationResult() - */ - public void setValue(@Nullable Object value) { - this.value = value; - } - - /** - * Return the result value returned by a successful invocation - * of the target method, if any. - * @see #hasException - */ - @Nullable - public Object getValue() { - return this.value; - } - - /** - * Set the exception thrown by an unsuccessful invocation of the - * target method, if any. - *

    This setter is intended for JavaBean-style deserialization. - * Use {@link #RemoteInvocationResult(Throwable)} otherwise. - * @see #RemoteInvocationResult() - */ - public void setException(@Nullable Throwable exception) { - this.exception = exception; - } - - /** - * Return the exception thrown by an unsuccessful invocation - * of the target method, if any. - * @see #hasException - */ - @Nullable - public Throwable getException() { - return this.exception; - } - - /** - * Return whether this invocation result holds an exception. - * If this returns {@code false}, the result value applies - * (even if it is {@code null}). - * @see #getValue - * @see #getException - */ - public boolean hasException() { - return (this.exception != null); - } - - /** - * Return whether this invocation result holds an InvocationTargetException, - * thrown by an invocation of the target method itself. - * @see #hasException() - */ - public boolean hasInvocationTargetException() { - return (this.exception instanceof InvocationTargetException); - } - - - /** - * Recreate the invocation result, either returning the result value - * in case of a successful invocation of the target method, or - * rethrowing the exception thrown by the target method. - * @return the result value, if any - * @throws Throwable the exception, if any - */ - @Nullable - public Object recreate() throws Throwable { - if (this.exception != null) { - Throwable exToThrow = this.exception; - if (this.exception instanceof InvocationTargetException) { - exToThrow = ((InvocationTargetException) this.exception).getTargetException(); - } - RemoteInvocationUtils.fillInClientStackTraceIfPossible(exToThrow); - throw exToThrow; - } - else { - return this.value; - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationTraceInterceptor.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationTraceInterceptor.java deleted file mode 100644 index 2d5dc8e39202..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationTraceInterceptor.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import java.lang.reflect.Method; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.lang.Nullable; -import org.springframework.util.ClassUtils; - -/** - * AOP Alliance MethodInterceptor for tracing remote invocations. - * Automatically applied by RemoteExporter and its subclasses. - * - *

    Logs an incoming remote call as well as the finished processing of a remote call - * at DEBUG level. If the processing of a remote call results in a checked exception, - * the exception will get logged at INFO level; if it results in an unchecked - * exception (or error), the exception will get logged at WARN level. - * - *

    The logging of exceptions is particularly useful to save the stacktrace - * information on the server-side rather than just propagating the exception - * to the client (who might or might not log it properly). - * - * @author Juergen Hoeller - * @since 1.2 - * @see RemoteExporter#setRegisterTraceInterceptor - * @see RemoteExporter#getProxyForService - */ -public class RemoteInvocationTraceInterceptor implements MethodInterceptor { - - protected static final Log logger = LogFactory.getLog(RemoteInvocationTraceInterceptor.class); - - private final String exporterNameClause; - - - /** - * Create a new RemoteInvocationTraceInterceptor. - */ - public RemoteInvocationTraceInterceptor() { - this.exporterNameClause = ""; - } - - /** - * Create a new RemoteInvocationTraceInterceptor. - * @param exporterName the name of the remote exporter - * (to be used as context information in log messages) - */ - public RemoteInvocationTraceInterceptor(String exporterName) { - this.exporterNameClause = exporterName + " "; - } - - - @Override - @Nullable - public Object invoke(MethodInvocation invocation) throws Throwable { - Method method = invocation.getMethod(); - if (logger.isDebugEnabled()) { - logger.debug("Incoming " + this.exporterNameClause + "remote call: " + - ClassUtils.getQualifiedMethodName(method)); - } - try { - Object retVal = invocation.proceed(); - if (logger.isDebugEnabled()) { - logger.debug("Finished processing of " + this.exporterNameClause + "remote call: " + - ClassUtils.getQualifiedMethodName(method)); - } - return retVal; - } - catch (Throwable ex) { - if (ex instanceof RuntimeException || ex instanceof Error) { - if (logger.isWarnEnabled()) { - logger.warn("Processing of " + this.exporterNameClause + "remote call resulted in fatal exception: " + - ClassUtils.getQualifiedMethodName(method), ex); - } - } - else { - if (logger.isInfoEnabled()) { - logger.info("Processing of " + this.exporterNameClause + "remote call resulted in exception: " + - ClassUtils.getQualifiedMethodName(method), ex); - } - } - throw ex; - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationUtils.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationUtils.java deleted file mode 100644 index 612b73c2e966..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationUtils.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import java.util.HashSet; -import java.util.Set; - -/** - * General utilities for handling remote invocations. - * - *

    Mainly intended for use within the remoting framework. - * - * @author Juergen Hoeller - * @since 2.0 - */ -public abstract class RemoteInvocationUtils { - - /** - * Fill the current client-side stack trace into the given exception. - *

    The given exception is typically thrown on the server and serialized - * as-is, with the client wanting it to contain the client-side portion - * of the stack trace as well. What we can do here is to update the - * {@code StackTraceElement} array with the current client-side stack - * trace, provided that we run on JDK 1.4+. - * @param ex the exception to update - * @see Throwable#getStackTrace() - * @see Throwable#setStackTrace(StackTraceElement[]) - */ - public static void fillInClientStackTraceIfPossible(Throwable ex) { - if (ex != null) { - StackTraceElement[] clientStack = new Throwable().getStackTrace(); - Set visitedExceptions = new HashSet<>(); - Throwable exToUpdate = ex; - while (exToUpdate != null && !visitedExceptions.contains(exToUpdate)) { - StackTraceElement[] serverStack = exToUpdate.getStackTrace(); - StackTraceElement[] combinedStack = new StackTraceElement[serverStack.length + clientStack.length]; - System.arraycopy(serverStack, 0, combinedStack, 0, serverStack.length); - System.arraycopy(clientStack, 0, combinedStack, serverStack.length, clientStack.length); - exToUpdate.setStackTrace(combinedStack); - visitedExceptions.add(exToUpdate); - exToUpdate = exToUpdate.getCause(); - } - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemotingSupport.java b/spring-context/src/main/java/org/springframework/remoting/support/RemotingSupport.java deleted file mode 100644 index 51acfdf4f4d7..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/RemotingSupport.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.lang.Nullable; -import org.springframework.util.ClassUtils; - -/** - * Generic support base class for remote accessor and exporters, - * providing common bean ClassLoader handling. - * - * @author Juergen Hoeller - * @since 2.5.2 - */ -public abstract class RemotingSupport implements BeanClassLoaderAware { - - /** Logger available to subclasses. */ - protected final Log logger = LogFactory.getLog(getClass()); - - private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); - - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } - - /** - * Return the ClassLoader that this accessor operates in, - * to be used for deserializing and for generating proxies. - */ - protected ClassLoader getBeanClassLoader() { - return this.beanClassLoader; - } - - - /** - * Override the thread context ClassLoader with the environment's bean ClassLoader - * if necessary, i.e. if the bean ClassLoader is not equivalent to the thread - * context ClassLoader already. - * @return the original thread context ClassLoader, or {@code null} if not overridden - */ - @Nullable - protected ClassLoader overrideThreadContextClassLoader() { - return ClassUtils.overrideThreadContextClassLoader(getBeanClassLoader()); - } - - /** - * Reset the original thread context ClassLoader if necessary. - * @param original the original thread context ClassLoader, - * or {@code null} if not overridden (and hence nothing to reset) - */ - protected void resetThreadContextClassLoader(@Nullable ClassLoader original) { - if (original != null) { - Thread.currentThread().setContextClassLoader(original); - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/SimpleHttpServerFactoryBean.java b/spring-context/src/main/java/org/springframework/remoting/support/SimpleHttpServerFactoryBean.java deleted file mode 100644 index f72fb9fdba8e..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/SimpleHttpServerFactoryBean.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Executor; - -import com.sun.net.httpserver.Authenticator; -import com.sun.net.httpserver.Filter; -import com.sun.net.httpserver.HttpContext; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; - -/** - * {@link org.springframework.beans.factory.FactoryBean} that creates a simple - * HTTP server, based on the HTTP server that is included in Sun's JRE 1.6. - * Starts the HTTP server on initialization and stops it on destruction. - * Exposes the resulting {@link com.sun.net.httpserver.HttpServer} object. - * - *

    Allows for registering {@link com.sun.net.httpserver.HttpHandler HttpHandlers} - * for specific {@link #setContexts context paths}. Alternatively, - * register such context-specific handlers programmatically on the - * {@link com.sun.net.httpserver.HttpServer} itself. - * - * @author Juergen Hoeller - * @author Arjen Poutsma - * @since 2.5.1 - * @see #setPort - * @see #setContexts - * @deprecated as of Spring Framework 5.1, in favor of embedded Tomcat/Jetty/Undertow - */ -@Deprecated -@org.springframework.lang.UsesSunHttpServer -public class SimpleHttpServerFactoryBean implements FactoryBean, InitializingBean, DisposableBean { - - protected final Log logger = LogFactory.getLog(getClass()); - - private int port = 8080; - - private String hostname; - - private int backlog = -1; - - private int shutdownDelay = 0; - - private Executor executor; - - private Map contexts; - - private List filters; - - private Authenticator authenticator; - - private HttpServer server; - - - /** - * Specify the HTTP server's port. Default is 8080. - */ - public void setPort(int port) { - this.port = port; - } - - /** - * Specify the HTTP server's hostname to bind to. Default is localhost; - * can be overridden with a specific network address to bind to. - */ - public void setHostname(String hostname) { - this.hostname = hostname; - } - - /** - * Specify the HTTP server's TCP backlog. Default is -1, - * indicating the system's default value. - */ - public void setBacklog(int backlog) { - this.backlog = backlog; - } - - /** - * Specify the number of seconds to wait until HTTP exchanges have - * completed when shutting down the HTTP server. Default is 0. - */ - public void setShutdownDelay(int shutdownDelay) { - this.shutdownDelay = shutdownDelay; - } - - /** - * Set the JDK concurrent executor to use for dispatching incoming requests. - * @see com.sun.net.httpserver.HttpServer#setExecutor - */ - public void setExecutor(Executor executor) { - this.executor = executor; - } - - /** - * Register {@link com.sun.net.httpserver.HttpHandler HttpHandlers} - * for specific context paths. - * @param contexts a Map with context paths as keys and HttpHandler - * objects as values - * @see org.springframework.remoting.httpinvoker.SimpleHttpInvokerServiceExporter - * @see org.springframework.remoting.caucho.SimpleHessianServiceExporter - */ - public void setContexts(Map contexts) { - this.contexts = contexts; - } - - /** - * Register common {@link com.sun.net.httpserver.Filter Filters} to be - * applied to all locally registered {@link #setContexts contexts}. - */ - public void setFilters(List filters) { - this.filters = filters; - } - - /** - * Register a common {@link com.sun.net.httpserver.Authenticator} to be - * applied to all locally registered {@link #setContexts contexts}. - */ - public void setAuthenticator(Authenticator authenticator) { - this.authenticator = authenticator; - } - - - @Override - public void afterPropertiesSet() throws IOException { - InetSocketAddress address = (this.hostname != null ? - new InetSocketAddress(this.hostname, this.port) : new InetSocketAddress(this.port)); - this.server = HttpServer.create(address, this.backlog); - if (this.executor != null) { - this.server.setExecutor(this.executor); - } - if (this.contexts != null) { - this.contexts.forEach((key, context) -> { - HttpContext httpContext = this.server.createContext(key, context); - if (this.filters != null) { - httpContext.getFilters().addAll(this.filters); - } - if (this.authenticator != null) { - httpContext.setAuthenticator(this.authenticator); - } - }); - } - if (logger.isInfoEnabled()) { - logger.info("Starting HttpServer at address " + address); - } - this.server.start(); - } - - @Override - public HttpServer getObject() { - return this.server; - } - - @Override - public Class getObjectType() { - return (this.server != null ? this.server.getClass() : HttpServer.class); - } - - @Override - public boolean isSingleton() { - return true; - } - - @Override - public void destroy() { - logger.info("Stopping HttpServer"); - this.server.stop(this.shutdownDelay); - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/UrlBasedRemoteAccessor.java b/spring-context/src/main/java/org/springframework/remoting/support/UrlBasedRemoteAccessor.java deleted file mode 100644 index 93c65ac220e6..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/UrlBasedRemoteAccessor.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import org.springframework.beans.factory.InitializingBean; - -/** - * Abstract base class for classes that access remote services via URLs. - * Provides a "serviceUrl" bean property, which is considered as required. - * - * @author Juergen Hoeller - * @since 15.12.2003 - */ -public abstract class UrlBasedRemoteAccessor extends RemoteAccessor implements InitializingBean { - - private String serviceUrl; - - - /** - * Set the URL of this remote accessor's target service. - * The URL must be compatible with the rules of the particular remoting provider. - */ - public void setServiceUrl(String serviceUrl) { - this.serviceUrl = serviceUrl; - } - - /** - * Return the URL of this remote accessor's target service. - */ - public String getServiceUrl() { - return this.serviceUrl; - } - - - @Override - public void afterPropertiesSet() { - if (getServiceUrl() == null) { - throw new IllegalArgumentException("Property 'serviceUrl' is required"); - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/remoting/support/package-info.java b/spring-context/src/main/java/org/springframework/remoting/support/package-info.java deleted file mode 100644 index 316306149a2b..000000000000 --- a/spring-context/src/main/java/org/springframework/remoting/support/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Generic support classes for remoting implementations. - * Provides abstract base classes for remote proxy factories. - */ -package org.springframework.remoting.support; diff --git a/spring-context/src/test/java/org/springframework/remoting/rmi/RmiSupportTests.java b/spring-context/src/test/java/org/springframework/remoting/rmi/RmiSupportTests.java deleted file mode 100644 index 82780251a59d..000000000000 --- a/spring-context/src/test/java/org/springframework/remoting/rmi/RmiSupportTests.java +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.rmi; - -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.rmi.ConnectException; -import java.rmi.ConnectIOException; -import java.rmi.MarshalException; -import java.rmi.NoSuchObjectException; -import java.rmi.Remote; -import java.rmi.RemoteException; -import java.rmi.StubNotFoundException; -import java.rmi.UnknownHostException; -import java.rmi.UnmarshalException; - -import org.aopalliance.intercept.MethodInvocation; -import org.junit.jupiter.api.Test; - -import org.springframework.remoting.RemoteAccessException; -import org.springframework.remoting.RemoteConnectFailureException; -import org.springframework.remoting.RemoteProxyFailureException; -import org.springframework.remoting.support.RemoteInvocation; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * @author Juergen Hoeller - * @since 16.05.2003 - */ -public class RmiSupportTests { - - @Test - public void rmiProxyFactoryBean() throws Exception { - CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean(); - factory.setServiceInterface(IRemoteBean.class); - factory.setServiceUrl("rmi://localhost:1090/test"); - factory.afterPropertiesSet(); - assertThat(factory.isSingleton()).as("Correct singleton value").isTrue(); - boolean condition = factory.getObject() instanceof IRemoteBean; - assertThat(condition).isTrue(); - IRemoteBean proxy = (IRemoteBean) factory.getObject(); - proxy.setName("myName"); - assertThat(RemoteBean.name).isEqualTo("myName"); - assertThat(factory.counter).isEqualTo(1); - } - - @Test - public void rmiProxyFactoryBeanWithRemoteException() throws Exception { - doTestRmiProxyFactoryBeanWithException(RemoteException.class); - } - - @Test - public void rmiProxyFactoryBeanWithConnectException() throws Exception { - doTestRmiProxyFactoryBeanWithException(ConnectException.class); - } - - @Test - public void rmiProxyFactoryBeanWithConnectIOException() throws Exception { - doTestRmiProxyFactoryBeanWithException(ConnectIOException.class); - } - - @Test - public void rmiProxyFactoryBeanWithUnknownHostException() throws Exception { - doTestRmiProxyFactoryBeanWithException(UnknownHostException.class); - } - - @Test - public void rmiProxyFactoryBeanWithNoSuchObjectException() throws Exception { - doTestRmiProxyFactoryBeanWithException(NoSuchObjectException.class); - } - - @Test - public void rmiProxyFactoryBeanWithStubNotFoundException() throws Exception { - doTestRmiProxyFactoryBeanWithException(StubNotFoundException.class); - } - - @Test - public void rmiProxyFactoryBeanWithMarshalException() throws Exception { - doTestRmiProxyFactoryBeanWithException(MarshalException.class); - } - - @Test - public void rmiProxyFactoryBeanWithUnmarshalException() throws Exception { - doTestRmiProxyFactoryBeanWithException(UnmarshalException.class); - } - - private void doTestRmiProxyFactoryBeanWithException(Class exceptionClass) throws Exception { - CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean(); - factory.setServiceInterface(IRemoteBean.class); - factory.setServiceUrl("rmi://localhost:1090/test"); - factory.afterPropertiesSet(); - boolean condition = factory.getObject() instanceof IRemoteBean; - assertThat(condition).isTrue(); - IRemoteBean proxy = (IRemoteBean) factory.getObject(); - assertThatExceptionOfType(exceptionClass).isThrownBy(() -> - proxy.setName(exceptionClass.getName())); - assertThat(factory.counter).isEqualTo(1); - } - - @Test - public void rmiProxyFactoryBeanWithConnectExceptionAndRefresh() throws Exception { - doTestRmiProxyFactoryBeanWithExceptionAndRefresh(ConnectException.class); - } - - @Test - public void rmiProxyFactoryBeanWithConnectIOExceptionAndRefresh() throws Exception { - doTestRmiProxyFactoryBeanWithExceptionAndRefresh(ConnectIOException.class); - } - - @Test - public void rmiProxyFactoryBeanWithUnknownHostExceptionAndRefresh() throws Exception { - doTestRmiProxyFactoryBeanWithExceptionAndRefresh(UnknownHostException.class); - } - - @Test - public void rmiProxyFactoryBeanWithNoSuchObjectExceptionAndRefresh() throws Exception { - doTestRmiProxyFactoryBeanWithExceptionAndRefresh(NoSuchObjectException.class); - } - - @Test - public void rmiProxyFactoryBeanWithStubNotFoundExceptionAndRefresh() throws Exception { - doTestRmiProxyFactoryBeanWithExceptionAndRefresh(StubNotFoundException.class); - } - - private void doTestRmiProxyFactoryBeanWithExceptionAndRefresh(Class exceptionClass) throws Exception { - CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean(); - factory.setServiceInterface(IRemoteBean.class); - factory.setServiceUrl("rmi://localhost:1090/test"); - factory.setRefreshStubOnConnectFailure(true); - factory.afterPropertiesSet(); - boolean condition = factory.getObject() instanceof IRemoteBean; - assertThat(condition).isTrue(); - IRemoteBean proxy = (IRemoteBean) factory.getObject(); - assertThatExceptionOfType(exceptionClass).isThrownBy(() -> - proxy.setName(exceptionClass.getName())); - assertThat(factory.counter).isEqualTo(2); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterface() throws Exception { - CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean(); - factory.setServiceInterface(IBusinessBean.class); - factory.setServiceUrl("rmi://localhost:1090/test"); - factory.afterPropertiesSet(); - boolean condition = factory.getObject() instanceof IBusinessBean; - assertThat(condition).isTrue(); - IBusinessBean proxy = (IBusinessBean) factory.getObject(); - boolean condition1 = proxy instanceof IRemoteBean; - assertThat(condition1).isFalse(); - proxy.setName("myName"); - assertThat(RemoteBean.name).isEqualTo("myName"); - assertThat(factory.counter).isEqualTo(1); - } - - @Test - public void rmiProxyFactoryBeanWithWrongBusinessInterface() throws Exception { - CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean(); - factory.setServiceInterface(IWrongBusinessBean.class); - factory.setServiceUrl("rmi://localhost:1090/test"); - factory.afterPropertiesSet(); - boolean condition = factory.getObject() instanceof IWrongBusinessBean; - assertThat(condition).isTrue(); - IWrongBusinessBean proxy = (IWrongBusinessBean) factory.getObject(); - boolean condition1 = proxy instanceof IRemoteBean; - assertThat(condition1).isFalse(); - assertThatExceptionOfType(RemoteProxyFailureException.class).isThrownBy(() -> - proxy.setOtherName("name")) - .withCauseInstanceOf(NoSuchMethodException.class) - .withMessageContaining("setOtherName") - .withMessageContaining("IWrongBusinessBean"); - assertThat(factory.counter).isEqualTo(1); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterfaceAndRemoteException() throws Exception { - doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException( - RemoteException.class, RemoteAccessException.class); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterfaceAndConnectException() throws Exception { - doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException( - ConnectException.class, RemoteConnectFailureException.class); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterfaceAndConnectIOException() throws Exception { - doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException( - ConnectIOException.class, RemoteConnectFailureException.class); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterfaceAndUnknownHostException() throws Exception { - doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException( - UnknownHostException.class, RemoteConnectFailureException.class); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterfaceAndNoSuchObjectExceptionException() throws Exception { - doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException( - NoSuchObjectException.class, RemoteConnectFailureException.class); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterfaceAndStubNotFoundException() throws Exception { - doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException( - StubNotFoundException.class, RemoteConnectFailureException.class); - } - - private void doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException( - Class rmiExceptionClass, Class springExceptionClass) throws Exception { - - CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean(); - factory.setServiceInterface(IBusinessBean.class); - factory.setServiceUrl("rmi://localhost:1090/test"); - factory.afterPropertiesSet(); - boolean condition = factory.getObject() instanceof IBusinessBean; - assertThat(condition).isTrue(); - IBusinessBean proxy = (IBusinessBean) factory.getObject(); - boolean condition1 = proxy instanceof IRemoteBean; - assertThat(condition1).isFalse(); - assertThatExceptionOfType(springExceptionClass).isThrownBy(() -> - proxy.setName(rmiExceptionClass.getName())); - assertThat(factory.counter).isEqualTo(1); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterfaceAndRemoteExceptionAndRefresh() throws Exception { - doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh( - RemoteException.class, RemoteAccessException.class); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterfaceAndConnectExceptionAndRefresh() throws Exception { - doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh( - ConnectException.class, RemoteConnectFailureException.class); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterfaceAndConnectIOExceptionAndRefresh() throws Exception { - doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh( - ConnectIOException.class, RemoteConnectFailureException.class); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterfaceAndUnknownHostExceptionAndRefresh() throws Exception { - doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh( - UnknownHostException.class, RemoteConnectFailureException.class); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterfaceAndNoSuchObjectExceptionAndRefresh() throws Exception { - doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh( - NoSuchObjectException.class, RemoteConnectFailureException.class); - } - - @Test - public void rmiProxyFactoryBeanWithBusinessInterfaceAndStubNotFoundExceptionAndRefresh() throws Exception { - doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh( - StubNotFoundException.class, RemoteConnectFailureException.class); - } - - private void doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh( - Class rmiExceptionClass, Class springExceptionClass) throws Exception { - - CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean(); - factory.setServiceInterface(IBusinessBean.class); - factory.setServiceUrl("rmi://localhost:1090/test"); - factory.setRefreshStubOnConnectFailure(true); - factory.afterPropertiesSet(); - boolean condition = factory.getObject() instanceof IBusinessBean; - assertThat(condition).isTrue(); - IBusinessBean proxy = (IBusinessBean) factory.getObject(); - boolean condition1 = proxy instanceof IRemoteBean; - assertThat(condition1).isFalse(); - assertThatExceptionOfType(springExceptionClass).isThrownBy(() -> - proxy.setName(rmiExceptionClass.getName())); - boolean isRemoteConnectFailure = RemoteConnectFailureException.class.isAssignableFrom(springExceptionClass); - assertThat(factory.counter).isEqualTo(isRemoteConnectFailure ? 2 : 1); - } - - @Test - public void rmiClientInterceptorRequiresUrl() throws Exception{ - RmiClientInterceptor client = new RmiClientInterceptor(); - client.setServiceInterface(IRemoteBean.class); - assertThatIllegalArgumentException().isThrownBy(client::afterPropertiesSet); - } - - @Test - public void remoteInvocation() throws NoSuchMethodException { - // let's see if the remote invocation object works - - final RemoteBean rb = new RemoteBean(); - final Method setNameMethod = rb.getClass().getDeclaredMethod("setName", String.class); - - MethodInvocation mi = new MethodInvocation() { - @Override - public Method getMethod() { - return setNameMethod; - } - @Override - public Object[] getArguments() { - return new Object[] {"bla"}; - } - @Override - public Object proceed() throws Throwable { - throw new UnsupportedOperationException(); - } - @Override - public Object getThis() { - return rb; - } - @Override - public AccessibleObject getStaticPart() { - return setNameMethod; - } - }; - - RemoteInvocation inv = new RemoteInvocation(mi); - - assertThat(inv.getMethodName()).isEqualTo("setName"); - assertThat(inv.getArguments()[0]).isEqualTo("bla"); - assertThat(inv.getParameterTypes()[0]).isEqualTo(String.class); - - // this is a bit BS, but we need to test it - inv = new RemoteInvocation(); - inv.setArguments(new Object[] { "bla" }); - assertThat(inv.getArguments()[0]).isEqualTo("bla"); - inv.setMethodName("setName"); - assertThat(inv.getMethodName()).isEqualTo("setName"); - inv.setParameterTypes(new Class[] {String.class}); - assertThat(inv.getParameterTypes()[0]).isEqualTo(String.class); - - inv = new RemoteInvocation("setName", new Class[] {String.class}, new Object[] {"bla"}); - assertThat(inv.getArguments()[0]).isEqualTo("bla"); - assertThat(inv.getMethodName()).isEqualTo("setName"); - assertThat(inv.getParameterTypes()[0]).isEqualTo(String.class); - } - - @Test - public void rmiInvokerWithSpecialLocalMethods() throws Exception { - String serviceUrl = "rmi://localhost:1090/test"; - RmiProxyFactoryBean factory = new RmiProxyFactoryBean() { - @Override - protected Remote lookupStub() { - return new RmiInvocationHandler() { - @Override - public String getTargetInterfaceName() { - return null; - } - @Override - public Object invoke(RemoteInvocation invocation) throws RemoteException { - throw new RemoteException(); - } - }; - } - }; - factory.setServiceInterface(IBusinessBean.class); - factory.setServiceUrl(serviceUrl); - factory.afterPropertiesSet(); - IBusinessBean proxy = (IBusinessBean) factory.getObject(); - - // shouldn't go through to remote service - assertThat(proxy.toString().contains("RMI invoker")).isTrue(); - assertThat(proxy.toString().contains(serviceUrl)).isTrue(); - assertThat(proxy.hashCode()).isEqualTo(proxy.hashCode()); - assertThat(proxy.equals(proxy)).isTrue(); - - // should go through - assertThatExceptionOfType(RemoteAccessException.class).isThrownBy(() -> - proxy.setName("test")); - } - - - private static class CountingRmiProxyFactoryBean extends RmiProxyFactoryBean { - - private int counter = 0; - - @Override - protected Remote lookupStub() { - counter++; - return new RemoteBean(); - } - } - - - public interface IBusinessBean { - - void setName(String name); - } - - - public interface IWrongBusinessBean { - - void setOtherName(String name); - } - - - public interface IRemoteBean extends Remote { - - void setName(String name) throws RemoteException; - } - - - public static class RemoteBean implements IRemoteBean { - - private static String name; - - @Override - public void setName(String nam) throws RemoteException { - if (nam != null && nam.endsWith("Exception")) { - RemoteException rex; - try { - Class exClass = Class.forName(nam); - Constructor ctor = exClass.getConstructor(String.class); - rex = (RemoteException) ctor.newInstance("myMessage"); - } - catch (Exception ex) { - throw new RemoteException("Illegal exception class name: " + nam, ex); - } - throw rex; - } - name = nam; - } - } - -} diff --git a/spring-context/src/test/java/org/springframework/remoting/support/RemoteInvocationUtilsTests.java b/spring-context/src/test/java/org/springframework/remoting/support/RemoteInvocationUtilsTests.java deleted file mode 100644 index dbaa7a429447..000000000000 --- a/spring-context/src/test/java/org/springframework/remoting/support/RemoteInvocationUtilsTests.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.support; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Rick Evans - */ -public class RemoteInvocationUtilsTests { - - @Test - public void fillInClientStackTraceIfPossibleSunnyDay() throws Exception { - try { - throw new IllegalStateException("Mmm"); - } - catch (Exception ex) { - int originalStackTraceLngth = ex.getStackTrace().length; - RemoteInvocationUtils.fillInClientStackTraceIfPossible(ex); - assertThat(ex.getStackTrace().length > originalStackTraceLngth).as("Stack trace not being filled in").isTrue(); - } - } - - @Test - public void fillInClientStackTraceIfPossibleWithNullThrowable() throws Exception { - // just want to ensure that it doesn't bomb - RemoteInvocationUtils.fillInClientStackTraceIfPossible(null); - } - -} diff --git a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerClientInterceptor.java b/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerClientInterceptor.java deleted file mode 100644 index 04566b4109e8..000000000000 --- a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerClientInterceptor.java +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jms.remoting; - -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageFormatException; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TemporaryQueue; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.aop.support.AopUtils; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.jms.connection.ConnectionFactoryUtils; -import org.springframework.jms.support.JmsUtils; -import org.springframework.jms.support.converter.MessageConverter; -import org.springframework.jms.support.converter.SimpleMessageConverter; -import org.springframework.jms.support.destination.DestinationResolver; -import org.springframework.jms.support.destination.DynamicDestinationResolver; -import org.springframework.lang.Nullable; -import org.springframework.remoting.RemoteAccessException; -import org.springframework.remoting.RemoteInvocationFailureException; -import org.springframework.remoting.RemoteTimeoutException; -import org.springframework.remoting.support.DefaultRemoteInvocationFactory; -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.remoting.support.RemoteInvocationFactory; -import org.springframework.remoting.support.RemoteInvocationResult; -import org.springframework.util.Assert; - -/** - * {@link org.aopalliance.intercept.MethodInterceptor} for accessing a - * JMS-based remote service. - * - *

    Serializes remote invocation objects and deserializes remote invocation - * result objects. Uses Java serialization just like RMI, but with the JMS - * provider as communication infrastructure. - * - *

    To be configured with a {@link javax.jms.QueueConnectionFactory} and a - * target queue (either as {@link javax.jms.Queue} reference or as queue name). - * - *

    Thanks to James Strachan for the original prototype that this - * JMS invoker mechanism was inspired by! - * - * @author Juergen Hoeller - * @author James Strachan - * @author Stephane Nicoll - * @since 2.0 - * @see #setConnectionFactory - * @see #setQueue - * @see #setQueueName - * @see org.springframework.jms.remoting.JmsInvokerServiceExporter - * @see org.springframework.jms.remoting.JmsInvokerProxyFactoryBean - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class JmsInvokerClientInterceptor implements MethodInterceptor, InitializingBean { - - @Nullable - private ConnectionFactory connectionFactory; - - @Nullable - private Object queue; - - private DestinationResolver destinationResolver = new DynamicDestinationResolver(); - - private RemoteInvocationFactory remoteInvocationFactory = new DefaultRemoteInvocationFactory(); - - private MessageConverter messageConverter = new SimpleMessageConverter(); - - private long receiveTimeout = 0; - - - /** - * Set the QueueConnectionFactory to use for obtaining JMS QueueConnections. - */ - public void setConnectionFactory(@Nullable ConnectionFactory connectionFactory) { - this.connectionFactory = connectionFactory; - } - - /** - * Return the QueueConnectionFactory to use for obtaining JMS QueueConnections. - */ - @Nullable - protected ConnectionFactory getConnectionFactory() { - return this.connectionFactory; - } - - /** - * Set the target Queue to send invoker requests to. - */ - public void setQueue(Queue queue) { - this.queue = queue; - } - - /** - * Set the name of target queue to send invoker requests to. - *

    The specified name will be dynamically resolved via the - * {@link #setDestinationResolver DestinationResolver}. - */ - public void setQueueName(String queueName) { - this.queue = queueName; - } - - /** - * Set the DestinationResolver that is to be used to resolve Queue - * references for this accessor. - *

    The default resolver is a {@code DynamicDestinationResolver}. Specify a - * {@code JndiDestinationResolver} for resolving destination names as JNDI locations. - * @see org.springframework.jms.support.destination.DynamicDestinationResolver - * @see org.springframework.jms.support.destination.JndiDestinationResolver - */ - public void setDestinationResolver(@Nullable DestinationResolver destinationResolver) { - this.destinationResolver = - (destinationResolver != null ? destinationResolver : new DynamicDestinationResolver()); - } - - /** - * Set the {@link RemoteInvocationFactory} to use for this accessor. - *

    Default is a {@link DefaultRemoteInvocationFactory}. - *

    A custom invocation factory can add further context information - * to the invocation, for example user credentials. - */ - public void setRemoteInvocationFactory(@Nullable RemoteInvocationFactory remoteInvocationFactory) { - this.remoteInvocationFactory = - (remoteInvocationFactory != null ? remoteInvocationFactory : new DefaultRemoteInvocationFactory()); - } - - /** - * Specify the {@link MessageConverter} to use for turning - * {@link org.springframework.remoting.support.RemoteInvocation} - * objects into request messages, as well as response messages into - * {@link org.springframework.remoting.support.RemoteInvocationResult} objects. - *

    Default is a {@link SimpleMessageConverter}, using a standard JMS - * {@link javax.jms.ObjectMessage} for each invocation / invocation result - * object. - *

    Custom implementations may generally adapt {@link java.io.Serializable} - * objects into special kinds of messages, or might be specifically tailored for - * translating {@code RemoteInvocation(Result)s} into specific kinds of messages. - */ - public void setMessageConverter(@Nullable MessageConverter messageConverter) { - this.messageConverter = (messageConverter != null ? messageConverter : new SimpleMessageConverter()); - } - - /** - * Set the timeout to use for receiving the response message for a request - * (in milliseconds). - *

    The default is 0, which indicates a blocking receive without timeout. - * @see javax.jms.MessageConsumer#receive(long) - * @see javax.jms.MessageConsumer#receive() - */ - public void setReceiveTimeout(long receiveTimeout) { - this.receiveTimeout = receiveTimeout; - } - - /** - * Return the timeout to use for receiving the response message for a request - * (in milliseconds). - */ - protected long getReceiveTimeout() { - return this.receiveTimeout; - } - - - @Override - public void afterPropertiesSet() { - if (getConnectionFactory() == null) { - throw new IllegalArgumentException("Property 'connectionFactory' is required"); - } - if (this.queue == null) { - throw new IllegalArgumentException("'queue' or 'queueName' is required"); - } - } - - - @Override - @Nullable - public Object invoke(MethodInvocation methodInvocation) throws Throwable { - if (AopUtils.isToStringMethod(methodInvocation.getMethod())) { - return "JMS invoker proxy for queue [" + this.queue + "]"; - } - - RemoteInvocation invocation = createRemoteInvocation(methodInvocation); - RemoteInvocationResult result; - try { - result = executeRequest(invocation); - } - catch (JMSException ex) { - throw convertJmsInvokerAccessException(ex); - } - try { - return recreateRemoteInvocationResult(result); - } - catch (Throwable ex) { - if (result.hasInvocationTargetException()) { - throw ex; - } - else { - throw new RemoteInvocationFailureException("Invocation of method [" + methodInvocation.getMethod() + - "] failed in JMS invoker remote service at queue [" + this.queue + "]", ex); - } - } - } - - /** - * Create a new {@code RemoteInvocation} object for the given AOP method invocation. - *

    The default implementation delegates to the {@link RemoteInvocationFactory}. - *

    Can be overridden in subclasses to provide custom {@code RemoteInvocation} - * subclasses, containing additional invocation parameters like user credentials. - * Note that it is preferable to use a custom {@code RemoteInvocationFactory} which - * is a reusable strategy. - * @param methodInvocation the current AOP method invocation - * @return the RemoteInvocation object - * @see RemoteInvocationFactory#createRemoteInvocation - */ - protected RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) { - return this.remoteInvocationFactory.createRemoteInvocation(methodInvocation); - } - - /** - * Execute the given remote invocation, sending an invoker request message - * to this accessor's target queue and waiting for a corresponding response. - * @param invocation the RemoteInvocation to execute - * @return the RemoteInvocationResult object - * @throws JMSException in case of JMS failure - * @see #doExecuteRequest - */ - protected RemoteInvocationResult executeRequest(RemoteInvocation invocation) throws JMSException { - Connection con = createConnection(); - Session session = null; - try { - session = createSession(con); - Queue queueToUse = resolveQueue(session); - Message requestMessage = createRequestMessage(session, invocation); - con.start(); - Message responseMessage = doExecuteRequest(session, queueToUse, requestMessage); - if (responseMessage != null) { - return extractInvocationResult(responseMessage); - } - else { - return onReceiveTimeout(invocation); - } - } - finally { - JmsUtils.closeSession(session); - ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory(), true); - } - } - - /** - * Create a new JMS Connection for this JMS invoker. - */ - protected Connection createConnection() throws JMSException { - ConnectionFactory connectionFactory = getConnectionFactory(); - Assert.state(connectionFactory != null, "No ConnectionFactory set"); - return connectionFactory.createConnection(); - } - - /** - * Create a new JMS Session for this JMS invoker. - */ - protected Session createSession(Connection con) throws JMSException { - return con.createSession(false, Session.AUTO_ACKNOWLEDGE); - } - - /** - * Resolve this accessor's target queue. - * @param session the current JMS Session - * @return the resolved target Queue - * @throws JMSException if resolution failed - */ - protected Queue resolveQueue(Session session) throws JMSException { - if (this.queue instanceof Queue) { - return (Queue) this.queue; - } - else if (this.queue instanceof String) { - return resolveQueueName(session, (String) this.queue); - } - else { - throw new javax.jms.IllegalStateException( - "Queue object [" + this.queue + "] is neither a [javax.jms.Queue] nor a queue name String"); - } - } - - /** - * Resolve the given queue name into a JMS {@link javax.jms.Queue}, - * via this accessor's {@link DestinationResolver}. - * @param session the current JMS Session - * @param queueName the name of the queue - * @return the located Queue - * @throws JMSException if resolution failed - * @see #setDestinationResolver - */ - protected Queue resolveQueueName(Session session, String queueName) throws JMSException { - return (Queue) this.destinationResolver.resolveDestinationName(session, queueName, false); - } - - /** - * Create the invoker request message. - *

    The default implementation creates a JMS {@link javax.jms.ObjectMessage} - * for the given RemoteInvocation object. - * @param session the current JMS Session - * @param invocation the remote invocation to send - * @return the JMS Message to send - * @throws JMSException if the message could not be created - */ - protected Message createRequestMessage(Session session, RemoteInvocation invocation) throws JMSException { - return this.messageConverter.toMessage(invocation, session); - } - - /** - * Actually execute the given request, sending the invoker request message - * to the specified target queue and waiting for a corresponding response. - *

    The default implementation is based on standard JMS send/receive, - * using a {@link javax.jms.TemporaryQueue} for receiving the response. - * @param session the JMS Session to use - * @param queue the resolved target Queue to send to - * @param requestMessage the JMS Message to send - * @return the RemoteInvocationResult object - * @throws JMSException in case of JMS failure - */ - @Nullable - protected Message doExecuteRequest(Session session, Queue queue, Message requestMessage) throws JMSException { - TemporaryQueue responseQueue = null; - MessageProducer producer = null; - MessageConsumer consumer = null; - try { - responseQueue = session.createTemporaryQueue(); - producer = session.createProducer(queue); - consumer = session.createConsumer(responseQueue); - requestMessage.setJMSReplyTo(responseQueue); - producer.send(requestMessage); - long timeout = getReceiveTimeout(); - return (timeout > 0 ? consumer.receive(timeout) : consumer.receive()); - } - finally { - JmsUtils.closeMessageConsumer(consumer); - JmsUtils.closeMessageProducer(producer); - if (responseQueue != null) { - responseQueue.delete(); - } - } - } - - /** - * Extract the invocation result from the response message. - *

    The default implementation expects a JMS {@link javax.jms.ObjectMessage} - * carrying a {@link RemoteInvocationResult} object. If an invalid response - * message is encountered, the {@code onInvalidResponse} callback gets invoked. - * @param responseMessage the response message - * @return the invocation result - * @throws JMSException is thrown if a JMS exception occurs - * @see #onInvalidResponse - */ - protected RemoteInvocationResult extractInvocationResult(Message responseMessage) throws JMSException { - Object content = this.messageConverter.fromMessage(responseMessage); - if (content instanceof RemoteInvocationResult) { - return (RemoteInvocationResult) content; - } - return onInvalidResponse(responseMessage); - } - - /** - * Callback that is invoked by {@link #executeRequest} when the receive - * timeout has expired for the specified {@link RemoteInvocation}. - *

    By default, an {@link RemoteTimeoutException} is thrown. Sub-classes - * can choose to either throw a more dedicated exception or even return - * a default {@link RemoteInvocationResult} as a fallback. - * @param invocation the invocation - * @return a default result when the receive timeout has expired - */ - protected RemoteInvocationResult onReceiveTimeout(RemoteInvocation invocation) { - throw new RemoteTimeoutException("Receive timeout after " + this.receiveTimeout + " ms for " + invocation); - } - - /** - * Callback that is invoked by {@link #extractInvocationResult} when - * it encounters an invalid response message. - *

    The default implementation throws a {@link MessageFormatException}. - * @param responseMessage the invalid response message - * @return an alternative invocation result that should be returned to - * the caller (if desired) - * @throws JMSException if the invalid response should lead to an - * infrastructure exception propagated to the caller - * @see #extractInvocationResult - */ - protected RemoteInvocationResult onInvalidResponse(Message responseMessage) throws JMSException { - throw new MessageFormatException("Invalid response message: " + responseMessage); - } - - /** - * Recreate the invocation result contained in the given {@link RemoteInvocationResult} - * object. - *

    The default implementation calls the default {@code recreate()} method. - *

    Can be overridden in subclasses to provide custom recreation, potentially - * processing the returned result object. - * @param result the RemoteInvocationResult to recreate - * @return a return value if the invocation result is a successful return - * @throws Throwable if the invocation result is an exception - * @see org.springframework.remoting.support.RemoteInvocationResult#recreate() - */ - @Nullable - protected Object recreateRemoteInvocationResult(RemoteInvocationResult result) throws Throwable { - return result.recreate(); - } - - /** - * Convert the given JMS invoker access exception to an appropriate - * Spring {@link RemoteAccessException}. - * @param ex the exception to convert - * @return the RemoteAccessException to throw - */ - protected RemoteAccessException convertJmsInvokerAccessException(JMSException ex) { - return new RemoteAccessException("Could not access JMS invoker queue [" + this.queue + "]", ex); - } - -} diff --git a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerProxyFactoryBean.java b/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerProxyFactoryBean.java deleted file mode 100644 index 4562b602a51e..000000000000 --- a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerProxyFactoryBean.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jms.remoting; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * FactoryBean for JMS invoker proxies. Exposes the proxied service for use - * as a bean reference, using the specified service interface. - * - *

    Serializes remote invocation objects and deserializes remote invocation - * result objects. Uses Java serialization just like RMI, but with the JMS - * provider as communication infrastructure. - * - *

    To be configured with a {@link javax.jms.QueueConnectionFactory} and a - * target queue (either as {@link javax.jms.Queue} reference or as queue name). - * - * @author Juergen Hoeller - * @since 2.0 - * @see #setConnectionFactory - * @see #setQueueName - * @see #setServiceInterface - * @see org.springframework.jms.remoting.JmsInvokerClientInterceptor - * @see org.springframework.jms.remoting.JmsInvokerServiceExporter - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class JmsInvokerProxyFactoryBean extends JmsInvokerClientInterceptor - implements FactoryBean, BeanClassLoaderAware { - - @Nullable - private Class serviceInterface; - - @Nullable - private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); - - @Nullable - private Object serviceProxy; - - - /** - * Set the interface that the proxy must implement. - * @param serviceInterface the interface that the proxy must implement - * @throws IllegalArgumentException if the supplied {@code serviceInterface} - * is not an interface type - */ - public void setServiceInterface(Class serviceInterface) { - Assert.notNull(serviceInterface, "'serviceInterface' must not be null"); - Assert.isTrue(serviceInterface.isInterface(), "'serviceInterface' must be an interface"); - this.serviceInterface = serviceInterface; - } - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } - - @Override - public void afterPropertiesSet() { - super.afterPropertiesSet(); - Assert.notNull(this.serviceInterface, "Property 'serviceInterface' is required"); - this.serviceProxy = new ProxyFactory(this.serviceInterface, this).getProxy(this.beanClassLoader); - } - - - @Override - @Nullable - public Object getObject() { - return this.serviceProxy; - } - - @Override - public Class getObjectType() { - return this.serviceInterface; - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerServiceExporter.java b/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerServiceExporter.java deleted file mode 100644 index 80e5f51b4788..000000000000 --- a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerServiceExporter.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jms.remoting; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageFormatException; -import javax.jms.MessageProducer; -import javax.jms.Session; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.jms.listener.SessionAwareMessageListener; -import org.springframework.jms.support.JmsUtils; -import org.springframework.jms.support.converter.MessageConverter; -import org.springframework.jms.support.converter.SimpleMessageConverter; -import org.springframework.lang.Nullable; -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.remoting.support.RemoteInvocationBasedExporter; -import org.springframework.remoting.support.RemoteInvocationResult; - -/** - * JMS message listener that exports the specified service bean as a - * JMS service endpoint, accessible via a JMS invoker proxy. - * - *

    Note that this class implements Spring's - * {@link org.springframework.jms.listener.SessionAwareMessageListener} - * interface, since it requires access to the active JMS Session. - * Hence, this class can only be used with message listener containers - * which support the SessionAwareMessageListener interface (e.g. Spring's - * {@link org.springframework.jms.listener.DefaultMessageListenerContainer}). - * - *

    Thanks to James Strachan for the original prototype that this - * JMS invoker mechanism was inspired by! - * - * @author Juergen Hoeller - * @author James Strachan - * @since 2.0 - * @see JmsInvokerClientInterceptor - * @see JmsInvokerProxyFactoryBean - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class JmsInvokerServiceExporter extends RemoteInvocationBasedExporter - implements SessionAwareMessageListener, InitializingBean { - - private MessageConverter messageConverter = new SimpleMessageConverter(); - - private boolean ignoreInvalidRequests = true; - - @Nullable - private Object proxy; - - - /** - * Specify the MessageConverter to use for turning request messages into - * {@link org.springframework.remoting.support.RemoteInvocation} objects, - * as well as {@link org.springframework.remoting.support.RemoteInvocationResult} - * objects into response messages. - *

    Default is a {@link org.springframework.jms.support.converter.SimpleMessageConverter}, - * using a standard JMS {@link javax.jms.ObjectMessage} for each invocation / - * invocation result object. - *

    Custom implementations may generally adapt Serializables into - * special kinds of messages, or might be specifically tailored for - * translating RemoteInvocation(Result)s into specific kinds of messages. - */ - public void setMessageConverter(@Nullable MessageConverter messageConverter) { - this.messageConverter = (messageConverter != null ? messageConverter : new SimpleMessageConverter()); - } - - /** - * Set whether invalidly formatted messages should be discarded. - * Default is "true". - *

    Switch this flag to "false" to throw an exception back to the - * listener container. This will typically lead to redelivery of - * the message, which is usually undesirable - since the message - * content will be the same (that is, still invalid). - */ - public void setIgnoreInvalidRequests(boolean ignoreInvalidRequests) { - this.ignoreInvalidRequests = ignoreInvalidRequests; - } - - @Override - public void afterPropertiesSet() { - this.proxy = getProxyForService(); - } - - - @Override - public void onMessage(Message requestMessage, Session session) throws JMSException { - RemoteInvocation invocation = readRemoteInvocation(requestMessage); - if (invocation != null) { - RemoteInvocationResult result = invokeAndCreateResult(invocation, this.proxy); - writeRemoteInvocationResult(requestMessage, session, result); - } - } - - /** - * Read a RemoteInvocation from the given JMS message. - * @param requestMessage current request message - * @return the RemoteInvocation object (or {@code null} - * in case of an invalid message that will simply be ignored) - * @throws javax.jms.JMSException in case of message access failure - */ - @Nullable - protected RemoteInvocation readRemoteInvocation(Message requestMessage) throws JMSException { - Object content = this.messageConverter.fromMessage(requestMessage); - if (content instanceof RemoteInvocation) { - return (RemoteInvocation) content; - } - return onInvalidRequest(requestMessage); - } - - - /** - * Send the given RemoteInvocationResult as a JMS message to the originator. - * @param requestMessage current request message - * @param session the JMS Session to use - * @param result the RemoteInvocationResult object - * @throws javax.jms.JMSException if thrown by trying to send the message - */ - protected void writeRemoteInvocationResult( - Message requestMessage, Session session, RemoteInvocationResult result) throws JMSException { - - Message response = createResponseMessage(requestMessage, session, result); - MessageProducer producer = session.createProducer(requestMessage.getJMSReplyTo()); - try { - producer.send(response); - } - finally { - JmsUtils.closeMessageProducer(producer); - } - } - - /** - * Create the invocation result response message. - *

    The default implementation creates a JMS ObjectMessage for the given - * RemoteInvocationResult object. It sets the response's correlation id - * to the request message's correlation id, if any; otherwise to the - * request message id. - * @param request the original request message - * @param session the JMS session to use - * @param result the invocation result - * @return the message response to send - * @throws javax.jms.JMSException if creating the message failed - */ - protected Message createResponseMessage(Message request, Session session, RemoteInvocationResult result) - throws JMSException { - - Message response = this.messageConverter.toMessage(result, session); - String correlation = request.getJMSCorrelationID(); - if (correlation == null) { - correlation = request.getJMSMessageID(); - } - response.setJMSCorrelationID(correlation); - return response; - } - - /** - * Callback that is invoked by {@link #readRemoteInvocation} - * when it encounters an invalid request message. - *

    The default implementation either discards the invalid message or - * throws a MessageFormatException - according to the "ignoreInvalidRequests" - * flag, which is set to "true" (that is, discard invalid messages) by default. - * @param requestMessage the invalid request message - * @return the RemoteInvocation to expose for the invalid request (typically - * {@code null} in case of an invalid message that will simply be ignored) - * @throws javax.jms.JMSException in case of the invalid request supposed - * to lead to an exception (instead of ignoring it) - * @see #readRemoteInvocation - * @see #setIgnoreInvalidRequests - */ - @Nullable - protected RemoteInvocation onInvalidRequest(Message requestMessage) throws JMSException { - if (this.ignoreInvalidRequests) { - if (logger.isDebugEnabled()) { - logger.debug("Invalid request message will be discarded: " + requestMessage); - } - return null; - } - else { - throw new MessageFormatException("Invalid request message: " + requestMessage); - } - } - -} diff --git a/spring-jms/src/main/java/org/springframework/jms/remoting/package-info.java b/spring-jms/src/main/java/org/springframework/jms/remoting/package-info.java deleted file mode 100644 index 20e030430ca8..000000000000 --- a/spring-jms/src/main/java/org/springframework/jms/remoting/package-info.java +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Remoting classes for transparent Java-to-Java remoting via a JMS provider. - * - *

    Allows the target service to be load-balanced across a number of queue - * receivers, and provides a level of indirection between the client and the - * service: They only need to agree on a queue name and a service interface. - */ -@NonNullApi -@NonNullFields -package org.springframework.jms.remoting; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-jms/src/test/java/org/springframework/jms/remoting/JmsInvokerTests.java b/spring-jms/src/test/java/org/springframework/jms/remoting/JmsInvokerTests.java deleted file mode 100644 index 299ee9321fe2..000000000000 --- a/spring-jms/src/test/java/org/springframework/jms/remoting/JmsInvokerTests.java +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jms.remoting; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Enumeration; - -import javax.jms.CompletionListener; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageProducer; -import javax.jms.ObjectMessage; -import javax.jms.Queue; -import javax.jms.QueueConnection; -import javax.jms.QueueConnectionFactory; -import javax.jms.QueueSession; -import javax.jms.Session; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.testfixture.beans.ITestBean; -import org.springframework.beans.testfixture.beans.TestBean; -import org.springframework.jms.support.converter.MessageConversionException; -import org.springframework.jms.support.converter.SimpleMessageConverter; -import org.springframework.remoting.RemoteTimeoutException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * @author Juergen Hoeller - * @author Stephane Nicoll - */ -class JmsInvokerTests { - - private QueueConnectionFactory mockConnectionFactory = mock(QueueConnectionFactory.class); - - private QueueConnection mockConnection = mock(QueueConnection.class); - - private QueueSession mockSession = mock(QueueSession.class); - - private Queue mockQueue = mock(Queue.class); - - - @BeforeEach - void setUpMocks() throws Exception { - given(mockConnectionFactory.createConnection()).willReturn(mockConnection); - given(mockConnection.createSession(false, Session.AUTO_ACKNOWLEDGE)).willReturn(mockSession); - } - - - @Test - void jmsInvokerProxyFactoryBeanAndServiceExporter() throws Throwable { - doTestJmsInvokerProxyFactoryBeanAndServiceExporter(false); - } - - @Test - void jmsInvokerProxyFactoryBeanAndServiceExporterWithDynamicQueue() throws Throwable { - given(mockSession.createQueue("myQueue")).willReturn(mockQueue); - doTestJmsInvokerProxyFactoryBeanAndServiceExporter(true); - } - - @Test - @SuppressWarnings("deprecation") - void receiveTimeoutExpired() { - JmsInvokerProxyFactoryBean pfb = new JmsInvokerProxyFactoryBean() { - @Override - protected Message doExecuteRequest(Session session, Queue queue, Message requestMessage) throws JMSException { - return null; // faking no message received - } - }; - pfb.setServiceInterface(ITestBean.class); - pfb.setConnectionFactory(this.mockConnectionFactory); - pfb.setQueue(this.mockQueue); - pfb.setReceiveTimeout(1500); - pfb.afterPropertiesSet(); - ITestBean proxy = (ITestBean) pfb.getObject(); - - assertThatExceptionOfType(RemoteTimeoutException.class).isThrownBy(() -> - proxy.getAge()) - .withMessageContaining("1500 ms") - .withMessageContaining("getAge"); - } - - @SuppressWarnings("deprecation") - private void doTestJmsInvokerProxyFactoryBeanAndServiceExporter(boolean dynamicQueue) throws Throwable { - TestBean target = new TestBean("myname", 99); - - final JmsInvokerServiceExporter exporter = new JmsInvokerServiceExporter(); - exporter.setServiceInterface(ITestBean.class); - exporter.setService(target); - exporter.setMessageConverter(new MockSimpleMessageConverter()); - exporter.afterPropertiesSet(); - - JmsInvokerProxyFactoryBean pfb = new JmsInvokerProxyFactoryBean() { - @Override - protected Message doExecuteRequest(Session session, Queue queue, Message requestMessage) throws JMSException { - Session mockExporterSession = mock(Session.class); - ResponseStoringProducer mockProducer = new ResponseStoringProducer(); - given(mockExporterSession.createProducer(requestMessage.getJMSReplyTo())).willReturn(mockProducer); - exporter.onMessage(requestMessage, mockExporterSession); - assertThat(mockProducer.closed).isTrue(); - return mockProducer.response; - } - }; - pfb.setServiceInterface(ITestBean.class); - pfb.setConnectionFactory(this.mockConnectionFactory); - if (dynamicQueue) { - pfb.setQueueName("myQueue"); - } - else { - pfb.setQueue(this.mockQueue); - } - pfb.setMessageConverter(new MockSimpleMessageConverter()); - - pfb.afterPropertiesSet(); - ITestBean proxy = (ITestBean) pfb.getObject(); - - assertThat(proxy.getName()).isEqualTo("myname"); - assertThat(proxy.getAge()).isEqualTo(99); - proxy.setAge(50); - assertThat(proxy.getAge()).isEqualTo(50); - proxy.setStringArray(new String[] {"str1", "str2"}); - assertThat(Arrays.equals(new String[] {"str1", "str2"}, proxy.getStringArray())).isTrue(); - assertThatIllegalStateException().isThrownBy(() -> - proxy.exceptional(new IllegalStateException())); - assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() -> - proxy.exceptional(new IllegalAccessException())); - } - - - private static class ResponseStoringProducer implements MessageProducer { - - Message response; - - boolean closed = false; - - @Override - public void setDisableMessageID(boolean b) throws JMSException { - } - - @Override - public boolean getDisableMessageID() throws JMSException { - return false; - } - - @Override - public void setDisableMessageTimestamp(boolean b) throws JMSException { - } - - @Override - public boolean getDisableMessageTimestamp() throws JMSException { - return false; - } - - @Override - public void setDeliveryMode(int i) throws JMSException { - } - - @Override - public int getDeliveryMode() throws JMSException { - return 0; - } - - @Override - public void setPriority(int i) throws JMSException { - } - - @Override - public int getPriority() throws JMSException { - return 0; - } - - @Override - public void setTimeToLive(long l) throws JMSException { - } - - @Override - public long getTimeToLive() throws JMSException { - return 0; - } - - @Override - public void setDeliveryDelay(long deliveryDelay) throws JMSException { - } - - @Override - public long getDeliveryDelay() throws JMSException { - return 0; - } - - @Override - public Destination getDestination() throws JMSException { - return null; - } - - @Override - public void close() throws JMSException { - this.closed = true; - } - - @Override - public void send(Message message) throws JMSException { - this.response = message; - } - - @Override - public void send(Message message, int i, int i1, long l) throws JMSException { - } - - @Override - public void send(Destination destination, Message message) throws JMSException { - } - - @Override - public void send(Destination destination, Message message, int i, int i1, long l) throws JMSException { - } - - @Override - public void send(Message message, CompletionListener completionListener) throws JMSException { - } - - @Override - public void send(Message message, int deliveryMode, int priority, long timeToLive, CompletionListener completionListener) throws JMSException { - } - - @Override - public void send(Destination destination, Message message, CompletionListener completionListener) throws JMSException { - } - - @Override - public void send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive, CompletionListener completionListener) throws JMSException { - } - } - - - private static class MockObjectMessage implements ObjectMessage { - - private Serializable serializable; - - private Destination replyTo; - - public MockObjectMessage(Serializable serializable) { - this.serializable = serializable; - } - - @Override - public void setObject(Serializable serializable) throws JMSException { - this.serializable = serializable; - } - - @Override - public Serializable getObject() throws JMSException { - return serializable; - } - - @Override - public String getJMSMessageID() throws JMSException { - return null; - } - - @Override - public void setJMSMessageID(String string) throws JMSException { - } - - @Override - public long getJMSTimestamp() throws JMSException { - return 0; - } - - @Override - public void setJMSTimestamp(long l) throws JMSException { - } - - @Override - public byte[] getJMSCorrelationIDAsBytes() throws JMSException { - return new byte[0]; - } - - @Override - public void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException { - } - - @Override - public void setJMSCorrelationID(String string) throws JMSException { - } - - @Override - public String getJMSCorrelationID() throws JMSException { - return null; - } - - @Override - public Destination getJMSReplyTo() throws JMSException { - return replyTo; - } - - @Override - public void setJMSReplyTo(Destination destination) throws JMSException { - this.replyTo = destination; - } - - @Override - public Destination getJMSDestination() throws JMSException { - return null; - } - - @Override - public void setJMSDestination(Destination destination) throws JMSException { - } - - @Override - public int getJMSDeliveryMode() throws JMSException { - return 0; - } - - @Override - public void setJMSDeliveryMode(int i) throws JMSException { - } - - @Override - public boolean getJMSRedelivered() throws JMSException { - return false; - } - - @Override - public void setJMSRedelivered(boolean b) throws JMSException { - } - - @Override - public String getJMSType() throws JMSException { - return null; - } - - @Override - public void setJMSType(String string) throws JMSException { - } - - @Override - public long getJMSExpiration() throws JMSException { - return 0; - } - - @Override - public void setJMSExpiration(long l) throws JMSException { - } - - @Override - public int getJMSPriority() throws JMSException { - return 0; - } - - @Override - public void setJMSPriority(int i) throws JMSException { - } - - @Override - public long getJMSDeliveryTime() throws JMSException { - return 0; - } - - @Override - public void setJMSDeliveryTime(long deliveryTime) throws JMSException { - } - - @Override - public T getBody(Class c) throws JMSException { - return null; - } - - @Override - @SuppressWarnings("rawtypes") - public boolean isBodyAssignableTo(Class c) throws JMSException { - return false; - } - - @Override - public void clearProperties() throws JMSException { - } - - @Override - public boolean propertyExists(String string) throws JMSException { - return false; - } - - @Override - public boolean getBooleanProperty(String string) throws JMSException { - return false; - } - - @Override - public byte getByteProperty(String string) throws JMSException { - return 0; - } - - @Override - public short getShortProperty(String string) throws JMSException { - return 0; - } - - @Override - public int getIntProperty(String string) throws JMSException { - return 0; - } - - @Override - public long getLongProperty(String string) throws JMSException { - return 0; - } - - @Override - public float getFloatProperty(String string) throws JMSException { - return 0; - } - - @Override - public double getDoubleProperty(String string) throws JMSException { - return 0; - } - - @Override - public String getStringProperty(String string) throws JMSException { - return null; - } - - @Override - public Object getObjectProperty(String string) throws JMSException { - return null; - } - - @Override - @SuppressWarnings("rawtypes") - public Enumeration getPropertyNames() throws JMSException { - return null; - } - - @Override - public void setBooleanProperty(String string, boolean b) throws JMSException { - } - - @Override - public void setByteProperty(String string, byte b) throws JMSException { - } - - @Override - public void setShortProperty(String string, short i) throws JMSException { - } - - @Override - public void setIntProperty(String string, int i) throws JMSException { - } - - @Override - public void setLongProperty(String string, long l) throws JMSException { - } - - @Override - public void setFloatProperty(String string, float v) throws JMSException { - } - - @Override - public void setDoubleProperty(String string, double v) throws JMSException { - } - - @Override - public void setStringProperty(String string, String string1) throws JMSException { - } - - @Override - public void setObjectProperty(String string, Object object) throws JMSException { - } - - @Override - public void acknowledge() throws JMSException { - } - - @Override - public void clearBody() throws JMSException { - } - } - - - private static class MockSimpleMessageConverter extends SimpleMessageConverter { - - @Override - public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException { - return new MockObjectMessage((Serializable) object); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianClientInterceptor.java b/spring-web/src/main/java/org/springframework/remoting/caucho/HessianClientInterceptor.java deleted file mode 100644 index 241a8580e192..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianClientInterceptor.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.caucho; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.UndeclaredThrowableException; -import java.net.ConnectException; -import java.net.MalformedURLException; - -import com.caucho.hessian.HessianException; -import com.caucho.hessian.client.HessianConnectionException; -import com.caucho.hessian.client.HessianConnectionFactory; -import com.caucho.hessian.client.HessianProxyFactory; -import com.caucho.hessian.client.HessianRuntimeException; -import com.caucho.hessian.io.SerializerFactory; -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.lang.Nullable; -import org.springframework.remoting.RemoteAccessException; -import org.springframework.remoting.RemoteConnectFailureException; -import org.springframework.remoting.RemoteLookupFailureException; -import org.springframework.remoting.RemoteProxyFailureException; -import org.springframework.remoting.support.UrlBasedRemoteAccessor; -import org.springframework.util.Assert; - -/** - * {@link org.aopalliance.intercept.MethodInterceptor} for accessing a Hessian service. - * Supports authentication via username and password. - * The service URL must be an HTTP URL exposing a Hessian service. - * - *

    Hessian is a slim, binary RPC protocol. - * For information on Hessian, see the - * Hessian website - * Note: As of Spring 4.0, this client requires Hessian 4.0 or above. - * - *

    Note: There is no requirement for services accessed with this proxy factory - * to have been exported using Spring's {@link HessianServiceExporter}, as there is - * no special handling involved. As a consequence, you can also access services that - * have been exported using Caucho's {@link com.caucho.hessian.server.HessianServlet}. - * - * @author Juergen Hoeller - * @since 29.09.2003 - * @see #setServiceInterface - * @see #setServiceUrl - * @see #setUsername - * @see #setPassword - * @see HessianServiceExporter - * @see HessianProxyFactoryBean - * @see com.caucho.hessian.client.HessianProxyFactory - * @see com.caucho.hessian.server.HessianServlet - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class HessianClientInterceptor extends UrlBasedRemoteAccessor implements MethodInterceptor { - - private HessianProxyFactory proxyFactory = new HessianProxyFactory(); - - @Nullable - private Object hessianProxy; - - - /** - * Set the HessianProxyFactory instance to use. - * If not specified, a default HessianProxyFactory will be created. - *

    Allows to use an externally configured factory instance, - * in particular a custom HessianProxyFactory subclass. - */ - public void setProxyFactory(@Nullable HessianProxyFactory proxyFactory) { - this.proxyFactory = (proxyFactory != null ? proxyFactory : new HessianProxyFactory()); - } - - /** - * Specify the Hessian SerializerFactory to use. - *

    This will typically be passed in as an inner bean definition - * of type {@code com.caucho.hessian.io.SerializerFactory}, - * with custom bean property values applied. - */ - public void setSerializerFactory(SerializerFactory serializerFactory) { - this.proxyFactory.setSerializerFactory(serializerFactory); - } - - /** - * Set whether to send the Java collection type for each serialized - * collection. Default is "true". - */ - public void setSendCollectionType(boolean sendCollectionType) { - this.proxyFactory.getSerializerFactory().setSendCollectionType(sendCollectionType); - } - - /** - * Set whether to allow non-serializable types as Hessian arguments - * and return values. Default is "true". - */ - public void setAllowNonSerializable(boolean allowNonSerializable) { - this.proxyFactory.getSerializerFactory().setAllowNonSerializable(allowNonSerializable); - } - - /** - * Set whether overloaded methods should be enabled for remote invocations. - * Default is "false". - * @see com.caucho.hessian.client.HessianProxyFactory#setOverloadEnabled - */ - public void setOverloadEnabled(boolean overloadEnabled) { - this.proxyFactory.setOverloadEnabled(overloadEnabled); - } - - /** - * Set the username that this factory should use to access the remote service. - * Default is none. - *

    The username will be sent by Hessian via HTTP Basic Authentication. - * @see com.caucho.hessian.client.HessianProxyFactory#setUser - */ - public void setUsername(String username) { - this.proxyFactory.setUser(username); - } - - /** - * Set the password that this factory should use to access the remote service. - * Default is none. - *

    The password will be sent by Hessian via HTTP Basic Authentication. - * @see com.caucho.hessian.client.HessianProxyFactory#setPassword - */ - public void setPassword(String password) { - this.proxyFactory.setPassword(password); - } - - /** - * Set whether Hessian's debug mode should be enabled. - * Default is "false". - * @see com.caucho.hessian.client.HessianProxyFactory#setDebug - */ - public void setDebug(boolean debug) { - this.proxyFactory.setDebug(debug); - } - - /** - * Set whether to use a chunked post for sending a Hessian request. - * @see com.caucho.hessian.client.HessianProxyFactory#setChunkedPost - */ - public void setChunkedPost(boolean chunkedPost) { - this.proxyFactory.setChunkedPost(chunkedPost); - } - - /** - * Specify a custom HessianConnectionFactory to use for the Hessian client. - */ - public void setConnectionFactory(HessianConnectionFactory connectionFactory) { - this.proxyFactory.setConnectionFactory(connectionFactory); - } - - /** - * Set the socket connect timeout to use for the Hessian client. - * @see com.caucho.hessian.client.HessianProxyFactory#setConnectTimeout - */ - public void setConnectTimeout(long timeout) { - this.proxyFactory.setConnectTimeout(timeout); - } - - /** - * Set the timeout to use when waiting for a reply from the Hessian service. - * @see com.caucho.hessian.client.HessianProxyFactory#setReadTimeout - */ - public void setReadTimeout(long timeout) { - this.proxyFactory.setReadTimeout(timeout); - } - - /** - * Set whether version 2 of the Hessian protocol should be used for - * parsing requests and replies. Default is "false". - * @see com.caucho.hessian.client.HessianProxyFactory#setHessian2Request - */ - public void setHessian2(boolean hessian2) { - this.proxyFactory.setHessian2Request(hessian2); - this.proxyFactory.setHessian2Reply(hessian2); - } - - /** - * Set whether version 2 of the Hessian protocol should be used for - * parsing requests. Default is "false". - * @see com.caucho.hessian.client.HessianProxyFactory#setHessian2Request - */ - public void setHessian2Request(boolean hessian2) { - this.proxyFactory.setHessian2Request(hessian2); - } - - /** - * Set whether version 2 of the Hessian protocol should be used for - * parsing replies. Default is "false". - * @see com.caucho.hessian.client.HessianProxyFactory#setHessian2Reply - */ - public void setHessian2Reply(boolean hessian2) { - this.proxyFactory.setHessian2Reply(hessian2); - } - - - @Override - public void afterPropertiesSet() { - super.afterPropertiesSet(); - prepare(); - } - - /** - * Initialize the Hessian proxy for this interceptor. - * @throws RemoteLookupFailureException if the service URL is invalid - */ - public void prepare() throws RemoteLookupFailureException { - try { - this.hessianProxy = createHessianProxy(this.proxyFactory); - } - catch (MalformedURLException ex) { - throw new RemoteLookupFailureException("Service URL [" + getServiceUrl() + "] is invalid", ex); - } - } - - /** - * Create the Hessian proxy that is wrapped by this interceptor. - * @param proxyFactory the proxy factory to use - * @return the Hessian proxy - * @throws MalformedURLException if thrown by the proxy factory - * @see com.caucho.hessian.client.HessianProxyFactory#create - */ - protected Object createHessianProxy(HessianProxyFactory proxyFactory) throws MalformedURLException { - Assert.notNull(getServiceInterface(), "'serviceInterface' is required"); - return proxyFactory.create(getServiceInterface(), getServiceUrl(), getBeanClassLoader()); - } - - - @Override - @Nullable - public Object invoke(MethodInvocation invocation) throws Throwable { - if (this.hessianProxy == null) { - throw new IllegalStateException("HessianClientInterceptor is not properly initialized - " + - "invoke 'prepare' before attempting any operations"); - } - - ClassLoader originalClassLoader = overrideThreadContextClassLoader(); - try { - return invocation.getMethod().invoke(this.hessianProxy, invocation.getArguments()); - } - catch (InvocationTargetException ex) { - Throwable targetEx = ex.getTargetException(); - // Hessian 4.0 check: another layer of InvocationTargetException. - if (targetEx instanceof InvocationTargetException) { - targetEx = ((InvocationTargetException) targetEx).getTargetException(); - } - if (targetEx instanceof HessianConnectionException) { - throw convertHessianAccessException(targetEx); - } - else if (targetEx instanceof HessianException || targetEx instanceof HessianRuntimeException) { - Throwable cause = targetEx.getCause(); - throw convertHessianAccessException(cause != null ? cause : targetEx); - } - else if (targetEx instanceof UndeclaredThrowableException) { - UndeclaredThrowableException utex = (UndeclaredThrowableException) targetEx; - throw convertHessianAccessException(utex.getUndeclaredThrowable()); - } - else { - throw targetEx; - } - } - catch (Throwable ex) { - throw new RemoteProxyFailureException( - "Failed to invoke Hessian proxy for remote service [" + getServiceUrl() + "]", ex); - } - finally { - resetThreadContextClassLoader(originalClassLoader); - } - } - - /** - * Convert the given Hessian access exception to an appropriate - * Spring RemoteAccessException. - * @param ex the exception to convert - * @return the RemoteAccessException to throw - */ - protected RemoteAccessException convertHessianAccessException(Throwable ex) { - if (ex instanceof HessianConnectionException || ex instanceof ConnectException) { - return new RemoteConnectFailureException( - "Cannot connect to Hessian remote service at [" + getServiceUrl() + "]", ex); - } - else { - return new RemoteAccessException( - "Cannot access Hessian remote service at [" + getServiceUrl() + "]", ex); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianExporter.java b/spring-web/src/main/java/org/springframework/remoting/caucho/HessianExporter.java deleted file mode 100644 index b6c70e5fd722..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianExporter.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.caucho; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintWriter; - -import com.caucho.hessian.io.AbstractHessianInput; -import com.caucho.hessian.io.AbstractHessianOutput; -import com.caucho.hessian.io.Hessian2Input; -import com.caucho.hessian.io.Hessian2Output; -import com.caucho.hessian.io.HessianDebugInputStream; -import com.caucho.hessian.io.HessianDebugOutputStream; -import com.caucho.hessian.io.HessianInput; -import com.caucho.hessian.io.HessianOutput; -import com.caucho.hessian.io.HessianRemoteResolver; -import com.caucho.hessian.io.SerializerFactory; -import com.caucho.hessian.server.HessianSkeleton; -import org.apache.commons.logging.Log; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; -import org.springframework.remoting.support.RemoteExporter; -import org.springframework.util.Assert; -import org.springframework.util.CommonsLogWriter; - -/** - * General stream-based protocol exporter for a Hessian endpoint. - * - *

    Hessian is a slim, binary RPC protocol. - * For information on Hessian, see the - * Hessian website. - * Note: As of Spring 4.0, this exporter requires Hessian 4.0 or above. - * - * @author Juergen Hoeller - * @since 2.5.1 - * @see #invoke(java.io.InputStream, java.io.OutputStream) - * @see HessianServiceExporter - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class HessianExporter extends RemoteExporter implements InitializingBean { - - /** - * The content type for hessian ({@code application/x-hessian}). - */ - public static final String CONTENT_TYPE_HESSIAN = "application/x-hessian"; - - - private SerializerFactory serializerFactory = new SerializerFactory(); - - @Nullable - private HessianRemoteResolver remoteResolver; - - @Nullable - private Log debugLogger; - - @Nullable - private HessianSkeleton skeleton; - - - /** - * Specify the Hessian SerializerFactory to use. - *

    This will typically be passed in as an inner bean definition - * of type {@code com.caucho.hessian.io.SerializerFactory}, - * with custom bean property values applied. - */ - public void setSerializerFactory(@Nullable SerializerFactory serializerFactory) { - this.serializerFactory = (serializerFactory != null ? serializerFactory : new SerializerFactory()); - } - - /** - * Set whether to send the Java collection type for each serialized - * collection. Default is "true". - */ - public void setSendCollectionType(boolean sendCollectionType) { - this.serializerFactory.setSendCollectionType(sendCollectionType); - } - - /** - * Set whether to allow non-serializable types as Hessian arguments - * and return values. Default is "true". - */ - public void setAllowNonSerializable(boolean allowNonSerializable) { - this.serializerFactory.setAllowNonSerializable(allowNonSerializable); - } - - /** - * Specify a custom HessianRemoteResolver to use for resolving remote - * object references. - */ - public void setRemoteResolver(HessianRemoteResolver remoteResolver) { - this.remoteResolver = remoteResolver; - } - - /** - * Set whether Hessian's debug mode should be enabled, logging to - * this exporter's Commons Logging log. Default is "false". - * @see com.caucho.hessian.client.HessianProxyFactory#setDebug - */ - public void setDebug(boolean debug) { - this.debugLogger = (debug ? logger : null); - } - - - @Override - public void afterPropertiesSet() { - prepare(); - } - - /** - * Initialize this exporter. - */ - public void prepare() { - checkService(); - checkServiceInterface(); - this.skeleton = new HessianSkeleton(getProxyForService(), getServiceInterface()); - } - - - /** - * Perform an invocation on the exported object. - * @param inputStream the request stream - * @param outputStream the response stream - * @throws Throwable if invocation failed - */ - public void invoke(InputStream inputStream, OutputStream outputStream) throws Throwable { - Assert.notNull(this.skeleton, "Hessian exporter has not been initialized"); - doInvoke(this.skeleton, inputStream, outputStream); - } - - /** - * Actually invoke the skeleton with the given streams. - * @param skeleton the skeleton to invoke - * @param inputStream the request stream - * @param outputStream the response stream - * @throws Throwable if invocation failed - */ - protected void doInvoke(HessianSkeleton skeleton, InputStream inputStream, OutputStream outputStream) - throws Throwable { - - ClassLoader originalClassLoader = overrideThreadContextClassLoader(); - try { - InputStream isToUse = inputStream; - OutputStream osToUse = outputStream; - - if (this.debugLogger != null && this.debugLogger.isDebugEnabled()) { - try (PrintWriter debugWriter = new PrintWriter(new CommonsLogWriter(this.debugLogger))){ - @SuppressWarnings("resource") - HessianDebugInputStream dis = new HessianDebugInputStream(inputStream, debugWriter); - @SuppressWarnings("resource") - HessianDebugOutputStream dos = new HessianDebugOutputStream(outputStream, debugWriter); - dis.startTop2(); - dos.startTop2(); - isToUse = dis; - osToUse = dos; - } - } - - if (!isToUse.markSupported()) { - isToUse = new BufferedInputStream(isToUse); - isToUse.mark(1); - } - - int code = isToUse.read(); - int major; - int minor; - - AbstractHessianInput in; - AbstractHessianOutput out; - - if (code == 'H') { - // Hessian 2.0 stream - major = isToUse.read(); - minor = isToUse.read(); - if (major != 0x02) { - throw new IOException("Version " + major + '.' + minor + " is not understood"); - } - in = new Hessian2Input(isToUse); - out = new Hessian2Output(osToUse); - in.readCall(); - } - else if (code == 'C') { - // Hessian 2.0 call... for some reason not handled in HessianServlet! - isToUse.reset(); - in = new Hessian2Input(isToUse); - out = new Hessian2Output(osToUse); - in.readCall(); - } - else if (code == 'c') { - // Hessian 1.0 call - major = isToUse.read(); - minor = isToUse.read(); - in = new HessianInput(isToUse); - if (major >= 2) { - out = new Hessian2Output(osToUse); - } - else { - out = new HessianOutput(osToUse); - } - } - else { - throw new IOException("Expected 'H'/'C' (Hessian 2.0) or 'c' (Hessian 1.0) in hessian input at " + code); - } - - in.setSerializerFactory(this.serializerFactory); - out.setSerializerFactory(this.serializerFactory); - if (this.remoteResolver != null) { - in.setRemoteResolver(this.remoteResolver); - } - - try { - skeleton.invoke(in, out); - } - finally { - try { - in.close(); - isToUse.close(); - } - catch (IOException ex) { - // ignore - } - try { - out.close(); - osToUse.close(); - } - catch (IOException ex) { - // ignore - } - } - } - finally { - resetThreadContextClassLoader(originalClassLoader); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianProxyFactoryBean.java b/spring-web/src/main/java/org/springframework/remoting/caucho/HessianProxyFactoryBean.java deleted file mode 100644 index 45a66eacf538..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianProxyFactoryBean.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.caucho; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.lang.Nullable; - -/** - * {@link FactoryBean} for Hessian proxies. Exposes the proxied service - * for use as a bean reference, using the specified service interface. - * - *

    Hessian is a slim, binary RPC protocol. - * For information on Hessian, see the - * Hessian website - * Note: As of Spring 4.0, this proxy factory requires Hessian 4.0 or above. - * - *

    The service URL must be an HTTP URL exposing a Hessian service. - * For details, see the {@link HessianClientInterceptor} javadoc. - * - * @author Juergen Hoeller - * @since 13.05.2003 - * @see #setServiceInterface - * @see #setServiceUrl - * @see HessianClientInterceptor - * @see HessianServiceExporter - * @see org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean - * @see org.springframework.remoting.rmi.RmiProxyFactoryBean - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class HessianProxyFactoryBean extends HessianClientInterceptor implements FactoryBean { - - @Nullable - private Object serviceProxy; - - - @Override - public void afterPropertiesSet() { - super.afterPropertiesSet(); - this.serviceProxy = new ProxyFactory(getServiceInterface(), this).getProxy(getBeanClassLoader()); - } - - - @Override - @Nullable - public Object getObject() { - return this.serviceProxy; - } - - @Override - public Class getObjectType() { - return getServiceInterface(); - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/caucho/HessianServiceExporter.java deleted file mode 100644 index f25139ccf263..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianServiceExporter.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.caucho; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.web.HttpRequestHandler; -import org.springframework.web.HttpRequestMethodNotSupportedException; -import org.springframework.web.util.NestedServletException; - -/** - * Servlet-API-based HTTP request handler that exports the specified service bean - * as Hessian service endpoint, accessible via a Hessian proxy. - * - *

    Hessian is a slim, binary RPC protocol. - * For information on Hessian, see the - * Hessian website. - * Note: As of Spring 4.0, this exporter requires Hessian 4.0 or above. - * - *

    Hessian services exported with this class can be accessed by - * any Hessian client, as there isn't any special handling involved. - * - * @author Juergen Hoeller - * @since 13.05.2003 - * @see HessianClientInterceptor - * @see HessianProxyFactoryBean - * @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter - * @see org.springframework.remoting.rmi.RmiServiceExporter - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class HessianServiceExporter extends HessianExporter implements HttpRequestHandler { - - /** - * Processes the incoming Hessian request and creates a Hessian response. - */ - @Override - public void handleRequest(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - - if (!"POST".equals(request.getMethod())) { - throw new HttpRequestMethodNotSupportedException(request.getMethod(), - new String[] {"POST"}, "HessianServiceExporter only supports POST requests"); - } - - response.setContentType(CONTENT_TYPE_HESSIAN); - try { - invoke(request.getInputStream(), response.getOutputStream()); - } - catch (Throwable ex) { - throw new NestedServletException("Hessian skeleton invocation failed", ex); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/SimpleHessianServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/caucho/SimpleHessianServiceExporter.java deleted file mode 100644 index cc96b28bfa0c..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/caucho/SimpleHessianServiceExporter.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.caucho; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; - -import org.springframework.util.FileCopyUtils; - -/** - * HTTP request handler that exports the specified service bean as - * Hessian service endpoint, accessible via a Hessian proxy. - * Designed for Sun's JRE 1.6 HTTP server, implementing the - * {@link com.sun.net.httpserver.HttpHandler} interface. - * - *

    Hessian is a slim, binary RPC protocol. - * For information on Hessian, see the - * Hessian website. - * Note: As of Spring 4.0, this exporter requires Hessian 4.0 or above. - * - *

    Hessian services exported with this class can be accessed by - * any Hessian client, as there isn't any special handling involved. - * - * @author Juergen Hoeller - * @since 2.5.1 - * @see org.springframework.remoting.caucho.HessianClientInterceptor - * @see org.springframework.remoting.caucho.HessianProxyFactoryBean - * @deprecated as of Spring Framework 5.1, in favor of {@link HessianServiceExporter} - */ -@Deprecated -@org.springframework.lang.UsesSunHttpServer -public class SimpleHessianServiceExporter extends HessianExporter implements HttpHandler { - - /** - * Processes the incoming Hessian request and creates a Hessian response. - */ - @Override - public void handle(HttpExchange exchange) throws IOException { - if (!"POST".equals(exchange.getRequestMethod())) { - exchange.getResponseHeaders().set("Allow", "POST"); - exchange.sendResponseHeaders(405, -1); - return; - } - - ByteArrayOutputStream output = new ByteArrayOutputStream(1024); - try { - invoke(exchange.getRequestBody(), output); - } - catch (Throwable ex) { - exchange.sendResponseHeaders(500, -1); - logger.error("Hessian skeleton invocation failed", ex); - return; - } - - exchange.getResponseHeaders().set("Content-Type", CONTENT_TYPE_HESSIAN); - exchange.sendResponseHeaders(200, output.size()); - FileCopyUtils.copy(output.toByteArray(), exchange.getResponseBody()); - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/package-info.java b/spring-web/src/main/java/org/springframework/remoting/caucho/package-info.java deleted file mode 100644 index 30d03c51762f..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/caucho/package-info.java +++ /dev/null @@ -1,15 +0,0 @@ -/** - * This package provides remoting classes for Caucho's Hessian protocol: - * a proxy factory for accessing Hessian services, and an exporter for - * making beans available to Hessian clients. - * - *

    Hessian is a slim, binary RPC protocol over HTTP. - * For information on Hessian, see the - * Hessian website - */ -@NonNullApi -@NonNullFields -package org.springframework.remoting.caucho; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java deleted file mode 100644 index b1a34258ad02..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.httpinvoker; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.rmi.RemoteException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.lang.Nullable; -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.remoting.support.RemoteInvocationResult; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * Abstract base implementation of the HttpInvokerRequestExecutor interface. - * - *

    Pre-implements serialization of RemoteInvocation objects and - * deserialization of RemoteInvocationResults objects. - * - * @author Juergen Hoeller - * @since 1.1 - * @see #doExecuteRequest - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public abstract class AbstractHttpInvokerRequestExecutor implements HttpInvokerRequestExecutor, BeanClassLoaderAware { - - /** - * Default content type: "application/x-java-serialized-object". - */ - public static final String CONTENT_TYPE_SERIALIZED_OBJECT = "application/x-java-serialized-object"; - - private static final int SERIALIZED_INVOCATION_BYTE_ARRAY_INITIAL_SIZE = 1024; - - - protected static final String HTTP_METHOD_POST = "POST"; - - protected static final String HTTP_HEADER_ACCEPT_LANGUAGE = "Accept-Language"; - - protected static final String HTTP_HEADER_ACCEPT_ENCODING = "Accept-Encoding"; - - protected static final String HTTP_HEADER_CONTENT_ENCODING = "Content-Encoding"; - - protected static final String HTTP_HEADER_CONTENT_TYPE = "Content-Type"; - - protected static final String HTTP_HEADER_CONTENT_LENGTH = "Content-Length"; - - protected static final String ENCODING_GZIP = "gzip"; - - - protected final Log logger = LogFactory.getLog(getClass()); - - private String contentType = CONTENT_TYPE_SERIALIZED_OBJECT; - - private boolean acceptGzipEncoding = true; - - @Nullable - private ClassLoader beanClassLoader; - - - /** - * Specify the content type to use for sending HTTP invoker requests. - *

    Default is "application/x-java-serialized-object". - */ - public void setContentType(String contentType) { - Assert.notNull(contentType, "'contentType' must not be null"); - this.contentType = contentType; - } - - /** - * Return the content type to use for sending HTTP invoker requests. - */ - public String getContentType() { - return this.contentType; - } - - /** - * Set whether to accept GZIP encoding, that is, whether to - * send the HTTP "Accept-Encoding" header with "gzip" as value. - *

    Default is "true". Turn this flag off if you do not want - * GZIP response compression even if enabled on the HTTP server. - */ - public void setAcceptGzipEncoding(boolean acceptGzipEncoding) { - this.acceptGzipEncoding = acceptGzipEncoding; - } - - /** - * Return whether to accept GZIP encoding, that is, whether to - * send the HTTP "Accept-Encoding" header with "gzip" as value. - */ - public boolean isAcceptGzipEncoding() { - return this.acceptGzipEncoding; - } - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } - - /** - * Return the bean ClassLoader that this executor is supposed to use. - */ - @Nullable - protected ClassLoader getBeanClassLoader() { - return this.beanClassLoader; - } - - - @Override - public final RemoteInvocationResult executeRequest( - HttpInvokerClientConfiguration config, RemoteInvocation invocation) throws Exception { - - ByteArrayOutputStream baos = getByteArrayOutputStream(invocation); - if (logger.isDebugEnabled()) { - logger.debug("Sending HTTP invoker request for service at [" + config.getServiceUrl() + - "], with size " + baos.size()); - } - return doExecuteRequest(config, baos); - } - - /** - * Serialize the given RemoteInvocation into a ByteArrayOutputStream. - * @param invocation the RemoteInvocation object - * @return a ByteArrayOutputStream with the serialized RemoteInvocation - * @throws IOException if thrown by I/O methods - */ - protected ByteArrayOutputStream getByteArrayOutputStream(RemoteInvocation invocation) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(SERIALIZED_INVOCATION_BYTE_ARRAY_INITIAL_SIZE); - writeRemoteInvocation(invocation, baos); - return baos; - } - - /** - * Serialize the given RemoteInvocation to the given OutputStream. - *

    The default implementation gives {@code decorateOutputStream} a chance - * to decorate the stream first (for example, for custom encryption or compression). - * Creates an {@code ObjectOutputStream} for the final stream and calls - * {@code doWriteRemoteInvocation} to actually write the object. - *

    Can be overridden for custom serialization of the invocation. - * @param invocation the RemoteInvocation object - * @param os the OutputStream to write to - * @throws IOException if thrown by I/O methods - * @see #decorateOutputStream - * @see #doWriteRemoteInvocation - */ - protected void writeRemoteInvocation(RemoteInvocation invocation, OutputStream os) throws IOException { - try (ObjectOutputStream oos = new ObjectOutputStream(decorateOutputStream(os))) { - doWriteRemoteInvocation(invocation, oos); - } - } - - /** - * Return the OutputStream to use for writing remote invocations, - * potentially decorating the given original OutputStream. - *

    The default implementation returns the given stream as-is. - * Can be overridden, for example, for custom encryption or compression. - * @param os the original OutputStream - * @return the potentially decorated OutputStream - */ - protected OutputStream decorateOutputStream(OutputStream os) throws IOException { - return os; - } - - /** - * Perform the actual writing of the given invocation object to the - * given ObjectOutputStream. - *

    The default implementation simply calls {@code writeObject}. - * Can be overridden for serialization of a custom wrapper object rather - * than the plain invocation, for example an encryption-aware holder. - * @param invocation the RemoteInvocation object - * @param oos the ObjectOutputStream to write to - * @throws IOException if thrown by I/O methods - * @see java.io.ObjectOutputStream#writeObject - */ - protected void doWriteRemoteInvocation(RemoteInvocation invocation, ObjectOutputStream oos) throws IOException { - oos.writeObject(invocation); - } - - - /** - * Execute a request to send the given serialized remote invocation. - *

    Implementations will usually call {@code readRemoteInvocationResult} - * to deserialize a returned RemoteInvocationResult object. - * @param config the HTTP invoker configuration that specifies the - * target service - * @param baos the ByteArrayOutputStream that contains the serialized - * RemoteInvocation object - * @return the RemoteInvocationResult object - * @throws IOException if thrown by I/O operations - * @throws ClassNotFoundException if thrown during deserialization - * @throws Exception in case of general errors - * @see #readRemoteInvocationResult(java.io.InputStream, String) - */ - protected abstract RemoteInvocationResult doExecuteRequest( - HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) - throws Exception; - - /** - * Deserialize a RemoteInvocationResult object from the given InputStream. - *

    Gives {@code decorateInputStream} a chance to decorate the stream - * first (for example, for custom encryption or compression). Creates an - * {@code ObjectInputStream} via {@code createObjectInputStream} and - * calls {@code doReadRemoteInvocationResult} to actually read the object. - *

    Can be overridden for custom serialization of the invocation. - * @param is the InputStream to read from - * @param codebaseUrl the codebase URL to load classes from if not found locally - * @return the RemoteInvocationResult object - * @throws IOException if thrown by I/O methods - * @throws ClassNotFoundException if thrown during deserialization - * @see #decorateInputStream - * @see #createObjectInputStream - * @see #doReadRemoteInvocationResult - */ - protected RemoteInvocationResult readRemoteInvocationResult(InputStream is, @Nullable String codebaseUrl) - throws IOException, ClassNotFoundException { - - try (ObjectInputStream ois = createObjectInputStream(decorateInputStream(is), codebaseUrl)) { - return doReadRemoteInvocationResult(ois); - } - } - - /** - * Return the InputStream to use for reading remote invocation results, - * potentially decorating the given original InputStream. - *

    The default implementation returns the given stream as-is. - * Can be overridden, for example, for custom encryption or compression. - * @param is the original InputStream - * @return the potentially decorated InputStream - */ - protected InputStream decorateInputStream(InputStream is) throws IOException { - return is; - } - - /** - * Create an ObjectInputStream for the given InputStream and codebase. - * The default implementation creates a CodebaseAwareObjectInputStream. - * @param is the InputStream to read from - * @param codebaseUrl the codebase URL to load classes from if not found locally - * (can be {@code null}) - * @return the new ObjectInputStream instance to use - * @throws IOException if creation of the ObjectInputStream failed - * @see org.springframework.remoting.rmi.CodebaseAwareObjectInputStream - */ - protected ObjectInputStream createObjectInputStream(InputStream is, @Nullable String codebaseUrl) throws IOException { - return new org.springframework.remoting.rmi.CodebaseAwareObjectInputStream(is, getBeanClassLoader(), codebaseUrl); - } - - /** - * Perform the actual reading of an invocation object from the - * given ObjectInputStream. - *

    The default implementation simply calls {@code readObject}. - * Can be overridden for deserialization of a custom wrapper object rather - * than the plain invocation, for example an encryption-aware holder. - * @param ois the ObjectInputStream to read from - * @return the RemoteInvocationResult object - * @throws IOException if thrown by I/O methods - * @throws ClassNotFoundException if the class name of a serialized object - * couldn't get resolved - * @see java.io.ObjectOutputStream#writeObject - */ - protected RemoteInvocationResult doReadRemoteInvocationResult(ObjectInputStream ois) - throws IOException, ClassNotFoundException { - - Object obj = ois.readObject(); - if (!(obj instanceof RemoteInvocationResult)) { - throw new RemoteException("Deserialized object needs to be assignable to type [" + - RemoteInvocationResult.class.getName() + "]: " + ClassUtils.getDescriptiveType(obj)); - } - return (RemoteInvocationResult) obj; - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutor.java deleted file mode 100644 index c8a278fec427..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutor.java +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.httpinvoker; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Locale; -import java.util.zip.GZIPInputStream; - -import org.apache.http.Header; -import org.apache.http.HttpResponse; -import org.apache.http.NoHttpResponseException; -import org.apache.http.StatusLine; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.Configurable; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.config.Registry; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.socket.ConnectionSocketFactory; -import org.apache.http.conn.socket.PlainConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.entity.ByteArrayEntity; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; - -import org.springframework.context.i18n.LocaleContext; -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.lang.Nullable; -import org.springframework.remoting.support.RemoteInvocationResult; -import org.springframework.util.Assert; - -/** - * {@link org.springframework.remoting.httpinvoker.HttpInvokerRequestExecutor} implementation that uses - * Apache HttpComponents HttpClient - * to execute POST requests. - * - *

    Allows to use a pre-configured {@link org.apache.http.client.HttpClient} - * instance, potentially with authentication, HTTP connection pooling, etc. - * Also designed for easy subclassing, providing specific template methods. - * - *

    As of Spring 4.1, this request executor requires Apache HttpComponents 4.3 or higher. - * - * @author Juergen Hoeller - * @author Stephane Nicoll - * @since 3.1 - * @see org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class HttpComponentsHttpInvokerRequestExecutor extends AbstractHttpInvokerRequestExecutor { - - private static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 100; - - private static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 5; - - private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (60 * 1000); - - - private HttpClient httpClient; - - @Nullable - private RequestConfig requestConfig; - - - /** - * Create a new instance of the HttpComponentsHttpInvokerRequestExecutor with a default - * {@link HttpClient} that uses a default {@code org.apache.http.impl.conn.PoolingClientConnectionManager}. - */ - public HttpComponentsHttpInvokerRequestExecutor() { - this(createDefaultHttpClient(), RequestConfig.custom() - .setSocketTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS).build()); - } - - /** - * Create a new instance of the HttpComponentsClientHttpRequestFactory - * with the given {@link HttpClient} instance. - * @param httpClient the HttpClient instance to use for this request executor - */ - public HttpComponentsHttpInvokerRequestExecutor(HttpClient httpClient) { - this(httpClient, null); - } - - private HttpComponentsHttpInvokerRequestExecutor(HttpClient httpClient, @Nullable RequestConfig requestConfig) { - this.httpClient = httpClient; - this.requestConfig = requestConfig; - } - - - private static HttpClient createDefaultHttpClient() { - Registry schemeRegistry = RegistryBuilder.create() - .register("http", PlainConnectionSocketFactory.getSocketFactory()) - .register("https", SSLConnectionSocketFactory.getSocketFactory()) - .build(); - - PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(schemeRegistry); - connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL_CONNECTIONS); - connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_CONNECTIONS_PER_ROUTE); - - return HttpClientBuilder.create().setConnectionManager(connectionManager).build(); - } - - - /** - * Set the {@link HttpClient} instance to use for this request executor. - */ - public void setHttpClient(HttpClient httpClient) { - this.httpClient = httpClient; - } - - /** - * Return the {@link HttpClient} instance that this request executor uses. - */ - public HttpClient getHttpClient() { - return this.httpClient; - } - - /** - * Set the connection timeout for the underlying HttpClient. - * A timeout value of 0 specifies an infinite timeout. - *

    Additional properties can be configured by specifying a - * {@link RequestConfig} instance on a custom {@link HttpClient}. - * @param timeout the timeout value in milliseconds - * @see RequestConfig#getConnectTimeout() - */ - public void setConnectTimeout(int timeout) { - Assert.isTrue(timeout >= 0, "Timeout must be a non-negative value"); - this.requestConfig = cloneRequestConfig().setConnectTimeout(timeout).build(); - } - - /** - * Set the timeout in milliseconds used when requesting a connection from the connection - * manager using the underlying HttpClient. - * A timeout value of 0 specifies an infinite timeout. - *

    Additional properties can be configured by specifying a - * {@link RequestConfig} instance on a custom {@link HttpClient}. - * @param connectionRequestTimeout the timeout value to request a connection in milliseconds - * @see RequestConfig#getConnectionRequestTimeout() - */ - public void setConnectionRequestTimeout(int connectionRequestTimeout) { - this.requestConfig = cloneRequestConfig().setConnectionRequestTimeout(connectionRequestTimeout).build(); - } - - /** - * Set the socket read timeout for the underlying HttpClient. - * A timeout value of 0 specifies an infinite timeout. - *

    Additional properties can be configured by specifying a - * {@link RequestConfig} instance on a custom {@link HttpClient}. - * @param timeout the timeout value in milliseconds - * @see #DEFAULT_READ_TIMEOUT_MILLISECONDS - * @see RequestConfig#getSocketTimeout() - */ - public void setReadTimeout(int timeout) { - Assert.isTrue(timeout >= 0, "Timeout must be a non-negative value"); - this.requestConfig = cloneRequestConfig().setSocketTimeout(timeout).build(); - } - - private RequestConfig.Builder cloneRequestConfig() { - return (this.requestConfig != null ? RequestConfig.copy(this.requestConfig) : RequestConfig.custom()); - } - - - /** - * Execute the given request through the HttpClient. - *

    This method implements the basic processing workflow: - * The actual work happens in this class's template methods. - * @see #createHttpPost - * @see #setRequestBody - * @see #executeHttpPost - * @see #validateResponse - * @see #getResponseBody - */ - @Override - protected RemoteInvocationResult doExecuteRequest( - HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) - throws IOException, ClassNotFoundException { - - HttpPost postMethod = createHttpPost(config); - setRequestBody(config, postMethod, baos); - try { - HttpResponse response = executeHttpPost(config, getHttpClient(), postMethod); - validateResponse(config, response); - InputStream responseBody = getResponseBody(config, response); - return readRemoteInvocationResult(responseBody, config.getCodebaseUrl()); - } - finally { - postMethod.releaseConnection(); - } - } - - /** - * Create an HttpPost for the given configuration. - *

    The default implementation creates a standard HttpPost with - * "application/x-java-serialized-object" as "Content-Type" header. - * @param config the HTTP invoker configuration that specifies the - * target service - * @return the HttpPost instance - * @throws java.io.IOException if thrown by I/O methods - */ - protected HttpPost createHttpPost(HttpInvokerClientConfiguration config) throws IOException { - HttpPost httpPost = new HttpPost(config.getServiceUrl()); - - RequestConfig requestConfig = createRequestConfig(config); - if (requestConfig != null) { - httpPost.setConfig(requestConfig); - } - - LocaleContext localeContext = LocaleContextHolder.getLocaleContext(); - if (localeContext != null) { - Locale locale = localeContext.getLocale(); - if (locale != null) { - httpPost.addHeader(HTTP_HEADER_ACCEPT_LANGUAGE, locale.toLanguageTag()); - } - } - - if (isAcceptGzipEncoding()) { - httpPost.addHeader(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP); - } - - return httpPost; - } - - /** - * Create a {@link RequestConfig} for the given configuration. Can return {@code null} - * to indicate that no custom request config should be set and the defaults of the - * {@link HttpClient} should be used. - *

    The default implementation tries to merge the defaults of the client with the - * local customizations of the instance, if any. - * @param config the HTTP invoker configuration that specifies the - * target service - * @return the RequestConfig to use - */ - @Nullable - protected RequestConfig createRequestConfig(HttpInvokerClientConfiguration config) { - HttpClient client = getHttpClient(); - if (client instanceof Configurable) { - RequestConfig clientRequestConfig = ((Configurable) client).getConfig(); - return mergeRequestConfig(clientRequestConfig); - } - return this.requestConfig; - } - - private RequestConfig mergeRequestConfig(RequestConfig defaultRequestConfig) { - if (this.requestConfig == null) { // nothing to merge - return defaultRequestConfig; - } - - RequestConfig.Builder builder = RequestConfig.copy(defaultRequestConfig); - int connectTimeout = this.requestConfig.getConnectTimeout(); - if (connectTimeout >= 0) { - builder.setConnectTimeout(connectTimeout); - } - int connectionRequestTimeout = this.requestConfig.getConnectionRequestTimeout(); - if (connectionRequestTimeout >= 0) { - builder.setConnectionRequestTimeout(connectionRequestTimeout); - } - int socketTimeout = this.requestConfig.getSocketTimeout(); - if (socketTimeout >= 0) { - builder.setSocketTimeout(socketTimeout); - } - return builder.build(); - } - - /** - * Set the given serialized remote invocation as request body. - *

    The default implementation simply sets the serialized invocation as the - * HttpPost's request body. This can be overridden, for example, to write a - * specific encoding and to potentially set appropriate HTTP request headers. - * @param config the HTTP invoker configuration that specifies the target service - * @param httpPost the HttpPost to set the request body on - * @param baos the ByteArrayOutputStream that contains the serialized - * RemoteInvocation object - * @throws java.io.IOException if thrown by I/O methods - */ - protected void setRequestBody( - HttpInvokerClientConfiguration config, HttpPost httpPost, ByteArrayOutputStream baos) - throws IOException { - - ByteArrayEntity entity = new ByteArrayEntity(baos.toByteArray()); - entity.setContentType(getContentType()); - httpPost.setEntity(entity); - } - - /** - * Execute the given HttpPost instance. - * @param config the HTTP invoker configuration that specifies the target service - * @param httpClient the HttpClient to execute on - * @param httpPost the HttpPost to execute - * @return the resulting HttpResponse - * @throws java.io.IOException if thrown by I/O methods - */ - protected HttpResponse executeHttpPost( - HttpInvokerClientConfiguration config, HttpClient httpClient, HttpPost httpPost) - throws IOException { - - return httpClient.execute(httpPost); - } - - /** - * Validate the given response as contained in the HttpPost object, - * throwing an exception if it does not correspond to a successful HTTP response. - *

    Default implementation rejects any HTTP status code beyond 2xx, to avoid - * parsing the response body and trying to deserialize from a corrupted stream. - * @param config the HTTP invoker configuration that specifies the target service - * @param response the resulting HttpResponse to validate - * @throws java.io.IOException if validation failed - */ - protected void validateResponse(HttpInvokerClientConfiguration config, HttpResponse response) - throws IOException { - - StatusLine status = response.getStatusLine(); - if (status.getStatusCode() >= 300) { - throw new NoHttpResponseException( - "Did not receive successful HTTP response: status code = " + status.getStatusCode() + - ", status message = [" + status.getReasonPhrase() + "]"); - } - } - - /** - * Extract the response body from the given executed remote invocation request. - *

    The default implementation simply fetches the HttpPost's response body stream. - * If the response is recognized as GZIP response, the InputStream will get wrapped - * in a GZIPInputStream. - * @param config the HTTP invoker configuration that specifies the target service - * @param httpResponse the resulting HttpResponse to read the response body from - * @return an InputStream for the response body - * @throws java.io.IOException if thrown by I/O methods - * @see #isGzipResponse - * @see java.util.zip.GZIPInputStream - */ - protected InputStream getResponseBody(HttpInvokerClientConfiguration config, HttpResponse httpResponse) - throws IOException { - - if (isGzipResponse(httpResponse)) { - return new GZIPInputStream(httpResponse.getEntity().getContent()); - } - else { - return httpResponse.getEntity().getContent(); - } - } - - /** - * Determine whether the given response indicates a GZIP response. - *

    The default implementation checks whether the HTTP "Content-Encoding" - * header contains "gzip" (in any casing). - * @param httpResponse the resulting HttpResponse to check - * @return whether the given response indicates a GZIP response - */ - protected boolean isGzipResponse(HttpResponse httpResponse) { - Header encodingHeader = httpResponse.getFirstHeader(HTTP_HEADER_CONTENT_ENCODING); - return (encodingHeader != null && encodingHeader.getValue() != null && - encodingHeader.getValue().toLowerCase().contains(ENCODING_GZIP)); - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientConfiguration.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientConfiguration.java deleted file mode 100644 index 9e81e1d289ec..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.httpinvoker; - -import org.springframework.lang.Nullable; - -/** - * Configuration interface for executing HTTP invoker requests. - * - * @author Juergen Hoeller - * @since 1.1 - * @see HttpInvokerRequestExecutor - * @see HttpInvokerClientInterceptor - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public interface HttpInvokerClientConfiguration { - - /** - * Return the HTTP URL of the target service. - */ - String getServiceUrl(); - - /** - * Return the codebase URL to download classes from if not found locally. - * Can consist of multiple URLs, separated by spaces. - * @return the codebase URL, or {@code null} if none - * @see java.rmi.server.RMIClassLoader - */ - @Nullable - String getCodebaseUrl(); - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientInterceptor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientInterceptor.java deleted file mode 100644 index 361101475e34..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientInterceptor.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.httpinvoker; - -import java.io.IOException; -import java.io.InvalidClassException; -import java.net.ConnectException; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.aop.support.AopUtils; -import org.springframework.lang.Nullable; -import org.springframework.remoting.RemoteAccessException; -import org.springframework.remoting.RemoteConnectFailureException; -import org.springframework.remoting.RemoteInvocationFailureException; -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.remoting.support.RemoteInvocationBasedAccessor; -import org.springframework.remoting.support.RemoteInvocationResult; - -/** - * {@link org.aopalliance.intercept.MethodInterceptor} for accessing an - * HTTP invoker service. The service URL must be an HTTP URL exposing - * an HTTP invoker service. - * - *

    Serializes remote invocation objects and deserializes remote invocation - * result objects. Uses Java serialization just like RMI, but provides the - * same ease of setup as Caucho's HTTP-based Hessian protocol. - * - *

    HTTP invoker is a very extensible and customizable protocol. - * It supports the RemoteInvocationFactory mechanism, like RMI invoker, - * allowing to include additional invocation attributes (for example, - * a security context). Furthermore, it allows to customize request - * execution via the {@link HttpInvokerRequestExecutor} strategy. - * - *

    Can use the JDK's {@link java.rmi.server.RMIClassLoader} to load classes - * from a given {@link #setCodebaseUrl codebase}, performing on-demand dynamic - * code download from a remote location. The codebase can consist of multiple - * URLs, separated by spaces. Note that RMIClassLoader requires a SecurityManager - * to be set, analogous to when using dynamic class download with standard RMI! - * (See the RMI documentation for details.) - * - *

    WARNING: Be aware of vulnerabilities due to unsafe Java deserialization: - * Manipulated input streams could lead to unwanted code execution on the server - * during the deserialization step. As a consequence, do not expose HTTP invoker - * endpoints to untrusted clients but rather just between your own services. - * In general, we strongly recommend any other message format (e.g. JSON) instead. - * - * @author Juergen Hoeller - * @since 1.1 - * @see #setServiceUrl - * @see #setCodebaseUrl - * @see #setRemoteInvocationFactory - * @see #setHttpInvokerRequestExecutor - * @see HttpInvokerServiceExporter - * @see HttpInvokerProxyFactoryBean - * @see java.rmi.server.RMIClassLoader - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class HttpInvokerClientInterceptor extends RemoteInvocationBasedAccessor - implements MethodInterceptor, HttpInvokerClientConfiguration { - - @Nullable - private String codebaseUrl; - - @Nullable - private HttpInvokerRequestExecutor httpInvokerRequestExecutor; - - - /** - * Set the codebase URL to download classes from if not found locally. - * Can consists of multiple URLs, separated by spaces. - *

    Follows RMI's codebase conventions for dynamic class download. - * In contrast to RMI, where the server determines the URL for class download - * (via the "java.rmi.server.codebase" system property), it's the client - * that determines the codebase URL here. The server will usually be the - * same as for the service URL, just pointing to a different path there. - * @see #setServiceUrl - * @see org.springframework.remoting.rmi.CodebaseAwareObjectInputStream - * @see java.rmi.server.RMIClassLoader - */ - public void setCodebaseUrl(@Nullable String codebaseUrl) { - this.codebaseUrl = codebaseUrl; - } - - /** - * Return the codebase URL to download classes from if not found locally. - */ - @Override - @Nullable - public String getCodebaseUrl() { - return this.codebaseUrl; - } - - /** - * Set the HttpInvokerRequestExecutor implementation to use for executing - * remote invocations. - *

    Default is {@link SimpleHttpInvokerRequestExecutor}. Alternatively, - * consider using {@link HttpComponentsHttpInvokerRequestExecutor} for more - * sophisticated needs. - * @see SimpleHttpInvokerRequestExecutor - * @see HttpComponentsHttpInvokerRequestExecutor - */ - public void setHttpInvokerRequestExecutor(HttpInvokerRequestExecutor httpInvokerRequestExecutor) { - this.httpInvokerRequestExecutor = httpInvokerRequestExecutor; - } - - /** - * Return the HttpInvokerRequestExecutor used by this remote accessor. - *

    Creates a default SimpleHttpInvokerRequestExecutor if no executor - * has been initialized already. - */ - public HttpInvokerRequestExecutor getHttpInvokerRequestExecutor() { - if (this.httpInvokerRequestExecutor == null) { - SimpleHttpInvokerRequestExecutor executor = new SimpleHttpInvokerRequestExecutor(); - executor.setBeanClassLoader(getBeanClassLoader()); - this.httpInvokerRequestExecutor = executor; - } - return this.httpInvokerRequestExecutor; - } - - @Override - public void afterPropertiesSet() { - super.afterPropertiesSet(); - - // Eagerly initialize the default HttpInvokerRequestExecutor, if needed. - getHttpInvokerRequestExecutor(); - } - - - @Override - @Nullable - public Object invoke(MethodInvocation methodInvocation) throws Throwable { - if (AopUtils.isToStringMethod(methodInvocation.getMethod())) { - return "HTTP invoker proxy for service URL [" + getServiceUrl() + "]"; - } - - RemoteInvocation invocation = createRemoteInvocation(methodInvocation); - RemoteInvocationResult result; - - try { - result = executeRequest(invocation, methodInvocation); - } - catch (Throwable ex) { - RemoteAccessException rae = convertHttpInvokerAccessException(ex); - throw (rae != null ? rae : ex); - } - - try { - return recreateRemoteInvocationResult(result); - } - catch (Throwable ex) { - if (result.hasInvocationTargetException()) { - throw ex; - } - else { - throw new RemoteInvocationFailureException("Invocation of method [" + methodInvocation.getMethod() + - "] failed in HTTP invoker remote service at [" + getServiceUrl() + "]", ex); - } - } - } - - /** - * Execute the given remote invocation via the {@link HttpInvokerRequestExecutor}. - *

    This implementation delegates to {@link #executeRequest(RemoteInvocation)}. - * Can be overridden to react to the specific original MethodInvocation. - * @param invocation the RemoteInvocation to execute - * @param originalInvocation the original MethodInvocation (can e.g. be cast - * to the ProxyMethodInvocation interface for accessing user attributes) - * @return the RemoteInvocationResult object - * @throws Exception in case of errors - */ - protected RemoteInvocationResult executeRequest( - RemoteInvocation invocation, MethodInvocation originalInvocation) throws Exception { - - return executeRequest(invocation); - } - - /** - * Execute the given remote invocation via the {@link HttpInvokerRequestExecutor}. - *

    Can be overridden in subclasses to pass a different configuration object - * to the executor. Alternatively, add further configuration properties in a - * subclass of this accessor: By default, the accessor passed itself as - * configuration object to the executor. - * @param invocation the RemoteInvocation to execute - * @return the RemoteInvocationResult object - * @throws IOException if thrown by I/O operations - * @throws ClassNotFoundException if thrown during deserialization - * @throws Exception in case of general errors - * @see #getHttpInvokerRequestExecutor - * @see HttpInvokerClientConfiguration - */ - protected RemoteInvocationResult executeRequest(RemoteInvocation invocation) throws Exception { - return getHttpInvokerRequestExecutor().executeRequest(this, invocation); - } - - /** - * Convert the given HTTP invoker access exception to an appropriate - * Spring {@link RemoteAccessException}. - * @param ex the exception to convert - * @return the RemoteAccessException to throw, or {@code null} to have the - * original exception propagated to the caller - */ - @Nullable - protected RemoteAccessException convertHttpInvokerAccessException(Throwable ex) { - if (ex instanceof ConnectException) { - return new RemoteConnectFailureException( - "Could not connect to HTTP invoker remote service at [" + getServiceUrl() + "]", ex); - } - - if (ex instanceof ClassNotFoundException || ex instanceof NoClassDefFoundError || - ex instanceof InvalidClassException) { - return new RemoteAccessException( - "Could not deserialize result from HTTP invoker remote service [" + getServiceUrl() + "]", ex); - } - - if (ex instanceof Exception) { - return new RemoteAccessException( - "Could not access HTTP invoker remote service at [" + getServiceUrl() + "]", ex); - } - - // For any other Throwable, e.g. OutOfMemoryError: let it get propagated as-is. - return null; - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java deleted file mode 100644 index ae483e45ff80..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.httpinvoker; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * {@link FactoryBean} for HTTP invoker proxies. Exposes the proxied service - * for use as a bean reference, using the specified service interface. - * - *

    The service URL must be an HTTP URL exposing an HTTP invoker service. - * Optionally, a codebase URL can be specified for on-demand dynamic code download - * from a remote location. For details, see HttpInvokerClientInterceptor docs. - * - *

    Serializes remote invocation objects and deserializes remote invocation - * result objects. Uses Java serialization just like RMI, but provides the - * same ease of setup as Caucho's HTTP-based Hessian protocol. - * - *

    HTTP invoker is the recommended protocol for Java-to-Java remoting. - * It is more powerful and more extensible than Hessian, at the expense of - * being tied to Java. Nevertheless, it is as easy to set up as Hessian, - * which is its main advantage compared to RMI. - * - *

    WARNING: Be aware of vulnerabilities due to unsafe Java deserialization: - * Manipulated input streams could lead to unwanted code execution on the server - * during the deserialization step. As a consequence, do not expose HTTP invoker - * endpoints to untrusted clients but rather just between your own services. - * In general, we strongly recommend any other message format (e.g. JSON) instead. - * - * @author Juergen Hoeller - * @since 1.1 - * @see #setServiceInterface - * @see #setServiceUrl - * @see #setCodebaseUrl - * @see HttpInvokerClientInterceptor - * @see HttpInvokerServiceExporter - * @see org.springframework.remoting.rmi.RmiProxyFactoryBean - * @see org.springframework.remoting.caucho.HessianProxyFactoryBean - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class HttpInvokerProxyFactoryBean extends HttpInvokerClientInterceptor implements FactoryBean { - - @Nullable - private Object serviceProxy; - - - @Override - public void afterPropertiesSet() { - super.afterPropertiesSet(); - Class ifc = getServiceInterface(); - Assert.notNull(ifc, "Property 'serviceInterface' is required"); - this.serviceProxy = new ProxyFactory(ifc, this).getProxy(getBeanClassLoader()); - } - - - @Override - @Nullable - public Object getObject() { - return this.serviceProxy; - } - - @Override - public Class getObjectType() { - return getServiceInterface(); - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerRequestExecutor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerRequestExecutor.java deleted file mode 100644 index d5236e517996..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerRequestExecutor.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.httpinvoker; - -import java.io.IOException; - -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.remoting.support.RemoteInvocationResult; - -/** - * Strategy interface for actual execution of an HTTP invoker request. - * Used by HttpInvokerClientInterceptor and its subclass - * HttpInvokerProxyFactoryBean. - * - *

    Two implementations are provided out of the box: - *

      - *
    • {@code SimpleHttpInvokerRequestExecutor}: - * Uses JDK facilities to execute POST requests, without support - * for HTTP authentication or advanced configuration options. - *
    • {@code HttpComponentsHttpInvokerRequestExecutor}: - * Uses Apache's Commons HttpClient to execute POST requests, - * allowing to use a preconfigured HttpClient instance - * (potentially with authentication, HTTP connection pooling, etc). - *
    - * - * @author Juergen Hoeller - * @since 1.1 - * @see HttpInvokerClientInterceptor#setHttpInvokerRequestExecutor - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -@FunctionalInterface -public interface HttpInvokerRequestExecutor { - - /** - * Execute a request to send the given remote invocation. - * @param config the HTTP invoker configuration that specifies the - * target service - * @param invocation the RemoteInvocation to execute - * @return the RemoteInvocationResult object - * @throws IOException if thrown by I/O operations - * @throws ClassNotFoundException if thrown during deserialization - * @throws Exception in case of general errors - */ - RemoteInvocationResult executeRequest(HttpInvokerClientConfiguration config, RemoteInvocation invocation) - throws Exception; - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.java deleted file mode 100644 index dc1a0ac746bf..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.httpinvoker; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.remoting.support.RemoteInvocationResult; -import org.springframework.web.HttpRequestHandler; -import org.springframework.web.util.NestedServletException; - -/** - * Servlet-API-based HTTP request handler that exports the specified service bean - * as HTTP invoker service endpoint, accessible via an HTTP invoker proxy. - * - *

    Deserializes remote invocation objects and serializes remote invocation - * result objects. Uses Java serialization just like RMI, but provides the - * same ease of setup as Caucho's HTTP-based Hessian protocol. - * - *

    HTTP invoker is the recommended protocol for Java-to-Java remoting. - * It is more powerful and more extensible than Hessian, at the expense of - * being tied to Java. Nevertheless, it is as easy to set up as Hessian, - * which is its main advantage compared to RMI. - * - *

    WARNING: Be aware of vulnerabilities due to unsafe Java deserialization: - * Manipulated input streams could lead to unwanted code execution on the server - * during the deserialization step. As a consequence, do not expose HTTP invoker - * endpoints to untrusted clients but rather just between your own services. - * In general, we strongly recommend any other message format (e.g. JSON) instead. - * - * @author Juergen Hoeller - * @since 1.1 - * @see HttpInvokerClientInterceptor - * @see HttpInvokerProxyFactoryBean - * @see org.springframework.remoting.rmi.RmiServiceExporter - * @see org.springframework.remoting.caucho.HessianServiceExporter - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class HttpInvokerServiceExporter extends org.springframework.remoting.rmi.RemoteInvocationSerializingExporter implements HttpRequestHandler { - - /** - * Reads a remote invocation from the request, executes it, - * and writes the remote invocation result to the response. - * @see #readRemoteInvocation(HttpServletRequest) - * @see #invokeAndCreateResult(org.springframework.remoting.support.RemoteInvocation, Object) - * @see #writeRemoteInvocationResult(HttpServletRequest, HttpServletResponse, RemoteInvocationResult) - */ - @Override - public void handleRequest(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - - try { - RemoteInvocation invocation = readRemoteInvocation(request); - RemoteInvocationResult result = invokeAndCreateResult(invocation, getProxy()); - writeRemoteInvocationResult(request, response, result); - } - catch (ClassNotFoundException ex) { - throw new NestedServletException("Class not found during deserialization", ex); - } - } - - /** - * Read a RemoteInvocation from the given HTTP request. - *

    Delegates to {@link #readRemoteInvocation(HttpServletRequest, InputStream)} with - * the {@link HttpServletRequest#getInputStream() servlet request's input stream}. - * @param request current HTTP request - * @return the RemoteInvocation object - * @throws IOException in case of I/O failure - * @throws ClassNotFoundException if thrown by deserialization - */ - protected RemoteInvocation readRemoteInvocation(HttpServletRequest request) - throws IOException, ClassNotFoundException { - - return readRemoteInvocation(request, request.getInputStream()); - } - - /** - * Deserialize a RemoteInvocation object from the given InputStream. - *

    Gives {@link #decorateInputStream} a chance to decorate the stream - * first (for example, for custom encryption or compression). Creates a - * {@link org.springframework.remoting.rmi.CodebaseAwareObjectInputStream} - * and calls {@link #doReadRemoteInvocation} to actually read the object. - *

    Can be overridden for custom serialization of the invocation. - * @param request current HTTP request - * @param is the InputStream to read from - * @return the RemoteInvocation object - * @throws IOException in case of I/O failure - * @throws ClassNotFoundException if thrown during deserialization - */ - protected RemoteInvocation readRemoteInvocation(HttpServletRequest request, InputStream is) - throws IOException, ClassNotFoundException { - - try (ObjectInputStream ois = createObjectInputStream(decorateInputStream(request, is))) { - return doReadRemoteInvocation(ois); - } - } - - /** - * Return the InputStream to use for reading remote invocations, - * potentially decorating the given original InputStream. - *

    The default implementation returns the given stream as-is. - * Can be overridden, for example, for custom encryption or compression. - * @param request current HTTP request - * @param is the original InputStream - * @return the potentially decorated InputStream - * @throws IOException in case of I/O failure - */ - protected InputStream decorateInputStream(HttpServletRequest request, InputStream is) throws IOException { - return is; - } - - /** - * Write the given RemoteInvocationResult to the given HTTP response. - * @param request current HTTP request - * @param response current HTTP response - * @param result the RemoteInvocationResult object - * @throws IOException in case of I/O failure - */ - protected void writeRemoteInvocationResult( - HttpServletRequest request, HttpServletResponse response, RemoteInvocationResult result) - throws IOException { - - response.setContentType(getContentType()); - writeRemoteInvocationResult(request, response, result, response.getOutputStream()); - } - - /** - * Serialize the given RemoteInvocation to the given OutputStream. - *

    The default implementation gives {@link #decorateOutputStream} a chance - * to decorate the stream first (for example, for custom encryption or compression). - * Creates an {@link java.io.ObjectOutputStream} for the final stream and calls - * {@link #doWriteRemoteInvocationResult} to actually write the object. - *

    Can be overridden for custom serialization of the invocation. - * @param request current HTTP request - * @param response current HTTP response - * @param result the RemoteInvocationResult object - * @param os the OutputStream to write to - * @throws IOException in case of I/O failure - * @see #decorateOutputStream - * @see #doWriteRemoteInvocationResult - */ - protected void writeRemoteInvocationResult( - HttpServletRequest request, HttpServletResponse response, RemoteInvocationResult result, OutputStream os) - throws IOException { - - try (ObjectOutputStream oos = - createObjectOutputStream(new FlushGuardedOutputStream(decorateOutputStream(request, response, os)))) { - doWriteRemoteInvocationResult(result, oos); - } - } - - /** - * Return the OutputStream to use for writing remote invocation results, - * potentially decorating the given original OutputStream. - *

    The default implementation returns the given stream as-is. - * Can be overridden, for example, for custom encryption or compression. - * @param request current HTTP request - * @param response current HTTP response - * @param os the original OutputStream - * @return the potentially decorated OutputStream - * @throws IOException in case of I/O failure - */ - protected OutputStream decorateOutputStream( - HttpServletRequest request, HttpServletResponse response, OutputStream os) throws IOException { - - return os; - } - - - /** - * Decorate an {@code OutputStream} to guard against {@code flush()} calls, - * which are turned into no-ops. - *

    Because {@link ObjectOutputStream#close()} will in fact flush/drain - * the underlying stream twice, this {@link FilterOutputStream} will - * guard against individual flush calls. Multiple flush calls can lead - * to performance issues, since writes aren't gathered as they should be. - * @see SPR-14040 - */ - private static class FlushGuardedOutputStream extends FilterOutputStream { - - public FlushGuardedOutputStream(OutputStream out) { - super(out); - } - - @Override - public void flush() throws IOException { - // Do nothing on flush - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerRequestExecutor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerRequestExecutor.java deleted file mode 100644 index b4c8f31c364b..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerRequestExecutor.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.httpinvoker; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.util.Locale; -import java.util.zip.GZIPInputStream; - -import org.springframework.context.i18n.LocaleContext; -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.remoting.support.RemoteInvocationResult; - -/** - * {@link org.springframework.remoting.httpinvoker.HttpInvokerRequestExecutor} implementation - * that uses standard Java facilities to execute POST requests, without support for HTTP - * authentication or advanced configuration options. - * - *

    Designed for easy subclassing, customizing specific template methods. However, - * consider {@code HttpComponentsHttpInvokerRequestExecutor} for more sophisticated needs: - * The standard {@link HttpURLConnection} class is rather limited in its capabilities. - * - * @author Juergen Hoeller - * @since 1.1 - * @see java.net.HttpURLConnection - * @deprecated as of 5.3 (phasing out serialization-based remoting) - */ -@Deprecated -public class SimpleHttpInvokerRequestExecutor extends AbstractHttpInvokerRequestExecutor { - - private int connectTimeout = -1; - - private int readTimeout = -1; - - - /** - * Set the underlying URLConnection's connect timeout (in milliseconds). - * A timeout value of 0 specifies an infinite timeout. - *

    Default is the system's default timeout. - * @see URLConnection#setConnectTimeout(int) - */ - public void setConnectTimeout(int connectTimeout) { - this.connectTimeout = connectTimeout; - } - - /** - * Set the underlying URLConnection's read timeout (in milliseconds). - * A timeout value of 0 specifies an infinite timeout. - *

    Default is the system's default timeout. - * @see URLConnection#setReadTimeout(int) - */ - public void setReadTimeout(int readTimeout) { - this.readTimeout = readTimeout; - } - - - /** - * Execute the given request through a standard {@link HttpURLConnection}. - *

    This method implements the basic processing workflow: - * The actual work happens in this class's template methods. - * @see #openConnection - * @see #prepareConnection - * @see #writeRequestBody - * @see #validateResponse - * @see #readResponseBody - */ - @Override - protected RemoteInvocationResult doExecuteRequest( - HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) - throws IOException, ClassNotFoundException { - - HttpURLConnection con = openConnection(config); - prepareConnection(con, baos.size()); - writeRequestBody(config, con, baos); - validateResponse(config, con); - InputStream responseBody = readResponseBody(config, con); - - return readRemoteInvocationResult(responseBody, config.getCodebaseUrl()); - } - - /** - * Open an {@link HttpURLConnection} for the given remote invocation request. - * @param config the HTTP invoker configuration that specifies the - * target service - * @return the HttpURLConnection for the given request - * @throws IOException if thrown by I/O methods - * @see java.net.URL#openConnection() - */ - protected HttpURLConnection openConnection(HttpInvokerClientConfiguration config) throws IOException { - URLConnection con = new URL(config.getServiceUrl()).openConnection(); - if (!(con instanceof HttpURLConnection)) { - throw new IOException( - "Service URL [" + config.getServiceUrl() + "] does not resolve to an HTTP connection"); - } - return (HttpURLConnection) con; - } - - /** - * Prepare the given HTTP connection. - *

    The default implementation specifies POST as method, - * "application/x-java-serialized-object" as "Content-Type" header, - * and the given content length as "Content-Length" header. - * @param connection the HTTP connection to prepare - * @param contentLength the length of the content to send - * @throws IOException if thrown by HttpURLConnection methods - * @see java.net.HttpURLConnection#setRequestMethod - * @see java.net.HttpURLConnection#setRequestProperty - */ - protected void prepareConnection(HttpURLConnection connection, int contentLength) throws IOException { - if (this.connectTimeout >= 0) { - connection.setConnectTimeout(this.connectTimeout); - } - if (this.readTimeout >= 0) { - connection.setReadTimeout(this.readTimeout); - } - - connection.setDoOutput(true); - connection.setRequestMethod(HTTP_METHOD_POST); - connection.setRequestProperty(HTTP_HEADER_CONTENT_TYPE, getContentType()); - connection.setRequestProperty(HTTP_HEADER_CONTENT_LENGTH, Integer.toString(contentLength)); - - LocaleContext localeContext = LocaleContextHolder.getLocaleContext(); - if (localeContext != null) { - Locale locale = localeContext.getLocale(); - if (locale != null) { - connection.setRequestProperty(HTTP_HEADER_ACCEPT_LANGUAGE, locale.toLanguageTag()); - } - } - - if (isAcceptGzipEncoding()) { - connection.setRequestProperty(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP); - } - } - - /** - * Set the given serialized remote invocation as request body. - *

    The default implementation simply write the serialized invocation to the - * HttpURLConnection's OutputStream. This can be overridden, for example, to write - * a specific encoding and potentially set appropriate HTTP request headers. - * @param config the HTTP invoker configuration that specifies the target service - * @param con the HttpURLConnection to write the request body to - * @param baos the ByteArrayOutputStream that contains the serialized - * RemoteInvocation object - * @throws IOException if thrown by I/O methods - * @see java.net.HttpURLConnection#getOutputStream() - * @see java.net.HttpURLConnection#setRequestProperty - */ - protected void writeRequestBody( - HttpInvokerClientConfiguration config, HttpURLConnection con, ByteArrayOutputStream baos) - throws IOException { - - baos.writeTo(con.getOutputStream()); - } - - /** - * Validate the given response as contained in the {@link HttpURLConnection} object, - * throwing an exception if it does not correspond to a successful HTTP response. - *

    Default implementation rejects any HTTP status code beyond 2xx, to avoid - * parsing the response body and trying to deserialize from a corrupted stream. - * @param config the HTTP invoker configuration that specifies the target service - * @param con the HttpURLConnection to validate - * @throws IOException if validation failed - * @see java.net.HttpURLConnection#getResponseCode() - */ - protected void validateResponse(HttpInvokerClientConfiguration config, HttpURLConnection con) - throws IOException { - - if (con.getResponseCode() >= 300) { - throw new IOException( - "Did not receive successful HTTP response: status code = " + con.getResponseCode() + - ", status message = [" + con.getResponseMessage() + "]"); - } - } - - /** - * Extract the response body from the given executed remote invocation - * request. - *

    The default implementation simply reads the serialized invocation - * from the HttpURLConnection's InputStream. If the response is recognized - * as GZIP response, the InputStream will get wrapped in a GZIPInputStream. - * @param config the HTTP invoker configuration that specifies the target service - * @param con the HttpURLConnection to read the response body from - * @return an InputStream for the response body - * @throws IOException if thrown by I/O methods - * @see #isGzipResponse - * @see java.util.zip.GZIPInputStream - * @see java.net.HttpURLConnection#getInputStream() - * @see java.net.HttpURLConnection#getHeaderField(int) - * @see java.net.HttpURLConnection#getHeaderFieldKey(int) - */ - protected InputStream readResponseBody(HttpInvokerClientConfiguration config, HttpURLConnection con) - throws IOException { - - if (isGzipResponse(con)) { - // GZIP response found - need to unzip. - return new GZIPInputStream(con.getInputStream()); - } - else { - // Plain response found. - return con.getInputStream(); - } - } - - /** - * Determine whether the given response is a GZIP response. - *

    Default implementation checks whether the HTTP "Content-Encoding" - * header contains "gzip" (in any casing). - * @param con the HttpURLConnection to check - */ - protected boolean isGzipResponse(HttpURLConnection con) { - String encodingHeader = con.getHeaderField(HTTP_HEADER_CONTENT_ENCODING); - return (encodingHeader != null && encodingHeader.toLowerCase().contains(ENCODING_GZIP)); - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerServiceExporter.java deleted file mode 100644 index 5c8e431fbaf2..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerServiceExporter.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.httpinvoker; - -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; - -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; - -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.remoting.support.RemoteInvocationResult; - -/** - * HTTP request handler that exports the specified service bean as - * HTTP invoker service endpoint, accessible via an HTTP invoker proxy. - * Designed for Sun's JRE 1.6 HTTP server, implementing the - * {@link com.sun.net.httpserver.HttpHandler} interface. - * - *

    Deserializes remote invocation objects and serializes remote invocation - * result objects. Uses Java serialization just like RMI, but provides the - * same ease of setup as Caucho's HTTP-based Hessian protocol. - * - *

    HTTP invoker is the recommended protocol for Java-to-Java remoting. - * It is more powerful and more extensible than Hessian, at the expense of - * being tied to Java. Nevertheless, it is as easy to set up as Hessian, - * which is its main advantage compared to RMI. - * - *

    WARNING: Be aware of vulnerabilities due to unsafe Java deserialization: - * Manipulated input streams could lead to unwanted code execution on the server - * during the deserialization step. As a consequence, do not expose HTTP invoker - * endpoints to untrusted clients but rather just between your own services. - * In general, we strongly recommend any other message format (e.g. JSON) instead. - * - * @author Juergen Hoeller - * @since 2.5.1 - * @see org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor - * @see org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean - * @deprecated as of Spring Framework 5.1, in favor of {@link HttpInvokerServiceExporter} - */ -@Deprecated -@org.springframework.lang.UsesSunHttpServer -public class SimpleHttpInvokerServiceExporter extends org.springframework.remoting.rmi.RemoteInvocationSerializingExporter implements HttpHandler { - - /** - * Reads a remote invocation from the request, executes it, - * and writes the remote invocation result to the response. - * @see #readRemoteInvocation(HttpExchange) - * @see #invokeAndCreateResult(RemoteInvocation, Object) - * @see #writeRemoteInvocationResult(HttpExchange, RemoteInvocationResult) - */ - @Override - public void handle(HttpExchange exchange) throws IOException { - try { - RemoteInvocation invocation = readRemoteInvocation(exchange); - RemoteInvocationResult result = invokeAndCreateResult(invocation, getProxy()); - writeRemoteInvocationResult(exchange, result); - exchange.close(); - } - catch (ClassNotFoundException ex) { - exchange.sendResponseHeaders(500, -1); - logger.error("Class not found during deserialization", ex); - } - } - - /** - * Read a RemoteInvocation from the given HTTP request. - *

    Delegates to {@link #readRemoteInvocation(HttpExchange, InputStream)} - * with the {@link HttpExchange#getRequestBody()} request's input stream}. - * @param exchange current HTTP request/response - * @return the RemoteInvocation object - * @throws java.io.IOException in case of I/O failure - * @throws ClassNotFoundException if thrown by deserialization - */ - protected RemoteInvocation readRemoteInvocation(HttpExchange exchange) - throws IOException, ClassNotFoundException { - - return readRemoteInvocation(exchange, exchange.getRequestBody()); - } - - /** - * Deserialize a RemoteInvocation object from the given InputStream. - *

    Gives {@link #decorateInputStream} a chance to decorate the stream - * first (for example, for custom encryption or compression). Creates a - * {@link org.springframework.remoting.rmi.CodebaseAwareObjectInputStream} - * and calls {@link #doReadRemoteInvocation} to actually read the object. - *

    Can be overridden for custom serialization of the invocation. - * @param exchange current HTTP request/response - * @param is the InputStream to read from - * @return the RemoteInvocation object - * @throws java.io.IOException in case of I/O failure - * @throws ClassNotFoundException if thrown during deserialization - */ - protected RemoteInvocation readRemoteInvocation(HttpExchange exchange, InputStream is) - throws IOException, ClassNotFoundException { - - ObjectInputStream ois = createObjectInputStream(decorateInputStream(exchange, is)); - return doReadRemoteInvocation(ois); - } - - /** - * Return the InputStream to use for reading remote invocations, - * potentially decorating the given original InputStream. - *

    The default implementation returns the given stream as-is. - * Can be overridden, for example, for custom encryption or compression. - * @param exchange current HTTP request/response - * @param is the original InputStream - * @return the potentially decorated InputStream - * @throws java.io.IOException in case of I/O failure - */ - protected InputStream decorateInputStream(HttpExchange exchange, InputStream is) throws IOException { - return is; - } - - /** - * Write the given RemoteInvocationResult to the given HTTP response. - * @param exchange current HTTP request/response - * @param result the RemoteInvocationResult object - * @throws java.io.IOException in case of I/O failure - */ - protected void writeRemoteInvocationResult(HttpExchange exchange, RemoteInvocationResult result) - throws IOException { - - exchange.getResponseHeaders().set("Content-Type", getContentType()); - exchange.sendResponseHeaders(200, 0); - writeRemoteInvocationResult(exchange, result, exchange.getResponseBody()); - } - - /** - * Serialize the given RemoteInvocation to the given OutputStream. - *

    The default implementation gives {@link #decorateOutputStream} a chance - * to decorate the stream first (for example, for custom encryption or compression). - * Creates an {@link java.io.ObjectOutputStream} for the final stream and calls - * {@link #doWriteRemoteInvocationResult} to actually write the object. - *

    Can be overridden for custom serialization of the invocation. - * @param exchange current HTTP request/response - * @param result the RemoteInvocationResult object - * @param os the OutputStream to write to - * @throws java.io.IOException in case of I/O failure - * @see #decorateOutputStream - * @see #doWriteRemoteInvocationResult - */ - protected void writeRemoteInvocationResult( - HttpExchange exchange, RemoteInvocationResult result, OutputStream os) throws IOException { - - ObjectOutputStream oos = createObjectOutputStream(decorateOutputStream(exchange, os)); - doWriteRemoteInvocationResult(result, oos); - oos.flush(); - } - - /** - * Return the OutputStream to use for writing remote invocation results, - * potentially decorating the given original OutputStream. - *

    The default implementation returns the given stream as-is. - * Can be overridden, for example, for custom encryption or compression. - * @param exchange current HTTP request/response - * @param os the original OutputStream - * @return the potentially decorated OutputStream - * @throws java.io.IOException in case of I/O failure - */ - protected OutputStream decorateOutputStream(HttpExchange exchange, OutputStream os) throws IOException { - return os; - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/package-info.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/package-info.java deleted file mode 100644 index e0dfd03aa651..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/package-info.java +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Remoting classes for transparent Java-to-Java remoting via HTTP invokers. - * Uses Java serialization just like RMI, but provides the same ease of setup - * as Caucho's HTTP-based Hessian protocol. - * - *

    HTTP invoker is the recommended protocol for Java-to-Java remoting. - * It is more powerful and more extensible than Hessian, at the expense of - * being tied to Java. Nevertheless, it is as easy to set up as Hessian, - * which is its main advantage compared to RMI. - */ -@NonNullApi -@NonNullFields -package org.springframework.remoting.httpinvoker; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/AbstractJaxWsServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/AbstractJaxWsServiceExporter.java deleted file mode 100644 index 610651bef206..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/jaxws/AbstractJaxWsServiceExporter.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.jaxws; - -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Executor; - -import javax.jws.WebService; -import javax.xml.ws.Endpoint; -import javax.xml.ws.WebServiceFeature; -import javax.xml.ws.WebServiceProvider; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.CannotLoadBeanClassException; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Abstract exporter for JAX-WS services, autodetecting annotated service beans - * (through the JAX-WS {@link javax.jws.WebService} annotation). - * - *

    Subclasses need to implement the {@link #publishEndpoint} template methods - * for actual endpoint exposure. - * - * @author Juergen Hoeller - * @since 2.5.5 - * @see javax.jws.WebService - * @see javax.xml.ws.Endpoint - * @see SimpleJaxWsServiceExporter - */ -public abstract class AbstractJaxWsServiceExporter implements BeanFactoryAware, InitializingBean, DisposableBean { - - @Nullable - private Map endpointProperties; - - @Nullable - private Executor executor; - - @Nullable - private String bindingType; - - @Nullable - private WebServiceFeature[] endpointFeatures; - - @Nullable - private ListableBeanFactory beanFactory; - - private final Set publishedEndpoints = new LinkedHashSet<>(); - - - /** - * Set the property bag for the endpoint, including properties such as - * "javax.xml.ws.wsdl.service" or "javax.xml.ws.wsdl.port". - * @see javax.xml.ws.Endpoint#setProperties - * @see javax.xml.ws.Endpoint#WSDL_SERVICE - * @see javax.xml.ws.Endpoint#WSDL_PORT - */ - public void setEndpointProperties(Map endpointProperties) { - this.endpointProperties = endpointProperties; - } - - /** - * Set the JDK concurrent executor to use for dispatching incoming requests - * to exported service instances. - * @see javax.xml.ws.Endpoint#setExecutor - */ - public void setExecutor(Executor executor) { - this.executor = executor; - } - - /** - * Specify the binding type to use, overriding the value of - * the JAX-WS {@link javax.xml.ws.BindingType} annotation. - */ - public void setBindingType(String bindingType) { - this.bindingType = bindingType; - } - - /** - * Specify WebServiceFeature objects (e.g. as inner bean definitions) - * to apply to JAX-WS endpoint creation. - * @since 4.0 - */ - public void setEndpointFeatures(WebServiceFeature... endpointFeatures) { - this.endpointFeatures = endpointFeatures; - } - - /** - * Obtains all web service beans and publishes them as JAX-WS endpoints. - */ - @Override - public void setBeanFactory(BeanFactory beanFactory) { - if (!(beanFactory instanceof ListableBeanFactory)) { - throw new IllegalStateException(getClass().getSimpleName() + " requires a ListableBeanFactory"); - } - this.beanFactory = (ListableBeanFactory) beanFactory; - } - - - /** - * Immediately publish all endpoints when fully configured. - * @see #publishEndpoints() - */ - @Override - public void afterPropertiesSet() throws Exception { - publishEndpoints(); - } - - /** - * Publish all {@link javax.jws.WebService} annotated beans in the - * containing BeanFactory. - * @see #publishEndpoint - */ - public void publishEndpoints() { - Assert.state(this.beanFactory != null, "No BeanFactory set"); - - Set beanNames = new LinkedHashSet<>(this.beanFactory.getBeanDefinitionCount()); - Collections.addAll(beanNames, this.beanFactory.getBeanDefinitionNames()); - if (this.beanFactory instanceof ConfigurableBeanFactory) { - Collections.addAll(beanNames, ((ConfigurableBeanFactory) this.beanFactory).getSingletonNames()); - } - - for (String beanName : beanNames) { - try { - Class type = this.beanFactory.getType(beanName); - if (type != null && !type.isInterface()) { - WebService wsAnnotation = type.getAnnotation(WebService.class); - WebServiceProvider wsProviderAnnotation = type.getAnnotation(WebServiceProvider.class); - if (wsAnnotation != null || wsProviderAnnotation != null) { - Endpoint endpoint = createEndpoint(this.beanFactory.getBean(beanName)); - if (this.endpointProperties != null) { - endpoint.setProperties(this.endpointProperties); - } - if (this.executor != null) { - endpoint.setExecutor(this.executor); - } - if (wsAnnotation != null) { - publishEndpoint(endpoint, wsAnnotation); - } - else { - publishEndpoint(endpoint, wsProviderAnnotation); - } - this.publishedEndpoints.add(endpoint); - } - } - } - catch (CannotLoadBeanClassException ex) { - // ignore beans where the class is not resolvable - } - } - } - - /** - * Create the actual Endpoint instance. - * @param bean the service object to wrap - * @return the Endpoint instance - * @see Endpoint#create(Object) - * @see Endpoint#create(String, Object) - */ - protected Endpoint createEndpoint(Object bean) { - return (this.endpointFeatures != null ? - Endpoint.create(this.bindingType, bean, this.endpointFeatures) : - Endpoint.create(this.bindingType, bean)); - } - - - /** - * Actually publish the given endpoint. To be implemented by subclasses. - * @param endpoint the JAX-WS Endpoint object - * @param annotation the service bean's WebService annotation - */ - protected abstract void publishEndpoint(Endpoint endpoint, WebService annotation); - - /** - * Actually publish the given provider endpoint. To be implemented by subclasses. - * @param endpoint the JAX-WS Provider Endpoint object - * @param annotation the service bean's WebServiceProvider annotation - */ - protected abstract void publishEndpoint(Endpoint endpoint, WebServiceProvider annotation); - - - /** - * Stops all published endpoints, taking the web services offline. - */ - @Override - public void destroy() { - for (Endpoint endpoint : this.publishedEndpoints) { - endpoint.stop(); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortClientInterceptor.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortClientInterceptor.java deleted file mode 100644 index e8ff14889aae..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortClientInterceptor.java +++ /dev/null @@ -1,561 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.jaxws; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -import javax.jws.WebService; -import javax.xml.namespace.QName; -import javax.xml.ws.BindingProvider; -import javax.xml.ws.ProtocolException; -import javax.xml.ws.Service; -import javax.xml.ws.WebServiceException; -import javax.xml.ws.WebServiceFeature; -import javax.xml.ws.soap.SOAPFaultException; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.aop.support.AopUtils; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; -import org.springframework.remoting.RemoteAccessException; -import org.springframework.remoting.RemoteConnectFailureException; -import org.springframework.remoting.RemoteLookupFailureException; -import org.springframework.remoting.RemoteProxyFailureException; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; - -/** - * {@link org.aopalliance.intercept.MethodInterceptor} for accessing a - * specific port of a JAX-WS service. - * - *

    Uses either {@link LocalJaxWsServiceFactory}'s facilities underneath, - * or takes an explicit reference to an existing JAX-WS Service instance - * (e.g. obtained via {@link org.springframework.jndi.JndiObjectFactoryBean}). - * - * @author Juergen Hoeller - * @since 2.5 - * @see #setPortName - * @see #setServiceInterface - * @see javax.xml.ws.Service#getPort - * @see org.springframework.remoting.RemoteAccessException - * @see org.springframework.jndi.JndiObjectFactoryBean - */ -public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory - implements MethodInterceptor, BeanClassLoaderAware, InitializingBean { - - @Nullable - private Service jaxWsService; - - @Nullable - private String portName; - - @Nullable - private String username; - - @Nullable - private String password; - - @Nullable - private String endpointAddress; - - private boolean maintainSession; - - private boolean useSoapAction; - - @Nullable - private String soapActionUri; - - @Nullable - private Map customProperties; - - @Nullable - private WebServiceFeature[] portFeatures; - - @Nullable - private Class serviceInterface; - - private boolean lookupServiceOnStartup = true; - - @Nullable - private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); - - @Nullable - private QName portQName; - - @Nullable - private Object portStub; - - private final Object preparationMonitor = new Object(); - - - /** - * Set a reference to an existing JAX-WS Service instance, - * for example obtained via {@link org.springframework.jndi.JndiObjectFactoryBean}. - * If not set, {@link LocalJaxWsServiceFactory}'s properties have to be specified. - * @see #setWsdlDocumentUrl - * @see #setNamespaceUri - * @see #setServiceName - * @see org.springframework.jndi.JndiObjectFactoryBean - */ - public void setJaxWsService(@Nullable Service jaxWsService) { - this.jaxWsService = jaxWsService; - } - - /** - * Return a reference to an existing JAX-WS Service instance, if any. - */ - @Nullable - public Service getJaxWsService() { - return this.jaxWsService; - } - - /** - * Set the name of the port. - * Corresponds to the "wsdl:port" name. - */ - public void setPortName(@Nullable String portName) { - this.portName = portName; - } - - /** - * Return the name of the port. - */ - @Nullable - public String getPortName() { - return this.portName; - } - - /** - * Set the username to specify on the stub. - * @see javax.xml.ws.BindingProvider#USERNAME_PROPERTY - */ - public void setUsername(@Nullable String username) { - this.username = username; - } - - /** - * Return the username to specify on the stub. - */ - @Nullable - public String getUsername() { - return this.username; - } - - /** - * Set the password to specify on the stub. - * @see javax.xml.ws.BindingProvider#PASSWORD_PROPERTY - */ - public void setPassword(@Nullable String password) { - this.password = password; - } - - /** - * Return the password to specify on the stub. - */ - @Nullable - public String getPassword() { - return this.password; - } - - /** - * Set the endpoint address to specify on the stub. - * @see javax.xml.ws.BindingProvider#ENDPOINT_ADDRESS_PROPERTY - */ - public void setEndpointAddress(@Nullable String endpointAddress) { - this.endpointAddress = endpointAddress; - } - - /** - * Return the endpoint address to specify on the stub. - */ - @Nullable - public String getEndpointAddress() { - return this.endpointAddress; - } - - /** - * Set the "session.maintain" flag to specify on the stub. - * @see javax.xml.ws.BindingProvider#SESSION_MAINTAIN_PROPERTY - */ - public void setMaintainSession(boolean maintainSession) { - this.maintainSession = maintainSession; - } - - /** - * Return the "session.maintain" flag to specify on the stub. - */ - public boolean isMaintainSession() { - return this.maintainSession; - } - - /** - * Set the "soapaction.use" flag to specify on the stub. - * @see javax.xml.ws.BindingProvider#SOAPACTION_USE_PROPERTY - */ - public void setUseSoapAction(boolean useSoapAction) { - this.useSoapAction = useSoapAction; - } - - /** - * Return the "soapaction.use" flag to specify on the stub. - */ - public boolean isUseSoapAction() { - return this.useSoapAction; - } - - /** - * Set the SOAP action URI to specify on the stub. - * @see javax.xml.ws.BindingProvider#SOAPACTION_URI_PROPERTY - */ - public void setSoapActionUri(@Nullable String soapActionUri) { - this.soapActionUri = soapActionUri; - } - - /** - * Return the SOAP action URI to specify on the stub. - */ - @Nullable - public String getSoapActionUri() { - return this.soapActionUri; - } - - /** - * Set custom properties to be set on the stub. - *

    Can be populated with a String "value" (parsed via PropertiesEditor) - * or a "props" element in XML bean definitions. - * @see javax.xml.ws.BindingProvider#getRequestContext() - */ - public void setCustomProperties(Map customProperties) { - this.customProperties = customProperties; - } - - /** - * Allow Map access to the custom properties to be set on the stub, - * with the option to add or override specific entries. - *

    Useful for specifying entries directly, for example via - * "customProperties[myKey]". This is particularly useful for - * adding or overriding entries in child bean definitions. - */ - public Map getCustomProperties() { - if (this.customProperties == null) { - this.customProperties = new HashMap<>(); - } - return this.customProperties; - } - - /** - * Add a custom property to this JAX-WS BindingProvider. - * @param name the name of the attribute to expose - * @param value the attribute value to expose - * @see javax.xml.ws.BindingProvider#getRequestContext() - */ - public void addCustomProperty(String name, Object value) { - getCustomProperties().put(name, value); - } - - /** - * Specify WebServiceFeature objects (e.g. as inner bean definitions) - * to apply to JAX-WS port stub creation. - * @since 4.0 - * @see Service#getPort(Class, javax.xml.ws.WebServiceFeature...) - * @see #setServiceFeatures - */ - public void setPortFeatures(WebServiceFeature... features) { - this.portFeatures = features; - } - - /** - * Set the interface of the service that this factory should create a proxy for. - */ - public void setServiceInterface(@Nullable Class serviceInterface) { - if (serviceInterface != null) { - Assert.isTrue(serviceInterface.isInterface(), "'serviceInterface' must be an interface"); - } - this.serviceInterface = serviceInterface; - } - - /** - * Return the interface of the service that this factory should create a proxy for. - */ - @Nullable - public Class getServiceInterface() { - return this.serviceInterface; - } - - /** - * Set whether to look up the JAX-WS service on startup. - *

    Default is "true". Turn this flag off to allow for late start - * of the target server. In this case, the JAX-WS service will be - * lazily fetched on first access. - */ - public void setLookupServiceOnStartup(boolean lookupServiceOnStartup) { - this.lookupServiceOnStartup = lookupServiceOnStartup; - } - - /** - * Set the bean ClassLoader to use for this interceptor: primarily for - * building a client proxy in the {@link JaxWsPortProxyFactoryBean} subclass. - */ - @Override - public void setBeanClassLoader(@Nullable ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } - - /** - * Return the bean ClassLoader to use for this interceptor. - */ - @Nullable - protected ClassLoader getBeanClassLoader() { - return this.beanClassLoader; - } - - - @Override - public void afterPropertiesSet() { - if (this.lookupServiceOnStartup) { - prepare(); - } - } - - /** - * Initialize the JAX-WS port for this interceptor. - */ - public void prepare() { - Class ifc = getServiceInterface(); - Assert.notNull(ifc, "Property 'serviceInterface' is required"); - - WebService ann = ifc.getAnnotation(WebService.class); - if (ann != null) { - applyDefaultsFromAnnotation(ann); - } - - Service serviceToUse = getJaxWsService(); - if (serviceToUse == null) { - serviceToUse = createJaxWsService(); - } - - this.portQName = getQName(getPortName() != null ? getPortName() : ifc.getName()); - Object stub = getPortStub(serviceToUse, (getPortName() != null ? this.portQName : null)); - preparePortStub(stub); - this.portStub = stub; - } - - /** - * Initialize this client interceptor's properties from the given WebService annotation, - * if necessary and possible (i.e. if "wsdlDocumentUrl", "namespaceUri", "serviceName" - * and "portName" haven't been set but corresponding values are declared at the - * annotation level of the specified service interface). - * @param ann the WebService annotation found on the specified service interface - */ - protected void applyDefaultsFromAnnotation(WebService ann) { - if (getWsdlDocumentUrl() == null) { - String wsdl = ann.wsdlLocation(); - if (StringUtils.hasText(wsdl)) { - try { - setWsdlDocumentUrl(new URL(wsdl)); - } - catch (MalformedURLException ex) { - throw new IllegalStateException( - "Encountered invalid @Service wsdlLocation value [" + wsdl + "]", ex); - } - } - } - if (getNamespaceUri() == null) { - String ns = ann.targetNamespace(); - if (StringUtils.hasText(ns)) { - setNamespaceUri(ns); - } - } - if (getServiceName() == null) { - String sn = ann.serviceName(); - if (StringUtils.hasText(sn)) { - setServiceName(sn); - } - } - if (getPortName() == null) { - String pn = ann.portName(); - if (StringUtils.hasText(pn)) { - setPortName(pn); - } - } - } - - /** - * Return whether this client interceptor has already been prepared, - * i.e. has already looked up the JAX-WS service and port. - */ - protected boolean isPrepared() { - synchronized (this.preparationMonitor) { - return (this.portStub != null); - } - } - - /** - * Return the prepared QName for the port. - * @see #setPortName - * @see #getQName - */ - @Nullable - protected final QName getPortQName() { - return this.portQName; - } - - /** - * Obtain the port stub from the given JAX-WS Service. - * @param service the Service object to obtain the port from - * @param portQName the name of the desired port, if specified - * @return the corresponding port object as returned from - * {@code Service.getPort(...)} - */ - protected Object getPortStub(Service service, @Nullable QName portQName) { - if (this.portFeatures != null) { - return (portQName != null ? service.getPort(portQName, getServiceInterface(), this.portFeatures) : - service.getPort(getServiceInterface(), this.portFeatures)); - } - else { - return (portQName != null ? service.getPort(portQName, getServiceInterface()) : - service.getPort(getServiceInterface())); - } - } - - /** - * Prepare the given JAX-WS port stub, applying properties to it. - * Called by {@link #prepare}. - * @param stub the current JAX-WS port stub - * @see #setUsername - * @see #setPassword - * @see #setEndpointAddress - * @see #setMaintainSession - * @see #setCustomProperties - */ - protected void preparePortStub(Object stub) { - Map stubProperties = new HashMap<>(); - String username = getUsername(); - if (username != null) { - stubProperties.put(BindingProvider.USERNAME_PROPERTY, username); - } - String password = getPassword(); - if (password != null) { - stubProperties.put(BindingProvider.PASSWORD_PROPERTY, password); - } - String endpointAddress = getEndpointAddress(); - if (endpointAddress != null) { - stubProperties.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointAddress); - } - if (isMaintainSession()) { - stubProperties.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE); - } - if (isUseSoapAction()) { - stubProperties.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE); - } - String soapActionUri = getSoapActionUri(); - if (soapActionUri != null) { - stubProperties.put(BindingProvider.SOAPACTION_URI_PROPERTY, soapActionUri); - } - stubProperties.putAll(getCustomProperties()); - if (!stubProperties.isEmpty()) { - if (!(stub instanceof BindingProvider)) { - throw new RemoteLookupFailureException("Port stub of class [" + stub.getClass().getName() + - "] is not a customizable JAX-WS stub: it does not implement interface [javax.xml.ws.BindingProvider]"); - } - ((BindingProvider) stub).getRequestContext().putAll(stubProperties); - } - } - - /** - * Return the underlying JAX-WS port stub that this interceptor delegates to - * for each method invocation on the proxy. - */ - @Nullable - protected Object getPortStub() { - return this.portStub; - } - - - @Override - @Nullable - public Object invoke(MethodInvocation invocation) throws Throwable { - if (AopUtils.isToStringMethod(invocation.getMethod())) { - return "JAX-WS proxy for port [" + getPortName() + "] of service [" + getServiceName() + "]"; - } - // Lazily prepare service and stub if necessary. - synchronized (this.preparationMonitor) { - if (!isPrepared()) { - prepare(); - } - } - return doInvoke(invocation); - } - - /** - * Perform a JAX-WS service invocation based on the given method invocation. - * @param invocation the AOP method invocation - * @return the invocation result, if any - * @throws Throwable in case of invocation failure - * @see #getPortStub() - * @see #doInvoke(org.aopalliance.intercept.MethodInvocation, Object) - */ - @Nullable - protected Object doInvoke(MethodInvocation invocation) throws Throwable { - try { - return doInvoke(invocation, getPortStub()); - } - catch (SOAPFaultException ex) { - throw new JaxWsSoapFaultException(ex); - } - catch (ProtocolException ex) { - throw new RemoteConnectFailureException( - "Could not connect to remote service [" + getEndpointAddress() + "]", ex); - } - catch (WebServiceException ex) { - throw new RemoteAccessException( - "Could not access remote service at [" + getEndpointAddress() + "]", ex); - } - } - - /** - * Perform a JAX-WS service invocation on the given port stub. - * @param invocation the AOP method invocation - * @param portStub the RMI port stub to invoke - * @return the invocation result, if any - * @throws Throwable in case of invocation failure - * @see #getPortStub() - */ - @Nullable - protected Object doInvoke(MethodInvocation invocation, @Nullable Object portStub) throws Throwable { - Method method = invocation.getMethod(); - try { - return method.invoke(portStub, invocation.getArguments()); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - catch (Throwable ex) { - throw new RemoteProxyFailureException("Invocation of stub method failed: " + method, ex); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortProxyFactoryBean.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortProxyFactoryBean.java deleted file mode 100644 index 3788d0e0e7a0..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortProxyFactoryBean.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.jaxws; - -import javax.xml.ws.BindingProvider; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * {@link org.springframework.beans.factory.FactoryBean} for a specific port of a - * JAX-WS service. Exposes a proxy for the port, to be used for bean references. - * Inherits configuration properties from {@link JaxWsPortClientInterceptor}. - * - * @author Juergen Hoeller - * @since 2.5 - * @see #setServiceInterface - * @see LocalJaxWsServiceFactoryBean - */ -public class JaxWsPortProxyFactoryBean extends JaxWsPortClientInterceptor implements FactoryBean { - - @Nullable - private Object serviceProxy; - - - @Override - public void afterPropertiesSet() { - super.afterPropertiesSet(); - - Class ifc = getServiceInterface(); - Assert.notNull(ifc, "Property 'serviceInterface' is required"); - - // Build a proxy that also exposes the JAX-WS BindingProvider interface. - ProxyFactory pf = new ProxyFactory(); - pf.addInterface(ifc); - pf.addInterface(BindingProvider.class); - pf.addAdvice(this); - this.serviceProxy = pf.getProxy(getBeanClassLoader()); - } - - - @Override - @Nullable - public Object getObject() { - return this.serviceProxy; - } - - @Override - public Class getObjectType() { - return getServiceInterface(); - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsSoapFaultException.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsSoapFaultException.java deleted file mode 100644 index 0205f56e68e3..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsSoapFaultException.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.jaxws; - -import javax.xml.namespace.QName; -import javax.xml.soap.SOAPFault; -import javax.xml.ws.soap.SOAPFaultException; - -import org.springframework.remoting.soap.SoapFaultException; - -/** - * Spring SoapFaultException adapter for the JAX-WS - * {@link javax.xml.ws.soap.SOAPFaultException} class. - * - * @author Juergen Hoeller - * @since 2.5 - */ -@SuppressWarnings("serial") -public class JaxWsSoapFaultException extends SoapFaultException { - - /** - * Constructor for JaxWsSoapFaultException. - * @param original the original JAX-WS SOAPFaultException to wrap - */ - public JaxWsSoapFaultException(SOAPFaultException original) { - super(original.getMessage(), original); - } - - /** - * Return the wrapped JAX-WS SOAPFault. - */ - public final SOAPFault getFault() { - return ((SOAPFaultException) getCause()).getFault(); - } - - - @Override - public String getFaultCode() { - return getFault().getFaultCode(); - } - - @Override - public QName getFaultCodeAsQName() { - return getFault().getFaultCodeAsQName(); - } - - @Override - public String getFaultString() { - return getFault().getFaultString(); - } - - @Override - public String getFaultActor() { - return getFault().getFaultActor(); - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactory.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactory.java deleted file mode 100644 index 8abc4f1b0298..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactory.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.jaxws; - -import java.io.IOException; -import java.net.URL; -import java.util.concurrent.Executor; - -import javax.xml.namespace.QName; -import javax.xml.ws.Service; -import javax.xml.ws.WebServiceFeature; -import javax.xml.ws.handler.HandlerResolver; - -import org.springframework.core.io.Resource; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Factory for locally defined JAX-WS {@link javax.xml.ws.Service} references. - * Uses the JAX-WS {@link javax.xml.ws.Service#create} factory API underneath. - * - *

    Serves as base class for {@link LocalJaxWsServiceFactoryBean} as well as - * {@link JaxWsPortClientInterceptor} and {@link JaxWsPortProxyFactoryBean}. - * - * @author Juergen Hoeller - * @since 2.5 - * @see javax.xml.ws.Service - * @see LocalJaxWsServiceFactoryBean - * @see JaxWsPortClientInterceptor - * @see JaxWsPortProxyFactoryBean - */ -public class LocalJaxWsServiceFactory { - - @Nullable - private URL wsdlDocumentUrl; - - @Nullable - private String namespaceUri; - - @Nullable - private String serviceName; - - @Nullable - private WebServiceFeature[] serviceFeatures; - - @Nullable - private Executor executor; - - @Nullable - private HandlerResolver handlerResolver; - - - /** - * Set the URL of the WSDL document that describes the service. - * @see #setWsdlDocumentResource(Resource) - */ - public void setWsdlDocumentUrl(@Nullable URL wsdlDocumentUrl) { - this.wsdlDocumentUrl = wsdlDocumentUrl; - } - - /** - * Set the WSDL document URL as a {@link Resource}. - * @since 3.2 - */ - public void setWsdlDocumentResource(Resource wsdlDocumentResource) throws IOException { - Assert.notNull(wsdlDocumentResource, "WSDL Resource must not be null"); - this.wsdlDocumentUrl = wsdlDocumentResource.getURL(); - } - - /** - * Return the URL of the WSDL document that describes the service. - */ - @Nullable - public URL getWsdlDocumentUrl() { - return this.wsdlDocumentUrl; - } - - /** - * Set the namespace URI of the service. - * Corresponds to the WSDL "targetNamespace". - */ - public void setNamespaceUri(@Nullable String namespaceUri) { - this.namespaceUri = (namespaceUri != null ? namespaceUri.trim() : null); - } - - /** - * Return the namespace URI of the service. - */ - @Nullable - public String getNamespaceUri() { - return this.namespaceUri; - } - - /** - * Set the name of the service to look up. - * Corresponds to the "wsdl:service" name. - */ - public void setServiceName(@Nullable String serviceName) { - this.serviceName = serviceName; - } - - /** - * Return the name of the service. - */ - @Nullable - public String getServiceName() { - return this.serviceName; - } - - /** - * Specify WebServiceFeature objects (e.g. as inner bean definitions) - * to apply to JAX-WS service creation. - * @since 4.0 - * @see Service#create(QName, WebServiceFeature...) - */ - public void setServiceFeatures(WebServiceFeature... serviceFeatures) { - this.serviceFeatures = serviceFeatures; - } - - /** - * Set the JDK concurrent executor to use for asynchronous executions - * that require callbacks. - * @see javax.xml.ws.Service#setExecutor - */ - public void setExecutor(Executor executor) { - this.executor = executor; - } - - /** - * Set the JAX-WS HandlerResolver to use for all proxies and dispatchers - * created through this factory. - * @see javax.xml.ws.Service#setHandlerResolver - */ - public void setHandlerResolver(HandlerResolver handlerResolver) { - this.handlerResolver = handlerResolver; - } - - - /** - * Create a JAX-WS Service according to the parameters of this factory. - * @see #setServiceName - * @see #setWsdlDocumentUrl - */ - public Service createJaxWsService() { - Assert.notNull(this.serviceName, "No service name specified"); - Service service; - - if (this.serviceFeatures != null) { - service = (this.wsdlDocumentUrl != null ? - Service.create(this.wsdlDocumentUrl, getQName(this.serviceName), this.serviceFeatures) : - Service.create(getQName(this.serviceName), this.serviceFeatures)); - } - else { - service = (this.wsdlDocumentUrl != null ? - Service.create(this.wsdlDocumentUrl, getQName(this.serviceName)) : - Service.create(getQName(this.serviceName))); - } - - if (this.executor != null) { - service.setExecutor(this.executor); - } - if (this.handlerResolver != null) { - service.setHandlerResolver(this.handlerResolver); - } - - return service; - } - - /** - * Return a QName for the given name, relative to the namespace URI - * of this factory, if given. - * @see #setNamespaceUri - */ - protected QName getQName(String name) { - return (getNamespaceUri() != null ? new QName(getNamespaceUri(), name) : new QName(name)); - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactoryBean.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactoryBean.java deleted file mode 100644 index d512f7de6f51..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactoryBean.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.jaxws; - -import javax.xml.ws.Service; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; - -/** - * {@link org.springframework.beans.factory.FactoryBean} for locally - * defined JAX-WS Service references. - * Uses {@link LocalJaxWsServiceFactory}'s facilities underneath. - * - *

    Alternatively, JAX-WS Service references can be looked up - * in the JNDI environment of the Java EE container. - * - * @author Juergen Hoeller - * @since 2.5 - * @see javax.xml.ws.Service - * @see org.springframework.jndi.JndiObjectFactoryBean - * @see JaxWsPortProxyFactoryBean - */ -public class LocalJaxWsServiceFactoryBean extends LocalJaxWsServiceFactory - implements FactoryBean, InitializingBean { - - @Nullable - private Service service; - - - @Override - public void afterPropertiesSet() { - this.service = createJaxWsService(); - } - - @Override - @Nullable - public Service getObject() { - return this.service; - } - - @Override - public Class getObjectType() { - return (this.service != null ? this.service.getClass() : Service.class); - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleHttpServerJaxWsServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleHttpServerJaxWsServiceExporter.java deleted file mode 100644 index 54382b30d6e7..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleHttpServerJaxWsServiceExporter.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.jaxws; - -import java.net.InetSocketAddress; -import java.util.List; - -import javax.jws.WebService; -import javax.xml.ws.Endpoint; -import javax.xml.ws.WebServiceProvider; - -import com.sun.net.httpserver.Authenticator; -import com.sun.net.httpserver.Filter; -import com.sun.net.httpserver.HttpContext; -import com.sun.net.httpserver.HttpServer; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Simple exporter for JAX-WS services, autodetecting annotated service beans - * (through the JAX-WS {@link javax.jws.WebService} annotation) and exporting - * them through the HTTP server included in Sun's JDK 1.6. The full address - * for each service will consist of the server's base address with the - * service name appended (e.g. "http://localhost:8080/OrderService"). - * - *

    Note that this exporter will only work on Sun's JDK 1.6 or higher, as well - * as on JDKs that ship Sun's entire class library as included in the Sun JDK. - * For a portable JAX-WS exporter, have a look at {@link SimpleJaxWsServiceExporter}. - * - * @author Juergen Hoeller - * @since 2.5.5 - * @see javax.jws.WebService - * @see javax.xml.ws.Endpoint#publish(Object) - * @see SimpleJaxWsServiceExporter - * @deprecated as of Spring Framework 5.1, in favor of {@link SimpleJaxWsServiceExporter} - */ -@Deprecated -@org.springframework.lang.UsesSunHttpServer -public class SimpleHttpServerJaxWsServiceExporter extends AbstractJaxWsServiceExporter { - - protected final Log logger = LogFactory.getLog(getClass()); - - @Nullable - private HttpServer server; - - private int port = 8080; - - @Nullable - private String hostname; - - private int backlog = -1; - - private int shutdownDelay = 0; - - private String basePath = "/"; - - @Nullable - private List filters; - - @Nullable - private Authenticator authenticator; - - private boolean localServer = false; - - - /** - * Specify an existing HTTP server to register the web service contexts - * with. This will typically be a server managed by the general Spring - * {@link org.springframework.remoting.support.SimpleHttpServerFactoryBean}. - *

    Alternatively, configure a local HTTP server through the - * {@link #setPort "port"}, {@link #setHostname "hostname"} and - * {@link #setBacklog "backlog"} properties (or rely on the defaults there). - */ - public void setServer(HttpServer server) { - this.server = server; - } - - /** - * Specify the HTTP server's port. Default is 8080. - *

    Only applicable for a locally configured HTTP server. - * Ignored when the {@link #setServer "server"} property has been specified. - */ - public void setPort(int port) { - this.port = port; - } - - /** - * Specify the HTTP server's hostname to bind to. Default is localhost; - * can be overridden with a specific network address to bind to. - *

    Only applicable for a locally configured HTTP server. - * Ignored when the {@link #setServer "server"} property has been specified. - */ - public void setHostname(String hostname) { - this.hostname = hostname; - } - - /** - * Specify the HTTP server's TCP backlog. Default is -1, - * indicating the system's default value. - *

    Only applicable for a locally configured HTTP server. - * Ignored when the {@link #setServer "server"} property has been specified. - */ - public void setBacklog(int backlog) { - this.backlog = backlog; - } - - /** - * Specify the number of seconds to wait until HTTP exchanges have - * completed when shutting down the HTTP server. Default is 0. - *

    Only applicable for a locally configured HTTP server. - * Ignored when the {@link #setServer "server"} property has been specified. - */ - public void setShutdownDelay(int shutdownDelay) { - this.shutdownDelay = shutdownDelay; - } - - /** - * Set the base path for context publication. Default is "/". - *

    For each context publication path, the service name will be - * appended to this base address. E.g. service name "OrderService" - * -> "/OrderService". - * @see javax.xml.ws.Endpoint#publish(Object) - * @see javax.jws.WebService#serviceName() - */ - public void setBasePath(String basePath) { - this.basePath = basePath; - } - - /** - * Register common {@link com.sun.net.httpserver.Filter Filters} to be - * applied to all detected {@link javax.jws.WebService} annotated beans. - */ - public void setFilters(List filters) { - this.filters = filters; - } - - /** - * Register a common {@link com.sun.net.httpserver.Authenticator} to be - * applied to all detected {@link javax.jws.WebService} annotated beans. - */ - public void setAuthenticator(Authenticator authenticator) { - this.authenticator = authenticator; - } - - - @Override - public void afterPropertiesSet() throws Exception { - if (this.server == null) { - InetSocketAddress address = (this.hostname != null ? - new InetSocketAddress(this.hostname, this.port) : new InetSocketAddress(this.port)); - HttpServer server = HttpServer.create(address, this.backlog); - if (logger.isInfoEnabled()) { - logger.info("Starting HttpServer at address " + address); - } - server.start(); - this.server = server; - this.localServer = true; - } - super.afterPropertiesSet(); - } - - @Override - protected void publishEndpoint(Endpoint endpoint, WebService annotation) { - endpoint.publish(buildHttpContext(endpoint, annotation.serviceName())); - } - - @Override - protected void publishEndpoint(Endpoint endpoint, WebServiceProvider annotation) { - endpoint.publish(buildHttpContext(endpoint, annotation.serviceName())); - } - - /** - * Build the HttpContext for the given endpoint. - * @param endpoint the JAX-WS Provider Endpoint object - * @param serviceName the given service name - * @return the fully populated HttpContext - */ - protected HttpContext buildHttpContext(Endpoint endpoint, String serviceName) { - Assert.state(this.server != null, "No HttpServer available"); - String fullPath = calculateEndpointPath(endpoint, serviceName); - HttpContext httpContext = this.server.createContext(fullPath); - if (this.filters != null) { - httpContext.getFilters().addAll(this.filters); - } - if (this.authenticator != null) { - httpContext.setAuthenticator(this.authenticator); - } - return httpContext; - } - - /** - * Calculate the full endpoint path for the given endpoint. - * @param endpoint the JAX-WS Provider Endpoint object - * @param serviceName the given service name - * @return the full endpoint path - */ - protected String calculateEndpointPath(Endpoint endpoint, String serviceName) { - return this.basePath + serviceName; - } - - - @Override - public void destroy() { - super.destroy(); - if (this.server != null && this.localServer) { - logger.info("Stopping HttpServer"); - this.server.stop(this.shutdownDelay); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleJaxWsServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleJaxWsServiceExporter.java deleted file mode 100644 index 06786578f9c0..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleJaxWsServiceExporter.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.jaxws; - -import javax.jws.WebService; -import javax.xml.ws.Endpoint; -import javax.xml.ws.WebServiceProvider; - -/** - * Simple exporter for JAX-WS services, autodetecting annotated service beans - * (through the JAX-WS {@link javax.jws.WebService} annotation) and exporting - * them with a configured base address (by default "http://localhost:8080/") - * using the JAX-WS provider's built-in publication support. The full address - * for each service will consist of the base address with the service name - * appended (e.g. "http://localhost:8080/OrderService"). - * - *

    Note that this exporter will only work if the JAX-WS runtime actually - * supports publishing with an address argument, i.e. if the JAX-WS runtime - * ships an internal HTTP server. - * - * @author Juergen Hoeller - * @since 2.5 - * @see javax.jws.WebService - * @see javax.xml.ws.Endpoint#publish(String) - */ -public class SimpleJaxWsServiceExporter extends AbstractJaxWsServiceExporter { - - /** - * The default base address. - */ - public static final String DEFAULT_BASE_ADDRESS = "http://localhost:8080/"; - - private String baseAddress = DEFAULT_BASE_ADDRESS; - - - /** - * Set the base address for exported services. - * Default is "http://localhost:8080/". - *

    For each actual publication address, the service name will be - * appended to this base address. E.g. service name "OrderService" - * -> "http://localhost:8080/OrderService". - * @see javax.xml.ws.Endpoint#publish(String) - * @see javax.jws.WebService#serviceName() - */ - public void setBaseAddress(String baseAddress) { - this.baseAddress = baseAddress; - } - - - @Override - protected void publishEndpoint(Endpoint endpoint, WebService annotation) { - endpoint.publish(calculateEndpointAddress(endpoint, annotation.serviceName())); - } - - @Override - protected void publishEndpoint(Endpoint endpoint, WebServiceProvider annotation) { - endpoint.publish(calculateEndpointAddress(endpoint, annotation.serviceName())); - } - - /** - * Calculate the full endpoint address for the given endpoint. - * @param endpoint the JAX-WS Provider Endpoint object - * @param serviceName the given service name - * @return the full endpoint address - */ - protected String calculateEndpointAddress(Endpoint endpoint, String serviceName) { - String fullAddress = this.baseAddress + serviceName; - if (endpoint.getClass().getName().startsWith("weblogic.")) { - // Workaround for WebLogic 10.3 - fullAddress = fullAddress + "/"; - } - return fullAddress; - } - -} diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/package-info.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/package-info.java deleted file mode 100644 index 6dc1423ab67d..000000000000 --- a/spring-web/src/main/java/org/springframework/remoting/jaxws/package-info.java +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Remoting classes for Web Services via JAX-WS (the successor of JAX-RPC), - * as included in Java 6 and Java EE 5. This package provides proxy - * factories for accessing JAX-WS services and ports. - */ -@NonNullApi -@NonNullFields -package org.springframework.remoting.jaxws; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java b/spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java deleted file mode 100644 index 58d1846bcf4a..000000000000 --- a/spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.caucho; - -import java.io.IOException; -import java.net.InetSocketAddress; - -import com.caucho.hessian.client.HessianProxyFactory; -import com.sun.net.httpserver.HttpServer; -import org.junit.jupiter.api.Test; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.testfixture.beans.ITestBean; -import org.springframework.beans.testfixture.beans.TestBean; -import org.springframework.remoting.RemoteAccessException; -import org.springframework.util.SocketUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * @author Juergen Hoeller - * @author Sam Brannen - * @since 16.05.2003 - */ -public class CauchoRemotingTests { - - @Test - public void hessianProxyFactoryBeanWithClassInsteadOfInterface() throws Exception { - HessianProxyFactoryBean factory = new HessianProxyFactoryBean(); - assertThatIllegalArgumentException().isThrownBy(() -> - factory.setServiceInterface(TestBean.class)); - } - - @Test - public void hessianProxyFactoryBeanWithAccessError() throws Exception { - HessianProxyFactoryBean factory = new HessianProxyFactoryBean(); - factory.setServiceInterface(ITestBean.class); - factory.setServiceUrl("http://localhosta/testbean"); - factory.afterPropertiesSet(); - - assertThat(factory.isSingleton()).as("Correct singleton value").isTrue(); - boolean condition = factory.getObject() instanceof ITestBean; - assertThat(condition).isTrue(); - ITestBean bean = (ITestBean) factory.getObject(); - - assertThatExceptionOfType(RemoteAccessException.class).isThrownBy(() -> - bean.setName("test")); - } - - @Test - public void hessianProxyFactoryBeanWithAuthenticationAndAccessError() throws Exception { - HessianProxyFactoryBean factory = new HessianProxyFactoryBean(); - factory.setServiceInterface(ITestBean.class); - factory.setServiceUrl("http://localhosta/testbean"); - factory.setUsername("test"); - factory.setPassword("bean"); - factory.setOverloadEnabled(true); - factory.afterPropertiesSet(); - - assertThat(factory.isSingleton()).as("Correct singleton value").isTrue(); - boolean condition = factory.getObject() instanceof ITestBean; - assertThat(condition).isTrue(); - ITestBean bean = (ITestBean) factory.getObject(); - - assertThatExceptionOfType(RemoteAccessException.class).isThrownBy(() -> - bean.setName("test")); - } - - @Test - public void hessianProxyFactoryBeanWithCustomProxyFactory() throws Exception { - TestHessianProxyFactory proxyFactory = new TestHessianProxyFactory(); - HessianProxyFactoryBean factory = new HessianProxyFactoryBean(); - factory.setServiceInterface(ITestBean.class); - factory.setServiceUrl("http://localhosta/testbean"); - factory.setProxyFactory(proxyFactory); - factory.setUsername("test"); - factory.setPassword("bean"); - factory.setOverloadEnabled(true); - factory.afterPropertiesSet(); - assertThat(factory.isSingleton()).as("Correct singleton value").isTrue(); - boolean condition = factory.getObject() instanceof ITestBean; - assertThat(condition).isTrue(); - ITestBean bean = (ITestBean) factory.getObject(); - - assertThat(proxyFactory.user).isEqualTo("test"); - assertThat(proxyFactory.password).isEqualTo("bean"); - assertThat(proxyFactory.overloadEnabled).isTrue(); - - assertThatExceptionOfType(RemoteAccessException.class).isThrownBy(() -> - bean.setName("test")); - } - - @Test - @SuppressWarnings("deprecation") - public void simpleHessianServiceExporter() throws IOException { - final int port = SocketUtils.findAvailableTcpPort(); - - TestBean tb = new TestBean("tb"); - SimpleHessianServiceExporter exporter = new SimpleHessianServiceExporter(); - exporter.setService(tb); - exporter.setServiceInterface(ITestBean.class); - exporter.setDebug(true); - exporter.prepare(); - - HttpServer server = HttpServer.create(new InetSocketAddress(port), -1); - server.createContext("/hessian", exporter); - server.start(); - try { - HessianClientInterceptor client = new HessianClientInterceptor(); - client.setServiceUrl("http://localhost:" + port + "/hessian"); - client.setServiceInterface(ITestBean.class); - //client.setHessian2(true); - client.prepare(); - ITestBean proxy = ProxyFactory.getProxy(ITestBean.class, client); - assertThat(proxy.getName()).isEqualTo("tb"); - proxy.setName("test"); - assertThat(proxy.getName()).isEqualTo("test"); - } - finally { - server.stop(Integer.MAX_VALUE); - } - } - - - private static class TestHessianProxyFactory extends HessianProxyFactory { - - private String user; - private String password; - private boolean overloadEnabled; - - @Override - public void setUser(String user) { - this.user = user; - } - - @Override - public void setPassword(String password) { - this.password = password; - } - - @Override - public void setOverloadEnabled(boolean overloadEnabled) { - this.overloadEnabled = overloadEnabled; - } - } - -} diff --git a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutorTests.java b/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutorTests.java deleted file mode 100644 index c5d486f05e62..000000000000 --- a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutorTests.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.httpinvoker; - -import java.io.IOException; - -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.Configurable; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.withSettings; - -/** - * @author Stephane Nicoll - */ -public class HttpComponentsHttpInvokerRequestExecutorTests { - - @Test - public void customizeConnectionTimeout() throws IOException { - HttpComponentsHttpInvokerRequestExecutor executor = new HttpComponentsHttpInvokerRequestExecutor(); - executor.setConnectTimeout(5000); - - HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service"); - HttpPost httpPost = executor.createHttpPost(config); - assertThat(httpPost.getConfig().getConnectTimeout()).isEqualTo(5000); - } - - @Test - public void customizeConnectionRequestTimeout() throws IOException { - HttpComponentsHttpInvokerRequestExecutor executor = new HttpComponentsHttpInvokerRequestExecutor(); - executor.setConnectionRequestTimeout(7000); - - HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service"); - HttpPost httpPost = executor.createHttpPost(config); - assertThat(httpPost.getConfig().getConnectionRequestTimeout()).isEqualTo(7000); - } - - @Test - public void customizeReadTimeout() throws IOException { - HttpComponentsHttpInvokerRequestExecutor executor = new HttpComponentsHttpInvokerRequestExecutor(); - executor.setReadTimeout(10000); - - HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service"); - HttpPost httpPost = executor.createHttpPost(config); - assertThat(httpPost.getConfig().getSocketTimeout()).isEqualTo(10000); - } - - @Test - public void defaultSettingsOfHttpClientMergedOnExecutorCustomization() throws IOException { - RequestConfig defaultConfig = RequestConfig.custom().setConnectTimeout(1234).build(); - CloseableHttpClient client = mock(CloseableHttpClient.class, - withSettings().extraInterfaces(Configurable.class)); - Configurable configurable = (Configurable) client; - given(configurable.getConfig()).willReturn(defaultConfig); - - HttpComponentsHttpInvokerRequestExecutor executor = - new HttpComponentsHttpInvokerRequestExecutor(client); - HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service"); - HttpPost httpPost = executor.createHttpPost(config); - assertThat(httpPost.getConfig()).as("Default client configuration is expected").isSameAs(defaultConfig); - - executor.setConnectionRequestTimeout(4567); - HttpPost httpPost2 = executor.createHttpPost(config); - assertThat(httpPost2.getConfig()).isNotNull(); - assertThat(httpPost2.getConfig().getConnectionRequestTimeout()).isEqualTo(4567); - // Default connection timeout merged - assertThat(httpPost2.getConfig().getConnectTimeout()).isEqualTo(1234); - } - - @Test - public void localSettingsOverrideClientDefaultSettings() throws Exception { - RequestConfig defaultConfig = RequestConfig.custom() - .setConnectTimeout(1234).setConnectionRequestTimeout(6789).build(); - CloseableHttpClient client = mock(CloseableHttpClient.class, - withSettings().extraInterfaces(Configurable.class)); - Configurable configurable = (Configurable) client; - given(configurable.getConfig()).willReturn(defaultConfig); - - HttpComponentsHttpInvokerRequestExecutor executor = - new HttpComponentsHttpInvokerRequestExecutor(client); - executor.setConnectTimeout(5000); - - HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service"); - HttpPost httpPost = executor.createHttpPost(config); - RequestConfig requestConfig = httpPost.getConfig(); - assertThat(requestConfig.getConnectTimeout()).isEqualTo(5000); - assertThat(requestConfig.getConnectionRequestTimeout()).isEqualTo(6789); - assertThat(requestConfig.getSocketTimeout()).isEqualTo(-1); - } - - @Test - public void mergeBasedOnCurrentHttpClient() throws Exception { - RequestConfig defaultConfig = RequestConfig.custom() - .setSocketTimeout(1234).build(); - final CloseableHttpClient client = mock(CloseableHttpClient.class, - withSettings().extraInterfaces(Configurable.class)); - Configurable configurable = (Configurable) client; - given(configurable.getConfig()).willReturn(defaultConfig); - - HttpComponentsHttpInvokerRequestExecutor executor = - new HttpComponentsHttpInvokerRequestExecutor() { - @Override - public HttpClient getHttpClient() { - return client; - } - }; - executor.setReadTimeout(5000); - HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service"); - HttpPost httpPost = executor.createHttpPost(config); - RequestConfig requestConfig = httpPost.getConfig(); - assertThat(requestConfig.getConnectTimeout()).isEqualTo(-1); - assertThat(requestConfig.getConnectionRequestTimeout()).isEqualTo(-1); - assertThat(requestConfig.getSocketTimeout()).isEqualTo(5000); - - // Update the Http client so that it returns an updated config - RequestConfig updatedDefaultConfig = RequestConfig.custom() - .setConnectTimeout(1234).build(); - given(configurable.getConfig()).willReturn(updatedDefaultConfig); - executor.setReadTimeout(7000); - HttpPost httpPost2 = executor.createHttpPost(config); - RequestConfig requestConfig2 = httpPost2.getConfig(); - assertThat(requestConfig2.getConnectTimeout()).isEqualTo(1234); - assertThat(requestConfig2.getConnectionRequestTimeout()).isEqualTo(-1); - assertThat(requestConfig2.getSocketTimeout()).isEqualTo(7000); - } - - @Test - public void ignoreFactorySettings() throws IOException { - CloseableHttpClient httpClient = HttpClientBuilder.create().build(); - HttpComponentsHttpInvokerRequestExecutor executor = new HttpComponentsHttpInvokerRequestExecutor(httpClient) { - @Override - protected RequestConfig createRequestConfig(HttpInvokerClientConfiguration config) { - return null; - } - }; - - HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service"); - HttpPost httpPost = executor.createHttpPost(config); - assertThat(httpPost.getConfig()).as("custom request config should not be set").isNull(); - } - - private HttpInvokerClientConfiguration mockHttpInvokerClientConfiguration(String serviceUrl) { - HttpInvokerClientConfiguration config = mock(HttpInvokerClientConfiguration.class); - given(config.getServiceUrl()).willReturn(serviceUrl); - return config; - } - -} diff --git a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerFactoryBeanIntegrationTests.java b/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerFactoryBeanIntegrationTests.java deleted file mode 100644 index a53d1e2e387d..000000000000 --- a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerFactoryBeanIntegrationTests.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.httpinvoker; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; -import org.springframework.core.env.Environment; -import org.springframework.remoting.support.RemoteInvocationResult; -import org.springframework.scheduling.annotation.Async; -import org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor; -import org.springframework.stereotype.Component; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Stephane Nicoll - */ -class HttpInvokerFactoryBeanIntegrationTests { - - @Test - @SuppressWarnings("resource") - void testLoadedConfigClass() { - ApplicationContext context = new AnnotationConfigApplicationContext(InvokerAutowiringConfig.class); - MyBean myBean = context.getBean("myBean", MyBean.class); - assertThat(myBean.myService).isSameAs(context.getBean("myService")); - myBean.myService.handle(); - myBean.myService.handleAsync(); - } - - @Test - @SuppressWarnings("resource") - void testNonLoadedConfigClass() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - context.registerBeanDefinition("config", new RootBeanDefinition(InvokerAutowiringConfig.class.getName())); - context.refresh(); - MyBean myBean = context.getBean("myBean", MyBean.class); - assertThat(myBean.myService).isSameAs(context.getBean("myService")); - myBean.myService.handle(); - myBean.myService.handleAsync(); - } - - @Test - @SuppressWarnings("resource") - void withConfigurationClassWithPlainFactoryBean() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - context.register(ConfigWithPlainFactoryBean.class); - context.refresh(); - MyBean myBean = context.getBean("myBean", MyBean.class); - assertThat(myBean.myService).isSameAs(context.getBean("myService")); - myBean.myService.handle(); - myBean.myService.handleAsync(); - } - - - interface MyService { - - void handle(); - - @Async - public void handleAsync(); - } - - - @Component("myBean") - static class MyBean { - - @Autowired - MyService myService; - } - - - @Configuration - @ComponentScan - @Lazy - static class InvokerAutowiringConfig { - - @Bean - AsyncAnnotationBeanPostProcessor aabpp() { - return new AsyncAnnotationBeanPostProcessor(); - } - - @Bean - @SuppressWarnings("deprecation") - HttpInvokerProxyFactoryBean myService() { - HttpInvokerProxyFactoryBean factory = new HttpInvokerProxyFactoryBean(); - factory.setServiceUrl("/svc/dummy"); - factory.setServiceInterface(MyService.class); - factory.setHttpInvokerRequestExecutor((config, invocation) -> new RemoteInvocationResult()); - return factory; - } - - @Bean - FactoryBean myOtherService() { - throw new IllegalStateException("Don't ever call me"); - } - } - - - @Configuration - static class ConfigWithPlainFactoryBean { - - @Autowired - Environment env; - - @Bean - MyBean myBean() { - return new MyBean(); - } - - @Bean - @SuppressWarnings("deprecation") - HttpInvokerProxyFactoryBean myService() { - String name = env.getProperty("testbean.name"); - HttpInvokerProxyFactoryBean factory = new HttpInvokerProxyFactoryBean(); - factory.setServiceUrl("/svc/" + name); - factory.setServiceInterface(MyService.class); - factory.setHttpInvokerRequestExecutor((config, invocation) -> new RemoteInvocationResult()); - return factory; - } - } - -} diff --git a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerTests.java b/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerTests.java deleted file mode 100644 index 8a2c697b69d8..000000000000 --- a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerTests.java +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.httpinvoker; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.aopalliance.intercept.MethodInvocation; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.testfixture.beans.ITestBean; -import org.springframework.beans.testfixture.beans.TestBean; -import org.springframework.remoting.RemoteAccessException; -import org.springframework.remoting.support.DefaultRemoteInvocationExecutor; -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.remoting.support.RemoteInvocationResult; -import org.springframework.web.testfixture.servlet.MockHttpServletRequest; -import org.springframework.web.testfixture.servlet.MockHttpServletResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * @author Juergen Hoeller - * @since 09.08.2004 - */ -@SuppressWarnings("deprecation") -class HttpInvokerTests { - - @Test - void httpInvokerProxyFactoryBeanAndServiceExporter() { - doTestHttpInvokerProxyFactoryBeanAndServiceExporter(false); - } - - @Test - void httpInvokerProxyFactoryBeanAndServiceExporterWithExplicitClassLoader() { - doTestHttpInvokerProxyFactoryBeanAndServiceExporter(true); - } - - private void doTestHttpInvokerProxyFactoryBeanAndServiceExporter(boolean explicitClassLoader) { - TestBean target = new TestBean("myname", 99); - - final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter(); - exporter.setServiceInterface(ITestBean.class); - exporter.setService(target); - exporter.afterPropertiesSet(); - - HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); - pfb.setServiceInterface(ITestBean.class); - pfb.setServiceUrl("https://myurl"); - - pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() { - @Override - protected RemoteInvocationResult doExecuteRequest( - HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws Exception { - assertThat(config.getServiceUrl()).isEqualTo("https://myurl"); - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setContent(baos.toByteArray()); - exporter.handleRequest(request, response); - return readRemoteInvocationResult( - new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl()); - } - }); - if (explicitClassLoader) { - ((BeanClassLoaderAware) pfb.getHttpInvokerRequestExecutor()).setBeanClassLoader(getClass().getClassLoader()); - } - - pfb.afterPropertiesSet(); - ITestBean proxy = (ITestBean) pfb.getObject(); - assertThat(proxy.getName()).isEqualTo("myname"); - assertThat(proxy.getAge()).isEqualTo(99); - proxy.setAge(50); - assertThat(proxy.getAge()).isEqualTo(50); - proxy.setStringArray(new String[] {"str1", "str2"}); - assertThat(Arrays.equals(new String[] {"str1", "str2"}, proxy.getStringArray())).isTrue(); - proxy.setSomeIntegerArray(new Integer[] {1, 2, 3}); - assertThat(Arrays.equals(new Integer[] {1, 2, 3}, proxy.getSomeIntegerArray())).isTrue(); - proxy.setNestedIntegerArray(new Integer[][] {{1, 2, 3}, {4, 5, 6}}); - Integer[][] integerArray = proxy.getNestedIntegerArray(); - assertThat(Arrays.equals(new Integer[] {1, 2, 3}, integerArray[0])).isTrue(); - assertThat(Arrays.equals(new Integer[] {4, 5, 6}, integerArray[1])).isTrue(); - proxy.setSomeIntArray(new int[] {1, 2, 3}); - assertThat(Arrays.equals(new int[] {1, 2, 3}, proxy.getSomeIntArray())).isTrue(); - proxy.setNestedIntArray(new int[][] {{1, 2, 3}, {4, 5, 6}}); - int[][] intArray = proxy.getNestedIntArray(); - assertThat(Arrays.equals(new int[] {1, 2, 3}, intArray[0])).isTrue(); - assertThat(Arrays.equals(new int[] {4, 5, 6}, intArray[1])).isTrue(); - - assertThatIllegalStateException().isThrownBy(() -> - proxy.exceptional(new IllegalStateException())); - assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() -> - proxy.exceptional(new IllegalAccessException())); - } - - @Test - void httpInvokerProxyFactoryBeanAndServiceExporterWithIOException() throws Exception { - TestBean target = new TestBean("myname", 99); - - final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter(); - exporter.setServiceInterface(ITestBean.class); - exporter.setService(target); - exporter.afterPropertiesSet(); - - HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); - pfb.setServiceInterface(ITestBean.class); - pfb.setServiceUrl("https://myurl"); - - pfb.setHttpInvokerRequestExecutor((config, invocation) -> { throw new IOException("argh"); }); - - pfb.afterPropertiesSet(); - ITestBean proxy = (ITestBean) pfb.getObject(); - assertThatExceptionOfType(RemoteAccessException.class) - .isThrownBy(() -> proxy.setAge(50)) - .withCauseInstanceOf(IOException.class); - } - - @Test - void httpInvokerProxyFactoryBeanAndServiceExporterWithGzipCompression() { - TestBean target = new TestBean("myname", 99); - - final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter() { - @Override - protected InputStream decorateInputStream(HttpServletRequest request, InputStream is) throws IOException { - if ("gzip".equals(request.getHeader("Compression"))) { - return new GZIPInputStream(is); - } - else { - return is; - } - } - @Override - protected OutputStream decorateOutputStream( - HttpServletRequest request, HttpServletResponse response, OutputStream os) throws IOException { - if ("gzip".equals(request.getHeader("Compression"))) { - return new GZIPOutputStream(os); - } - else { - return os; - } - } - }; - exporter.setServiceInterface(ITestBean.class); - exporter.setService(target); - exporter.afterPropertiesSet(); - - HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); - pfb.setServiceInterface(ITestBean.class); - pfb.setServiceUrl("https://myurl"); - - pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() { - @Override - protected RemoteInvocationResult doExecuteRequest( - HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) - throws IOException, ClassNotFoundException { - assertThat(config.getServiceUrl()).isEqualTo("https://myurl"); - MockHttpServletRequest request = new MockHttpServletRequest(); - request.addHeader("Compression", "gzip"); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setContent(baos.toByteArray()); - try { - exporter.handleRequest(request, response); - } - catch (ServletException ex) { - throw new IOException(ex.toString()); - } - return readRemoteInvocationResult( - new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl()); - } - @Override - protected OutputStream decorateOutputStream(OutputStream os) throws IOException { - return new GZIPOutputStream(os); - } - @Override - protected InputStream decorateInputStream(InputStream is) throws IOException { - return new GZIPInputStream(is); - } - }); - - pfb.afterPropertiesSet(); - ITestBean proxy = (ITestBean) pfb.getObject(); - assertThat(proxy.getName()).isEqualTo("myname"); - assertThat(proxy.getAge()).isEqualTo(99); - proxy.setAge(50); - assertThat(proxy.getAge()).isEqualTo(50); - - assertThatIllegalStateException().isThrownBy(() -> - proxy.exceptional(new IllegalStateException())); - assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() -> - proxy.exceptional(new IllegalAccessException())); - } - - @Test - void httpInvokerProxyFactoryBeanAndServiceExporterWithWrappedInvocations() { - TestBean target = new TestBean("myname", 99); - - final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter() { - @Override - protected RemoteInvocation doReadRemoteInvocation(ObjectInputStream ois) - throws IOException, ClassNotFoundException { - Object obj = ois.readObject(); - if (!(obj instanceof TestRemoteInvocationWrapper)) { - throw new IOException("Deserialized object needs to be assignable to type [" + - TestRemoteInvocationWrapper.class.getName() + "]: " + obj); - } - return ((TestRemoteInvocationWrapper) obj).remoteInvocation; - } - @Override - protected void doWriteRemoteInvocationResult(RemoteInvocationResult result, ObjectOutputStream oos) - throws IOException { - oos.writeObject(new TestRemoteInvocationResultWrapper(result)); - } - }; - exporter.setServiceInterface(ITestBean.class); - exporter.setService(target); - exporter.afterPropertiesSet(); - - HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); - pfb.setServiceInterface(ITestBean.class); - pfb.setServiceUrl("https://myurl"); - - pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() { - @Override - protected RemoteInvocationResult doExecuteRequest( - HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws Exception { - assertThat(config.getServiceUrl()).isEqualTo("https://myurl"); - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setContent(baos.toByteArray()); - exporter.handleRequest(request, response); - return readRemoteInvocationResult( - new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl()); - } - @Override - protected void doWriteRemoteInvocation(RemoteInvocation invocation, ObjectOutputStream oos) throws IOException { - oos.writeObject(new TestRemoteInvocationWrapper(invocation)); - } - @Override - protected RemoteInvocationResult doReadRemoteInvocationResult(ObjectInputStream ois) - throws IOException, ClassNotFoundException { - Object obj = ois.readObject(); - if (!(obj instanceof TestRemoteInvocationResultWrapper)) { - throw new IOException("Deserialized object needs to be assignable to type [" - + TestRemoteInvocationResultWrapper.class.getName() + "]: " + obj); - } - return ((TestRemoteInvocationResultWrapper) obj).remoteInvocationResult; - } - }); - - pfb.afterPropertiesSet(); - ITestBean proxy = (ITestBean) pfb.getObject(); - assertThat(proxy.getName()).isEqualTo("myname"); - assertThat(proxy.getAge()).isEqualTo(99); - proxy.setAge(50); - assertThat(proxy.getAge()).isEqualTo(50); - - assertThatIllegalStateException().isThrownBy(() -> - proxy.exceptional(new IllegalStateException())); - assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() -> - proxy.exceptional(new IllegalAccessException())); - } - - @Test - void httpInvokerProxyFactoryBeanAndServiceExporterWithInvocationAttributes() { - TestBean target = new TestBean("myname", 99); - - final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter(); - exporter.setServiceInterface(ITestBean.class); - exporter.setService(target); - exporter.setRemoteInvocationExecutor(new DefaultRemoteInvocationExecutor() { - @Override - public Object invoke(RemoteInvocation invocation, Object targetObject) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - assertThat(invocation.getAttributes()).isNotNull(); - assertThat(invocation.getAttributes().size()).isEqualTo(1); - assertThat(invocation.getAttributes().get("myKey")).isEqualTo("myValue"); - assertThat(invocation.getAttribute("myKey")).isEqualTo("myValue"); - return super.invoke(invocation, targetObject); - } - }); - exporter.afterPropertiesSet(); - - HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); - pfb.setServiceInterface(ITestBean.class); - pfb.setServiceUrl("https://myurl"); - pfb.setRemoteInvocationFactory(methodInvocation -> { - RemoteInvocation invocation = new RemoteInvocation(methodInvocation); - invocation.addAttribute("myKey", "myValue"); - assertThatIllegalStateException().isThrownBy(() -> - invocation.addAttribute("myKey", "myValue")); - assertThat(invocation.getAttributes()).isNotNull(); - assertThat(invocation.getAttributes().size()).isEqualTo(1); - assertThat(invocation.getAttributes().get("myKey")).isEqualTo("myValue"); - assertThat(invocation.getAttribute("myKey")).isEqualTo("myValue"); - return invocation; - }); - - pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() { - @Override - protected RemoteInvocationResult doExecuteRequest( - HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws Exception { - assertThat(config.getServiceUrl()).isEqualTo("https://myurl"); - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setContent(baos.toByteArray()); - exporter.handleRequest(request, response); - return readRemoteInvocationResult( - new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl()); - } - }); - - pfb.afterPropertiesSet(); - ITestBean proxy = (ITestBean) pfb.getObject(); - assertThat(proxy.getName()).isEqualTo("myname"); - assertThat(proxy.getAge()).isEqualTo(99); - } - - @Test - void httpInvokerProxyFactoryBeanAndServiceExporterWithCustomInvocationObject() { - TestBean target = new TestBean("myname", 99); - - final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter(); - exporter.setServiceInterface(ITestBean.class); - exporter.setService(target); - exporter.setRemoteInvocationExecutor(new DefaultRemoteInvocationExecutor() { - @Override - public Object invoke(RemoteInvocation invocation, Object targetObject) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - boolean condition = invocation instanceof TestRemoteInvocation; - assertThat(condition).isTrue(); - assertThat(invocation.getAttributes()).isNull(); - assertThat(invocation.getAttribute("myKey")).isNull(); - return super.invoke(invocation, targetObject); - } - }); - exporter.afterPropertiesSet(); - - HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); - pfb.setServiceInterface(ITestBean.class); - pfb.setServiceUrl("https://myurl"); - pfb.setRemoteInvocationFactory(methodInvocation -> { - RemoteInvocation invocation = new TestRemoteInvocation(methodInvocation); - assertThat(invocation.getAttributes()).isNull(); - assertThat(invocation.getAttribute("myKey")).isNull(); - return invocation; - }); - - pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() { - @Override - protected RemoteInvocationResult doExecuteRequest( - HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws Exception { - assertThat(config.getServiceUrl()).isEqualTo("https://myurl"); - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setContent(baos.toByteArray()); - exporter.handleRequest(request, response); - return readRemoteInvocationResult( - new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl()); - } - }); - - pfb.afterPropertiesSet(); - ITestBean proxy = (ITestBean) pfb.getObject(); - assertThat(proxy.getName()).isEqualTo("myname"); - assertThat(proxy.getAge()).isEqualTo(99); - } - - @Test - void httpInvokerWithSpecialLocalMethods() { - String serviceUrl = "https://myurl"; - HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); - pfb.setServiceInterface(ITestBean.class); - pfb.setServiceUrl(serviceUrl); - - pfb.setHttpInvokerRequestExecutor((config, invocation) -> { throw new IOException("argh"); }); - - pfb.afterPropertiesSet(); - ITestBean proxy = (ITestBean) pfb.getObject(); - - // shouldn't go through to remote service - assertThat(proxy.toString().contains("HTTP invoker")).isTrue(); - assertThat(proxy.toString().contains(serviceUrl)).isTrue(); - assertThat(proxy.hashCode()).isEqualTo(proxy.hashCode()); - assertThat(proxy.equals(proxy)).isTrue(); - - // should go through - assertThatExceptionOfType(RemoteAccessException.class) - .isThrownBy(() -> proxy.setAge(50)) - .withCauseInstanceOf(IOException.class); - } - - - @SuppressWarnings("serial") - private static class TestRemoteInvocation extends RemoteInvocation { - - TestRemoteInvocation(MethodInvocation methodInvocation) { - super(methodInvocation); - } - } - - - @SuppressWarnings("serial") - private static class TestRemoteInvocationWrapper implements Serializable { - - private final RemoteInvocation remoteInvocation; - - TestRemoteInvocationWrapper(RemoteInvocation remoteInvocation) { - this.remoteInvocation = remoteInvocation; - } - } - - - @SuppressWarnings("serial") - private static class TestRemoteInvocationResultWrapper implements Serializable { - - private final RemoteInvocationResult remoteInvocationResult; - - TestRemoteInvocationResultWrapper(RemoteInvocationResult remoteInvocationResult) { - this.remoteInvocationResult = remoteInvocationResult; - } - } - -} diff --git a/spring-web/src/test/java/org/springframework/remoting/jaxws/JaxWsSupportTests.java b/spring-web/src/test/java/org/springframework/remoting/jaxws/JaxWsSupportTests.java deleted file mode 100644 index 1a2d4f06a5e1..000000000000 --- a/spring-web/src/test/java/org/springframework/remoting/jaxws/JaxWsSupportTests.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.jaxws; - -import java.net.MalformedURLException; -import java.net.URL; - -import javax.xml.namespace.QName; -import javax.xml.ws.BindingProvider; -import javax.xml.ws.Service; -import javax.xml.ws.WebServiceClient; -import javax.xml.ws.WebServiceException; -import javax.xml.ws.WebServiceFeature; -import javax.xml.ws.WebServiceRef; -import javax.xml.ws.soap.AddressingFeature; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.support.GenericBeanDefinition; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.context.annotation.AnnotationConfigUtils; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.remoting.RemoteAccessException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * @author Juergen Hoeller - * @since 2.5 - */ -public class JaxWsSupportTests { - - @Test - public void testJaxWsPortAccess() throws Exception { - doTestJaxWsPortAccess((WebServiceFeature[]) null); - } - - @Test - public void testJaxWsPortAccessWithFeature() throws Exception { - doTestJaxWsPortAccess(new AddressingFeature()); - } - - private void doTestJaxWsPortAccess(WebServiceFeature... features) throws Exception { - GenericApplicationContext ac = new GenericApplicationContext(); - - GenericBeanDefinition serviceDef = new GenericBeanDefinition(); - serviceDef.setBeanClass(OrderServiceImpl.class); - ac.registerBeanDefinition("service", serviceDef); - - GenericBeanDefinition exporterDef = new GenericBeanDefinition(); - exporterDef.setBeanClass(SimpleJaxWsServiceExporter.class); - exporterDef.getPropertyValues().add("baseAddress", "http://localhost:9999/"); - ac.registerBeanDefinition("exporter", exporterDef); - - GenericBeanDefinition clientDef = new GenericBeanDefinition(); - clientDef.setBeanClass(JaxWsPortProxyFactoryBean.class); - clientDef.getPropertyValues().add("wsdlDocumentUrl", "http://localhost:9999/OrderService?wsdl"); - clientDef.getPropertyValues().add("namespaceUri", "http://jaxws.remoting.springframework.org/"); - clientDef.getPropertyValues().add("username", "juergen"); - clientDef.getPropertyValues().add("password", "hoeller"); - clientDef.getPropertyValues().add("serviceName", "OrderService"); - clientDef.getPropertyValues().add("serviceInterface", OrderService.class); - clientDef.getPropertyValues().add("lookupServiceOnStartup", Boolean.FALSE); - if (features != null) { - clientDef.getPropertyValues().add("portFeatures", features); - } - ac.registerBeanDefinition("client", clientDef); - - GenericBeanDefinition serviceFactoryDef = new GenericBeanDefinition(); - serviceFactoryDef.setBeanClass(LocalJaxWsServiceFactoryBean.class); - serviceFactoryDef.getPropertyValues().add("wsdlDocumentUrl", "http://localhost:9999/OrderService?wsdl"); - serviceFactoryDef.getPropertyValues().add("namespaceUri", "http://jaxws.remoting.springframework.org/"); - serviceFactoryDef.getPropertyValues().add("serviceName", "OrderService"); - ac.registerBeanDefinition("orderService", serviceFactoryDef); - - ac.registerBeanDefinition("accessor", new RootBeanDefinition(ServiceAccessor.class)); - AnnotationConfigUtils.registerAnnotationConfigProcessors(ac); - - try { - ac.refresh(); - - OrderService orderService = ac.getBean("client", OrderService.class); - boolean condition = orderService instanceof BindingProvider; - assertThat(condition).isTrue(); - ((BindingProvider) orderService).getRequestContext(); - - String order = orderService.getOrder(1000); - assertThat(order).isEqualTo("order 1000"); - assertThatExceptionOfType(Exception.class).isThrownBy(() -> - orderService.getOrder(0)) - .matches(ex -> ex instanceof OrderNotFoundException || - ex instanceof RemoteAccessException); - // ignore RemoteAccessException as probably setup issue with JAX-WS provider vs JAXB - - ServiceAccessor serviceAccessor = ac.getBean("accessor", ServiceAccessor.class); - order = serviceAccessor.orderService.getOrder(1000); - assertThat(order).isEqualTo("order 1000"); - assertThatExceptionOfType(Exception.class).isThrownBy(() -> - serviceAccessor.orderService.getOrder(0)) - .matches(ex -> ex instanceof OrderNotFoundException || - ex instanceof WebServiceException); - // ignore WebServiceException as probably setup issue with JAX-WS provider vs JAXB - } - catch (BeanCreationException ex) { - if ("exporter".equals(ex.getBeanName()) && ex.getRootCause() instanceof ClassNotFoundException) { - // ignore - probably running on JDK without the JAX-WS impl present - } - else { - throw ex; - } - } - finally { - ac.close(); - } - } - - - public static class ServiceAccessor { - - @WebServiceRef - public OrderService orderService; - - public OrderService myService; - - @WebServiceRef(value = OrderServiceService.class, wsdlLocation = "http://localhost:9999/OrderService?wsdl") - public void setMyService(OrderService myService) { - this.myService = myService; - } - } - - - @WebServiceClient(targetNamespace = "http://jaxws.remoting.springframework.org/", name="OrderService") - public static class OrderServiceService extends Service { - - public OrderServiceService() throws MalformedURLException { - super(new URL("http://localhost:9999/OrderService?wsdl"), - new QName("http://jaxws.remoting.springframework.org/", "OrderService")); - } - - public OrderServiceService(URL wsdlDocumentLocation, QName serviceName) { - super(wsdlDocumentLocation, serviceName); - } - } - -} diff --git a/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderNotFoundException.java b/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderNotFoundException.java deleted file mode 100644 index 58cc650d1039..000000000000 --- a/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderNotFoundException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.jaxws; - -import javax.xml.ws.WebFault; - -/** - * @author Juergen Hoeller - */ -@WebFault -@SuppressWarnings("serial") -public class OrderNotFoundException extends Exception { - - private final String faultInfo; - - public OrderNotFoundException(String message) { - super(message); - this.faultInfo = null; - } - - public OrderNotFoundException(String message, String faultInfo) { - super(message); - this.faultInfo = faultInfo; - } - - public String getFaultInfo() { - return this.faultInfo; - } - -} diff --git a/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderService.java b/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderService.java deleted file mode 100644 index 2b29d13cb3aa..000000000000 --- a/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderService.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2002-2007 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.jaxws; - -import javax.jws.WebService; -import javax.jws.soap.SOAPBinding; - -/** - * @author Juergen Hoeller - */ -@WebService -@SOAPBinding(style = SOAPBinding.Style.RPC) -public interface OrderService { - - String getOrder(int id) throws OrderNotFoundException; - -} diff --git a/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderServiceImpl.java b/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderServiceImpl.java deleted file mode 100644 index 3f9c9781b386..000000000000 --- a/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderServiceImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.remoting.jaxws; - -import javax.annotation.Resource; -import javax.jws.WebService; -import javax.xml.ws.WebServiceContext; - -import org.springframework.util.Assert; - -/** - * @author Juergen Hoeller - */ -@WebService(serviceName="OrderService", portName="OrderService", - endpointInterface = "org.springframework.remoting.jaxws.OrderService") -public class OrderServiceImpl implements OrderService { - - @Resource - private WebServiceContext webServiceContext; - - @Override - public String getOrder(int id) throws OrderNotFoundException { - Assert.notNull(this.webServiceContext, "WebServiceContext has not been injected"); - if (id == 0) { - throw new OrderNotFoundException("Order 0 not found"); - } - return "order " + id; - } - -} From d84ca2ba90d27a7c63d7b35a6259b5b9cf341118 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 17 Sep 2021 09:14:07 +0200 Subject: [PATCH 109/735] Jakarta EE 9 migration Upgrades many dependency declarations; removes old EJB 2.x support and outdated Servlet-based integrations (Commons FileUpload, FreeMarker JSP support, Tiles). Closes gh-22093 Closes gh-25354 Closes gh-26185 Closes gh-27423 See gh-27424 --- build.gradle | 120 ++-- integration-tests/integration-tests.gradle | 8 +- ...visorAutoProxyCreatorIntegrationTests.java | 3 +- ...ionScannerJsr330ScopeIntegrationTests.java | 15 +- .../EnvironmentSystemIntegrationTests.java | 19 - ...toProxyCreatorIntegrationTests-context.xml | 2 +- .../AsyncExecutionInterceptor.java | 4 +- spring-aspects/spring-aspects.gradle | 4 +- ...JtaTransactionManagementConfiguration.java | 2 +- .../aspectj/JtaAnnotationTransactionAspect.aj | 8 +- .../aspectj/JtaTransactionAspectsTests.java | 3 +- spring-beans/spring-beans.gradle | 4 +- .../beans/factory/annotation/Autowired.java | 2 +- .../AutowiredAnnotationBeanPostProcessor.java | 14 +- ...nitDestroyAnnotationBeanPostProcessor.java | 8 +- ...erAnnotationAutowireCandidateResolver.java | 6 +- .../factory/config/DependencyDescriptor.java | 2 +- .../config/ProviderCreatingFactoryBean.java | 8 +- .../beans/factory/config/Scope.java | 2 +- .../support/DefaultListableBeanFactory.java | 12 +- .../DefaultListableBeanFactoryTests.java | 3 +- ...njectAnnotationBeanPostProcessorTests.java | 9 +- ...ObjectFactoryCreatingFactoryBeanTests.java | 3 +- .../spring-context-indexer.gradle | 8 +- .../StandardStereotypesProvider.java | 2 +- .../CandidateComponentsIndexerTests.java | 15 +- .../index/sample/cdi/SampleManagedBean.java | 2 +- .../context/index/sample/cdi/SampleNamed.java | 2 +- .../index/sample/cdi/SampleTransactional.java | 2 +- .../index/sample/jpa/SampleConverter.java | 2 +- .../index/sample/jpa/SampleEmbeddable.java | 2 +- .../index/sample/jpa/SampleEntity.java | 2 +- .../sample/jpa/SampleMappedSuperClass.java | 2 +- .../spring-context-support.gradle | 13 +- .../cache/ehcache/EhCacheCache.java | 171 ----- .../cache/ehcache/EhCacheCacheManager.java | 117 ---- .../cache/ehcache/EhCacheFactoryBean.java | 329 --------- .../ehcache/EhCacheManagerFactoryBean.java | 199 ------ .../cache/ehcache/EhCacheManagerUtils.java | 125 ---- .../cache/ehcache/package-info.java | 17 - .../mail/MailSendException.java | 2 +- .../javamail/ConfigurableMimeFileTypeMap.java | 10 +- .../mail/javamail/InternetAddressEditor.java | 6 +- .../mail/javamail/JavaMailSender.java | 8 +- .../mail/javamail/JavaMailSenderImpl.java | 24 +- .../mail/javamail/MimeMailMessage.java | 6 +- .../mail/javamail/MimeMessageHelper.java | 76 +- .../mail/javamail/MimeMessagePreparator.java | 4 +- .../mail/javamail/SmartMimeMessage.java | 10 +- .../commonj/DelegatingTimerListener.java | 58 -- .../scheduling/commonj/DelegatingWork.java | 85 --- .../commonj/ScheduledTimerListener.java | 229 ------ .../commonj/TimerManagerAccessor.java | 192 ----- .../commonj/TimerManagerFactoryBean.java | 165 ----- .../commonj/TimerManagerTaskScheduler.java | 201 ------ .../commonj/WorkManagerTaskExecutor.java | 234 ------- .../scheduling/commonj/package-info.java | 10 - .../ehcache/EhCacheCacheManagerTests.java | 85 --- .../cache/ehcache/EhCacheCacheTests.java | 91 --- .../cache/ehcache/EhCacheSupportTests.java | 287 -------- .../jcache/JCacheEhCache3AnnotationTests.java | 35 - .../cache/jcache/JCacheEhCache3ApiTests.java | 35 - .../jcache/JCacheEhCacheAnnotationTests.java | 2 +- .../cache/jcache/JCacheEhCacheApiTests.java | 2 +- .../mail/javamail/JavaMailSenderTests.java | 23 +- .../BeanValidationPostProcessorTests.java | 155 ----- .../MethodValidationTests.java | 218 ------ .../SpringValidatorAdapterTests.java | 563 --------------- .../ValidatorFactoryTests.java | 505 -------------- spring-context/spring-context.gradle | 24 +- .../AnnotationProcessorBenchmark.java | 3 +- .../AnnotationBeanNameGenerator.java | 10 +- .../AnnotationConfigApplicationContext.java | 2 +- .../annotation/AnnotationConfigUtils.java | 4 +- .../context/annotation/Bean.java | 2 +- .../ClassPathBeanDefinitionScanner.java | 4 +- ...athScanningCandidateComponentProvider.java | 14 +- .../CommonAnnotationBeanPostProcessor.java | 51 +- .../context/annotation/Configuration.java | 2 +- .../Jsr330ScopeMetadataResolver.java | 6 +- .../context/annotation/Lazy.java | 4 +- .../annotation/MBeanExportConfiguration.java | 70 +- .../MBeanExportBeanDefinitionParser.java | 8 +- .../MBeanServerBeanDefinitionParser.java | 37 +- .../weaving/DefaultContextLoadTimeWeaver.java | 17 +- .../AbstractRemoteSlsbInvokerInterceptor.java | 213 ------ .../AbstractSlsbInvokerInterceptor.java | 238 ------- .../ejb/access/EjbAccessException.java | 47 -- .../access/LocalSlsbInvokerInterceptor.java | 179 ----- ...LocalStatelessSessionProxyFactoryBean.java | 116 ---- .../SimpleRemoteSlsbInvokerInterceptor.java | 188 ----- ...emoteStatelessSessionProxyFactoryBean.java | 130 ---- .../ejb/access/package-info.java | 27 - ...lStatelessSessionBeanDefinitionParser.java | 10 +- ...eStatelessSessionBeanDefinitionParser.java | 10 +- .../ejb/config/package-info.java | 2 +- .../weblogic/WebLogicClassLoaderAdapter.java | 117 ---- .../WebLogicClassPreProcessorAdapter.java | 97 --- .../weblogic/WebLogicLoadTimeWeaver.java | 78 --- .../classloading/weblogic/package-info.java | 9 - .../WebSphereClassLoaderAdapter.java | 120 ---- .../WebSphereClassPreDefinePlugin.java | 95 --- .../websphere/WebSphereLoadTimeWeaver.java | 75 -- .../classloading/websphere/package-info.java | 9 - .../WebSphereMBeanServerFactoryBean.java | 105 --- .../jndi/JndiLocatorDelegate.java | 2 +- .../jndi/JndiLocatorSupport.java | 8 +- .../jndi/JndiObjectLocator.java | 2 +- .../jndi/JndiObjectTargetSource.java | 2 +- .../jndi/support/SimpleJndiBeanFactory.java | 2 +- .../scheduling/TaskScheduler.java | 2 +- .../scheduling/annotation/Async.java | 2 +- .../annotation/AsyncAnnotationAdvisor.java | 6 +- .../AsyncAnnotationBeanPostProcessor.java | 4 +- .../scheduling/annotation/EnableAsync.java | 4 +- .../concurrent/ConcurrentTaskExecutor.java | 20 +- .../concurrent/ConcurrentTaskScheduler.java | 18 +- .../DefaultManagedAwareThreadFactory.java | 6 +- .../DefaultManagedTaskExecutor.java | 8 +- .../DefaultManagedTaskScheduler.java | 8 +- .../ExecutorConfigurationSupport.java | 4 +- .../scheduling/concurrent/package-info.java | 2 +- .../stereotype/Repository.java | 2 +- .../validation/ObjectError.java | 6 +- .../validation/SmartValidator.java | 4 +- .../validation/annotation/Validated.java | 4 +- .../annotation/ValidationAnnotationUtils.java | 4 +- .../BeanValidationPostProcessor.java | 12 +- .../beanvalidation/CustomValidatorBean.java | 14 +- .../LocalValidatorFactoryBean.java | 70 +- .../LocaleContextMessageInterpolator.java | 2 +- .../MethodValidationInterceptor.java | 15 +- .../MethodValidationPostProcessor.java | 9 +- .../OptionalValidatorFactoryBean.java | 5 +- .../SpringConstraintValidatorFactory.java | 4 +- .../SpringValidatorAdapter.java | 30 +- .../springframework/ejb/config/spring-jee.xsd | 86 +-- .../AutowiredQualifierFooService.java | 2 +- .../example/scannable/FooServiceImpl.java | 2 +- .../BridgeMethodAutowiringTests.java | 5 +- .../InjectAnnotationAutowireContextTests.java | 9 +- .../annotation/AutoProxyLazyInitTests.java | 3 +- ...ommonAnnotationBeanPostProcessorTests.java | 9 +- ...nClassPostConstructAndAutowiringTests.java | 3 +- .../ConfigurationClassPostProcessorTests.java | 3 +- ...PrimitiveBeanLookupAndAutowiringTests.java | 3 +- .../PropertySourceAnnotationTests.java | 3 +- .../Spr3775InitDestroyLifecycleTests.java | 9 +- .../AutowiredConfigurationTests.java | 3 +- .../ConfigurationClassProcessingTests.java | 5 +- .../configuration/Spr12526Tests.java | 3 +- .../annotation6/Jsr330NamedForScanning.java | 2 +- .../AnnotationDrivenEventListenerTests.java | 5 +- .../LocalSlsbInvokerInterceptorTests.java | 207 ------ ...StatelessSessionProxyFactoryBeanTests.java | 197 ------ ...mpleRemoteSlsbInvokerInterceptorTests.java | 349 ---------- ...StatelessSessionProxyFactoryBeanTests.java | 288 -------- .../config/JeeNamespaceHandlerEventTests.java | 11 +- .../ejb/config/JeeNamespaceHandlerTests.java | 37 +- .../BeanValidationPostProcessorTests.java | 9 +- .../beanvalidation/MethodValidationTests.java | 22 +- .../SpringValidatorAdapterTests.java | 97 ++- .../beanvalidation/ValidatorFactoryTests.java | 19 +- .../ejb/config/jeeNamespaceHandlerTests.xml | 35 +- .../jndi/SimpleNamingContextBuilder.java | 2 +- spring-core/spring-core.gradle | 4 +- .../springframework/core/MethodParameter.java | 2 +- .../AnnotationAwareOrderComparator.java | 8 +- .../core/annotation/Order.java | 4 +- .../core/annotation/OrderUtils.java | 18 +- .../core/io/ContextResource.java | 2 +- .../core/task/SimpleAsyncTaskExecutor.java | 2 +- .../task/support/ExecutorServiceAdapter.java | 4 +- .../AnnotatedElementUtilsTests.java | 2 +- .../AnnotationAwareOrderComparatorTests.java | 3 +- .../annotation/MergedAnnotationsTests.java | 7 +- .../core/annotation/OrderUtilsTests.java | 3 +- .../util/Base64UtilsTests.java | 3 +- spring-jdbc/spring-jdbc.gradle | 2 +- .../DataSourceTransactionManager.java | 4 +- .../datasource/DriverManagerDataSource.java | 4 +- .../LazyConnectionDataSourceProxy.java | 2 +- .../datasource/SimpleDriverDataSource.java | 2 +- .../TransactionAwareDataSourceProxy.java | 4 +- .../WebSphereDataSourceAdapter.java | 204 ------ .../DataSourceJtaTransactionTests.java | 12 +- spring-jms/spring-jms.gradle | 9 +- .../jms/IllegalStateException.java | 4 +- .../jms/InvalidClientIDException.java | 4 +- .../jms/InvalidDestinationException.java | 4 +- .../jms/InvalidSelectorException.java | 4 +- .../org/springframework/jms/JmsException.java | 10 +- .../jms/JmsSecurityException.java | 4 +- .../jms/MessageEOFException.java | 4 +- .../jms/MessageFormatException.java | 4 +- .../jms/MessageNotReadableException.java | 4 +- .../jms/MessageNotWriteableException.java | 4 +- .../jms/ResourceAllocationException.java | 4 +- .../jms/TransactionInProgressException.java | 4 +- .../jms/TransactionRolledBackException.java | 4 +- .../jms/UncategorizedJmsException.java | 4 +- .../jms/annotation/EnableJms.java | 4 +- .../jms/annotation/JmsListener.java | 4 +- .../AbstractJmsListenerContainerFactory.java | 5 +- .../config/AbstractJmsListenerEndpoint.java | 2 +- .../AbstractListenerContainerParser.java | 3 +- .../DefaultJcaListenerContainerFactory.java | 2 +- .../config/JmsListenerContainerParser.java | 3 +- .../jms/config/SimpleJmsListenerEndpoint.java | 2 +- .../jms/connection/CachedMessageConsumer.java | 16 +- .../jms/connection/CachedMessageProducer.java | 18 +- .../connection/CachingConnectionFactory.java | 28 +- .../connection/ChainedExceptionListener.java | 4 +- .../connection/ConnectionFactoryUtils.java | 25 +- .../DelegatingConnectionFactory.java | 28 +- .../jms/connection/JmsResourceHolder.java | 13 +- .../jms/connection/JmsTransactionManager.java | 20 +- .../jms/connection/SessionProxy.java | 6 +- .../connection/SingleConnectionFactory.java | 49 +- .../connection/SmartConnectionFactory.java | 8 +- ...ynchedLocalTransactionFailedException.java | 2 +- ...ransactionAwareConnectionFactoryProxy.java | 36 +- ...erCredentialsConnectionFactoryAdapter.java | 34 +- .../jms/core/BrowserCallback.java | 12 +- .../jms/core/JmsMessageOperations.java | 4 +- .../jms/core/JmsMessagingTemplate.java | 24 +- .../jms/core/JmsOperations.java | 14 +- .../springframework/jms/core/JmsTemplate.java | 66 +- .../jms/core/MessageCreator.java | 10 +- .../jms/core/MessagePostProcessor.java | 8 +- .../jms/core/ProducerCallback.java | 10 +- .../jms/core/SessionCallback.java | 6 +- .../jms/core/support/JmsGatewaySupport.java | 7 +- .../AbstractJmsListeningContainer.java | 16 +- .../AbstractMessageListenerContainer.java | 52 +- ...stractPollingMessageListenerContainer.java | 28 +- .../DefaultMessageListenerContainer.java | 24 +- .../LocallyExposedJmsResourceHolder.java | 2 +- .../listener/MessageListenerContainer.java | 10 +- .../listener/SessionAwareMessageListener.java | 10 +- .../SimpleMessageListenerContainer.java | 20 +- .../listener/SubscriptionNameProvider.java | 2 +- .../AbstractAdaptableMessageListener.java | 53 +- .../jms/listener/adapter/JmsResponse.java | 6 +- .../adapter/MessageListenerAdapter.java | 16 +- .../MessagingMessageListenerAdapter.java | 18 +- .../DefaultJmsActivationSpecFactory.java | 5 +- .../endpoint/JmsActivationSpecConfig.java | 22 +- .../endpoint/JmsActivationSpecFactory.java | 6 +- .../endpoint/JmsMessageEndpointFactory.java | 14 +- .../endpoint/JmsMessageEndpointManager.java | 12 +- .../StandardJmsActivationSpecFactory.java | 22 +- .../jms/support/JmsAccessor.java | 43 +- .../jms/support/JmsHeaderMapper.java | 4 +- .../jms/support/JmsHeaders.java | 28 +- .../jms/support/JmsMessageHeaderAccessor.java | 2 +- .../springframework/jms/support/JmsUtils.java | 73 +- .../jms/support/QosSettings.java | 18 +- .../jms/support/SimpleJmsHeaderMapper.java | 10 +- .../MappingJackson2MessageConverter.java | 17 +- .../MarshallingMessageConverter.java | 15 +- .../converter/MessageConversionException.java | 2 +- .../support/converter/MessageConverter.java | 10 +- .../jms/support/converter/MessageType.java | 12 +- .../converter/MessagingMessageConverter.java | 20 +- .../converter/SimpleMessageConverter.java | 28 +- .../converter/SmartMessageConverter.java | 8 +- .../BeanFactoryDestinationResolver.java | 10 +- .../destination/DestinationResolver.java | 8 +- .../DynamicDestinationResolver.java | 24 +- .../destination/JmsDestinationAccessor.java | 22 +- .../destination/JndiDestinationResolver.java | 11 +- .../springframework/jms/config/spring-jms.xsd | 12 +- .../jca/StubActivationSpec.java | 8 +- .../jca/StubResourceAdapter.java | 13 +- .../jms/StubConnectionFactory.java | 8 +- .../org/springframework/jms/StubQueue.java | 4 +- .../springframework/jms/StubTextMessage.java | 6 +- .../org/springframework/jms/StubTopic.java | 2 +- .../AbstractJmsAnnotationDrivenTests.java | 5 +- .../AnnotationDrivenNamespaceTests.java | 5 +- .../jms/annotation/EnableJmsTests.java | 5 +- ...tenerContainerFactoryIntegrationTests.java | 11 +- .../JmsListenerContainerFactoryTests.java | 9 +- .../jms/config/JmsListenerEndpointTests.java | 3 +- .../jms/config/JmsNamespaceHandlerTests.java | 9 +- .../MethodJmsListenerEndpointTests.java | 19 +- .../SimpleJmsListenerEndpointTests.java | 3 +- .../JmsTransactionManagerTests.java | 15 +- .../SingleConnectionFactoryTests.java | 23 +- .../jms/connection/TestConnection.java | 18 +- .../jms/connection/TestExceptionListener.java | 4 +- .../jms/core/JmsMessagingTemplateTests.java | 59 +- .../jms/core/JmsTemplateTests.java | 50 +- .../jms/core/JmsTemplateTransactedTests.java | 3 +- .../core/support/JmsGatewaySupportTests.java | 3 +- .../DefaultMessageListenerContainerTests.java | 9 +- ...sageListenerContainerIntegrationTests.java | 119 ---- .../SimpleMessageListenerContainerTests.java | 17 +- .../listener/adapter/JmsResponseTests.java | 11 +- .../jms/listener/adapter/MessageDelegate.java | 8 +- .../adapter/MessageListenerAdapterTests.java | 23 +- .../MessagingMessageListenerAdapterTests.java | 51 +- ...msTextMessageReturningMessageDelegate.java | 2 +- .../adapter/ResponsiveMessageDelegate.java | 8 +- .../DefaultJmsActivationSpecFactoryTests.java | 5 +- .../endpoint/StubJmsActivationSpec.java | 2 +- .../StubJmsActivationSpecFactory.java | 4 +- .../jms/support/JmsAccessorTests.java | 3 +- .../JmsMessageHeaderAccessorTests.java | 5 +- .../support/SimpleJmsHeaderMapperTests.java | 95 ++- .../support/SimpleMessageConverterTests.java | 15 +- .../MappingJackson2MessageConverterTests.java | 9 +- .../MarshallingMessageConverterTests.java | 6 +- .../MessagingMessageConverterTests.java | 11 +- .../DynamicDestinationResolverTests.java | 15 +- .../JmsDestinationAccessorTests.java | 3 +- .../JndiDestinationResolverTests.java | 4 +- spring-messaging/spring-messaging.gradle | 16 +- .../converter/JsonbMessageConverter.java | 10 +- .../PayloadMethodArgumentResolver.java | 4 +- .../PayloadMethodArgumentResolver.java | 2 +- .../AbstractMessageBrokerConfiguration.java | 4 +- .../converter/JsonbMessageConverterTests.java | 11 +- .../MarshallingMessageConverterTests.java | 3 +- spring-orm/spring-orm.gradle | 6 +- .../hibernate5/ConfigurableJtaPlatform.java | 15 +- .../HibernateExceptionTranslator.java | 3 +- .../orm/hibernate5/HibernateTemplate.java | 3 +- .../HibernateTransactionManager.java | 2 +- .../hibernate5/LocalSessionFactoryBean.java | 6 +- .../LocalSessionFactoryBuilder.java | 16 +- .../orm/hibernate5/SessionFactoryUtils.java | 2 +- .../orm/hibernate5/SpringSessionContext.java | 7 +- .../support/OpenSessionInViewFilter.java | 9 +- .../jpa/AbstractEntityManagerFactoryBean.java | 40 +- .../orm/jpa/DefaultJpaDialect.java | 6 +- .../orm/jpa/EntityManagerFactoryAccessor.java | 21 +- .../orm/jpa/EntityManagerFactoryInfo.java | 13 +- .../orm/jpa/EntityManagerFactoryUtils.java | 43 +- .../orm/jpa/EntityManagerHolder.java | 4 +- .../orm/jpa/EntityManagerProxy.java | 6 +- .../orm/jpa/ExtendedEntityManagerCreator.java | 31 +- .../springframework/orm/jpa/JpaDialect.java | 14 +- .../JpaObjectRetrievalFailureException.java | 2 +- .../JpaOptimisticLockingFailureException.java | 2 +- .../orm/jpa/JpaTransactionManager.java | 19 +- .../orm/jpa/JpaVendorAdapter.java | 20 +- ...ocalContainerEntityManagerFactoryBean.java | 31 +- .../jpa/LocalEntityManagerFactoryBean.java | 18 +- .../orm/jpa/SharedEntityManagerCreator.java | 25 +- .../ClassFileTransformerAdapter.java | 5 +- .../DefaultPersistenceUnitManager.java | 24 +- .../MutablePersistenceUnitInfo.java | 13 +- .../PersistenceUnitManager.java | 6 +- .../PersistenceUnitReader.java | 6 +- .../SmartPersistenceUnitInfo.java | 4 +- .../SpringPersistenceUnitInfo.java | 2 +- .../jpa/support/AsyncRequestInterceptor.java | 3 +- .../OpenEntityManagerInViewFilter.java | 16 +- .../OpenEntityManagerInViewInterceptor.java | 6 +- ...ersistenceAnnotationBeanPostProcessor.java | 58 +- .../jpa/support/SharedEntityManagerBean.java | 12 +- .../jpa/vendor/AbstractJpaVendorAdapter.java | 8 +- .../orm/jpa/vendor/EclipseLinkJpaDialect.java | 5 +- .../vendor/EclipseLinkJpaVendorAdapter.java | 5 +- .../orm/jpa/vendor/HibernateJpaDialect.java | 5 +- .../HibernateJpaSessionFactoryBean.java | 3 +- .../jpa/vendor/HibernateJpaVendorAdapter.java | 11 +- ...SpringHibernateJpaPersistenceProvider.java | 5 +- ...rEntityManagerFactoryIntegrationTests.java | 9 +- ...AbstractEntityManagerFactoryBeanTests.java | 7 +- ...tEntityManagerFactoryIntegrationTests.java | 6 +- ...nManagedEntityManagerIntegrationTests.java | 7 +- ...rManagedEntityManagerIntegrationTests.java | 9 +- .../orm/jpa/DefaultJpaDialectTests.java | 7 +- .../jpa/EntityManagerFactoryUtilsTests.java | 19 +- .../orm/jpa/JpaTransactionManagerTests.java | 9 +- ...ontainerEntityManagerFactoryBeanTests.java | 19 +- .../LocalEntityManagerFactoryBeanTests.java | 9 +- .../jpa/SharedEntityManagerCreatorTests.java | 13 +- .../orm/jpa/domain/DriversLicense.java | 6 +- .../orm/jpa/domain/Person.java | 20 +- .../orm/jpa/domain/PersonListener.java | 2 +- ...eEntityManagerFactoryIntegrationTests.java | 3 +- ...iEntityManagerFactoryIntegrationTests.java | 5 +- ...rySpringBeanContainerIntegrationTests.java | 3 +- .../PersistenceXmlParsingTests.java | 4 +- .../support/OpenEntityManagerInViewTests.java | 11 +- .../PersistenceContextTransactionTests.java | 13 +- .../support/PersistenceInjectionTests.java | 13 +- .../SharedEntityManagerFactoryTests.java | 5 +- .../orm/jpa/domain/spring.components | 4 +- .../hibernate/hibernate-manager-native.xml | 2 +- spring-oxm/spring-oxm.gradle | 38 +- .../oxm/jaxb/ClassPathJaxb2TypeScanner.java | 10 +- .../oxm/jaxb/Jaxb2Marshaller.java | 50 +- .../oxm/mime/MimeContainer.java | 2 +- .../springframework/oxm/jaxb/Airplane.java | 2 +- .../oxm/jaxb/BinaryObject.java | 8 +- .../oxm/jaxb/Jaxb2MarshallerTests.java | 20 +- .../oxm/jaxb/Jaxb2UnmarshallerTests.java | 6 +- .../springframework/oxm/jaxb/Primitives.java | 3 +- .../oxm/jaxb/StandardClasses.java | 11 +- .../oxm/jaxb/XmlRegObjectFactory.java | 7 +- spring-test/spring-test.gradle | 36 +- .../mock/jndi/SimpleNamingContextBuilder.java | 2 +- .../mock/jndi/package-info.java | 2 +- .../web/DelegatingServletInputStream.java | 6 +- .../web/DelegatingServletOutputStream.java | 6 +- .../mock/web/MockAsyncContext.java | 18 +- .../mock/web/MockBodyContent.java | 8 +- .../springframework/mock/web/MockCookie.java | 2 +- .../mock/web/MockExpressionEvaluator.java | 84 --- .../mock/web/MockFilterChain.java | 16 +- .../mock/web/MockFilterConfig.java | 8 +- .../mock/web/MockHttpServletMapping.java | 4 +- .../mock/web/MockHttpServletRequest.java | 36 +- .../mock/web/MockHttpServletResponse.java | 10 +- .../mock/web/MockHttpSession.java | 12 +- .../mock/web/MockJspWriter.java | 6 +- .../web/MockMultipartHttpServletRequest.java | 6 +- .../mock/web/MockPageContext.java | 35 +- .../springframework/mock/web/MockPart.java | 4 +- .../mock/web/MockRequestDispatcher.java | 11 +- .../mock/web/MockServletConfig.java | 6 +- .../mock/web/MockServletContext.java | 31 +- .../mock/web/MockSessionCookieConfig.java | 6 +- .../mock/web/PassThroughFilterChain.java | 18 +- .../test/context/ContextConfiguration.java | 2 +- .../test/context/ContextLoader.java | 4 +- .../test/context/SmartContextLoader.java | 4 +- .../web/AbstractGenericWebContextLoader.java | 3 +- .../web/ServletTestExecutionListener.java | 3 +- .../web/socket/MockServerContainer.java | 16 +- .../MockServerContainerContextCustomizer.java | 6 +- ...rverContainerContextCustomizerFactory.java | 2 +- .../test/util/ReflectionTestUtils.java | 8 +- .../client/match/ContentRequestMatchers.java | 72 +- .../test/web/servlet/MockMvc.java | 14 +- .../web/servlet/MockMvcBuilderSupport.java | 4 +- .../test/web/servlet/RequestBuilder.java | 2 +- .../web/servlet/TestDispatcherServlet.java | 8 +- .../client/AbstractMockMvcServerSpec.java | 2 +- .../servlet/client/MockMvcHttpConnector.java | 5 +- .../servlet/client/MockMvcWebTestClient.java | 2 +- .../htmlunit/HtmlUnitRequestBuilder.java | 9 +- .../htmlunit/MockMvcWebConnection.java | 10 +- .../MockHttpServletRequestBuilder.java | 14 +- ...ockMultipartHttpServletRequestBuilder.java | 4 +- .../request/MockMvcRequestBuilders.java | 2 +- .../servlet/result/ContentResultMatchers.java | 2 +- .../servlet/result/CookieResultMatchers.java | 3 +- .../servlet/result/PrintingResultHandler.java | 6 +- .../servlet/result/RequestResultMatchers.java | 5 +- .../servlet/setup/AbstractMockMvcBuilder.java | 4 +- .../setup/ConfigurableMockMvcBuilder.java | 2 +- .../servlet/setup/DefaultMockMvcBuilder.java | 2 +- .../web/servlet/setup/MockMvcBuilders.java | 2 +- .../setup/PatternMappingFilterProxy.java | 14 +- .../setup/SharedHttpSessionConfigurer.java | 2 +- .../setup/StandaloneMockMvcBuilder.java | 2 +- .../setup/StubWebApplicationContext.java | 2 +- .../web/servlet/MockHttpServletRequestDsl.kt | 2 +- .../MockMultipartHttpServletRequestDsl.kt | 2 +- .../mock/web/MockFilterChainTests.java | 15 +- .../mock/web/MockHttpServletRequestTests.java | 3 +- .../web/MockHttpServletResponseTests.java | 5 +- .../mock/web/MockHttpSessionTests.java | 5 +- .../mock/web/MockPageContextTests.java | 3 +- .../mock/web/MockServletContextTests.java | 7 +- .../groovy/GroovySpringContextTests.java | 3 +- .../web/ControllerIntegrationTests.java | 3 +- .../web/DispatcherWacRootWacEarTests.java | 3 +- ...TransactionalJUnit4SpringContextTests.java | 3 +- .../SpringJUnit4ClassRunnerAppCtxTests.java | 7 +- .../orm/HibernateSessionFlushingTests.java | 3 +- .../junit4/spr4868/Jsr250LifecycleTests.java | 5 +- .../context/junit4/spr4868/LifecycleBean.java | 5 +- .../context/junit4/spr8849/TestClass1.java | 2 +- .../context/junit4/spr8849/TestClass2.java | 2 +- .../context/junit4/spr8849/TestClass3.java | 2 +- .../context/junit4/spr8849/TestClass4.java | 2 +- .../context/junit4/spr9051/LifecycleBean.java | 2 +- ...TransactionalTestNGSpringContextTests.java | 3 +- .../ejb/AbstractEjbTxDaoTestNGTests.java | 7 +- .../web/TestNGSpringContextWebTests.java | 3 +- .../ejb/AbstractEjbTxDaoTests.java | 7 +- .../ejb/dao/AbstractEjbTxTestEntityDao.java | 6 +- .../ejb/dao/RequiredEjbTxTestEntityDao.java | 8 +- .../dao/RequiresNewEjbTxTestEntityDao.java | 8 +- .../transaction/ejb/model/TestEntity.java | 8 +- .../context/web/AbstractBasicWacTests.java | 3 +- .../web/JUnit4SpringContextWebTests.java | 3 +- .../context/web/ServletContextAwareBean.java | 2 +- ...ervletServerContainerFactoryBeanTests.java | 3 +- .../test/util/subpackage/Component.java | 4 +- .../org/springframework/test/web/Person.java | 4 +- .../match/ContentRequestMatchersTests.java | 11 +- .../match/MultipartRequestMatchersTests.java | 4 +- ...ontentRequestMatchersIntegrationTests.java | 11 +- .../XpathRequestMatchersIntegrationTests.java | 11 +- .../web/reactive/server/samples/Person.java | 3 +- .../server/samples/XmlContentTests.java | 9 +- .../web/servlet/htmlunit/HelloController.java | 2 +- .../htmlunit/HtmlUnitRequestBuilderTests.java | 9 +- .../MockMvcConnectionBuilderSupportTests.java | 3 +- .../MockMvcWebClientBuilderTests.java | 9 +- .../htmlunit/MockWebResponseBuilderTests.java | 3 +- .../MockMvcHtmlUnitDriverBuilderTests.java | 3 +- .../MockHttpServletRequestBuilderTests.java | 5 +- ...ltipartHttpServletRequestBuilderTests.java | 3 +- .../result/PrintingResultHandlerTests.java | 5 +- .../client/context/JavaConfigTests.java | 24 +- .../client/context/WebAppResourceTests.java | 12 +- .../client/context/XmlConfigTests.java | 10 +- .../client/standalone/FilterTests.java | 25 +- .../standalone/MultipartControllerTests.java | 13 +- .../client/standalone/RedirectTests.java | 3 +- .../client/standalone/ResponseBodyTests.java | 3 +- .../PrintingResultHandlerSmokeTests.java | 5 +- .../resultmatches/ModelAssertionTests.java | 3 +- .../XmlContentAssertionTests.java | 11 +- .../resultmatches/XpathAssertionTests.java | 11 +- .../samples/context/JavaConfigTests.java | 25 +- .../samples/context/WebAppResourceTests.java | 10 +- .../samples/context/XmlConfigTests.java | 10 +- ...stAttributesRequestContextHolderTests.java | 7 +- .../spr/RequestContextHolderTests.java | 9 +- .../samples/standalone/FilterTests.java | 27 +- .../standalone/MultipartControllerTests.java | 15 +- .../samples/standalone/RedirectTests.java | 3 +- ...PrintingResultHandlerIntegrationTests.java | 5 +- .../PrintingResultHandlerSmokeTests.java | 5 +- .../resultmatchers/ModelAssertionTests.java | 3 +- .../XmlContentAssertionTests.java | 11 +- .../resultmatchers/XpathAssertionTests.java | 11 +- ...ConditionalDelegatingFilterProxyTests.java | 13 +- .../servlet/setup/SharedHttpSessionTests.java | 3 +- .../setup/StandaloneMockMvcBuilderTests.java | 11 +- .../samples/context/servlet-context.xml | 23 +- spring-tx/spring-tx.gradle | 11 +- .../jca/cci/CannotCreateRecordException.java | 45 -- .../cci/CannotGetCciConnectionException.java | 45 -- .../CciOperationNotSupportedException.java | 44 -- .../cci/InvalidResultSetAccessException.java | 49 -- .../cci/RecordTypeNotSupportedException.java | 45 -- .../CciLocalTransactionManager.java | 297 -------- .../connection/ConnectionFactoryUtils.java | 220 ------ .../jca/cci/connection/ConnectionHolder.java | 53 -- ...onnectionSpecConnectionFactoryAdapter.java | 144 ---- .../DelegatingConnectionFactory.java | 118 ---- .../connection/NotSupportedRecordFactory.java | 57 -- .../connection/SingleConnectionFactory.java | 264 ------- ...ransactionAwareConnectionFactoryProxy.java | 171 ----- .../jca/cci/connection/package-info.java | 11 - .../jca/cci/core/CciOperations.java | 130 ---- .../jca/cci/core/CciTemplate.java | 461 ------------ .../jca/cci/core/ConnectionCallback.java | 83 --- .../jca/cci/core/InteractionCallback.java | 84 --- .../jca/cci/core/RecordCreator.java | 68 -- .../jca/cci/core/RecordExtractor.java | 70 -- .../jca/cci/core/package-info.java | 10 - .../jca/cci/core/support/CciDaoSupport.java | 147 ---- .../jca/cci/core/support/CommAreaRecord.java | 107 --- .../jca/cci/core/support/package-info.java | 10 - .../jca/cci/object/EisOperation.java | 99 --- .../cci/object/MappingCommAreaOperation.java | 100 --- .../cci/object/MappingRecordOperation.java | 157 ----- .../jca/cci/object/SimpleRecordOperation.java | 87 --- .../jca/cci/object/package-info.java | 13 - .../springframework/jca/cci/package-info.java | 12 - .../jca/context/BootstrapContextAware.java | 47 -- .../BootstrapContextAwareProcessor.java | 64 -- .../ResourceAdapterApplicationContext.java | 66 -- .../context/SpringContextResourceAdapter.java | 260 ------- .../jca/context/package-info.java | 10 - .../AbstractMessageEndpointFactory.java | 20 +- .../GenericMessageEndpointFactory.java | 18 +- .../GenericMessageEndpointManager.java | 28 +- .../support/LocalConnectionFactoryBean.java | 24 +- .../support/ResourceAdapterFactoryBean.java | 22 +- .../jca/support/SimpleBootstrapContext.java | 16 +- .../jca/work/DelegatingWork.java | 69 -- .../jca/work/SimpleTaskWorkManager.java | 257 ------- .../jca/work/WorkManagerTaskExecutor.java | 337 --------- .../jca/work/package-info.java | 10 - .../transaction/TransactionDefinition.java | 8 +- .../AnnotationTransactionAttributeSource.java | 12 +- .../Ejb3TransactionAnnotationParser.java | 12 +- .../JtaTransactionAnnotationParser.java | 8 +- .../transaction/annotation/Propagation.java | 8 +- .../TransactionAnnotationParser.java | 4 +- ...actionManagementConfigurationSelector.java | 2 +- .../transaction/annotation/Transactional.java | 2 +- .../AnnotationDrivenBeanDefinitionParser.java | 2 +- ...ransactionManagerBeanDefinitionParser.java | 13 +- .../JtaTransactionManagerFactoryBean.java | 62 +- .../interceptor/RollbackRuleAttribute.java | 2 +- .../JtaAfterCompletionSynchronization.java | 4 +- .../jta/JtaTransactionManager.java | 91 ++- .../transaction/jta/JtaTransactionObject.java | 10 +- .../jta/ManagedTransactionAdapter.java | 19 +- .../jta/SimpleTransactionFactory.java | 16 +- .../jta/SpringJtaSynchronizationAdapter.java | 23 +- .../transaction/jta/TransactionFactory.java | 16 +- .../jta/UserTransactionAdapter.java | 18 +- .../jta/WebLogicJtaTransactionManager.java | 366 ---------- .../jta/WebSphereUowTransactionManager.java | 423 ----------- .../AbstractPlatformTransactionManager.java | 4 +- .../support/SmartTransactionObject.java | 4 +- ...tenceExceptionTranslationAdvisorTests.java | 3 +- ...xceptionTranslationPostProcessorTests.java | 3 +- .../jca/cci/CciLocalTransactionTests.java | 132 ---- .../jca/cci/CciTemplateTests.java | 545 --------------- .../jca/cci/EisOperationTests.java | 217 ------ .../LocalConnectionFactoryBeanTests.java | 5 +- .../JndiJtaTransactionManagerTests.java | 9 +- .../JtaTransactionManagerTests.java | 21 +- .../transaction/MockJtaTransaction.java | 7 +- ...tationTransactionAttributeSourceTests.java | 27 +- .../transaction/jta/MockUOWManager.java | 132 ---- .../WebSphereUowTransactionManagerTests.java | 656 ------------------ ...aTransactionManagerSerializationTests.java | 5 +- spring-web/spring-web.gradle | 36 +- .../reactive/JettyClientHttpRequest.java | 11 +- .../reactive/JettyClientHttpResponse.java | 60 +- .../client/reactive/JettyHeadersAdapter.java | 40 +- .../http/codec/ServerCodecConfigurer.java | 9 +- .../SynchronossPartHttpMessageReader.java | 597 ---------------- .../http/codec/support/BaseDefaultCodecs.java | 13 +- .../http/codec/xml/Jaxb2XmlDecoder.java | 20 +- .../http/codec/xml/Jaxb2XmlEncoder.java | 15 +- .../http/codec/xml/JaxbContextContainer.java | 8 +- .../converter/FormHttpMessageConverter.java | 4 +- .../json/JsonbHttpMessageConverter.java | 10 +- ...lEncompassingFormHttpMessageConverter.java | 4 +- .../AbstractJaxb2HttpMessageConverter.java | 8 +- .../Jaxb2CollectionHttpMessageConverter.java | 11 +- .../Jaxb2RootElementHttpMessageConverter.java | 22 +- .../ServletServerHttpAsyncRequestControl.java | 10 +- .../http/server/ServletServerHttpRequest.java | 4 +- .../server/ServletServerHttpResponse.java | 2 +- .../server/reactive/JettyHeadersAdapter.java | 40 +- .../reactive/JettyHttpHandlerAdapter.java | 74 +- .../reactive/ServletHttpHandlerAdapter.java | 27 +- .../reactive/ServletServerHttpRequest.java | 19 +- .../reactive/ServletServerHttpResponse.java | 13 +- .../reactive/TomcatHttpHandlerAdapter.java | 17 +- .../web/HttpMediaTypeException.java | 2 +- .../web/HttpRequestHandler.java | 10 +- ...ttpRequestMethodNotSupportedException.java | 2 +- .../web/HttpSessionRequiredException.java | 2 +- .../SpringServletContainerInitializer.java | 10 +- .../web/WebApplicationInitializer.java | 4 +- ...ractMappingContentNegotiationStrategy.java | 2 +- .../ContentNegotiationManagerFactoryBean.java | 2 +- ...thExtensionContentNegotiationStrategy.java | 2 +- ...thExtensionContentNegotiationStrategy.java | 2 +- .../web/bind/ServletRequestDataBinder.java | 6 +- ...ServletRequestParameterPropertyValues.java | 2 +- .../web/bind/ServletRequestUtils.java | 2 +- ...sfiedServletRequestParameterException.java | 2 +- .../web/bind/annotation/ControllerAdvice.java | 2 +- .../web/bind/annotation/CookieValue.java | 4 +- .../web/bind/annotation/ExceptionHandler.java | 6 +- .../web/bind/annotation/RequestMapping.java | 2 +- .../web/bind/annotation/RequestPart.java | 2 +- .../web/bind/annotation/ResponseStatus.java | 8 +- .../web/bind/annotation/SessionAttribute.java | 2 +- .../SpringWebConstraintValidatorFactory.java | 4 +- .../bind/support/WebRequestDataBinder.java | 4 +- .../web/client/RestTemplate.java | 4 +- .../AbstractContextLoaderInitializer.java | 5 +- .../ConfigurableWebApplicationContext.java | 6 +- .../context/ConfigurableWebEnvironment.java | 4 +- .../web/context/ContextCleanupListener.java | 7 +- .../web/context/ContextLoader.java | 3 +- .../web/context/ContextLoaderListener.java | 6 +- .../web/context/ServletConfigAware.java | 2 +- .../web/context/ServletContextAware.java | 2 +- .../web/context/WebApplicationContext.java | 16 +- .../DestructionCallbackBindingListener.java | 4 +- .../request/FacesRequestAttributes.java | 17 +- .../web/context/request/FacesWebRequest.java | 8 +- .../web/context/request/NativeWebRequest.java | 8 +- .../context/request/RequestContextHolder.java | 18 +- .../request/RequestContextListener.java | 8 +- .../request/ServletRequestAttributes.java | 10 +- .../context/request/ServletWebRequest.java | 8 +- .../web/context/request/WebRequest.java | 26 +- .../async/StandardServletAsyncWebRequest.java | 10 +- .../request/async/WebAsyncManager.java | 5 +- .../context/request/async/WebAsyncUtils.java | 6 +- ...tractRefreshableWebApplicationContext.java | 4 +- ...AnnotationConfigWebApplicationContext.java | 2 +- .../ContextExposingHttpServletRequest.java | 4 +- .../support/GenericWebApplicationContext.java | 4 +- .../support/HttpRequestHandlerServlet.java | 8 +- .../context/support/LiveBeansViewServlet.java | 8 +- .../context/support/RequestHandledEvent.java | 2 +- .../support/ServletConfigPropertySource.java | 2 +- .../ServletContextAttributeExporter.java | 5 +- .../ServletContextAttributeFactoryBean.java | 2 +- .../support/ServletContextAwareProcessor.java | 4 +- .../support/ServletContextLiveBeansView.java | 2 +- .../ServletContextParameterFactoryBean.java | 2 +- .../support/ServletContextPropertySource.java | 2 +- .../support/ServletContextResource.java | 22 +- .../support/ServletContextResourceLoader.java | 2 +- ...ServletContextResourcePatternResolver.java | 9 +- .../context/support/ServletContextScope.java | 2 +- .../support/SpringBeanAutowiringSupport.java | 5 +- .../support/StandardServletEnvironment.java | 4 +- .../support/StaticWebApplicationContext.java | 4 +- .../support/WebApplicationContextUtils.java | 16 +- .../support/WebApplicationObjectSupport.java | 8 +- .../web/cors/CorsConfigurationSource.java | 2 +- .../web/cors/CorsProcessor.java | 4 +- .../springframework/web/cors/CorsUtils.java | 2 +- .../web/cors/DefaultCorsProcessor.java | 5 +- .../cors/UrlBasedCorsConfigurationSource.java | 2 +- .../filter/AbstractRequestLoggingFilter.java | 10 +- .../web/filter/CharacterEncodingFilter.java | 18 +- .../filter/CommonsRequestLoggingFilter.java | 2 +- .../web/filter/CompositeFilter.java | 12 +- .../web/filter/CorsFilter.java | 12 +- .../web/filter/DelegatingFilterProxy.java | 24 +- .../web/filter/FormContentFilter.java | 10 +- .../web/filter/ForwardedHeaderFilter.java | 12 +- .../web/filter/GenericFilterBean.java | 25 +- .../web/filter/HiddenHttpMethodFilter.java | 12 +- .../web/filter/HttpPutFormContentFilter.java | 12 +- .../web/filter/OncePerRequestFilter.java | 24 +- .../web/filter/RelativeRedirectFilter.java | 8 +- .../RelativeRedirectResponseWrapper.java | 4 +- .../web/filter/RequestContextFilter.java | 8 +- .../ServletContextRequestLoggingFilter.java | 4 +- .../web/filter/ServletRequestPathFilter.java | 12 +- .../web/filter/ShallowEtagHeaderFilter.java | 14 +- .../web/jsf/DecoratingNavigationHandler.java | 8 +- .../jsf/DelegatingNavigationHandlerProxy.java | 4 +- .../DelegatingPhaseListenerMulticaster.java | 8 +- .../web/jsf/FacesContextUtils.java | 4 +- .../web/jsf/el/SpringBeanFacesELResolver.java | 10 +- .../WebApplicationContextFacesELResolver.java | 9 +- ...tractNamedValueMethodArgumentResolver.java | 2 +- ...ExpressionValueMethodArgumentResolver.java | 2 +- .../ModelAttributeMethodProcessor.java | 11 +- ...RequestParamMapMethodArgumentResolver.java | 4 +- .../RequestParamMethodArgumentResolver.java | 6 +- .../web/multipart/MultipartFile.java | 2 +- .../MultipartHttpServletRequest.java | 10 +- .../web/multipart/MultipartResolver.java | 10 +- .../commons/CommonsFileUploadSupport.java | 374 ---------- .../commons/CommonsMultipartFile.java | 242 ------- .../commons/CommonsMultipartResolver.java | 237 ------- .../web/multipart/commons/package-info.java | 10 - .../AbstractMultipartHttpServletRequest.java | 4 +- .../DefaultMultipartHttpServletRequest.java | 2 +- .../MissingServletRequestPartException.java | 2 +- .../multipart/support/MultipartFilter.java | 8 +- .../support/MultipartResolutionDelegate.java | 4 +- .../RequestPartServletServerHttpRequest.java | 4 +- .../StandardMultipartHttpServletRequest.java | 6 +- .../StandardServletMultipartResolver.java | 11 +- .../support/StandardServletPartUtils.java | 4 +- .../AbstractReactiveWebInitializer.java | 10 +- .../util/ContentCachingRequestWrapper.java | 10 +- .../util/ContentCachingResponseWrapper.java | 10 +- .../web/util/CookieGenerator.java | 17 +- .../web/util/HttpSessionMutexListener.java | 6 +- .../web/util/IntrospectorCleanupListener.java | 4 +- .../web/util/NestedServletException.java | 2 +- .../web/util/ServletContextPropertyUtils.java | 2 +- .../web/util/ServletRequestPathUtils.java | 10 +- .../springframework/web/util/TagUtils.java | 14 +- .../web/util/UrlPathHelper.java | 25 +- .../web/util/WebAppRootListener.java | 4 +- .../springframework/web/util/WebUtils.java | 92 +-- .../MultipartHttpMessageWriterTests.java | 9 +- ...SynchronossPartHttpMessageReaderTests.java | 237 ------- .../http/codec/xml/Jaxb2XmlDecoderTests.java | 2 +- .../http/codec/xml/Jaxb2XmlEncoderTests.java | 7 +- .../http/codec/xml/jaxb/XmlRootElement.java | 2 +- .../xml/jaxb/XmlRootElementWithName.java | 2 +- .../XmlRootElementWithNameAndNamespace.java | 2 +- .../http/codec/xml/jaxb/XmlType.java | 2 +- .../http/codec/xml/jaxb/XmlTypeWithName.java | 2 +- .../xml/jaxb/XmlTypeWithNameAndNamespace.java | 2 +- .../http/codec/xml/jaxb/package-info.java | 2 +- .../FormHttpMessageConverterTests.java | 26 +- .../json/JsonbHttpMessageConverterTests.java | 6 +- ...b2CollectionHttpMessageConverterTests.java | 8 +- ...2RootElementHttpMessageConverterTests.java | 17 +- .../ErrorHandlerIntegrationTests.java | 4 +- .../server/reactive/HeadersAdaptersTests.java | 2 +- .../reactive/ServerHttpRequestTests.java | 9 +- .../WebRequestDataBinderIntegrationTests.java | 11 +- .../ContextLoaderInitializerTests.java | 5 +- .../RequestAndSessionScopedBeanTests.java | 9 +- .../request/RequestContextListenerTests.java | 3 +- .../ServletRequestAttributesTests.java | 5 +- .../request/ServletWebRequestTests.java | 13 +- .../WebApplicationContextScopeTests.java | 3 +- .../StandardServletAsyncWebRequestTests.java | 3 +- .../async/WebAsyncManagerErrorTests.java | 3 +- .../request/async/WebAsyncManagerTests.java | 3 +- .../async/WebAsyncManagerTimeoutTests.java | 3 +- .../web/context/support/Spr8510Tests.java | 3 +- .../web/cors/DefaultCorsProcessorTests.java | 3 +- .../web/cors/reactive/CorsWebFilterTests.java | 3 +- .../filter/CharacterEncodingFilterTests.java | 9 +- .../web/filter/CompositeFilterTests.java | 15 +- .../ContentCachingResponseWrapperTests.java | 3 +- .../web/filter/CorsFilterTests.java | 5 +- .../filter/DelegatingFilterProxyTests.java | 15 +- .../filter/ForwardedHeaderFilterTests.java | 15 +- .../filter/HiddenHttpMethodFilterTests.java | 11 +- .../web/filter/OncePerRequestFilterTests.java | 13 +- .../filter/RelativeRedirectFilterTests.java | 5 +- .../web/filter/RequestContextFilterTests.java | 9 +- .../web/filter/RequestLoggingFilterTests.java | 7 +- .../filter/ShallowEtagHeaderFilterTests.java | 5 +- .../jsf/DelegatingNavigationHandlerTests.java | 5 +- .../web/jsf/DelegatingPhaseListenerTests.java | 9 +- .../web/jsf/MockFacesContext.java | 20 +- .../web/jsf/MockLifecycle.java | 8 +- .../web/method/ControllerAdviceBeanTests.java | 3 +- ...ookieValueMethodArgumentResolverTests.java | 3 +- .../ExceptionHandlerMethodResolverTests.java | 5 +- ...stParamMapMethodArgumentResolverTests.java | 3 +- ...questParamMethodArgumentResolverTests.java | 3 +- .../CommonsMultipartResolverTests.java | 618 ----------------- ...uestPartServletServerHttpRequestTests.java | 5 +- .../util/ServletRequestPathUtilsTests.java | 3 +- .../web/util/TagUtilsTests.java | 7 +- .../web/util/WebUtilsTests.java | 3 +- .../servlet/DelegatingServletInputStream.java | 6 +- .../DelegatingServletOutputStream.java | 6 +- .../testfixture/servlet/MockAsyncContext.java | 18 +- .../testfixture/servlet/MockBodyContent.java | 8 +- .../web/testfixture/servlet/MockCookie.java | 2 +- .../servlet/MockExpressionEvaluator.java | 84 --- .../testfixture/servlet/MockFilterChain.java | 16 +- .../testfixture/servlet/MockFilterConfig.java | 8 +- .../servlet/MockHttpServletMapping.java | 4 +- .../servlet/MockHttpServletRequest.java | 38 +- .../servlet/MockHttpServletResponse.java | 10 +- .../testfixture/servlet/MockHttpSession.java | 12 +- .../testfixture/servlet/MockJspWriter.java | 6 +- .../MockMultipartHttpServletRequest.java | 6 +- .../testfixture/servlet/MockPageContext.java | 35 +- .../web/testfixture/servlet/MockPart.java | 4 +- .../servlet/MockRequestDispatcher.java | 11 +- .../servlet/MockServletConfig.java | 6 +- .../servlet/MockServletContext.java | 31 +- .../servlet/MockSessionCookieConfig.java | 6 +- .../servlet/PassThroughFilterChain.java | 18 +- .../web/testfixture/xml/Pojo.java | 2 +- spring-webflux/spring-webflux.gradle | 20 +- .../config/WebFluxConfigurationSupport.java | 2 +- .../ModelAttributeMethodArgumentResolver.java | 2 +- .../RequestBodyMethodArgumentResolver.java | 2 +- .../reactive/result/view/RedirectView.java | 2 +- .../Jetty10WebSocketHandlerAdapter.java | 146 ---- .../adapter/JettyWebSocketHandlerAdapter.java | 6 +- .../StandardWebSocketHandlerAdapter.java | 10 +- .../adapter/StandardWebSocketSession.java | 13 +- .../adapter/TomcatWebSocketSession.java | 5 +- .../socket/client/JettyWebSocketClient.java | 113 +-- .../client/StandardWebSocketClient.java | 15 +- .../socket/client/TomcatWebSocketClient.java | 5 +- .../support/HandshakeWebSocketService.java | 8 +- .../upgrade/DefaultServerEndpointConfig.java | 14 +- .../Jetty10RequestUpgradeStrategy.java | 158 ----- .../upgrade/JettyRequestUpgradeStrategy.java | 178 ++--- .../upgrade/TomcatRequestUpgradeStrategy.java | 21 +- .../WebFluxConfigurationSupportTests.java | 3 +- .../function/BodyExtractorsTests.java | 6 +- .../MessageReaderArgumentResolverTests.java | 3 +- ...lAttributeMethodArgumentResolverTests.java | 3 +- ...pingMessageConversionIntegrationTests.java | 5 +- spring-webmvc/spring-webmvc.gradle | 30 +- .../web/servlet/AsyncHandlerInterceptor.java | 6 +- .../web/servlet/DispatcherServlet.java | 13 +- .../web/servlet/FlashMapManager.java | 4 +- .../web/servlet/FrameworkServlet.java | 22 +- .../web/servlet/HandlerAdapter.java | 4 +- .../web/servlet/HandlerExceptionResolver.java | 4 +- .../web/servlet/HandlerExecutionChain.java | 5 +- .../web/servlet/HandlerInterceptor.java | 6 +- .../web/servlet/HandlerMapping.java | 4 +- .../web/servlet/HttpServletBean.java | 9 +- .../web/servlet/LocaleContextResolver.java | 4 +- .../web/servlet/LocaleResolver.java | 4 +- .../ModelAndViewDefiningException.java | 2 +- .../web/servlet/NoHandlerFoundException.java | 6 +- .../servlet/RequestToViewNameTranslator.java | 4 +- .../web/servlet/ThemeResolver.java | 4 +- .../org/springframework/web/servlet/View.java | 4 +- .../AnnotationDrivenBeanDefinitionParser.java | 4 +- .../servlet/config/MvcNamespaceHandler.java | 3 +- .../TilesConfigurerBeanDefinitionParser.java | 81 --- .../ViewResolversBeanDefinitionParser.java | 7 +- .../ContentNegotiationConfigurer.java | 4 +- .../DefaultServletHandlerConfigurer.java | 2 +- .../annotation/ResourceHandlerRegistry.java | 2 +- .../annotation/ViewResolverRegistry.java | 25 - .../WebMvcConfigurationSupport.java | 12 +- .../function/AbstractServerResponse.java | 8 +- .../function/DefaultAsyncServerResponse.java | 9 +- .../DefaultEntityResponseBuilder.java | 11 +- .../DefaultRenderingResponseBuilder.java | 6 +- .../function/DefaultServerRequest.java | 14 +- .../function/DefaultServerRequestBuilder.java | 14 +- .../DefaultServerResponseBuilder.java | 6 +- .../web/servlet/function/EntityResponse.java | 2 +- .../function/ErrorHandlingServerResponse.java | 7 +- .../servlet/function/RenderingResponse.java | 2 +- .../servlet/function/RequestPredicates.java | 11 +- .../web/servlet/function/ServerRequest.java | 10 +- .../web/servlet/function/ServerResponse.java | 9 +- .../servlet/function/SseServerResponse.java | 8 +- .../support/HandlerFunctionAdapter.java | 7 +- .../support/RouterFunctionMapping.java | 2 +- .../AbstractHandlerExceptionResolver.java | 5 +- .../handler/AbstractHandlerMapping.java | 7 +- ...bstractHandlerMethodExceptionResolver.java | 4 +- .../handler/AbstractHandlerMethodMapping.java | 4 +- .../handler/AbstractUrlHandlerMapping.java | 4 +- .../ConversionServiceExposingInterceptor.java | 6 +- .../handler/DispatcherServletWebRequest.java | 4 +- .../HandlerExceptionResolverComposite.java | 4 +- .../handler/HandlerMappingIntrospector.java | 4 +- .../servlet/handler/MappedInterceptor.java | 4 +- .../handler/MatchableHandlerMapping.java | 2 +- .../PathPatternMatchableHandlerMapping.java | 2 +- .../SimpleMappingExceptionResolver.java | 6 +- .../handler/SimpleServletHandlerAdapter.java | 10 +- .../handler/SimpleServletPostProcessor.java | 14 +- .../UserRoleAuthorizationInterceptor.java | 10 +- .../WebRequestHandlerInterceptorAdapter.java | 4 +- .../i18n/AbstractLocaleContextResolver.java | 4 +- .../i18n/AcceptHeaderLocaleResolver.java | 6 +- .../servlet/i18n/CookieLocaleResolver.java | 8 +- .../web/servlet/i18n/FixedLocaleResolver.java | 4 +- .../servlet/i18n/LocaleChangeInterceptor.java | 7 +- .../servlet/i18n/SessionLocaleResolver.java | 6 +- .../web/servlet/mvc/AbstractController.java | 8 +- .../mvc/AbstractUrlViewController.java | 4 +- .../web/servlet/mvc/Controller.java | 4 +- .../mvc/HttpRequestHandlerAdapter.java | 4 +- .../web/servlet/mvc/LastModified.java | 6 +- .../mvc/ParameterizableViewController.java | 4 +- .../mvc/ServletForwardingController.java | 16 +- .../mvc/ServletWrappingController.java | 20 +- .../mvc/SimpleControllerHandlerAdapter.java | 4 +- .../mvc/UrlFilenameViewController.java | 2 +- .../servlet/mvc/WebContentInterceptor.java | 8 +- .../ResponseStatusExceptionResolver.java | 4 +- .../AbstractNameValueExpression.java | 2 +- .../condition/CompositeRequestCondition.java | 2 +- .../condition/ConsumesRequestCondition.java | 2 +- .../condition/HeadersRequestCondition.java | 2 +- .../mvc/condition/ParamsRequestCondition.java | 2 +- .../PathPatternsRequestCondition.java | 2 +- .../condition/PatternsRequestCondition.java | 2 +- .../condition/ProducesRequestCondition.java | 2 +- .../mvc/condition/RequestCondition.java | 2 +- .../mvc/condition/RequestConditionHolder.java | 2 +- .../RequestMethodsRequestCondition.java | 4 +- .../method/AbstractHandlerMethodAdapter.java | 6 +- .../mvc/method/RequestMappingInfo.java | 4 +- .../RequestMappingInfoHandlerMapping.java | 4 +- ...essageConverterMethodArgumentResolver.java | 5 +- ...stractMessageConverterMethodProcessor.java | 6 +- .../ExceptionHandlerExceptionResolver.java | 4 +- .../ExtendedServletRequestDataBinder.java | 2 +- .../annotation/HttpEntityMethodProcessor.java | 4 +- .../HttpHeadersReturnValueHandler.java | 2 +- .../annotation/MvcUriComponentsBuilder.java | 3 +- .../PrincipalMethodArgumentResolver.java | 2 +- ...equestAttributeMethodArgumentResolver.java | 2 +- .../RequestMappingHandlerAdapter.java | 8 +- .../RequestMappingHandlerMapping.java | 2 +- .../RequestPartMethodArgumentResolver.java | 6 +- .../RequestResponseBodyMethodProcessor.java | 2 +- ...ResponseBodyEmitterReturnValueHandler.java | 4 +- .../ResponseEntityExceptionHandler.java | 3 +- ...vletCookieValueMethodArgumentResolver.java | 4 +- .../ServletInvocableHandlerMethod.java | 4 +- .../ServletModelAttributeMethodProcessor.java | 2 +- .../ServletRequestMethodArgumentResolver.java | 10 +- ...ServletResponseMethodArgumentResolver.java | 2 +- ...essionAttributeMethodArgumentResolver.java | 2 +- ...reamingResponseBodyReturnValueHandler.java | 4 +- ...mponentsBuilderMethodArgumentResolver.java | 2 +- .../DefaultHandlerExceptionResolver.java | 11 +- .../resource/AbstractResourceResolver.java | 3 +- .../resource/AppCacheManifestTransformer.java | 3 +- .../resource/CachingResourceResolver.java | 2 +- .../resource/CachingResourceTransformer.java | 3 +- .../resource/CssLinkResourceTransformer.java | 3 +- .../DefaultResourceResolverChain.java | 2 +- .../DefaultResourceTransformerChain.java | 2 +- .../DefaultServletHttpRequestHandler.java | 10 +- .../resource/EncodedResourceResolver.java | 2 +- .../resource/GzipResourceResolver.java | 2 +- .../resource/PathResourceResolver.java | 2 +- .../resource/ResourceHttpRequestHandler.java | 11 +- .../servlet/resource/ResourceResolver.java | 2 +- .../resource/ResourceResolverChain.java | 2 +- .../servlet/resource/ResourceTransformer.java | 2 +- .../resource/ResourceTransformerChain.java | 2 +- .../resource/ResourceTransformerSupport.java | 2 +- .../resource/ResourceUrlEncodingFilter.java | 17 +- .../servlet/resource/ResourceUrlProvider.java | 5 +- ...esourceUrlProviderExposingInterceptor.java | 4 +- .../resource/VersionResourceResolver.java | 2 +- .../resource/WebJarsResourceResolver.java | 3 +- .../AbstractDispatcherServletInitializer.java | 14 +- .../support/AbstractFlashMapManager.java | 5 +- .../support/JspAwareRequestContext.java | 10 +- .../web/servlet/support/JstlUtils.java | 12 +- .../web/servlet/support/RequestContext.java | 22 +- .../servlet/support/RequestContextUtils.java | 10 +- .../support/RequestDataValueProcessor.java | 2 +- .../support/ServletUriComponentsBuilder.java | 2 +- .../support/SessionFlashMapManager.java | 6 +- .../servlet/support/WebContentGenerator.java | 6 +- .../web/servlet/tags/ArgumentAware.java | 2 +- .../web/servlet/tags/ArgumentTag.java | 4 +- .../web/servlet/tags/BindErrorsTag.java | 6 +- .../web/servlet/tags/BindTag.java | 4 +- .../web/servlet/tags/EditorAwareTag.java | 2 +- .../web/servlet/tags/EscapeBodyTag.java | 6 +- .../web/servlet/tags/EvalTag.java | 8 +- .../web/servlet/tags/HtmlEscapeTag.java | 2 +- .../servlet/tags/HtmlEscapingAwareTag.java | 2 +- .../web/servlet/tags/MessageTag.java | 8 +- .../web/servlet/tags/NestedPathTag.java | 8 +- .../web/servlet/tags/ParamTag.java | 4 +- .../servlet/tags/RequestContextAwareTag.java | 13 +- .../web/servlet/tags/TransformTag.java | 8 +- .../web/servlet/tags/UrlTag.java | 10 +- .../tags/form/AbstractCheckedElementTag.java | 2 +- .../form/AbstractDataBoundFormElementTag.java | 8 +- .../servlet/tags/form/AbstractFormTag.java | 12 +- .../tags/form/AbstractHtmlElementBodyTag.java | 14 +- .../tags/form/AbstractHtmlElementTag.java | 4 +- .../form/AbstractHtmlInputElementTag.java | 2 +- .../form/AbstractMultiCheckedElementTag.java | 2 +- .../form/AbstractSingleCheckedElementTag.java | 2 +- .../web/servlet/tags/form/ButtonTag.java | 2 +- .../web/servlet/tags/form/CheckboxTag.java | 2 +- .../web/servlet/tags/form/CheckboxesTag.java | 2 +- .../web/servlet/tags/form/ErrorsTag.java | 6 +- .../web/servlet/tags/form/FormTag.java | 20 +- .../web/servlet/tags/form/HiddenInputTag.java | 2 +- .../web/servlet/tags/form/InputTag.java | 2 +- .../web/servlet/tags/form/LabelTag.java | 4 +- .../web/servlet/tags/form/OptionTag.java | 6 +- .../web/servlet/tags/form/OptionWriter.java | 2 +- .../web/servlet/tags/form/OptionsTag.java | 2 +- .../servlet/tags/form/PasswordInputTag.java | 2 +- .../web/servlet/tags/form/RadioButtonTag.java | 2 +- .../web/servlet/tags/form/SelectTag.java | 4 +- .../web/servlet/tags/form/TagIdGenerator.java | 2 +- .../web/servlet/tags/form/TagWriter.java | 4 +- .../web/servlet/tags/form/TextareaTag.java | 2 +- .../servlet/theme/CookieThemeResolver.java | 6 +- .../web/servlet/theme/FixedThemeResolver.java | 4 +- .../servlet/theme/SessionThemeResolver.java | 4 +- .../servlet/theme/ThemeChangeInterceptor.java | 6 +- .../view/AbstractCachingViewResolver.java | 4 +- .../servlet/view/AbstractTemplateView.java | 8 +- .../web/servlet/view/AbstractView.java | 10 +- .../view/ContentNegotiatingViewResolver.java | 6 +- .../DefaultRequestToViewNameTranslator.java | 4 +- .../servlet/view/InternalResourceView.java | 28 +- .../view/InternalResourceViewResolver.java | 2 +- .../web/servlet/view/JstlView.java | 8 +- .../web/servlet/view/RedirectView.java | 10 +- .../servlet/view/UrlBasedViewResolver.java | 2 +- .../servlet/view/ViewResolverComposite.java | 2 +- .../view/document/AbstractPdfStamperView.java | 5 +- .../view/document/AbstractPdfView.java | 5 +- .../view/document/AbstractXlsView.java | 7 +- .../document/AbstractXlsxStreamingView.java | 5 +- .../view/document/AbstractXlsxView.java | 3 +- .../view/feed/AbstractAtomFeedView.java | 5 +- .../servlet/view/feed/AbstractFeedView.java | 7 +- .../view/feed/AbstractRssFeedView.java | 5 +- .../view/freemarker/FreeMarkerConfig.java | 9 +- .../view/freemarker/FreeMarkerConfigurer.java | 28 +- .../view/freemarker/FreeMarkerView.java | 121 +--- .../servlet/view/groovy/GroovyMarkupView.java | 5 +- .../view/json/AbstractJackson2View.java | 5 +- .../view/script/ScriptTemplateView.java | 7 +- .../tiles3/AbstractSpringPreparerFactory.java | 64 -- .../tiles3/SimpleSpringPreparerFactory.java | 72 -- .../tiles3/SpringBeanPreparerFactory.java | 42 -- .../view/tiles3/SpringLocaleResolver.java | 57 -- ...ildcardServletTilesApplicationContext.java | 106 --- .../servlet/view/tiles3/TilesConfigurer.java | 442 ------------ .../web/servlet/view/tiles3/TilesView.java | 166 ----- .../view/tiles3/TilesViewResolver.java | 95 --- .../web/servlet/view/tiles3/package-info.java | 12 - .../web/servlet/view/xml/MarshallingView.java | 7 +- .../web/servlet/view/xslt/XsltView.java | 4 +- .../web/servlet/config/spring-mvc.xsd | 67 +- .../web/context/ContextLoaderTests.java | 7 +- .../web/context/ServletConfigAwareBean.java | 2 +- .../web/context/ServletContextAwareBean.java | 2 +- .../ServletContextAwareProcessorTests.java | 5 +- .../XmlWebApplicationContextTests.java | 3 +- .../support/HttpRequestHandlerTests.java | 9 +- .../servlet/ComplexWebApplicationContext.java | 14 +- .../web/servlet/DispatcherServletTests.java | 17 +- .../servlet/SimpleWebApplicationContext.java | 6 +- .../web/servlet/config/MvcNamespaceTests.java | 40 +- .../DefaultServletHandlerConfigurerTests.java | 3 +- .../ViewResolutionIntegrationTests.java | 44 +- .../annotation/ViewResolverRegistryTests.java | 11 +- .../WebMvcConfigurationSupportTests.java | 9 +- .../DefaultEntityResponseBuilderTests.java | 5 +- .../DefaultRenderingResponseTests.java | 3 +- .../DefaultServerRequestBuilderTests.java | 5 +- .../function/DefaultServerRequestTests.java | 5 +- .../DefaultServerResponseBuilderTests.java | 3 +- .../ResourceHandlerFunctionTests.java | 3 +- .../BeanNameUrlHandlerMappingTests.java | 3 +- .../CorsAbstractHandlerMappingTests.java | 4 +- .../HandlerMappingIntrospectorTests.java | 3 +- .../servlet/handler/HandlerMappingTests.java | 3 +- .../handler/HandlerMethodMappingTests.java | 3 +- .../handler/MappedInterceptorTests.java | 5 +- .../SimpleMappingExceptionResolverTests.java | 3 +- .../i18n/AcceptHeaderLocaleResolverTests.java | 3 +- .../i18n/CookieLocaleResolverTests.java | 5 +- .../i18n/SessionLocaleResolverTests.java | 3 +- .../web/servlet/mvc/ControllerTests.java | 17 +- .../annotation/CglibProxyControllerTests.java | 3 +- .../annotation/JdkProxyControllerTests.java | 3 +- .../CompositeRequestConditionTests.java | 3 +- .../PathPatternsRequestConditionTests.java | 3 +- .../PatternsRequestConditionTests.java | 3 +- .../ProducesRequestConditionTests.java | 3 +- .../RequestConditionHolderTests.java | 3 +- .../RequestMethodsRequestConditionTests.java | 5 +- ...RequestMappingInfoHandlerMappingTests.java | 3 +- .../mvc/method/RequestMappingInfoTests.java | 3 +- ...equestAttributesArgumentResolverTests.java | 5 +- .../AbstractServletHandlerMethodTests.java | 3 +- .../method/annotation/CrossOriginTests.java | 3 +- .../HttpEntityMethodProcessorMockTests.java | 3 +- .../HttpEntityMethodProcessorTests.java | 7 +- .../MvcUriComponentsBuilderTests.java | 15 +- .../PrincipalMethodArgumentResolverTests.java | 3 +- ...MappingHandlerAdapterIntegrationTests.java | 9 +- .../RequestPartIntegrationTests.java | 33 +- ...equestPartMethodArgumentResolverTests.java | 7 +- ...tResponseBodyMethodProcessorMockTests.java | 5 +- .../ResponseEntityExceptionHandlerTests.java | 5 +- ...nnotationControllerHandlerMethodTests.java | 23 +- ...ookieValueMethodArgumentResolverTests.java | 3 +- .../ServletInvocableHandlerMethodTests.java | 5 +- ...letRequestMethodArgumentResolverTests.java | 7 +- ...etResponseMethodArgumentResolverTests.java | 3 +- ...nnotationControllerHandlerMethodTests.java | 4 +- .../DefaultHandlerExceptionResolverTests.java | 2 +- .../AppCacheManifestTransformerTests.java | 3 +- ...rceHttpRequestHandlerIntegrationTests.java | 3 +- .../ResourceHttpRequestHandlerTests.java | 3 +- .../ResourceTransformerSupportTests.java | 3 +- .../ResourceUrlEncodingFilterTests.java | 9 +- .../ResourceUrlProviderJavaConfigTests.java | 7 +- .../WebJarsResourceResolverTests.java | 3 +- ...nfigDispatcherServletInitializerTests.java | 17 +- .../DispatcherServletInitializerTests.java | 7 +- .../servlet/support/FlashMapManagerTests.java | 5 +- .../support/MockFilterRegistration.java | 4 +- .../support/MockServletRegistration.java | 6 +- .../RequestDataValueProcessorWrapper.java | 2 +- .../ServletUriComponentsBuilderTests.java | 3 +- .../web/servlet/tags/ArgumentTagTests.java | 9 +- .../web/servlet/tags/BindTagTests.java | 7 +- .../web/servlet/tags/EvalTagTests.java | 3 +- .../web/servlet/tags/HtmlEscapeTagTests.java | 9 +- .../web/servlet/tags/MessageTagTests.java | 11 +- .../web/servlet/tags/ParamTagTests.java | 9 +- .../web/servlet/tags/ThemeTagTests.java | 11 +- .../web/servlet/tags/UrlTagTests.java | 7 +- .../tags/form/AbstractFormTagTests.java | 2 +- .../form/AbstractHtmlElementTagTests.java | 5 +- .../web/servlet/tags/form/ButtonTagTests.java | 3 +- .../servlet/tags/form/CheckboxTagTests.java | 5 +- .../servlet/tags/form/CheckboxesTagTests.java | 5 +- .../web/servlet/tags/form/ErrorsTagTests.java | 11 +- .../web/servlet/tags/form/FormTagTests.java | 5 +- .../tags/form/HiddenInputTagTests.java | 5 +- .../web/servlet/tags/form/InputTagTests.java | 5 +- .../web/servlet/tags/form/LabelTagTests.java | 5 +- .../servlet/tags/form/OptionTagEnumTests.java | 5 +- .../web/servlet/tags/form/OptionTagTests.java | 5 +- .../servlet/tags/form/OptionsTagTests.java | 7 +- .../tags/form/PasswordInputTagTests.java | 5 +- .../tags/form/RadioButtonTagTests.java | 5 +- .../tags/form/RadioButtonsTagTests.java | 5 +- .../web/servlet/tags/form/SelectTagTests.java | 5 +- .../tags/form/TagIdGeneratorTests.java | 3 +- .../servlet/tags/form/TextareaTagTests.java | 3 +- .../web/servlet/view/BaseViewTests.java | 7 +- .../view/DummyMacroRequestContext.java | 2 +- .../view/InternalResourceViewTests.java | 3 +- .../view/ResourceBundleViewResolverTests.java | 5 +- .../web/servlet/view/ViewResolverTests.java | 15 +- .../servlet/view/document/XlsViewTests.java | 5 +- .../servlet/view/feed/AtomFeedViewTests.java | 5 +- .../servlet/view/feed/RssFeedViewTests.java | 5 +- .../view/freemarker/FreeMarkerMacroTests.java | 12 +- .../view/freemarker/FreeMarkerViewTests.java | 15 +- .../view/groovy/GroovyMarkupViewTests.java | 3 +- .../view/script/JRubyScriptTemplateTests.java | 3 +- .../script/JythonScriptTemplateTests.java | 3 +- .../script/KotlinScriptTemplateTests.java | 3 +- .../script/NashornScriptTemplateTests.java | 3 +- .../view/tiles3/TilesConfigurerTests.java | 66 -- .../view/tiles3/TilesViewResolverTests.java | 72 -- .../servlet/view/tiles3/TilesViewTests.java | 101 --- .../view/xml/MarshallingViewTests.java | 2 +- .../web/context/WEB-INF/empty-servlet.xml | 2 +- ...ig-view-resolution-content-negotiation.xml | 5 - .../config/mvc-config-view-resolution.xml | 8 - spring-websocket/spring-websocket.gradle | 16 +- .../jetty/Jetty10WebSocketHandlerAdapter.java | 137 ---- .../jetty/JettyWebSocketHandlerAdapter.java | 6 +- .../adapter/jetty/JettyWebSocketSession.java | 160 +---- ...ebSocketToJettyExtensionConfigAdapter.java | 7 +- .../ConvertingEncoderDecoderSupport.java | 44 +- .../StandardToWebSocketExtensionAdapter.java | 4 +- .../StandardWebSocketHandlerAdapter.java | 25 +- .../standard/StandardWebSocketSession.java | 8 +- .../WebSocketToStandardExtensionAdapter.java | 4 +- .../client/jetty/JettyWebSocketClient.java | 89 +-- .../AnnotatedEndpointConnectionManager.java | 8 +- .../standard/EndpointConnectionManager.java | 18 +- .../standard/StandardWebSocketClient.java | 14 +- .../WebSocketContainerFactoryBean.java | 6 +- .../MessageBrokerBeanDefinitionParser.java | 4 +- .../jetty/Jetty10RequestUpgradeStrategy.java | 167 ----- .../jetty/JettyRequestUpgradeStrategy.java | 257 ++----- .../AbstractStandardUpgradeStrategy.java | 19 +- .../AbstractTyrusRequestUpgradeStrategy.java | 17 +- .../GlassFishRequestUpgradeStrategy.java | 7 +- .../standard/ServerEndpointExporter.java | 16 +- .../standard/ServerEndpointRegistration.java | 24 +- .../ServletServerContainerFactoryBean.java | 16 +- .../server/standard/SpringConfigurator.java | 7 +- .../TomcatRequestUpgradeStrategy.java | 15 +- .../UndertowRequestUpgradeStrategy.java | 11 +- .../WebLogicRequestUpgradeStrategy.java | 15 +- .../WebSphereRequestUpgradeStrategy.java | 12 +- .../support/AbstractHandshakeHandler.java | 10 +- .../support/DefaultHandshakeHandler.java | 2 +- .../HttpSessionHandshakeInterceptor.java | 4 +- .../support/WebSocketHandlerMapping.java | 4 +- .../support/WebSocketHttpRequestHandler.java | 9 +- .../sockjs/client/JettyXhrTransport.java | 16 +- .../sockjs/support/AbstractSockJsService.java | 3 +- .../support/SockJsHttpRequestHandler.java | 8 +- .../handler/DefaultSockJsService.java | 3 +- .../handler/WebSocketTransportHandler.java | 2 +- .../session/AbstractHttpSockJsSession.java | 2 +- .../AbstractWebSocketIntegrationTests.java | 2 +- .../web/socket/JettyWebSocketTestServer.java | 7 +- .../web/socket/TomcatWebSocketTestServer.java | 5 +- .../web/socket/UndertowTestServer.java | 11 +- .../web/socket/WebSocketTestServer.java | 4 +- .../ConvertingEncoderDecoderSupportTests.java | 9 +- .../StandardWebSocketHandlerAdapterTests.java | 9 +- .../StandardWebSocketSessionTests.java | 3 +- .../jetty/JettyWebSocketClientTests.java | 35 +- .../StandardWebSocketClientTests.java | 7 +- .../standard/ServerEndpointExporterTests.java | 17 +- .../ServerEndpointRegistrationTests.java | 7 +- .../standard/SpringConfiguratorTests.java | 3 +- .../WebSocketHttpRequestHandlerTests.java | 3 +- .../AbstractSockJsIntegrationTests.java | 17 +- .../sockjs/support/SockJsServiceTests.java | 5 +- 1291 files changed, 4988 insertions(+), 25318 deletions(-) delete mode 100644 spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java delete mode 100644 spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java delete mode 100644 spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java delete mode 100644 spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java delete mode 100644 spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerUtils.java delete mode 100644 spring-context-support/src/main/java/org/springframework/cache/ehcache/package-info.java delete mode 100644 spring-context-support/src/main/java/org/springframework/scheduling/commonj/DelegatingTimerListener.java delete mode 100644 spring-context-support/src/main/java/org/springframework/scheduling/commonj/DelegatingWork.java delete mode 100644 spring-context-support/src/main/java/org/springframework/scheduling/commonj/ScheduledTimerListener.java delete mode 100644 spring-context-support/src/main/java/org/springframework/scheduling/commonj/TimerManagerAccessor.java delete mode 100644 spring-context-support/src/main/java/org/springframework/scheduling/commonj/TimerManagerFactoryBean.java delete mode 100644 spring-context-support/src/main/java/org/springframework/scheduling/commonj/TimerManagerTaskScheduler.java delete mode 100644 spring-context-support/src/main/java/org/springframework/scheduling/commonj/WorkManagerTaskExecutor.java delete mode 100644 spring-context-support/src/main/java/org/springframework/scheduling/commonj/package-info.java delete mode 100644 spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheCacheManagerTests.java delete mode 100644 spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java delete mode 100644 spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java delete mode 100644 spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCache3AnnotationTests.java delete mode 100644 spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCache3ApiTests.java delete mode 100644 spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/BeanValidationPostProcessorTests.java delete mode 100644 spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/MethodValidationTests.java delete mode 100644 spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/SpringValidatorAdapterTests.java delete mode 100644 spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/ValidatorFactoryTests.java delete mode 100644 spring-context/src/main/java/org/springframework/ejb/access/AbstractRemoteSlsbInvokerInterceptor.java delete mode 100644 spring-context/src/main/java/org/springframework/ejb/access/AbstractSlsbInvokerInterceptor.java delete mode 100644 spring-context/src/main/java/org/springframework/ejb/access/EjbAccessException.java delete mode 100644 spring-context/src/main/java/org/springframework/ejb/access/LocalSlsbInvokerInterceptor.java delete mode 100644 spring-context/src/main/java/org/springframework/ejb/access/LocalStatelessSessionProxyFactoryBean.java delete mode 100644 spring-context/src/main/java/org/springframework/ejb/access/SimpleRemoteSlsbInvokerInterceptor.java delete mode 100644 spring-context/src/main/java/org/springframework/ejb/access/SimpleRemoteStatelessSessionProxyFactoryBean.java delete mode 100644 spring-context/src/main/java/org/springframework/ejb/access/package-info.java delete mode 100644 spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/WebLogicClassLoaderAdapter.java delete mode 100644 spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/WebLogicClassPreProcessorAdapter.java delete mode 100644 spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/WebLogicLoadTimeWeaver.java delete mode 100644 spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/package-info.java delete mode 100644 spring-context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassLoaderAdapter.java delete mode 100644 spring-context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassPreDefinePlugin.java delete mode 100644 spring-context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereLoadTimeWeaver.java delete mode 100644 spring-context/src/main/java/org/springframework/instrument/classloading/websphere/package-info.java delete mode 100644 spring-context/src/main/java/org/springframework/jmx/support/WebSphereMBeanServerFactoryBean.java delete mode 100644 spring-context/src/test/java/org/springframework/ejb/access/LocalSlsbInvokerInterceptorTests.java delete mode 100644 spring-context/src/test/java/org/springframework/ejb/access/LocalStatelessSessionProxyFactoryBeanTests.java delete mode 100644 spring-context/src/test/java/org/springframework/ejb/access/SimpleRemoteSlsbInvokerInterceptorTests.java delete mode 100644 spring-context/src/test/java/org/springframework/ejb/access/SimpleRemoteStatelessSessionProxyFactoryBeanTests.java delete mode 100644 spring-jdbc/src/main/java/org/springframework/jdbc/datasource/WebSphereDataSourceAdapter.java delete mode 100644 spring-jms/src/test/java/org/springframework/jms/listener/MessageListenerContainerIntegrationTests.java delete mode 100644 spring-test/src/main/java/org/springframework/mock/web/MockExpressionEvaluator.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/CannotCreateRecordException.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/CannotGetCciConnectionException.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/CciOperationNotSupportedException.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/InvalidResultSetAccessException.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/RecordTypeNotSupportedException.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/connection/CciLocalTransactionManager.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionFactoryUtils.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionHolder.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/connection/DelegatingConnectionFactory.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/connection/NotSupportedRecordFactory.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/connection/SingleConnectionFactory.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/connection/TransactionAwareConnectionFactoryProxy.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/connection/package-info.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/core/CciOperations.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/core/CciTemplate.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/core/ConnectionCallback.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/core/InteractionCallback.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/core/RecordCreator.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/core/RecordExtractor.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/core/package-info.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/core/support/CciDaoSupport.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/core/support/CommAreaRecord.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/core/support/package-info.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/object/EisOperation.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/object/MappingCommAreaOperation.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/object/MappingRecordOperation.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/object/SimpleRecordOperation.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/object/package-info.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/cci/package-info.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/context/BootstrapContextAware.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/context/BootstrapContextAwareProcessor.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/context/ResourceAdapterApplicationContext.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/context/SpringContextResourceAdapter.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/context/package-info.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/work/DelegatingWork.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/work/SimpleTaskWorkManager.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/work/WorkManagerTaskExecutor.java delete mode 100644 spring-tx/src/main/java/org/springframework/jca/work/package-info.java delete mode 100644 spring-tx/src/main/java/org/springframework/transaction/jta/WebLogicJtaTransactionManager.java delete mode 100644 spring-tx/src/main/java/org/springframework/transaction/jta/WebSphereUowTransactionManager.java delete mode 100644 spring-tx/src/test/java/org/springframework/jca/cci/CciLocalTransactionTests.java delete mode 100644 spring-tx/src/test/java/org/springframework/jca/cci/CciTemplateTests.java delete mode 100644 spring-tx/src/test/java/org/springframework/jca/cci/EisOperationTests.java delete mode 100644 spring-tx/src/test/java/org/springframework/transaction/jta/MockUOWManager.java delete mode 100644 spring-tx/src/test/java/org/springframework/transaction/jta/WebSphereUowTransactionManagerTests.java delete mode 100644 spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java delete mode 100644 spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java delete mode 100644 spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartFile.java delete mode 100644 spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartResolver.java delete mode 100644 spring-web/src/main/java/org/springframework/web/multipart/commons/package-info.java delete mode 100644 spring-web/src/test/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReaderTests.java delete mode 100644 spring-web/src/test/java/org/springframework/web/multipart/commons/CommonsMultipartResolverTests.java delete mode 100644 spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockExpressionEvaluator.java delete mode 100644 spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/Jetty10WebSocketHandlerAdapter.java delete mode 100644 spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/Jetty10RequestUpgradeStrategy.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/config/TilesConfigurerBeanDefinitionParser.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/AbstractSpringPreparerFactory.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SimpleSpringPreparerFactory.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SpringBeanPreparerFactory.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SpringLocaleResolver.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SpringWildcardServletTilesApplicationContext.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesConfigurer.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesView.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesViewResolver.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/package-info.java delete mode 100644 spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesConfigurerTests.java delete mode 100644 spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewResolverTests.java delete mode 100644 spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewTests.java delete mode 100644 spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/Jetty10WebSocketHandlerAdapter.java delete mode 100644 spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/Jetty10RequestUpgradeStrategy.java diff --git a/build.gradle b/build.gradle index 255ecde3a6df..c6cdde1364e8 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ configure(allprojects) { project -> mavenBom "io.projectreactor:reactor-bom:2020.0.11" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" mavenBom "io.rsocket:rsocket-bom:1.1.1" - mavenBom "org.eclipse.jetty:jetty-bom:9.4.43.v20210629" + mavenBom "org.eclipse.jetty:jetty-bom:11.0.6" mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.30" mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2" mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2" @@ -83,14 +83,10 @@ configure(allprojects) { project -> exclude group: "xpp3", name: "xpp3_min" exclude group: "xmlpull", name: "xmlpull" } - dependency "org.apache.johnzon:johnzon-jsonb:1.2.10" + dependency "org.eclipse:yasson:2.0.2" dependency("org.codehaus.jettison:jettison:1.3.8") { exclude group: "stax", name: "stax-api" } - dependencySet(group: 'org.jibx', version: '1.3.3') { - entry 'jibx-bind' - entry 'jibx-run' - } dependency "org.ogce:xpp3:1.1.6" dependency "org.yaml:snakeyaml:1.29" @@ -108,7 +104,6 @@ configure(allprojects) { project -> } entry 'activemq-stomp' } - dependency "org.apache.bcel:bcel:6.0" dependency "org.apache.commons:commons-pool2:2.9.0" dependencySet(group: 'org.apache.derby', version: '10.14.2.0') { entry 'derby' @@ -119,35 +114,28 @@ configure(allprojects) { project -> dependency "org.freemarker:freemarker:2.3.31" dependency "org.hsqldb:hsqldb:2.5.2" dependency "org.quartz-scheduler:quartz:2.3.2" - dependency "org.codehaus.fabric3.api:commonj:1.1.0" - dependency "net.sf.ehcache:ehcache:2.10.6" dependency "org.ehcache:jcache:1.0.1" dependency "org.ehcache:ehcache:3.4.0" - dependency "org.hibernate:hibernate-core:5.5.7.Final" - dependency "org.hibernate:hibernate-validator:6.2.0.Final" + dependency "org.hibernate:hibernate-core-jakarta:5.5.7.Final" + dependency "org.hibernate:hibernate-validator:7.0.1.Final" dependency "org.webjars:webjars-locator-core:0.47" dependency "org.webjars:underscorejs:1.8.3" - dependencySet(group: 'org.apache.tomcat', version: '9.0.52') { + dependencySet(group: 'org.apache.tomcat', version: '10.0.11') { entry 'tomcat-util' entry('tomcat-websocket') { exclude group: "org.apache.tomcat", name: "tomcat-websocket-api" exclude group: "org.apache.tomcat", name: "tomcat-servlet-api" } } - dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.52') { + dependencySet(group: 'org.apache.tomcat.embed', version: '10.0.11') { entry 'tomcat-embed-core' entry 'tomcat-embed-websocket' } dependencySet(group: 'io.undertow', version: '2.2.10.Final') { entry 'undertow-core' - entry('undertow-websockets-jsr') { - exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec" - } - entry('undertow-servlet') { - exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_3.1_spec" - exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.2_spec" - } + entry('undertow-servlet-jakartaee9') + entry('undertow-websockets-jsr-jakartaee9') } dependencySet(group: 'com.squareup.okhttp3', version: '3.14.9') { @@ -162,15 +150,12 @@ configure(allprojects) { project -> } dependency 'org.apache.httpcomponents.client5:httpclient5:5.1' dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.1' - dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.9" + dependency "org.eclipse.jetty:jetty-reactive-httpclient:3.0.4" dependency "org.jruby:jruby:9.2.19.0" dependency "org.python:jython-standalone:2.7.1" dependency "org.mozilla:rhino:1.7.11" - dependency "commons-fileupload:commons-fileupload:1.4" - dependency "org.synchronoss.cloud:nio-multipart-parser:1.1.0" - dependency("org.dom4j:dom4j:2.1.3") { exclude group: "jaxen", name: "jaxen" exclude group: "net.java.dev.msv", name: "xsdlib" @@ -218,69 +203,50 @@ configure(allprojects) { project -> dependency "org.skyscreamer:jsonassert:1.5.0" dependency "com.jayway.jsonpath:json-path:2.6.0" dependency "org.bouncycastle:bcpkix-jdk15on:1.66" - - dependencySet(group: 'org.apache.tiles', version: '3.0.8') { - entry 'tiles-api' - entry('tiles-core', withoutJclOverSlf4j) - entry('tiles-servlet', withoutJclOverSlf4j) - entry('tiles-jsp', withoutJclOverSlf4j) - entry('tiles-el', withoutJclOverSlf4j) - entry('tiles-extras') { - exclude group: "org.springframework", name: "spring-web" - exclude group: "org.slf4j", name: "jcl-over-slf4j" - } - } - dependency("org.apache.taglibs:taglibs-standard-jstlel:1.2.5") { - exclude group: "org.apache.taglibs", name: "taglibs-standard-spec" - } - - dependency "com.ibm.websphere:uow:6.0.2.17" dependency "com.jamonapi:jamon:2.82" - dependency "joda-time:joda-time:2.10.10" - dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.9" - dependency "org.javamoney:moneta:1.3" - dependency "com.sun.activation:javax.activation:1.2.0" - dependency "com.sun.mail:javax.mail:1.6.2" - dependencySet(group: 'com.sun.xml.bind', version: '2.3.0.1') { + dependency "javax.cache:cache-api:1.1.1" + dependency "javax.money:money-api:1.1" + dependency "org.javamoney:moneta:1.4.2" + + dependency "jakarta.activation:jakarta.activation-api:2.0.1" + dependency "jakarta.annotation:jakarta.annotation-api:2.0.0" + dependency "jakarta.ejb:jakarta.ejb-api:4.0.0" + dependency "jakarta.el:jakarta.el-api:4.0.0" + dependency "jakarta.enterprise.concurrent:jakarta.enterprise.concurrent-api:2.0.0" + dependency "jakarta.faces:jakarta.faces-api:3.0.0" + dependency "jakarta.inject:jakarta.inject-api:2.0.0" + dependency "jakarta.inject:jakarta.inject-tck:2.0.1" + dependency "jakarta.interceptor:jakarta.interceptor-api:2.0.0" + dependency "jakarta.jms:jakarta.jms-api:3.0.0" + dependency "jakarta.json:jakarta.json-api:2.0.1" + dependency "jakarta.json.bind:jakarta.json.bind-api:2.0.0" + dependency "jakarta.mail:jakarta.mail-api:2.0.1" + dependency "jakarta.persistence:jakarta.persistence-api:3.0.0" + dependency "jakarta.resource:jakarta.resource-api:2.0.0" + dependency "jakarta.servlet:jakarta.servlet-api:5.0.0" + dependency "jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.0.0" + dependency "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:2.0.0" + dependency "jakarta.transaction:jakarta.transaction-api:2.0.0" + dependency "jakarta.validation:jakarta.validation-api:3.0.0" + dependency "jakarta.websocket:jakarta.websocket-api:2.0.0" + dependency "jakarta.xml.bind:jakarta.xml.bind-api:3.0.1" + dependency "jakarta.xml.ws:jakarta.xml.ws-api:3.0.1" + + dependency "com.sun.activation:jakarta.activation:2.0.1" + dependency "com.sun.mail:jakarta.mail:2.0.1" + dependencySet(group: 'com.sun.xml.bind', version: '3.0.2') { entry 'jaxb-core' entry 'jaxb-impl' entry 'jaxb-xjc' } - dependency "javax.activation:javax.activation-api:1.2.0" - dependency "javax.annotation:javax.annotation-api:1.3.2" - dependency "javax.cache:cache-api:1.1.0" - dependency "javax.ejb:javax.ejb-api:3.2" - dependency "javax.el:javax.el-api:3.0.1-b04" - dependency "javax.enterprise.concurrent:javax.enterprise.concurrent-api:1.0" - dependency "javax.faces:javax.faces-api:2.2" - dependency "javax.inject:javax.inject:1" - dependency "javax.inject:javax.inject-tck:1" - dependency "javax.interceptor:javax.interceptor-api:1.2.2" - dependency "javax.jms:javax.jms-api:2.0.1" - dependency "javax.json:javax.json-api:1.1.4" - dependency "javax.json.bind:javax.json.bind-api:1.0" - dependency "javax.mail:javax.mail-api:1.6.2" - dependency "javax.money:money-api:1.0.3" - dependency "javax.resource:javax.resource-api:1.7.1" - dependency "javax.servlet:javax.servlet-api:4.0.1" - dependency "javax.servlet.jsp:javax.servlet.jsp-api:2.3.2-b02" - dependency "javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1" - dependency "javax.transaction:javax.transaction-api:1.3" - dependency "javax.validation:validation-api:2.0.1.Final" - dependency "javax.websocket:javax.websocket-api:1.1" - dependency "javax.xml.bind:jaxb-api:2.3.1" - dependency "javax.xml.ws:jaxws-api:2.3.1" - - dependency "org.eclipse.persistence:javax.persistence:2.2.0" - // Substitute for "javax.management:jmxremote_optional:1.0.1_04" which // is not available on Maven Central dependency "org.glassfish.external:opendmk_jmxremote_optional_jar:1.0-b01-ea" - dependency "org.glassfish:javax.el:3.0.1-b08" - dependency "org.glassfish.main:javax.jws:4.0-b33" - dependency "org.glassfish.tyrus:tyrus-container-servlet:1.13.1" + dependency "org.glassfish:jakarta.el:4.0.2" + dependency "org.glassfish.tyrus:tyrus-container-servlet:2.0.1" + dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:3.0.2" } generatedPomCustomization { enabled = false diff --git a/integration-tests/integration-tests.gradle b/integration-tests/integration-tests.gradle index f7408e5c6ec4..5d864c7ba05b 100644 --- a/integration-tests/integration-tests.gradle +++ b/integration-tests/integration-tests.gradle @@ -15,12 +15,12 @@ dependencies { testImplementation(project(":spring-test")) testImplementation(project(":spring-tx")) testImplementation(project(":spring-web")) - testImplementation("javax.inject:javax.inject") - testImplementation("javax.resource:javax.resource-api") - testImplementation("javax.servlet:javax.servlet-api") + testImplementation("jakarta.inject:jakarta.inject-api") + testImplementation("jakarta.resource:jakarta.resource-api") + testImplementation("jakarta.servlet:jakarta.servlet-api") testImplementation("org.aspectj:aspectjweaver") testImplementation("org.hsqldb:hsqldb") - testImplementation("org.hibernate:hibernate-core") + testImplementation("org.hibernate:hibernate-core-jakarta") } normalization { diff --git a/integration-tests/src/test/java/org/springframework/aop/framework/autoproxy/AdvisorAutoProxyCreatorIntegrationTests.java b/integration-tests/src/test/java/org/springframework/aop/framework/autoproxy/AdvisorAutoProxyCreatorIntegrationTests.java index cf067e01415c..48142f4c9374 100644 --- a/integration-tests/src/test/java/org/springframework/aop/framework/autoproxy/AdvisorAutoProxyCreatorIntegrationTests.java +++ b/integration-tests/src/test/java/org/springframework/aop/framework/autoproxy/AdvisorAutoProxyCreatorIntegrationTests.java @@ -20,8 +20,7 @@ import java.lang.reflect.Method; import java.util.List; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletException; import org.junit.jupiter.api.Test; import org.springframework.aop.support.AopUtils; diff --git a/integration-tests/src/test/java/org/springframework/context/annotation/jsr330/ClassPathBeanDefinitionScannerJsr330ScopeIntegrationTests.java b/integration-tests/src/test/java/org/springframework/context/annotation/jsr330/ClassPathBeanDefinitionScannerJsr330ScopeIntegrationTests.java index bd86cc9041d1..f2bcce460c47 100644 --- a/integration-tests/src/test/java/org/springframework/context/annotation/jsr330/ClassPathBeanDefinitionScannerJsr330ScopeIntegrationTests.java +++ b/integration-tests/src/test/java/org/springframework/context/annotation/jsr330/ClassPathBeanDefinitionScannerJsr330ScopeIntegrationTests.java @@ -21,9 +21,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.inject.Named; -import javax.inject.Singleton; - +import jakarta.inject.Named; +import jakarta.inject.Singleton; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -314,16 +313,16 @@ public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) { if (definition instanceof AnnotatedBeanDefinition) { AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition; for (String type : annDef.getMetadata().getAnnotationTypes()) { - if (type.equals(javax.inject.Singleton.class.getName())) { + if (type.equals(jakarta.inject.Singleton.class.getName())) { metadata.setScopeName(BeanDefinition.SCOPE_SINGLETON); break; } - else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(javax.inject.Scope.class.getName())) { + else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(jakarta.inject.Scope.class.getName())) { metadata.setScopeName(type.substring(type.length() - 13, type.length() - 6).toLowerCase()); metadata.setScopedProxyMode(scopedProxyMode); break; } - else if (type.startsWith("javax.inject")) { + else if (type.startsWith("jakarta.inject")) { metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE); } } @@ -391,14 +390,14 @@ public static class SessionScopedTestBean extends ScopedTestBean implements Anot @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) - @javax.inject.Scope + @jakarta.inject.Scope public @interface RequestScoped { } @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) - @javax.inject.Scope + @jakarta.inject.Scope public @interface SessionScoped { } diff --git a/integration-tests/src/test/java/org/springframework/core/env/EnvironmentSystemIntegrationTests.java b/integration-tests/src/test/java/org/springframework/core/env/EnvironmentSystemIntegrationTests.java index 20e23ecca310..2bbc001f28eb 100644 --- a/integration-tests/src/test/java/org/springframework/core/env/EnvironmentSystemIntegrationTests.java +++ b/integration-tests/src/test/java/org/springframework/core/env/EnvironmentSystemIntegrationTests.java @@ -41,9 +41,6 @@ import org.springframework.context.support.GenericXmlApplicationContext; import org.springframework.context.support.StaticApplicationContext; import org.springframework.core.io.ClassPathResource; -import org.springframework.jca.context.ResourceAdapterApplicationContext; -import org.springframework.jca.support.SimpleBootstrapContext; -import org.springframework.jca.work.SimpleTaskWorkManager; import org.springframework.mock.env.MockEnvironment; import org.springframework.mock.env.MockPropertySource; import org.springframework.mock.web.MockServletConfig; @@ -535,22 +532,6 @@ void registerServletParamPropertySources_StaticWebApplicationContext() { assertThat(environment.getProperty("pSysProps1")).isEqualTo("pSysProps1Value"); } - @Test - void resourceAdapterApplicationContext() { - ResourceAdapterApplicationContext ctx = new ResourceAdapterApplicationContext(new SimpleBootstrapContext(new SimpleTaskWorkManager())); - - assertHasStandardEnvironment(ctx); - - registerEnvironmentBeanDefinition(ctx); - - ctx.setEnvironment(prodEnv); - ctx.refresh(); - - assertHasEnvironment(ctx, prodEnv); - assertEnvironmentBeanRegistered(ctx); - assertEnvironmentAwareInvoked(ctx, prodEnv); - } - @Test void abstractApplicationContextValidatesRequiredPropertiesOnRefresh() { { diff --git a/integration-tests/src/test/resources/org/springframework/aop/framework/autoproxy/AdvisorAutoProxyCreatorIntegrationTests-context.xml b/integration-tests/src/test/resources/org/springframework/aop/framework/autoproxy/AdvisorAutoProxyCreatorIntegrationTests-context.xml index 90ea7dc1f663..92abf56386a1 100644 --- a/integration-tests/src/test/resources/org/springframework/aop/framework/autoproxy/AdvisorAutoProxyCreatorIntegrationTests-context.xml +++ b/integration-tests/src/test/resources/org/springframework/aop/framework/autoproxy/AdvisorAutoProxyCreatorIntegrationTests-context.xml @@ -41,7 +41,7 @@ PROPAGATION_REQUIRED PROPAGATION_REQUIRED - PROPAGATION_REQUIRED,+javax.servlet.ServletException,-java.lang.Exception + PROPAGATION_REQUIRED,+jakarta.servlet.ServletException,-java.lang.Exception diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionInterceptor.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionInterceptor.java index 8d97ad311c70..a466164bcc7b 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionInterceptor.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,7 +47,7 @@ * target method needs to implement the same signature, it will have to return * a temporary Future handle that just passes the return value through * (like Spring's {@link org.springframework.scheduling.annotation.AsyncResult} - * or EJB 3.1's {@code javax.ejb.AsyncResult}). + * or EJB's {@code jakarta.ejb.AsyncResult}). * *

    When the return type is {@code java.util.concurrent.Future}, any exception thrown * during the execution can be accessed and managed by the caller. With {@code void} diff --git a/spring-aspects/spring-aspects.gradle b/spring-aspects/spring-aspects.gradle index 85c84bfd4670..ec29638bf5ec 100644 --- a/spring-aspects/spring-aspects.gradle +++ b/spring-aspects/spring-aspects.gradle @@ -29,14 +29,14 @@ dependencies { optional(project(":spring-orm")) // for JPA exception translation support optional(project(":spring-tx")) // for JPA, @Transactional support optional("javax.cache:cache-api") // for JCache aspect - optional("javax.transaction:javax.transaction-api") // for @javax.transaction.Transactional support + optional("jakarta.transaction:jakarta.transaction-api") // for @javax.transaction.Transactional support testImplementation(project(":spring-core")) // for CodeStyleAspect testImplementation(project(":spring-test")) testImplementation(testFixtures(project(":spring-context"))) testImplementation(testFixtures(project(":spring-context-support"))) testImplementation(testFixtures(project(":spring-core"))) testImplementation(testFixtures(project(":spring-tx"))) - testImplementation("javax.mail:javax.mail-api") + testImplementation("jakarta.mail:jakarta.mail-api") testCompileOnly("org.aspectj:aspectjrt") } diff --git a/spring-aspects/src/main/java/org/springframework/transaction/aspectj/AspectJJtaTransactionManagementConfiguration.java b/spring-aspects/src/main/java/org/springframework/transaction/aspectj/AspectJJtaTransactionManagementConfiguration.java index ec733d3cf2b9..0ed7ffb69eb8 100644 --- a/spring-aspects/src/main/java/org/springframework/transaction/aspectj/AspectJJtaTransactionManagementConfiguration.java +++ b/spring-aspects/src/main/java/org/springframework/transaction/aspectj/AspectJJtaTransactionManagementConfiguration.java @@ -27,7 +27,7 @@ /** * {@code @Configuration} class that registers the Spring infrastructure beans necessary * to enable AspectJ-based annotation-driven transaction management for the JTA 1.2 - * {@link javax.transaction.Transactional} annotation in addition to Spring's own + * {@link jakarta.transaction.Transactional} annotation in addition to Spring's own * {@link org.springframework.transaction.annotation.Transactional} annotation. * * @author Juergen Hoeller diff --git a/spring-aspects/src/main/java/org/springframework/transaction/aspectj/JtaAnnotationTransactionAspect.aj b/spring-aspects/src/main/java/org/springframework/transaction/aspectj/JtaAnnotationTransactionAspect.aj index 1644ce50651f..8b374ea0d86e 100644 --- a/spring-aspects/src/main/java/org/springframework/transaction/aspectj/JtaAnnotationTransactionAspect.aj +++ b/spring-aspects/src/main/java/org/springframework/transaction/aspectj/JtaAnnotationTransactionAspect.aj @@ -16,7 +16,7 @@ package org.springframework.transaction.aspectj; -import javax.transaction.Transactional; +import jakarta.transaction.Transactional; import org.aspectj.lang.annotation.RequiredTypes; @@ -24,7 +24,7 @@ import org.springframework.transaction.annotation.AnnotationTransactionAttribute /** * Concrete AspectJ transaction aspect using the JTA 1.2 - * {@link javax.transaction.Transactional} annotation. + * {@link jakarta.transaction.Transactional} annotation. * *

    When using this aspect, you must annotate the implementation class * (and/or methods within that class), not the interface (if any) that @@ -42,10 +42,10 @@ import org.springframework.transaction.annotation.AnnotationTransactionAttribute * * @author Stephane Nicoll * @since 4.2 - * @see javax.transaction.Transactional + * @see jakarta.transaction.Transactional * @see AnnotationTransactionAspect */ -@RequiredTypes("javax.transaction.Transactional") +@RequiredTypes("jakarta.transaction.Transactional") public aspect JtaAnnotationTransactionAspect extends AbstractTransactionAspect { public JtaAnnotationTransactionAspect() { diff --git a/spring-aspects/src/test/java/org/springframework/transaction/aspectj/JtaTransactionAspectsTests.java b/spring-aspects/src/test/java/org/springframework/transaction/aspectj/JtaTransactionAspectsTests.java index e0bd918a72ea..b6ef121a7962 100644 --- a/spring-aspects/src/test/java/org/springframework/transaction/aspectj/JtaTransactionAspectsTests.java +++ b/spring-aspects/src/test/java/org/springframework/transaction/aspectj/JtaTransactionAspectsTests.java @@ -18,8 +18,7 @@ import java.io.IOException; -import javax.transaction.Transactional; - +import jakarta.transaction.Transactional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-beans/spring-beans.gradle b/spring-beans/spring-beans.gradle index bf5fad779f0f..9c4d0af79e1a 100644 --- a/spring-beans/spring-beans.gradle +++ b/spring-beans/spring-beans.gradle @@ -5,13 +5,13 @@ apply plugin: "kotlin" dependencies { api(project(":spring-core")) - optional("javax.inject:javax.inject") + optional("jakarta.inject:jakarta.inject-api") optional("org.yaml:snakeyaml") optional("org.codehaus.groovy:groovy-xml") optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") testImplementation(testFixtures(project(":spring-core"))) - testImplementation("javax.annotation:javax.annotation-api") + testImplementation("jakarta.annotation:jakarta.annotation-api") testFixturesApi("org.junit.jupiter:junit-jupiter-api") testFixturesImplementation("org.assertj:assertj-core") } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Autowired.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Autowired.java index 242fddbad8e1..fad36ac5bf08 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Autowired.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Autowired.java @@ -25,7 +25,7 @@ /** * Marks a constructor, field, setter method, or config method as to be autowired by * Spring's dependency injection facilities. This is an alternative to the JSR-330 - * {@link javax.inject.Inject} annotation, adding required-vs-optional semantics. + * {@link jakarta.inject.Inject} annotation, adding required-vs-optional semantics. * *

    Autowired Constructors

    *

    Only one constructor of any given bean class may declare this annotation with the diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index 2065f6b6e9b0..fdbf93539128 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -75,7 +75,7 @@ * by default, Spring's {@link Autowired @Autowired} and {@link Value @Value} * annotations. * - *

    Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation, + *

    Also supports JSR-330's {@link jakarta.inject.Inject @Inject} annotation, * if available, as a direct alternative to Spring's own {@code @Autowired}. * *

    Autowired Constructors

    @@ -154,7 +154,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA /** * Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's * standard {@link Autowired @Autowired} and {@link Value @Value} annotations. - *

    Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation, + *

    Also supports JSR-330's {@link jakarta.inject.Inject @Inject} annotation, * if available. */ @SuppressWarnings("unchecked") @@ -163,8 +163,8 @@ public AutowiredAnnotationBeanPostProcessor() { this.autowiredAnnotationTypes.add(Value.class); try { this.autowiredAnnotationTypes.add((Class) - ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader())); - logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring"); + ClassUtils.forName("jakarta.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader())); + logger.trace("JSR-330 'jakarta.inject.Inject' annotation found and supported for autowiring"); } catch (ClassNotFoundException ex) { // JSR-330 API not available - simply skip. @@ -177,7 +177,7 @@ public AutowiredAnnotationBeanPostProcessor() { * setter methods, and arbitrary config methods. *

    The default autowired annotation types are the Spring-provided * {@link Autowired @Autowired} and {@link Value @Value} annotations as well - * as JSR-330's {@link javax.inject.Inject @Inject} annotation, if available. + * as JSR-330's {@link jakarta.inject.Inject @Inject} annotation, if available. *

    This setter property exists so that developers can provide their own * (non-Spring-specific) annotation type to indicate that a member is supposed * to be autowired. @@ -193,7 +193,7 @@ public void setAutowiredAnnotationType(Class autowiredAnno * setter methods, and arbitrary config methods. *

    The default autowired annotation types are the Spring-provided * {@link Autowired @Autowired} and {@link Value @Value} annotations as well - * as JSR-330's {@link javax.inject.Inject @Inject} annotation, if available. + * as JSR-330's {@link jakarta.inject.Inject @Inject} annotation, if available. *

    This setter property exists so that developers can provide their own * (non-Spring-specific) annotation types to indicate that a member is supposed * to be autowired. @@ -537,9 +537,7 @@ private MergedAnnotation findAutowiredAnnotation(AccessibleObject ao) { * @param ann the Autowired annotation * @return whether the annotation indicates that a dependency is required */ - @SuppressWarnings({"deprecation", "cast"}) protected boolean determineRequiredStatus(MergedAnnotation ann) { - // The following (AnnotationAttributes) cast is required on JDK 9+. return determineRequiredStatus((AnnotationAttributes) ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType()))); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java index f76a03b8dc9d..6316848a5a77 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java @@ -66,9 +66,9 @@ * init method and destroy method, respectively. * *

    Spring's {@link org.springframework.context.annotation.CommonAnnotationBeanPostProcessor} - * supports the JSR-250 {@link javax.annotation.PostConstruct} and {@link javax.annotation.PreDestroy} + * supports the JSR-250 {@link jakarta.annotation.PostConstruct} and {@link jakarta.annotation.PreDestroy} * annotations out of the box, as init annotation and destroy annotation, respectively. - * Furthermore, it also supports the {@link javax.annotation.Resource} annotation + * Furthermore, it also supports the {@link jakarta.annotation.Resource} annotation * for annotation-driven injection of named beans. * * @author Juergen Hoeller @@ -117,7 +117,7 @@ public boolean hasDestroyMethods() { * methods to call after configuration of a bean. *

    Any custom annotation can be used, since there are no required * annotation attributes. There is no default, although a typical choice - * is the JSR-250 {@link javax.annotation.PostConstruct} annotation. + * is the JSR-250 {@link jakarta.annotation.PostConstruct} annotation. */ public void setInitAnnotationType(Class initAnnotationType) { this.initAnnotationType = initAnnotationType; @@ -128,7 +128,7 @@ public void setInitAnnotationType(Class initAnnotationType * methods to call when the context is shutting down. *

    Any custom annotation can be used, since there are no required * annotation attributes. There is no default, although a typical choice - * is the JSR-250 {@link javax.annotation.PreDestroy} annotation. + * is the JSR-250 {@link jakarta.annotation.PreDestroy} annotation. */ public void setDestroyAnnotationType(Class destroyAnnotationType) { this.destroyAnnotationType = destroyAnnotationType; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java index e4e104b4c8e4..e38c67338641 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java @@ -46,7 +46,7 @@ * against {@link Qualifier qualifier annotations} on the field or parameter to be autowired. * Also supports suggested expression values through a {@link Value value} annotation. * - *

    Also supports JSR-330's {@link javax.inject.Qualifier} annotation, if available. + *

    Also supports JSR-330's {@link jakarta.inject.Qualifier} annotation, if available. * * @author Mark Fisher * @author Juergen Hoeller @@ -66,13 +66,13 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa /** * Create a new QualifierAnnotationAutowireCandidateResolver * for Spring's standard {@link Qualifier} annotation. - *

    Also supports JSR-330's {@link javax.inject.Qualifier} annotation, if available. + *

    Also supports JSR-330's {@link jakarta.inject.Qualifier} annotation, if available. */ @SuppressWarnings("unchecked") public QualifierAnnotationAutowireCandidateResolver() { this.qualifierTypes.add(Qualifier.class); try { - this.qualifierTypes.add((Class) ClassUtils.forName("javax.inject.Qualifier", + this.qualifierTypes.add((Class) ClassUtils.forName("jakarta.inject.Qualifier", QualifierAnnotationAutowireCandidateResolver.class.getClassLoader())); } catch (ClassNotFoundException ex) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java index d5fd082162b6..c16db6ca73ae 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java @@ -182,7 +182,7 @@ public boolean isRequired() { /** * Check whether the underlying field is annotated with any variant of a - * {@code Nullable} annotation, e.g. {@code javax.annotation.Nullable} or + * {@code Nullable} annotation, e.g. {@code jakarta.annotation.Nullable} or * {@code edu.umd.cs.findbugs.annotations.Nullable}. */ private boolean hasNullableAnnotation() { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/ProviderCreatingFactoryBean.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/ProviderCreatingFactoryBean.java index 11933292d418..96d7bf3a6035 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/ProviderCreatingFactoryBean.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/ProviderCreatingFactoryBean.java @@ -18,7 +18,7 @@ import java.io.Serializable; -import javax.inject.Provider; +import jakarta.inject.Provider; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; @@ -27,18 +27,18 @@ /** * A {@link org.springframework.beans.factory.FactoryBean} implementation that - * returns a value which is a JSR-330 {@link javax.inject.Provider} that in turn + * returns a value which is a JSR-330 {@link jakarta.inject.Provider} that in turn * returns a bean sourced from a {@link org.springframework.beans.factory.BeanFactory}. * *

    This is basically a JSR-330 compliant variant of Spring's good old * {@link ObjectFactoryCreatingFactoryBean}. It can be used for traditional * external dependency injection configuration that targets a property or - * constructor argument of type {@code javax.inject.Provider}, as an + * constructor argument of type {@code jakarta.inject.Provider}, as an * alternative to JSR-330's {@code @Inject} annotation-driven approach. * * @author Juergen Hoeller * @since 3.0.2 - * @see javax.inject.Provider + * @see jakarta.inject.Provider * @see ObjectFactoryCreatingFactoryBean */ public class ProviderCreatingFactoryBean extends AbstractFactoryBean> { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/Scope.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/Scope.java index d2054ae059a2..9606eb87264b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/Scope.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/Scope.java @@ -138,7 +138,7 @@ public interface Scope { *

    The exact meaning of the conversation ID depends on the underlying * storage mechanism. In the case of session-scoped objects, the * conversation ID would typically be equal to (or derived from) the - * {@link javax.servlet.http.HttpSession#getId() session ID}; in the + * {@link jakarta.servlet.http.HttpSession#getId() session ID}; in the * case of a custom conversation that sits within the overall session, * the specific ID for the current conversation would be appropriate. *

    Note: This is an optional operation. It is perfectly valid to 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 a4f29b0ce879..7c16748e1414 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 @@ -41,7 +41,7 @@ import java.util.function.Predicate; import java.util.stream.Stream; -import javax.inject.Provider; +import jakarta.inject.Provider; import org.springframework.beans.BeansException; import org.springframework.beans.TypeConverter; @@ -125,7 +125,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto static { try { javaxInjectProviderClass = - ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader()); + ClassUtils.forName("jakarta.inject.Provider", DefaultListableBeanFactory.class.getClassLoader()); } catch (ClassNotFoundException ex) { // JSR-330 API not available - Provider interface simply not supported then. @@ -1651,7 +1651,7 @@ else if (candidateLocal) { /** * Determine the candidate with the highest priority in the given set of beans. - *

    Based on {@code @javax.annotation.Priority}. As defined by the related + *

    Based on {@code @jakarta.annotation.Priority}. As defined by the related * {@link org.springframework.core.Ordered} interface, the lowest value has * the highest priority. * @param candidates a Map of candidate names and candidate instances @@ -1711,7 +1711,7 @@ protected boolean isPrimary(String beanName, Object beanInstance) { /** * Return the priority assigned for the given bean instance by - * the {@code javax.annotation.Priority} annotation. + * the {@code jakarta.annotation.Priority} annotation. *

    The default implementation delegates to the specified * {@link #setDependencyComparator dependency comparator}, checking its * {@link OrderComparator#getPriority method} if it is an extension of @@ -2086,8 +2086,8 @@ private Stream resolveStream(boolean ordered) { /** - * Separate inner class for avoiding a hard dependency on the {@code javax.inject} API. - * Actual {@code javax.inject.Provider} implementation is nested here in order to make it + * Separate inner class for avoiding a hard dependency on the {@code jakarta.inject} API. + * Actual {@code jakarta.inject.Provider} implementation is nested here in order to make it * invisible for Graal's introspection of DefaultListableBeanFactory's nested classes. */ private class Jsr330Factory implements Serializable { 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 2cb8d8a9cd1a..fce8a043b1b0 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 @@ -36,8 +36,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import javax.annotation.Priority; - +import jakarta.annotation.Priority; import org.junit.jupiter.api.Test; import org.springframework.beans.BeansException; diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/InjectAnnotationBeanPostProcessorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/InjectAnnotationBeanPostProcessorTests.java index aa4c1cb20bff..d4b97bdb19c2 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/InjectAnnotationBeanPostProcessorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/InjectAnnotationBeanPostProcessorTests.java @@ -23,10 +23,9 @@ import java.util.Map; import java.util.Optional; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Provider; - +import jakarta.inject.Inject; +import jakarta.inject.Named; +import jakarta.inject.Provider; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -51,7 +50,7 @@ /** * Unit tests for {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor} - * processing the JSR-330 {@link javax.inject.Inject} annotation. + * processing the JSR-330 {@link jakarta.inject.Inject} annotation. * * @author Juergen Hoeller * @since 3.0 diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/config/ObjectFactoryCreatingFactoryBeanTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/config/ObjectFactoryCreatingFactoryBeanTests.java index 7357ba9069dd..d55d48bb64a7 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/config/ObjectFactoryCreatingFactoryBeanTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/config/ObjectFactoryCreatingFactoryBeanTests.java @@ -18,8 +18,7 @@ import java.util.Date; -import javax.inject.Provider; - +import jakarta.inject.Provider; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-context-indexer/spring-context-indexer.gradle b/spring-context-indexer/spring-context-indexer.gradle index 2c1df2e91dc3..40d69a22670d 100644 --- a/spring-context-indexer/spring-context-indexer.gradle +++ b/spring-context-indexer/spring-context-indexer.gradle @@ -2,8 +2,8 @@ description = "Spring Context Indexer" dependencies { testImplementation(project(":spring-context")) - testImplementation("javax.inject:javax.inject") - testImplementation("javax.annotation:javax.annotation-api") - testImplementation("javax.transaction:javax.transaction-api") - testImplementation("org.eclipse.persistence:javax.persistence") + testImplementation("jakarta.inject:jakarta.inject-api") + testImplementation("jakarta.annotation:jakarta.annotation-api") + testImplementation("jakarta.persistence:jakarta.persistence-api") + testImplementation("jakarta.transaction:jakarta.transaction-api") } diff --git a/spring-context-indexer/src/main/java/org/springframework/context/index/processor/StandardStereotypesProvider.java b/spring-context-indexer/src/main/java/org/springframework/context/index/processor/StandardStereotypesProvider.java index 3a7eb01dbbc0..082c25849622 100644 --- a/spring-context-indexer/src/main/java/org/springframework/context/index/processor/StandardStereotypesProvider.java +++ b/spring-context-indexer/src/main/java/org/springframework/context/index/processor/StandardStereotypesProvider.java @@ -49,7 +49,7 @@ public Set getStereotypes(Element element) { } for (AnnotationMirror annotation : this.typeHelper.getAllAnnotationMirrors(element)) { String type = this.typeHelper.getType(annotation); - if (type.startsWith("javax.")) { + if (type.startsWith("jakarta.")) { stereotypes.add(type); } } diff --git a/spring-context-indexer/src/test/java/org/springframework/context/index/processor/CandidateComponentsIndexerTests.java b/spring-context-indexer/src/test/java/org/springframework/context/index/processor/CandidateComponentsIndexerTests.java index aa1a21d7367c..be3d30dc4207 100644 --- a/spring-context-indexer/src/test/java/org/springframework/context/index/processor/CandidateComponentsIndexerTests.java +++ b/spring-context-indexer/src/test/java/org/springframework/context/index/processor/CandidateComponentsIndexerTests.java @@ -21,14 +21,13 @@ import java.io.IOException; import java.nio.file.Path; -import javax.annotation.ManagedBean; -import javax.inject.Named; -import javax.persistence.Converter; -import javax.persistence.Embeddable; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; -import javax.transaction.Transactional; - +import jakarta.annotation.ManagedBean; +import jakarta.inject.Named; +import jakarta.persistence.Converter; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.persistence.MappedSuperclass; +import jakarta.transaction.Transactional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; diff --git a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/cdi/SampleManagedBean.java b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/cdi/SampleManagedBean.java index d3bf3dd8b785..fb34361664d6 100644 --- a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/cdi/SampleManagedBean.java +++ b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/cdi/SampleManagedBean.java @@ -16,7 +16,7 @@ package org.springframework.context.index.sample.cdi; -import javax.annotation.ManagedBean; +import jakarta.annotation.ManagedBean; /** * Test candidate for a CDI {@link ManagedBean}. diff --git a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/cdi/SampleNamed.java b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/cdi/SampleNamed.java index 20ca0342e68f..d975af6b1f30 100644 --- a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/cdi/SampleNamed.java +++ b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/cdi/SampleNamed.java @@ -16,7 +16,7 @@ package org.springframework.context.index.sample.cdi; -import javax.inject.Named; +import jakarta.inject.Named; /** * Test candidate for a CDI {@link Named} bean. diff --git a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/cdi/SampleTransactional.java b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/cdi/SampleTransactional.java index f104d5604e88..273aabcb14f3 100644 --- a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/cdi/SampleTransactional.java +++ b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/cdi/SampleTransactional.java @@ -16,7 +16,7 @@ package org.springframework.context.index.sample.cdi; -import javax.transaction.Transactional; +import jakarta.transaction.Transactional; /** * Test candidate for {@link Transactional}. This verifies that the annotation processor diff --git a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleConverter.java b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleConverter.java index 129f090f5779..474dd5c1a298 100644 --- a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleConverter.java +++ b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleConverter.java @@ -16,7 +16,7 @@ package org.springframework.context.index.sample.jpa; -import javax.persistence.Converter; +import jakarta.persistence.Converter; /** * Test candidate for {@link Converter}. diff --git a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleEmbeddable.java b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleEmbeddable.java index 79269507395a..15f3356ce70c 100644 --- a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleEmbeddable.java +++ b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleEmbeddable.java @@ -16,7 +16,7 @@ package org.springframework.context.index.sample.jpa; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; /** * Test candidate for {@link Embeddable}. diff --git a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleEntity.java b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleEntity.java index 101c3891d902..ae6e87559d29 100644 --- a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleEntity.java +++ b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleEntity.java @@ -16,7 +16,7 @@ package org.springframework.context.index.sample.jpa; -import javax.persistence.Entity; +import jakarta.persistence.Entity; /** * Test candidate for {@link Entity}. diff --git a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleMappedSuperClass.java b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleMappedSuperClass.java index 73737f4e98be..fbca3e43613b 100644 --- a/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleMappedSuperClass.java +++ b/spring-context-indexer/src/test/java/org/springframework/context/index/sample/jpa/SampleMappedSuperClass.java @@ -16,7 +16,7 @@ package org.springframework.context.index.sample.jpa; -import javax.persistence.MappedSuperclass; +import jakarta.persistence.MappedSuperclass; /** * Test candidate for {@link MappedSuperclass}. diff --git a/spring-context-support/spring-context-support.gradle b/spring-context-support/spring-context-support.gradle index 843d1920ebe4..160f8028985c 100644 --- a/spring-context-support/spring-context-support.gradle +++ b/spring-context-support/spring-context-support.gradle @@ -6,13 +6,11 @@ dependencies { api(project(":spring-core")) optional(project(":spring-jdbc")) // for Quartz support optional(project(":spring-tx")) // for Quartz support - optional("javax.activation:javax.activation-api") - optional("javax.mail:javax.mail-api") + optional("jakarta.activation:jakarta.activation-api") + optional("jakarta.mail:jakarta.mail-api") optional("javax.cache:cache-api") optional("com.github.ben-manes.caffeine:caffeine") - optional("net.sf.ehcache:ehcache") optional("org.quartz-scheduler:quartz") - optional("org.codehaus.fabric3.api:commonj") optional("org.freemarker:freemarker") testImplementation(project(":spring-context")) testImplementation(testFixtures(project(":spring-beans"))) @@ -20,12 +18,11 @@ dependencies { testImplementation(testFixtures(project(":spring-core"))) testImplementation(testFixtures(project(":spring-tx"))) testImplementation("org.hsqldb:hsqldb") - testImplementation("org.hibernate:hibernate-validator") - testImplementation("javax.annotation:javax.annotation-api") + testImplementation("jakarta.annotation:jakarta.annotation-api") testRuntimeOnly("org.ehcache:jcache") testRuntimeOnly("org.ehcache:ehcache") - testRuntimeOnly("org.glassfish:javax.el") - testRuntimeOnly("com.sun.mail:javax.mail") + testRuntimeOnly("org.glassfish:jakarta.el") + testRuntimeOnly("com.sun.mail:jakarta.mail") testFixturesApi("org.junit.jupiter:junit-jupiter-api") testFixturesImplementation("org.assertj:assertj-core") testFixturesImplementation("org.mockito:mockito-core") diff --git a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java deleted file mode 100644 index 4309fa73a2cb..000000000000 --- a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.ehcache; - -import java.util.concurrent.Callable; - -import net.sf.ehcache.Ehcache; -import net.sf.ehcache.Element; -import net.sf.ehcache.Status; - -import org.springframework.cache.Cache; -import org.springframework.cache.support.SimpleValueWrapper; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * {@link Cache} implementation on top of an {@link Ehcache} instance. - * - * @author Costin Leau - * @author Juergen Hoeller - * @author Stephane Nicoll - * @since 3.1 - * @see EhCacheCacheManager - */ -public class EhCacheCache implements Cache { - - private final Ehcache cache; - - - /** - * Create an {@link EhCacheCache} instance. - * @param ehcache the backing Ehcache instance - */ - public EhCacheCache(Ehcache ehcache) { - Assert.notNull(ehcache, "Ehcache must not be null"); - Status status = ehcache.getStatus(); - if (!Status.STATUS_ALIVE.equals(status)) { - throw new IllegalArgumentException( - "An 'alive' Ehcache is required - current cache is " + status.toString()); - } - this.cache = ehcache; - } - - - @Override - public final String getName() { - return this.cache.getName(); - } - - @Override - public final Ehcache getNativeCache() { - return this.cache; - } - - @Override - @Nullable - public ValueWrapper get(Object key) { - Element element = lookup(key); - return toValueWrapper(element); - } - - @SuppressWarnings("unchecked") - @Override - @Nullable - public T get(Object key, @Nullable Class type) { - Element element = this.cache.get(key); - Object value = (element != null ? element.getObjectValue() : null); - if (value != null && type != null && !type.isInstance(value)) { - throw new IllegalStateException( - "Cached value is not of required type [" + type.getName() + "]: " + value); - } - return (T) value; - } - - @SuppressWarnings("unchecked") - @Override - @Nullable - public T get(Object key, Callable valueLoader) { - Element element = lookup(key); - if (element != null) { - return (T) element.getObjectValue(); - } - else { - this.cache.acquireWriteLockOnKey(key); - try { - element = lookup(key); // one more attempt with the write lock - if (element != null) { - return (T) element.getObjectValue(); - } - else { - return loadValue(key, valueLoader); - } - } - finally { - this.cache.releaseWriteLockOnKey(key); - } - } - } - - private T loadValue(Object key, Callable valueLoader) { - T value; - try { - value = valueLoader.call(); - } - catch (Throwable ex) { - throw new ValueRetrievalException(key, valueLoader, ex); - } - put(key, value); - return value; - } - - @Override - public void put(Object key, @Nullable Object value) { - this.cache.put(new Element(key, value)); - } - - @Override - @Nullable - public ValueWrapper putIfAbsent(Object key, @Nullable Object value) { - Element existingElement = this.cache.putIfAbsent(new Element(key, value)); - return toValueWrapper(existingElement); - } - - @Override - public void evict(Object key) { - this.cache.remove(key); - } - - @Override - public boolean evictIfPresent(Object key) { - return this.cache.remove(key); - } - - @Override - public void clear() { - this.cache.removeAll(); - } - - @Override - public boolean invalidate() { - boolean notEmpty = (this.cache.getSize() > 0); - this.cache.removeAll(); - return notEmpty; - } - - - @Nullable - private Element lookup(Object key) { - return this.cache.get(key); - } - - @Nullable - private ValueWrapper toValueWrapper(@Nullable Element element) { - return (element != null ? new SimpleValueWrapper(element.getObjectValue()) : null); - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java deleted file mode 100644 index f3e58a55b288..000000000000 --- a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.ehcache; - -import java.util.Collection; -import java.util.LinkedHashSet; - -import net.sf.ehcache.Ehcache; -import net.sf.ehcache.Status; - -import org.springframework.cache.Cache; -import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * CacheManager backed by an EhCache {@link net.sf.ehcache.CacheManager}. - * - * @author Costin Leau - * @author Juergen Hoeller - * @author Stephane Nicoll - * @since 3.1 - * @see EhCacheCache - */ -public class EhCacheCacheManager extends AbstractTransactionSupportingCacheManager { - - @Nullable - private net.sf.ehcache.CacheManager cacheManager; - - - /** - * Create a new EhCacheCacheManager, setting the target EhCache CacheManager - * through the {@link #setCacheManager} bean property. - */ - public EhCacheCacheManager() { - } - - /** - * Create a new EhCacheCacheManager for the given backing EhCache CacheManager. - * @param cacheManager the backing EhCache {@link net.sf.ehcache.CacheManager} - */ - public EhCacheCacheManager(net.sf.ehcache.CacheManager cacheManager) { - this.cacheManager = cacheManager; - } - - - /** - * Set the backing EhCache {@link net.sf.ehcache.CacheManager}. - */ - public void setCacheManager(@Nullable net.sf.ehcache.CacheManager cacheManager) { - this.cacheManager = cacheManager; - } - - /** - * Return the backing EhCache {@link net.sf.ehcache.CacheManager}. - */ - @Nullable - public net.sf.ehcache.CacheManager getCacheManager() { - return this.cacheManager; - } - - @Override - public void afterPropertiesSet() { - if (getCacheManager() == null) { - setCacheManager(EhCacheManagerUtils.buildCacheManager()); - } - super.afterPropertiesSet(); - } - - - @Override - protected Collection loadCaches() { - net.sf.ehcache.CacheManager cacheManager = getCacheManager(); - Assert.state(cacheManager != null, "No CacheManager set"); - - Status status = cacheManager.getStatus(); - if (!Status.STATUS_ALIVE.equals(status)) { - throw new IllegalStateException( - "An 'alive' EhCache CacheManager is required - current cache is " + status.toString()); - } - - String[] names = getCacheManager().getCacheNames(); - Collection caches = new LinkedHashSet<>(names.length); - for (String name : names) { - caches.add(new EhCacheCache(getCacheManager().getEhcache(name))); - } - return caches; - } - - @Override - protected Cache getMissingCache(String name) { - net.sf.ehcache.CacheManager cacheManager = getCacheManager(); - Assert.state(cacheManager != null, "No CacheManager set"); - - // Check the EhCache cache again (in case the cache was added at runtime) - Ehcache ehcache = cacheManager.getEhcache(name); - if (ehcache != null) { - return new EhCacheCache(ehcache); - } - return null; - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java deleted file mode 100644 index 3d4f839a3b93..000000000000 --- a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.ehcache; - -import java.util.Set; - -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheException; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.Ehcache; -import net.sf.ehcache.bootstrap.BootstrapCacheLoader; -import net.sf.ehcache.config.CacheConfiguration; -import net.sf.ehcache.constructs.blocking.BlockingCache; -import net.sf.ehcache.constructs.blocking.CacheEntryFactory; -import net.sf.ehcache.constructs.blocking.SelfPopulatingCache; -import net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory; -import net.sf.ehcache.constructs.blocking.UpdatingSelfPopulatingCache; -import net.sf.ehcache.event.CacheEventListener; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.BeanNameAware; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; - -/** - * {@link FactoryBean} that creates a named EhCache {@link net.sf.ehcache.Cache} instance - * (or a decorator that implements the {@link net.sf.ehcache.Ehcache} interface), - * representing a cache region within an EhCache {@link net.sf.ehcache.CacheManager}. - * - *

    If the specified named cache is not configured in the cache configuration descriptor, - * this FactoryBean will construct an instance of a Cache with the provided name and the - * specified cache properties and add it to the CacheManager for later retrieval. If some - * or all properties are not set at configuration time, this FactoryBean will use defaults. - * - *

    Note: If the named Cache instance is found, the properties will be ignored and the - * Cache instance will be retrieved from the CacheManager. - * - *

    Note: As of Spring 5.0, Spring's EhCache support requires EhCache 2.10 or higher. - * - * @author Juergen Hoeller - * @author Dmitriy Kopylenko - * @since 1.1.1 - * @see #setCacheManager - * @see EhCacheManagerFactoryBean - * @see net.sf.ehcache.Cache - */ -public class EhCacheFactoryBean extends CacheConfiguration implements FactoryBean, BeanNameAware, InitializingBean { - - protected final Log logger = LogFactory.getLog(getClass()); - - @Nullable - private CacheManager cacheManager; - - private boolean blocking = false; - - @Nullable - private CacheEntryFactory cacheEntryFactory; - - @Nullable - private BootstrapCacheLoader bootstrapCacheLoader; - - @Nullable - private Set cacheEventListeners; - - private boolean disabled = false; - - @Nullable - private String beanName; - - @Nullable - private Ehcache cache; - - - public EhCacheFactoryBean() { - setMaxEntriesLocalHeap(10000); - setMaxEntriesLocalDisk(10000000); - setTimeToLiveSeconds(120); - setTimeToIdleSeconds(120); - } - - - /** - * Set a CacheManager from which to retrieve a named Cache instance. - * By default, {@code CacheManager.getInstance()} will be called. - *

    Note that in particular for persistent caches, it is advisable to - * properly handle the shutdown of the CacheManager: Set up a separate - * EhCacheManagerFactoryBean and pass a reference to this bean property. - *

    A separate EhCacheManagerFactoryBean is also necessary for loading - * EhCache configuration from a non-default config location. - * @see EhCacheManagerFactoryBean - * @see net.sf.ehcache.CacheManager#getInstance - */ - public void setCacheManager(CacheManager cacheManager) { - this.cacheManager = cacheManager; - } - - /** - * Set a name for which to retrieve or create a cache instance. - * Default is the bean name of this EhCacheFactoryBean. - */ - public void setCacheName(String cacheName) { - setName(cacheName); - } - - /** - * Set the time to live. - * @see #setTimeToLiveSeconds(long) - */ - public void setTimeToLive(int timeToLive) { - setTimeToLiveSeconds(timeToLive); - } - - /** - * Set the time to idle. - * @see #setTimeToIdleSeconds(long) - */ - public void setTimeToIdle(int timeToIdle) { - setTimeToIdleSeconds(timeToIdle); - } - - /** - * Set the disk spool buffer size (in MB). - * @see #setDiskSpoolBufferSizeMB(int) - */ - public void setDiskSpoolBufferSize(int diskSpoolBufferSize) { - setDiskSpoolBufferSizeMB(diskSpoolBufferSize); - } - - /** - * Set whether to use a blocking cache that lets read attempts block - * until the requested element is created. - *

    If you intend to build a self-populating blocking cache, - * consider specifying a {@link #setCacheEntryFactory CacheEntryFactory}. - * @see net.sf.ehcache.constructs.blocking.BlockingCache - * @see #setCacheEntryFactory - */ - public void setBlocking(boolean blocking) { - this.blocking = blocking; - } - - /** - * Set an EhCache {@link net.sf.ehcache.constructs.blocking.CacheEntryFactory} - * to use for a self-populating cache. If such a factory is specified, - * the cache will be decorated with EhCache's - * {@link net.sf.ehcache.constructs.blocking.SelfPopulatingCache}. - *

    The specified factory can be of type - * {@link net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory}, - * which will lead to the use of an - * {@link net.sf.ehcache.constructs.blocking.UpdatingSelfPopulatingCache}. - *

    Note: Any such self-populating cache is automatically a blocking cache. - * @see net.sf.ehcache.constructs.blocking.SelfPopulatingCache - * @see net.sf.ehcache.constructs.blocking.UpdatingSelfPopulatingCache - * @see net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory - */ - public void setCacheEntryFactory(CacheEntryFactory cacheEntryFactory) { - this.cacheEntryFactory = cacheEntryFactory; - } - - /** - * Set an EhCache {@link net.sf.ehcache.bootstrap.BootstrapCacheLoader} - * for this cache, if any. - */ - public void setBootstrapCacheLoader(BootstrapCacheLoader bootstrapCacheLoader) { - this.bootstrapCacheLoader = bootstrapCacheLoader; - } - - /** - * Specify EhCache {@link net.sf.ehcache.event.CacheEventListener cache event listeners} - * to registered with this cache. - */ - public void setCacheEventListeners(Set cacheEventListeners) { - this.cacheEventListeners = cacheEventListeners; - } - - /** - * Set whether this cache should be marked as disabled. - * @see net.sf.ehcache.Cache#setDisabled - */ - public void setDisabled(boolean disabled) { - this.disabled = disabled; - } - - @Override - public void setBeanName(String name) { - this.beanName = name; - } - - - @Override - public void afterPropertiesSet() throws CacheException { - // If no cache name given, use bean name as cache name. - String cacheName = getName(); - if (cacheName == null) { - cacheName = this.beanName; - if (cacheName != null) { - setName(cacheName); - } - } - - // If no CacheManager given, fetch the default. - if (this.cacheManager == null) { - if (logger.isDebugEnabled()) { - logger.debug("Using default EhCache CacheManager for cache region '" + cacheName + "'"); - } - this.cacheManager = CacheManager.getInstance(); - } - - synchronized (this.cacheManager) { - // Fetch cache region: If none with the given name exists, create one on the fly. - Ehcache rawCache; - boolean cacheExists = this.cacheManager.cacheExists(cacheName); - - if (cacheExists) { - if (logger.isDebugEnabled()) { - logger.debug("Using existing EhCache cache region '" + cacheName + "'"); - } - rawCache = this.cacheManager.getEhcache(cacheName); - } - else { - if (logger.isDebugEnabled()) { - logger.debug("Creating new EhCache cache region '" + cacheName + "'"); - } - rawCache = createCache(); - rawCache.setBootstrapCacheLoader(this.bootstrapCacheLoader); - } - - if (this.cacheEventListeners != null) { - for (CacheEventListener listener : this.cacheEventListeners) { - rawCache.getCacheEventNotificationService().registerListener(listener); - } - } - - // Needs to happen after listener registration but before setStatisticsEnabled - if (!cacheExists) { - this.cacheManager.addCache(rawCache); - } - - if (this.disabled) { - rawCache.setDisabled(true); - } - - Ehcache decoratedCache = decorateCache(rawCache); - if (decoratedCache != rawCache) { - this.cacheManager.replaceCacheWithDecoratedCache(rawCache, decoratedCache); - } - this.cache = decoratedCache; - } - } - - /** - * Create a raw Cache object based on the configuration of this FactoryBean. - */ - protected Cache createCache() { - return new Cache(this); - } - - /** - * Decorate the given Cache, if necessary. - * @param cache the raw Cache object, based on the configuration of this FactoryBean - * @return the (potentially decorated) cache object to be registered with the CacheManager - */ - protected Ehcache decorateCache(Ehcache cache) { - if (this.cacheEntryFactory != null) { - if (this.cacheEntryFactory instanceof UpdatingCacheEntryFactory) { - return new UpdatingSelfPopulatingCache(cache, (UpdatingCacheEntryFactory) this.cacheEntryFactory); - } - else { - return new SelfPopulatingCache(cache, this.cacheEntryFactory); - } - } - if (this.blocking) { - return new BlockingCache(cache); - } - return cache; - } - - - @Override - @Nullable - public Ehcache getObject() { - return this.cache; - } - - /** - * Predict the particular {@code Ehcache} implementation that will be returned from - * {@link #getObject()} based on logic in {@link #createCache()} and - * {@link #decorateCache(Ehcache)} as orchestrated by {@link #afterPropertiesSet()}. - */ - @Override - public Class getObjectType() { - if (this.cache != null) { - return this.cache.getClass(); - } - if (this.cacheEntryFactory != null) { - if (this.cacheEntryFactory instanceof UpdatingCacheEntryFactory) { - return UpdatingSelfPopulatingCache.class; - } - else { - return SelfPopulatingCache.class; - } - } - if (this.blocking) { - return BlockingCache.class; - } - return Cache.class; - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java deleted file mode 100644 index 8a7137819d31..000000000000 --- a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.ehcache; - -import net.sf.ehcache.CacheException; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.config.Configuration; -import net.sf.ehcache.config.ConfigurationFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.io.Resource; -import org.springframework.lang.Nullable; - -/** - * {@link FactoryBean} that exposes an EhCache {@link net.sf.ehcache.CacheManager} - * instance (independent or shared), configured from a specified config location. - * - *

    If no config location is specified, a CacheManager will be configured from - * "ehcache.xml" in the root of the class path (that is, default EhCache initialization - * - as defined in the EhCache docs - will apply). - * - *

    Setting up a separate EhCacheManagerFactoryBean is also advisable when using - * EhCacheFactoryBean, as it provides a (by default) independent CacheManager instance - * and cares for proper shutdown of the CacheManager. EhCacheManagerFactoryBean is - * also necessary for loading EhCache configuration from a non-default config location. - * - *

    Note: As of Spring 5.0, Spring's EhCache support requires EhCache 2.10 or higher. - * - * @author Juergen Hoeller - * @author Dmitriy Kopylenko - * @since 1.1.1 - * @see #setConfigLocation - * @see #setShared - * @see EhCacheFactoryBean - * @see net.sf.ehcache.CacheManager - */ -public class EhCacheManagerFactoryBean implements FactoryBean, InitializingBean, DisposableBean { - - protected final Log logger = LogFactory.getLog(getClass()); - - @Nullable - private Resource configLocation; - - @Nullable - private String cacheManagerName; - - private boolean acceptExisting = false; - - private boolean shared = false; - - @Nullable - private CacheManager cacheManager; - - private boolean locallyManaged = true; - - - /** - * Set the location of the EhCache config file. A typical value is "/WEB-INF/ehcache.xml". - *

    Default is "ehcache.xml" in the root of the class path, or if not found, - * "ehcache-failsafe.xml" in the EhCache jar (default EhCache initialization). - * @see net.sf.ehcache.CacheManager#create(java.io.InputStream) - * @see net.sf.ehcache.CacheManager#CacheManager(java.io.InputStream) - */ - public void setConfigLocation(Resource configLocation) { - this.configLocation = configLocation; - } - - /** - * Set the name of the EhCache CacheManager (if a specific name is desired). - * @see net.sf.ehcache.config.Configuration#setName(String) - */ - public void setCacheManagerName(String cacheManagerName) { - this.cacheManagerName = cacheManagerName; - } - - /** - * Set whether an existing EhCache CacheManager of the same name will be accepted - * for this EhCacheManagerFactoryBean setup. Default is "false". - *

    Typically used in combination with {@link #setCacheManagerName "cacheManagerName"} - * but will simply work with the default CacheManager name if none specified. - * All references to the same CacheManager name (or the same default) in the - * same ClassLoader space will share the specified CacheManager then. - * @see #setCacheManagerName - * #see #setShared - * @see net.sf.ehcache.CacheManager#getCacheManager(String) - * @see net.sf.ehcache.CacheManager#CacheManager() - */ - public void setAcceptExisting(boolean acceptExisting) { - this.acceptExisting = acceptExisting; - } - - /** - * Set whether the EhCache CacheManager should be shared (as a singleton at the - * ClassLoader level) or independent (typically local within the application). - * Default is "false", creating an independent local instance. - *

    NOTE: This feature allows for sharing this EhCacheManagerFactoryBean's - * CacheManager with any code calling CacheManager.create() in the same - * ClassLoader space, with no need to agree on a specific CacheManager name. - * However, it only supports a single EhCacheManagerFactoryBean involved which will - * control the lifecycle of the underlying CacheManager (in particular, its shutdown). - *

    This flag overrides {@link #setAcceptExisting "acceptExisting"} if both are set, - * since it indicates the 'stronger' mode of sharing. - * @see #setCacheManagerName - * @see #setAcceptExisting - * @see net.sf.ehcache.CacheManager#create() - * @see net.sf.ehcache.CacheManager#CacheManager() - */ - public void setShared(boolean shared) { - this.shared = shared; - } - - - @Override - public void afterPropertiesSet() throws CacheException { - if (logger.isDebugEnabled()) { - logger.debug("Initializing EhCache CacheManager" + - (this.cacheManagerName != null ? " '" + this.cacheManagerName + "'" : "")); - } - - Configuration configuration = (this.configLocation != null ? - EhCacheManagerUtils.parseConfiguration(this.configLocation) : ConfigurationFactory.parseConfiguration()); - if (this.cacheManagerName != null) { - configuration.setName(this.cacheManagerName); - } - - if (this.shared) { - // Old-school EhCache singleton sharing... - // No way to find out whether we actually created a new CacheManager - // or just received an existing singleton reference. - this.cacheManager = CacheManager.create(configuration); - } - else if (this.acceptExisting) { - // EhCache 2.5+: Reusing an existing CacheManager of the same name. - // Basically the same code as in CacheManager.getInstance(String), - // just storing whether we're dealing with an existing instance. - synchronized (CacheManager.class) { - this.cacheManager = CacheManager.getCacheManager(this.cacheManagerName); - if (this.cacheManager == null) { - this.cacheManager = new CacheManager(configuration); - } - else { - this.locallyManaged = false; - } - } - } - else { - // Throwing an exception if a CacheManager of the same name exists already... - this.cacheManager = new CacheManager(configuration); - } - } - - - @Override - @Nullable - public CacheManager getObject() { - return this.cacheManager; - } - - @Override - public Class getObjectType() { - return (this.cacheManager != null ? this.cacheManager.getClass() : CacheManager.class); - } - - @Override - public boolean isSingleton() { - return true; - } - - - @Override - public void destroy() { - if (this.cacheManager != null && this.locallyManaged) { - if (logger.isDebugEnabled()) { - logger.debug("Shutting down EhCache CacheManager" + - (this.cacheManagerName != null ? " '" + this.cacheManagerName + "'" : "")); - } - this.cacheManager.shutdown(); - } - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerUtils.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerUtils.java deleted file mode 100644 index 7d6654a86acd..000000000000 --- a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerUtils.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2002-2014 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.ehcache; - -import java.io.IOException; -import java.io.InputStream; - -import net.sf.ehcache.CacheException; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.config.Configuration; -import net.sf.ehcache.config.ConfigurationFactory; - -import org.springframework.core.io.Resource; - -/** - * Convenient builder methods for EhCache 2.5+ {@link CacheManager} setup, - * providing easy programmatic bootstrapping from a Spring-provided resource. - * This is primarily intended for use within {@code @Bean} methods in a - * Spring configuration class. - * - *

    These methods are a simple alternative to custom {@link CacheManager} setup - * code. For any advanced purposes, consider using {@link #parseConfiguration}, - * customizing the configuration object, and then calling the - * {@link CacheManager#CacheManager(Configuration)} constructor. - * - * @author Juergen Hoeller - * @since 4.1 - */ -public abstract class EhCacheManagerUtils { - - /** - * Build an EhCache {@link CacheManager} from the default configuration. - *

    The CacheManager will be configured from "ehcache.xml" in the root of the class path - * (that is, default EhCache initialization - as defined in the EhCache docs - will apply). - * If no configuration file can be found, a fail-safe fallback configuration will be used. - * @return the new EhCache CacheManager - * @throws CacheException in case of configuration parsing failure - */ - public static CacheManager buildCacheManager() throws CacheException { - return new CacheManager(ConfigurationFactory.parseConfiguration()); - } - - /** - * Build an EhCache {@link CacheManager} from the default configuration. - *

    The CacheManager will be configured from "ehcache.xml" in the root of the class path - * (that is, default EhCache initialization - as defined in the EhCache docs - will apply). - * If no configuration file can be found, a fail-safe fallback configuration will be used. - * @param name the desired name of the cache manager - * @return the new EhCache CacheManager - * @throws CacheException in case of configuration parsing failure - */ - public static CacheManager buildCacheManager(String name) throws CacheException { - Configuration configuration = ConfigurationFactory.parseConfiguration(); - configuration.setName(name); - return new CacheManager(configuration); - } - - /** - * Build an EhCache {@link CacheManager} from the given configuration resource. - * @param configLocation the location of the configuration file (as a Spring resource) - * @return the new EhCache CacheManager - * @throws CacheException in case of configuration parsing failure - */ - public static CacheManager buildCacheManager(Resource configLocation) throws CacheException { - return new CacheManager(parseConfiguration(configLocation)); - } - - /** - * Build an EhCache {@link CacheManager} from the given configuration resource. - * @param name the desired name of the cache manager - * @param configLocation the location of the configuration file (as a Spring resource) - * @return the new EhCache CacheManager - * @throws CacheException in case of configuration parsing failure - */ - public static CacheManager buildCacheManager(String name, Resource configLocation) throws CacheException { - Configuration configuration = parseConfiguration(configLocation); - configuration.setName(name); - return new CacheManager(configuration); - } - - /** - * Parse EhCache configuration from the given resource, for further use with - * custom {@link CacheManager} creation. - * @param configLocation the location of the configuration file (as a Spring resource) - * @return the EhCache Configuration handle - * @throws CacheException in case of configuration parsing failure - * @see CacheManager#CacheManager(Configuration) - * @see CacheManager#create(Configuration) - */ - public static Configuration parseConfiguration(Resource configLocation) throws CacheException { - InputStream is = null; - try { - is = configLocation.getInputStream(); - return ConfigurationFactory.parseConfiguration(is); - } - catch (IOException ex) { - throw new CacheException("Failed to parse EhCache configuration resource", ex); - } - finally { - if (is != null) { - try { - is.close(); - } - catch (IOException ex) { - // ignore - } - } - } - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/cache/ehcache/package-info.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/package-info.java deleted file mode 100644 index d786a802512f..000000000000 --- a/spring-context-support/src/main/java/org/springframework/cache/ehcache/package-info.java +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Support classes for the open source cache - * EhCache 2.x, - * allowing to set up an EhCache CacheManager and Caches - * as beans in a Spring context. - * - *

    Note: EhCache 3.x lives in a different package namespace - * and is not covered by the traditional support classes here. - * Instead, consider using it through JCache (JSR-107), with - * Spring's support in {@code org.springframework.cache.jcache}. - */ -@NonNullApi -@NonNullFields -package org.springframework.cache.ehcache; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-context-support/src/main/java/org/springframework/mail/MailSendException.java b/spring-context-support/src/main/java/org/springframework/mail/MailSendException.java index 693082c840c2..af7f0417f29b 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/MailSendException.java +++ b/spring-context-support/src/main/java/org/springframework/mail/MailSendException.java @@ -104,7 +104,7 @@ public MailSendException(Map failedMessages) { * be available after serialization as well. * @return the Map of failed messages as keys and thrown exceptions as values * @see SimpleMailMessage - * @see javax.mail.internet.MimeMessage + * @see jakarta.mail.internet.MimeMessage */ public final Map getFailedMessages() { return this.failedMessages; diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/ConfigurableMimeFileTypeMap.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/ConfigurableMimeFileTypeMap.java index ff6921b37183..7fe0a9aca896 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/ConfigurableMimeFileTypeMap.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/ConfigurableMimeFileTypeMap.java @@ -20,8 +20,8 @@ import java.io.IOException; import java.io.InputStream; -import javax.activation.FileTypeMap; -import javax.activation.MimetypesFileTypeMap; +import jakarta.activation.FileTypeMap; +import jakarta.activation.MimetypesFileTypeMap; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.io.ClassPathResource; @@ -58,7 +58,7 @@ * @since 1.2 * @see #setMappingLocation * @see #setMappings - * @see javax.activation.MimetypesFileTypeMap + * @see jakarta.activation.MimetypesFileTypeMap */ public class ConfigurableMimeFileTypeMap extends FileTypeMap implements InitializingBean { @@ -140,8 +140,8 @@ protected final FileTypeMap getFileTypeMap() { * @param mappings an array of MIME type mapping lines (can be {@code null}) * @return the compiled FileTypeMap * @throws IOException if resource access failed - * @see javax.activation.MimetypesFileTypeMap#MimetypesFileTypeMap(java.io.InputStream) - * @see javax.activation.MimetypesFileTypeMap#addMimeTypes(String) + * @see jakarta.activation.MimetypesFileTypeMap#MimetypesFileTypeMap(java.io.InputStream) + * @see jakarta.activation.MimetypesFileTypeMap#addMimeTypes(String) */ protected FileTypeMap createFileTypeMap(@Nullable Resource mappingLocation, @Nullable String[] mappings) throws IOException { MimetypesFileTypeMap fileTypeMap = null; diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/InternetAddressEditor.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/InternetAddressEditor.java index 7738328c563f..c4981581ebd3 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/InternetAddressEditor.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/InternetAddressEditor.java @@ -18,8 +18,8 @@ import java.beans.PropertyEditorSupport; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; +import jakarta.mail.internet.AddressException; +import jakarta.mail.internet.InternetAddress; import org.springframework.util.StringUtils; @@ -32,7 +32,7 @@ * * @author Juergen Hoeller * @since 1.2.3 - * @see javax.mail.internet.InternetAddress + * @see jakarta.mail.internet.InternetAddress */ public class InternetAddressEditor extends PropertyEditorSupport { diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSender.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSender.java index f810be606dd8..61f4ecb01d77 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSender.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSender.java @@ -18,7 +18,7 @@ import java.io.InputStream; -import javax.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMessage; import org.springframework.mail.MailException; import org.springframework.mail.MailSender; @@ -40,7 +40,7 @@ * mechanism, possibly using a {@link MimeMessageHelper} for populating the message. * See {@link MimeMessageHelper MimeMessageHelper's javadoc} for an example. * - *

    The entire JavaMail {@link javax.mail.Session} management is abstracted + *

    The entire JavaMail {@link jakarta.mail.Session} management is abstracted * by the JavaMailSender. Client code should not deal with a Session in any way, * rather leave the entire JavaMail configuration and resource handling to the * JavaMailSender implementation. This also increases testability. @@ -54,8 +54,8 @@ * * @author Juergen Hoeller * @since 07.10.2003 - * @see javax.mail.internet.MimeMessage - * @see javax.mail.Session + * @see jakarta.mail.internet.MimeMessage + * @see jakarta.mail.Session * @see JavaMailSenderImpl * @see MimeMessagePreparator * @see MimeMessageHelper diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSenderImpl.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSenderImpl.java index 9286d0ef665a..e13f61dcf438 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSenderImpl.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSenderImpl.java @@ -24,14 +24,14 @@ import java.util.Map; import java.util.Properties; -import javax.activation.FileTypeMap; -import javax.mail.Address; -import javax.mail.AuthenticationFailedException; -import javax.mail.MessagingException; -import javax.mail.NoSuchProviderException; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.MimeMessage; +import jakarta.activation.FileTypeMap; +import jakarta.mail.Address; +import jakarta.mail.AuthenticationFailedException; +import jakarta.mail.MessagingException; +import jakarta.mail.NoSuchProviderException; +import jakarta.mail.Session; +import jakarta.mail.Transport; +import jakarta.mail.internet.MimeMessage; import org.springframework.lang.Nullable; import org.springframework.mail.MailAuthenticationException; @@ -49,7 +49,7 @@ * plain {@link org.springframework.mail.MailSender} implementation. * *

    Allows for defining all settings locally as bean properties. - * Alternatively, a pre-configured JavaMail {@link javax.mail.Session} can be + * Alternatively, a pre-configured JavaMail {@link jakarta.mail.Session} can be * specified, possibly pulled from an application server's JNDI environment. * *

    Non-default properties in this object will always override the settings @@ -59,8 +59,8 @@ * @author Dmitriy Kopylenko * @author Juergen Hoeller * @since 10.09.2003 - * @see javax.mail.internet.MimeMessage - * @see javax.mail.Session + * @see jakarta.mail.internet.MimeMessage + * @see jakarta.mail.Session * @see #setSession * @see #setJavaMailProperties * @see #setHost @@ -523,7 +523,7 @@ protected Transport connectTransport() throws MessagingException { * Obtain a Transport object from the given JavaMail Session, * using the configured protocol. *

    Can be overridden in subclasses, e.g. to return a mock Transport object. - * @see javax.mail.Session#getTransport(String) + * @see jakarta.mail.Session#getTransport(String) * @see #getSession() * @see #getProtocol() */ diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMailMessage.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMailMessage.java index e62690a6d763..9161ea69d7ae 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMailMessage.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMailMessage.java @@ -18,8 +18,8 @@ import java.util.Date; -import javax.mail.MessagingException; -import javax.mail.internet.MimeMessage; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; import org.springframework.mail.MailMessage; import org.springframework.mail.MailParseException; @@ -35,7 +35,7 @@ * @author Juergen Hoeller * @since 1.1.5 * @see MimeMessageHelper - * @see javax.mail.internet.MimeMessage + * @see jakarta.mail.internet.MimeMessage */ public class MimeMailMessage implements MailMessage { diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java index f795390fa24d..0bf5c1bba6ca 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java @@ -23,20 +23,20 @@ import java.io.UnsupportedEncodingException; import java.util.Date; -import javax.activation.DataHandler; -import javax.activation.DataSource; -import javax.activation.FileDataSource; -import javax.activation.FileTypeMap; -import javax.mail.BodyPart; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; -import javax.mail.internet.MimePart; -import javax.mail.internet.MimeUtility; +import jakarta.activation.DataHandler; +import jakarta.activation.DataSource; +import jakarta.activation.FileDataSource; +import jakarta.activation.FileTypeMap; +import jakarta.mail.BodyPart; +import jakarta.mail.Message; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.AddressException; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeBodyPart; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMultipart; +import jakarta.mail.internet.MimePart; +import jakarta.mail.internet.MimeUtility; import org.springframework.core.io.InputStreamSource; import org.springframework.core.io.Resource; @@ -44,7 +44,7 @@ import org.springframework.util.Assert; /** - * Helper class for populating a {@link javax.mail.internet.MimeMessage}. + * Helper class for populating a {@link jakarta.mail.internet.MimeMessage}. * *

    Mirrors the simple setters of {@link org.springframework.mail.SimpleMailMessage}, * directly applying the values to the underlying MimeMessage. Allows for defining @@ -186,8 +186,8 @@ public class MimeMessageHelper { * the passed-in MimeMessage object, if carried there. Else, * JavaMail's default encoding will be used. * @param mimeMessage the mime message to work on - * @see #MimeMessageHelper(javax.mail.internet.MimeMessage, boolean) - * @see #getDefaultEncoding(javax.mail.internet.MimeMessage) + * @see #MimeMessageHelper(jakarta.mail.internet.MimeMessage, boolean) + * @see #getDefaultEncoding(jakarta.mail.internet.MimeMessage) * @see JavaMailSenderImpl#setDefaultEncoding */ public MimeMessageHelper(MimeMessage mimeMessage) { @@ -200,7 +200,7 @@ public MimeMessageHelper(MimeMessage mimeMessage) { * i.e. no alternative texts and no inline elements or attachments). * @param mimeMessage the mime message to work on * @param encoding the character encoding to use for the message - * @see #MimeMessageHelper(javax.mail.internet.MimeMessage, boolean) + * @see #MimeMessageHelper(jakarta.mail.internet.MimeMessage, boolean) */ public MimeMessageHelper(MimeMessage mimeMessage, @Nullable String encoding) { this.mimeMessage = mimeMessage; @@ -223,8 +223,8 @@ public MimeMessageHelper(MimeMessage mimeMessage, @Nullable String encoding) { * supports alternative texts, inline elements and attachments * (corresponds to MULTIPART_MODE_MIXED_RELATED) * @throws MessagingException if multipart creation failed - * @see #MimeMessageHelper(javax.mail.internet.MimeMessage, int) - * @see #getDefaultEncoding(javax.mail.internet.MimeMessage) + * @see #MimeMessageHelper(jakarta.mail.internet.MimeMessage, int) + * @see #getDefaultEncoding(jakarta.mail.internet.MimeMessage) * @see JavaMailSenderImpl#setDefaultEncoding */ public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart) throws MessagingException { @@ -244,7 +244,7 @@ public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart) throws Mess * (corresponds to MULTIPART_MODE_MIXED_RELATED) * @param encoding the character encoding to use for the message * @throws MessagingException if multipart creation failed - * @see #MimeMessageHelper(javax.mail.internet.MimeMessage, int, String) + * @see #MimeMessageHelper(jakarta.mail.internet.MimeMessage, int, String) */ public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart, @Nullable String encoding) throws MessagingException { @@ -267,7 +267,7 @@ public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart, @Nullable S * @see #MULTIPART_MODE_MIXED * @see #MULTIPART_MODE_RELATED * @see #MULTIPART_MODE_MIXED_RELATED - * @see #getDefaultEncoding(javax.mail.internet.MimeMessage) + * @see #getDefaultEncoding(jakarta.mail.internet.MimeMessage) * @see JavaMailSenderImpl#setDefaultEncoding */ public MimeMessageHelper(MimeMessage mimeMessage, int multipartMode) throws MessagingException { @@ -388,7 +388,7 @@ public final boolean isMultipart() { * @throws IllegalStateException if this helper is not in multipart mode * @see #isMultipart * @see #getMimeMessage - * @see javax.mail.internet.MimeMultipart#addBodyPart + * @see jakarta.mail.internet.MimeMultipart#addBodyPart */ public final MimeMultipart getRootMimeMultipart() throws IllegalStateException { if (this.rootMimeMultipart == null) { @@ -407,7 +407,7 @@ public final MimeMultipart getRootMimeMultipart() throws IllegalStateException { * @throws IllegalStateException if this helper is not in multipart mode * @see #isMultipart * @see #getRootMimeMultipart - * @see javax.mail.internet.MimeMultipart#addBodyPart + * @see jakarta.mail.internet.MimeMultipart#addBodyPart */ public final MimeMultipart getMimeMultipart() throws IllegalStateException { if (this.mimeMultipart == null) { @@ -469,9 +469,9 @@ protected FileTypeMap getDefaultFileTypeMap(MimeMessage mimeMessage) { * {@code FileTypeMap} instance else. * @see #addInline * @see #addAttachment - * @see #getDefaultFileTypeMap(javax.mail.internet.MimeMessage) + * @see #getDefaultFileTypeMap(jakarta.mail.internet.MimeMessage) * @see JavaMailSenderImpl#setDefaultFileTypeMap - * @see javax.activation.FileTypeMap#getDefaultFileTypeMap + * @see jakarta.activation.FileTypeMap#getDefaultFileTypeMap * @see ConfigurableMimeFileTypeMap */ public void setFileTypeMap(@Nullable FileTypeMap fileTypeMap) { @@ -538,7 +538,7 @@ public boolean isValidateAddresses() { * @param address the address to validate * @throws AddressException if validation failed * @see #isValidateAddresses() - * @see javax.mail.internet.InternetAddress#validate() + * @see jakarta.mail.internet.InternetAddress#validate() */ protected void validateAddress(InternetAddress address) throws AddressException { if (isValidateAddresses()) { @@ -889,7 +889,7 @@ private void setHtmlTextToMimePart(MimePart mimePart, String text) throws Messag /** * Add an inline element to the MimeMessage, taking the content from a - * {@code javax.activation.DataSource}. + * {@code jakarta.activation.DataSource}. *

    Note that the InputStream returned by the DataSource implementation * needs to be a fresh one on each call, as JavaMail will invoke * {@code getInputStream()} multiple times. @@ -898,7 +898,7 @@ private void setHtmlTextToMimePart(MimePart mimePart, String text) throws Messag * @param contentId the content ID to use. Will end up as "Content-ID" header * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>". * Can be referenced in HTML source via src="cid:myId" expressions. - * @param dataSource the {@code javax.activation.DataSource} to take + * @param dataSource the {@code jakarta.activation.DataSource} to take * the content from, determining the InputStream and the content type * @throws MessagingException in case of errors * @see #addInline(String, java.io.File) @@ -929,7 +929,7 @@ public void addInline(String contentId, DataSource dataSource) throws MessagingE * @throws MessagingException in case of errors * @see #setText * @see #addInline(String, org.springframework.core.io.Resource) - * @see #addInline(String, javax.activation.DataSource) + * @see #addInline(String, jakarta.activation.DataSource) */ public void addInline(String contentId, File file) throws MessagingException { Assert.notNull(file, "File must not be null"); @@ -956,7 +956,7 @@ public void addInline(String contentId, File file) throws MessagingException { * @throws MessagingException in case of errors * @see #setText * @see #addInline(String, java.io.File) - * @see #addInline(String, javax.activation.DataSource) + * @see #addInline(String, jakarta.activation.DataSource) */ public void addInline(String contentId, Resource resource) throws MessagingException { Assert.notNull(resource, "Resource must not be null"); @@ -984,7 +984,7 @@ public void addInline(String contentId, Resource resource) throws MessagingExcep * @see #setText * @see #getFileTypeMap * @see #addInline(String, org.springframework.core.io.Resource) - * @see #addInline(String, javax.activation.DataSource) + * @see #addInline(String, jakarta.activation.DataSource) */ public void addInline(String contentId, InputStreamSource inputStreamSource, String contentType) throws MessagingException { @@ -1001,13 +1001,13 @@ public void addInline(String contentId, InputStreamSource inputStreamSource, Str /** * Add an attachment to the MimeMessage, taking the content from a - * {@code javax.activation.DataSource}. + * {@code jakarta.activation.DataSource}. *

    Note that the InputStream returned by the DataSource implementation * needs to be a fresh one on each call, as JavaMail will invoke * {@code getInputStream()} multiple times. * @param attachmentFilename the name of the attachment as it will * appear in the mail (the content type will be determined by this) - * @param dataSource the {@code javax.activation.DataSource} to take + * @param dataSource the {@code jakarta.activation.DataSource} to take * the content from, determining the InputStream and the content type * @throws MessagingException in case of errors * @see #addAttachment(String, org.springframework.core.io.InputStreamSource) @@ -1040,7 +1040,7 @@ public void addAttachment(String attachmentFilename, DataSource dataSource) thro * @param file the File resource to take the content from * @throws MessagingException in case of errors * @see #addAttachment(String, org.springframework.core.io.InputStreamSource) - * @see #addAttachment(String, javax.activation.DataSource) + * @see #addAttachment(String, jakarta.activation.DataSource) */ public void addAttachment(String attachmentFilename, File file) throws MessagingException { Assert.notNull(file, "File must not be null"); @@ -1064,7 +1064,7 @@ public void addAttachment(String attachmentFilename, File file) throws Messaging * (all of Spring's Resource implementations can be passed in here) * @throws MessagingException in case of errors * @see #addAttachment(String, java.io.File) - * @see #addAttachment(String, javax.activation.DataSource) + * @see #addAttachment(String, jakarta.activation.DataSource) * @see org.springframework.core.io.Resource */ public void addAttachment(String attachmentFilename, InputStreamSource inputStreamSource) @@ -1087,7 +1087,7 @@ public void addAttachment(String attachmentFilename, InputStreamSource inputStre * @param contentType the content type to use for the element * @throws MessagingException in case of errors * @see #addAttachment(String, java.io.File) - * @see #addAttachment(String, javax.activation.DataSource) + * @see #addAttachment(String, jakarta.activation.DataSource) * @see org.springframework.core.io.Resource */ public void addAttachment( @@ -1121,7 +1121,7 @@ public InputStream getInputStream() throws IOException { } @Override public OutputStream getOutputStream() { - throw new UnsupportedOperationException("Read-only javax.activation.DataSource"); + throw new UnsupportedOperationException("Read-only jakarta.activation.DataSource"); } @Override public String getContentType() { diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessagePreparator.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessagePreparator.java index 5973d17104b6..04e6cc34cd29 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessagePreparator.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessagePreparator.java @@ -16,7 +16,7 @@ package org.springframework.mail.javamail; -import javax.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMessage; /** * Callback interface for the preparation of JavaMail MIME messages. @@ -42,7 +42,7 @@ public interface MimeMessagePreparator { /** * Prepare the given new MimeMessage instance. * @param mimeMessage the message to prepare - * @throws javax.mail.MessagingException passing any exceptions thrown by MimeMessage + * @throws jakarta.mail.MessagingException passing any exceptions thrown by MimeMessage * methods through for automatic conversion to the MailException hierarchy * @throws java.io.IOException passing any exceptions thrown by MimeMessage methods * through for automatic conversion to the MailException hierarchy diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/SmartMimeMessage.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/SmartMimeMessage.java index 2fa44c910af9..e41d4a226558 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/SmartMimeMessage.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/SmartMimeMessage.java @@ -16,9 +16,9 @@ package org.springframework.mail.javamail; -import javax.activation.FileTypeMap; -import javax.mail.Session; -import javax.mail.internet.MimeMessage; +import jakarta.activation.FileTypeMap; +import jakarta.mail.Session; +import jakarta.mail.internet.MimeMessage; import org.springframework.lang.Nullable; @@ -34,8 +34,8 @@ * @author Juergen Hoeller * @since 1.2 * @see JavaMailSenderImpl#createMimeMessage() - * @see MimeMessageHelper#getDefaultEncoding(javax.mail.internet.MimeMessage) - * @see MimeMessageHelper#getDefaultFileTypeMap(javax.mail.internet.MimeMessage) + * @see MimeMessageHelper#getDefaultEncoding(jakarta.mail.internet.MimeMessage) + * @see MimeMessageHelper#getDefaultFileTypeMap(jakarta.mail.internet.MimeMessage) */ class SmartMimeMessage extends MimeMessage { diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/DelegatingTimerListener.java b/spring-context-support/src/main/java/org/springframework/scheduling/commonj/DelegatingTimerListener.java deleted file mode 100644 index d6d493e1cac1..000000000000 --- a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/DelegatingTimerListener.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.commonj; - -import commonj.timers.Timer; -import commonj.timers.TimerListener; - -import org.springframework.util.Assert; - -/** - * Simple TimerListener adapter that delegates to a given Runnable. - * - * @author Juergen Hoeller - * @since 2.0 - * @see commonj.timers.TimerListener - * @see java.lang.Runnable - * @deprecated as of 5.1, in favor of EE 7's - * {@link org.springframework.scheduling.concurrent.DefaultManagedTaskScheduler} - */ -@Deprecated -public class DelegatingTimerListener implements TimerListener { - - private final Runnable runnable; - - - /** - * Create a new DelegatingTimerListener. - * @param runnable the Runnable implementation to delegate to - */ - public DelegatingTimerListener(Runnable runnable) { - Assert.notNull(runnable, "Runnable is required"); - this.runnable = runnable; - } - - - /** - * Delegates execution to the underlying Runnable. - */ - @Override - public void timerExpired(Timer timer) { - this.runnable.run(); - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/DelegatingWork.java b/spring-context-support/src/main/java/org/springframework/scheduling/commonj/DelegatingWork.java deleted file mode 100644 index 9f7eb9110ae8..000000000000 --- a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/DelegatingWork.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.commonj; - -import commonj.work.Work; - -import org.springframework.scheduling.SchedulingAwareRunnable; -import org.springframework.util.Assert; - -/** - * Simple Work adapter that delegates to a given Runnable. - * - * @author Juergen Hoeller - * @since 2.0 - * @deprecated as of 5.1, in favor of EE 7's - * {@link org.springframework.scheduling.concurrent.DefaultManagedTaskExecutor} - */ -@Deprecated -public class DelegatingWork implements Work { - - private final Runnable delegate; - - - /** - * Create a new DelegatingWork. - * @param delegate the Runnable implementation to delegate to - * (may be a SchedulingAwareRunnable for extended support) - * @see org.springframework.scheduling.SchedulingAwareRunnable - * @see #isDaemon() - */ - public DelegatingWork(Runnable delegate) { - Assert.notNull(delegate, "Delegate must not be null"); - this.delegate = delegate; - } - - /** - * Return the wrapped Runnable implementation. - */ - public final Runnable getDelegate() { - return this.delegate; - } - - - /** - * Delegates execution to the underlying Runnable. - */ - @Override - public void run() { - this.delegate.run(); - } - - /** - * This implementation delegates to - * {@link org.springframework.scheduling.SchedulingAwareRunnable#isLongLived()}, - * if available. - */ - @Override - public boolean isDaemon() { - return (this.delegate instanceof SchedulingAwareRunnable && - ((SchedulingAwareRunnable) this.delegate).isLongLived()); - } - - /** - * This implementation is empty, since we expect the Runnable - * to terminate based on some specific shutdown signal. - */ - @Override - public void release() { - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/ScheduledTimerListener.java b/spring-context-support/src/main/java/org/springframework/scheduling/commonj/ScheduledTimerListener.java deleted file mode 100644 index 52ca0afe1265..000000000000 --- a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/ScheduledTimerListener.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.commonj; - -import commonj.timers.TimerListener; - -import org.springframework.lang.Nullable; - -/** - * JavaBean that describes a scheduled TimerListener, consisting of - * the TimerListener itself (or a Runnable to create a TimerListener for) - * and a delay plus period. Period needs to be specified; - * there is no point in a default for it. - * - *

    The CommonJ TimerManager does not offer more sophisticated scheduling - * options such as cron expressions. Consider using Quartz for such - * advanced needs. - * - *

    Note that the TimerManager uses a TimerListener instance that is - * shared between repeated executions, in contrast to Quartz which - * instantiates a new Job for each execution. - * - * @author Juergen Hoeller - * @since 2.0 - * @deprecated as of 5.1, in favor of EE 7's - * {@link org.springframework.scheduling.concurrent.DefaultManagedTaskScheduler} - */ -@Deprecated -public class ScheduledTimerListener { - - @Nullable - private TimerListener timerListener; - - private long delay = 0; - - private long period = -1; - - private boolean fixedRate = false; - - - /** - * Create a new ScheduledTimerListener, - * to be populated via bean properties. - * @see #setTimerListener - * @see #setDelay - * @see #setPeriod - * @see #setFixedRate - */ - public ScheduledTimerListener() { - } - - /** - * Create a new ScheduledTimerListener, with default - * one-time execution without delay. - * @param timerListener the TimerListener to schedule - */ - public ScheduledTimerListener(TimerListener timerListener) { - this.timerListener = timerListener; - } - - /** - * Create a new ScheduledTimerListener, with default - * one-time execution with the given delay. - * @param timerListener the TimerListener to schedule - * @param delay the delay before starting the task for the first time (ms) - */ - public ScheduledTimerListener(TimerListener timerListener, long delay) { - this.timerListener = timerListener; - this.delay = delay; - } - - /** - * Create a new ScheduledTimerListener. - * @param timerListener the TimerListener to schedule - * @param delay the delay before starting the task for the first time (ms) - * @param period the period between repeated task executions (ms) - * @param fixedRate whether to schedule as fixed-rate execution - */ - public ScheduledTimerListener(TimerListener timerListener, long delay, long period, boolean fixedRate) { - this.timerListener = timerListener; - this.delay = delay; - this.period = period; - this.fixedRate = fixedRate; - } - - /** - * Create a new ScheduledTimerListener, with default - * one-time execution without delay. - * @param timerTask the Runnable to schedule as TimerListener - */ - public ScheduledTimerListener(Runnable timerTask) { - setRunnable(timerTask); - } - - /** - * Create a new ScheduledTimerListener, with default - * one-time execution with the given delay. - * @param timerTask the Runnable to schedule as TimerListener - * @param delay the delay before starting the task for the first time (ms) - */ - public ScheduledTimerListener(Runnable timerTask, long delay) { - setRunnable(timerTask); - this.delay = delay; - } - - /** - * Create a new ScheduledTimerListener. - * @param timerTask the Runnable to schedule as TimerListener - * @param delay the delay before starting the task for the first time (ms) - * @param period the period between repeated task executions (ms) - * @param fixedRate whether to schedule as fixed-rate execution - */ - public ScheduledTimerListener(Runnable timerTask, long delay, long period, boolean fixedRate) { - setRunnable(timerTask); - this.delay = delay; - this.period = period; - this.fixedRate = fixedRate; - } - - - /** - * Set the Runnable to schedule as TimerListener. - * @see DelegatingTimerListener - */ - public void setRunnable(Runnable timerTask) { - this.timerListener = new DelegatingTimerListener(timerTask); - } - - /** - * Set the TimerListener to schedule. - */ - public void setTimerListener(@Nullable TimerListener timerListener) { - this.timerListener = timerListener; - } - - /** - * Return the TimerListener to schedule. - */ - @Nullable - public TimerListener getTimerListener() { - return this.timerListener; - } - - /** - * Set the delay before starting the task for the first time, - * in milliseconds. Default is 0, immediately starting the - * task after successful scheduling. - *

    If the "firstTime" property is specified, this property will be ignored. - * Specify one or the other, not both. - */ - public void setDelay(long delay) { - this.delay = delay; - } - - /** - * Return the delay before starting the job for the first time. - */ - public long getDelay() { - return this.delay; - } - - /** - * Set the period between repeated task executions, in milliseconds. - *

    Default is -1, leading to one-time execution. In case of zero or a - * positive value, the task will be executed repeatedly, with the given - * interval in-between executions. - *

    Note that the semantics of the period value vary between fixed-rate - * and fixed-delay execution. - *

    Note: A period of 0 (for example as fixed delay) is - * supported, because the CommonJ specification defines this as a legal value. - * Hence a value of 0 will result in immediate re-execution after a job has - * finished (not in one-time execution like with {@code java.util.Timer}). - * @see #setFixedRate - * @see #isOneTimeTask() - * @see commonj.timers.TimerManager#schedule(commonj.timers.TimerListener, long, long) - */ - public void setPeriod(long period) { - this.period = period; - } - - /** - * Return the period between repeated task executions. - */ - public long getPeriod() { - return this.period; - } - - /** - * Is this task only ever going to execute once? - * @return {@code true} if this task is only ever going to execute once - * @see #getPeriod() - */ - public boolean isOneTimeTask() { - return (this.period < 0); - } - - /** - * Set whether to schedule as fixed-rate execution, rather than - * fixed-delay execution. Default is "false", i.e. fixed delay. - *

    See TimerManager javadoc for details on those execution modes. - * @see commonj.timers.TimerManager#schedule(commonj.timers.TimerListener, long, long) - * @see commonj.timers.TimerManager#scheduleAtFixedRate(commonj.timers.TimerListener, long, long) - */ - public void setFixedRate(boolean fixedRate) { - this.fixedRate = fixedRate; - } - - /** - * Return whether to schedule as fixed-rate execution. - */ - public boolean isFixedRate() { - return this.fixedRate; - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/TimerManagerAccessor.java b/spring-context-support/src/main/java/org/springframework/scheduling/commonj/TimerManagerAccessor.java deleted file mode 100644 index b5c0e15a068c..000000000000 --- a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/TimerManagerAccessor.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.commonj; - -import javax.naming.NamingException; - -import commonj.timers.TimerManager; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.Lifecycle; -import org.springframework.jndi.JndiLocatorSupport; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Base class for classes that are accessing a CommonJ {@link commonj.timers.TimerManager} - * Defines common configuration settings and common lifecycle handling. - * - * @author Juergen Hoeller - * @since 3.0 - * @see commonj.timers.TimerManager - * @deprecated as of 5.1, in favor of EE 7's - * {@link org.springframework.scheduling.concurrent.DefaultManagedTaskScheduler} - */ -@Deprecated -public abstract class TimerManagerAccessor extends JndiLocatorSupport - implements InitializingBean, DisposableBean, Lifecycle { - - @Nullable - private TimerManager timerManager; - - @Nullable - private String timerManagerName; - - private boolean shared = false; - - - /** - * Specify the CommonJ TimerManager to delegate to. - *

    Note that the given TimerManager's lifecycle will be managed - * by this FactoryBean. - *

    Alternatively (and typically), you can specify the JNDI name - * of the target TimerManager. - * @see #setTimerManagerName - */ - public void setTimerManager(TimerManager timerManager) { - this.timerManager = timerManager; - } - - /** - * Set the JNDI name of the CommonJ TimerManager. - *

    This can either be a fully qualified JNDI name, or the JNDI name relative - * to the current environment naming context if "resourceRef" is set to "true". - * @see #setTimerManager - * @see #setResourceRef - */ - public void setTimerManagerName(String timerManagerName) { - this.timerManagerName = timerManagerName; - } - - /** - * Specify whether the TimerManager obtained by this FactoryBean - * is a shared instance ("true") or an independent instance ("false"). - * The lifecycle of the former is supposed to be managed by the application - * server, while the lifecycle of the latter is up to the application. - *

    Default is "false", i.e. managing an independent TimerManager instance. - * This is what the CommonJ specification suggests that application servers - * are supposed to offer via JNDI lookups, typically declared as a - * {@code resource-ref} of type {@code commonj.timers.TimerManager} - * in {@code web.xml}, with {@code res-sharing-scope} set to 'Unshareable'. - *

    Switch this flag to "true" if you are obtaining a shared TimerManager, - * typically through specifying the JNDI location of a TimerManager that - * has been explicitly declared as 'Shareable'. Note that WebLogic's - * cluster-aware Job Scheduler is a shared TimerManager too. - *

    The sole difference between this FactoryBean being in shared or - * non-shared mode is that it will only attempt to suspend / resume / stop - * the underlying TimerManager in case of an independent (non-shared) instance. - * This only affects the {@link org.springframework.context.Lifecycle} support - * as well as application context shutdown. - * @see #stop() - * @see #start() - * @see #destroy() - * @see commonj.timers.TimerManager - */ - public void setShared(boolean shared) { - this.shared = shared; - } - - - @Override - public void afterPropertiesSet() throws NamingException { - if (this.timerManager == null) { - if (this.timerManagerName == null) { - throw new IllegalArgumentException("Either 'timerManager' or 'timerManagerName' must be specified"); - } - this.timerManager = lookup(this.timerManagerName, TimerManager.class); - } - } - - /** - * Return the configured TimerManager, if any. - * @return the TimerManager, or {@code null} if not available - */ - @Nullable - protected final TimerManager getTimerManager() { - return this.timerManager; - } - - /** - * Obtain the TimerManager for actual use. - * @return the TimerManager (never {@code null}) - * @throws IllegalStateException in case of no TimerManager set - * @since 5.0 - */ - protected TimerManager obtainTimerManager() { - Assert.notNull(this.timerManager, "No TimerManager set"); - return this.timerManager; - } - - - //--------------------------------------------------------------------- - // Implementation of Lifecycle interface - //--------------------------------------------------------------------- - - /** - * Resumes the underlying TimerManager (if not shared). - * @see commonj.timers.TimerManager#resume() - */ - @Override - public void start() { - if (!this.shared) { - obtainTimerManager().resume(); - } - } - - /** - * Suspends the underlying TimerManager (if not shared). - * @see commonj.timers.TimerManager#suspend() - */ - @Override - public void stop() { - if (!this.shared) { - obtainTimerManager().suspend(); - } - } - - /** - * Considers the underlying TimerManager as running if it is - * neither suspending nor stopping. - * @see commonj.timers.TimerManager#isSuspending() - * @see commonj.timers.TimerManager#isStopping() - */ - @Override - public boolean isRunning() { - TimerManager tm = obtainTimerManager(); - return (!tm.isSuspending() && !tm.isStopping()); - } - - - //--------------------------------------------------------------------- - // Implementation of DisposableBean interface - //--------------------------------------------------------------------- - - /** - * Stops the underlying TimerManager (if not shared). - * @see commonj.timers.TimerManager#stop() - */ - @Override - public void destroy() { - // Stop the entire TimerManager, if necessary. - if (this.timerManager != null && !this.shared) { - // May return early, but at least we already cancelled all known Timers. - this.timerManager.stop(); - } - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/TimerManagerFactoryBean.java b/spring-context-support/src/main/java/org/springframework/scheduling/commonj/TimerManagerFactoryBean.java deleted file mode 100644 index 1d6db6c820fb..000000000000 --- a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/TimerManagerFactoryBean.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.commonj; - -import java.util.ArrayList; -import java.util.List; - -import javax.naming.NamingException; - -import commonj.timers.Timer; -import commonj.timers.TimerManager; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.Lifecycle; -import org.springframework.lang.Nullable; - -/** - * {@link org.springframework.beans.factory.FactoryBean} that retrieves a - * CommonJ {@link commonj.timers.TimerManager} and exposes it for bean references. - * - *

    This is the central convenience class for setting up a - * CommonJ TimerManager in a Spring context. - * - *

    Allows for registration of ScheduledTimerListeners. This is the main - * purpose of this class; the TimerManager itself could also be fetched - * from JNDI via {@link org.springframework.jndi.JndiObjectFactoryBean}. - * In scenarios that just require static registration of tasks at startup, - * there is no need to access the TimerManager itself in application code. - * - *

    Note that the TimerManager uses a TimerListener instance that is - * shared between repeated executions, in contrast to Quartz which - * instantiates a new Job for each execution. - * - * @author Juergen Hoeller - * @since 2.0 - * @see ScheduledTimerListener - * @see commonj.timers.TimerManager - * @see commonj.timers.TimerListener - * @deprecated as of 5.1, in favor of EE 7's - * {@link org.springframework.scheduling.concurrent.DefaultManagedTaskScheduler} - */ -@Deprecated -public class TimerManagerFactoryBean extends TimerManagerAccessor - implements FactoryBean, InitializingBean, DisposableBean, Lifecycle { - - @Nullable - private ScheduledTimerListener[] scheduledTimerListeners; - - @Nullable - private List timers; - - - /** - * Register a list of ScheduledTimerListener objects with the TimerManager - * that this FactoryBean creates. Depending on each ScheduledTimerListener's settings, - * it will be registered via one of TimerManager's schedule methods. - * @see commonj.timers.TimerManager#schedule(commonj.timers.TimerListener, long) - * @see commonj.timers.TimerManager#schedule(commonj.timers.TimerListener, long, long) - * @see commonj.timers.TimerManager#scheduleAtFixedRate(commonj.timers.TimerListener, long, long) - */ - public void setScheduledTimerListeners(ScheduledTimerListener[] scheduledTimerListeners) { - this.scheduledTimerListeners = scheduledTimerListeners; - } - - - //--------------------------------------------------------------------- - // Implementation of InitializingBean interface - //--------------------------------------------------------------------- - - @Override - public void afterPropertiesSet() throws NamingException { - super.afterPropertiesSet(); - - if (this.scheduledTimerListeners != null) { - this.timers = new ArrayList<>(this.scheduledTimerListeners.length); - TimerManager timerManager = obtainTimerManager(); - for (ScheduledTimerListener scheduledTask : this.scheduledTimerListeners) { - Timer timer; - if (scheduledTask.isOneTimeTask()) { - timer = timerManager.schedule(scheduledTask.getTimerListener(), scheduledTask.getDelay()); - } - else { - if (scheduledTask.isFixedRate()) { - timer = timerManager.scheduleAtFixedRate( - scheduledTask.getTimerListener(), scheduledTask.getDelay(), scheduledTask.getPeriod()); - } - else { - timer = timerManager.schedule( - scheduledTask.getTimerListener(), scheduledTask.getDelay(), scheduledTask.getPeriod()); - } - } - this.timers.add(timer); - } - } - } - - - //--------------------------------------------------------------------- - // Implementation of FactoryBean interface - //--------------------------------------------------------------------- - - @Override - @Nullable - public TimerManager getObject() { - return getTimerManager(); - } - - @Override - public Class getObjectType() { - TimerManager timerManager = getTimerManager(); - return (timerManager != null ? timerManager.getClass() : TimerManager.class); - } - - @Override - public boolean isSingleton() { - return true; - } - - - //--------------------------------------------------------------------- - // Implementation of DisposableBean interface - //--------------------------------------------------------------------- - - /** - * Cancels all statically registered Timers on shutdown, - * and stops the underlying TimerManager (if not shared). - * @see commonj.timers.Timer#cancel() - * @see commonj.timers.TimerManager#stop() - */ - @Override - public void destroy() { - // Cancel all registered timers. - if (this.timers != null) { - for (Timer timer : this.timers) { - try { - timer.cancel(); - } - catch (Throwable ex) { - logger.debug("Could not cancel CommonJ Timer", ex); - } - } - this.timers.clear(); - } - - // Stop the TimerManager itself. - super.destroy(); - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/TimerManagerTaskScheduler.java b/spring-context-support/src/main/java/org/springframework/scheduling/commonj/TimerManagerTaskScheduler.java deleted file mode 100644 index 97ea5b86a81d..000000000000 --- a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/TimerManagerTaskScheduler.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.commonj; - -import java.util.Date; -import java.util.concurrent.Delayed; -import java.util.concurrent.FutureTask; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import commonj.timers.Timer; -import commonj.timers.TimerListener; - -import org.springframework.lang.Nullable; -import org.springframework.scheduling.TaskScheduler; -import org.springframework.scheduling.Trigger; -import org.springframework.scheduling.support.SimpleTriggerContext; -import org.springframework.scheduling.support.TaskUtils; -import org.springframework.util.Assert; -import org.springframework.util.ErrorHandler; - -/** - * Implementation of Spring's {@link TaskScheduler} interface, wrapping - * a CommonJ {@link commonj.timers.TimerManager}. - * - * @author Juergen Hoeller - * @author Mark Fisher - * @since 3.0 - * @deprecated as of 5.1, in favor of EE 7's - * {@link org.springframework.scheduling.concurrent.DefaultManagedTaskScheduler} - */ -@Deprecated -public class TimerManagerTaskScheduler extends TimerManagerAccessor implements TaskScheduler { - - @Nullable - private volatile ErrorHandler errorHandler; - - - /** - * Provide an {@link ErrorHandler} strategy. - */ - public void setErrorHandler(ErrorHandler errorHandler) { - this.errorHandler = errorHandler; - } - - - @Override - @Nullable - public ScheduledFuture schedule(Runnable task, Trigger trigger) { - return new ReschedulingTimerListener(errorHandlingTask(task, true), trigger).schedule(); - } - - @Override - public ScheduledFuture schedule(Runnable task, Date startTime) { - TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, false)); - Timer timer = obtainTimerManager().schedule(futureTask, startTime); - futureTask.setTimer(timer); - return futureTask; - } - - @Override - public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) { - TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true)); - Timer timer = obtainTimerManager().scheduleAtFixedRate(futureTask, startTime, period); - futureTask.setTimer(timer); - return futureTask; - } - - @Override - public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) { - TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true)); - Timer timer = obtainTimerManager().scheduleAtFixedRate(futureTask, 0, period); - futureTask.setTimer(timer); - return futureTask; - } - - @Override - public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) { - TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true)); - Timer timer = obtainTimerManager().schedule(futureTask, startTime, delay); - futureTask.setTimer(timer); - return futureTask; - } - - @Override - public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) { - TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true)); - Timer timer = obtainTimerManager().schedule(futureTask, 0, delay); - futureTask.setTimer(timer); - return futureTask; - } - - private Runnable errorHandlingTask(Runnable delegate, boolean isRepeatingTask) { - return TaskUtils.decorateTaskWithErrorHandler(delegate, this.errorHandler, isRepeatingTask); - } - - - /** - * ScheduledFuture adapter that wraps a CommonJ Timer. - */ - private static class TimerScheduledFuture extends FutureTask implements TimerListener, ScheduledFuture { - - @Nullable - protected transient Timer timer; - - protected transient boolean cancelled = false; - - public TimerScheduledFuture(Runnable runnable) { - super(runnable, null); - } - - public void setTimer(Timer timer) { - this.timer = timer; - } - - @Override - public void timerExpired(Timer timer) { - runAndReset(); - } - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - boolean result = super.cancel(mayInterruptIfRunning); - if (this.timer != null) { - this.timer.cancel(); - } - this.cancelled = true; - return result; - } - - @Override - public long getDelay(TimeUnit unit) { - Assert.state(this.timer != null, "No Timer available"); - return unit.convert(this.timer.getScheduledExecutionTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS); - } - - @Override - public int compareTo(Delayed other) { - if (this == other) { - return 0; - } - long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS); - return (diff == 0 ? 0 : ((diff < 0) ? -1 : 1)); - } - } - - - /** - * ScheduledFuture adapter for trigger-based rescheduling. - */ - private class ReschedulingTimerListener extends TimerScheduledFuture { - - private final Trigger trigger; - - private final SimpleTriggerContext triggerContext = new SimpleTriggerContext(); - - private volatile Date scheduledExecutionTime = new Date(); - - public ReschedulingTimerListener(Runnable runnable, Trigger trigger) { - super(runnable); - this.trigger = trigger; - } - - @Nullable - public ScheduledFuture schedule() { - Date nextExecutionTime = this.trigger.nextExecutionTime(this.triggerContext); - if (nextExecutionTime == null) { - return null; - } - this.scheduledExecutionTime = nextExecutionTime; - setTimer(obtainTimerManager().schedule(this, this.scheduledExecutionTime)); - return this; - } - - @Override - public void timerExpired(Timer timer) { - Date actualExecutionTime = new Date(); - super.timerExpired(timer); - Date completionTime = new Date(); - this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime); - if (!this.cancelled) { - schedule(); - } - } - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/WorkManagerTaskExecutor.java b/spring-context-support/src/main/java/org/springframework/scheduling/commonj/WorkManagerTaskExecutor.java deleted file mode 100644 index a9adcc823d5a..000000000000 --- a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/WorkManagerTaskExecutor.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.commonj; - -import java.util.Collection; -import java.util.concurrent.Callable; -import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; - -import javax.naming.NamingException; - -import commonj.work.Work; -import commonj.work.WorkException; -import commonj.work.WorkItem; -import commonj.work.WorkListener; -import commonj.work.WorkManager; -import commonj.work.WorkRejectedException; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.task.AsyncListenableTaskExecutor; -import org.springframework.core.task.TaskDecorator; -import org.springframework.core.task.TaskRejectedException; -import org.springframework.jndi.JndiLocatorSupport; -import org.springframework.lang.Nullable; -import org.springframework.scheduling.SchedulingException; -import org.springframework.scheduling.SchedulingTaskExecutor; -import org.springframework.util.Assert; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureTask; - -/** - * TaskExecutor implementation that delegates to a CommonJ WorkManager, - * implementing the {@link commonj.work.WorkManager} interface, - * which either needs to be specified as reference or through the JNDI name. - * - *

    This is the central convenience class for setting up a - * CommonJ WorkManager in a Spring context. - * - *

    Also implements the CommonJ WorkManager interface itself, delegating all - * calls to the target WorkManager. Hence, a caller can choose whether it wants - * to talk to this executor through the Spring TaskExecutor interface or the - * CommonJ WorkManager interface. - * - *

    The CommonJ WorkManager will usually be retrieved from the application - * server's JNDI environment, as defined in the server's management console. - * - *

    Note: On EE 7/8 compliant versions of WebLogic and WebSphere, a - * {@link org.springframework.scheduling.concurrent.DefaultManagedTaskExecutor} - * should be preferred, following JSR-236 support in Java EE 7/8. - * - * @author Juergen Hoeller - * @since 2.0 - * @deprecated as of 5.1, in favor of the EE 7/8 based - * {@link org.springframework.scheduling.concurrent.DefaultManagedTaskExecutor} - */ -@Deprecated -public class WorkManagerTaskExecutor extends JndiLocatorSupport - implements AsyncListenableTaskExecutor, SchedulingTaskExecutor, WorkManager, InitializingBean { - - @Nullable - private WorkManager workManager; - - @Nullable - private String workManagerName; - - @Nullable - private WorkListener workListener; - - @Nullable - private TaskDecorator taskDecorator; - - - /** - * Specify the CommonJ WorkManager to delegate to. - *

    Alternatively, you can also specify the JNDI name of the target WorkManager. - * @see #setWorkManagerName - */ - public void setWorkManager(WorkManager workManager) { - this.workManager = workManager; - } - - /** - * Set the JNDI name of the CommonJ WorkManager. - *

    This can either be a fully qualified JNDI name, or the JNDI name relative - * to the current environment naming context if "resourceRef" is set to "true". - * @see #setWorkManager - * @see #setResourceRef - */ - public void setWorkManagerName(String workManagerName) { - this.workManagerName = workManagerName; - } - - /** - * Specify a CommonJ WorkListener to apply, if any. - *

    This shared WorkListener instance will be passed on to the - * WorkManager by all {@link #execute} calls on this TaskExecutor. - */ - public void setWorkListener(WorkListener workListener) { - this.workListener = workListener; - } - - /** - * Specify a custom {@link TaskDecorator} to be applied to any {@link Runnable} - * about to be executed. - *

    Note that such a decorator is not necessarily being applied to the - * user-supplied {@code Runnable}/{@code Callable} but rather to the actual - * execution callback (which may be a wrapper around the user-supplied task). - *

    The primary use case is to set some execution context around the task's - * invocation, or to provide some monitoring/statistics for task execution. - *

    NOTE: Exception handling in {@code TaskDecorator} implementations - * is limited to plain {@code Runnable} execution via {@code execute} calls. - * In case of {@code #submit} calls, the exposed {@code Runnable} will be a - * {@code FutureTask} which does not propagate any exceptions; you might - * have to cast it and call {@code Future#get} to evaluate exceptions. - * @since 4.3 - */ - public void setTaskDecorator(TaskDecorator taskDecorator) { - this.taskDecorator = taskDecorator; - } - - @Override - public void afterPropertiesSet() throws NamingException { - if (this.workManager == null) { - if (this.workManagerName == null) { - throw new IllegalArgumentException("Either 'workManager' or 'workManagerName' must be specified"); - } - this.workManager = lookup(this.workManagerName, WorkManager.class); - } - } - - private WorkManager obtainWorkManager() { - Assert.state(this.workManager != null, "No WorkManager specified"); - return this.workManager; - } - - - //------------------------------------------------------------------------- - // Implementation of the Spring SchedulingTaskExecutor interface - //------------------------------------------------------------------------- - - @Override - public void execute(Runnable task) { - Work work = new DelegatingWork(this.taskDecorator != null ? this.taskDecorator.decorate(task) : task); - try { - if (this.workListener != null) { - obtainWorkManager().schedule(work, this.workListener); - } - else { - obtainWorkManager().schedule(work); - } - } - catch (WorkRejectedException ex) { - throw new TaskRejectedException("CommonJ WorkManager did not accept task: " + task, ex); - } - catch (WorkException ex) { - throw new SchedulingException("Could not schedule task on CommonJ WorkManager", ex); - } - } - - @Override - public void execute(Runnable task, long startTimeout) { - execute(task); - } - - @Override - public Future submit(Runnable task) { - FutureTask future = new FutureTask<>(task, null); - execute(future); - return future; - } - - @Override - public Future submit(Callable task) { - FutureTask future = new FutureTask<>(task); - execute(future); - return future; - } - - @Override - public ListenableFuture submitListenable(Runnable task) { - ListenableFutureTask future = new ListenableFutureTask<>(task, null); - execute(future); - return future; - } - - @Override - public ListenableFuture submitListenable(Callable task) { - ListenableFutureTask future = new ListenableFutureTask<>(task); - execute(future); - return future; - } - - - //------------------------------------------------------------------------- - // Implementation of the CommonJ WorkManager interface - //------------------------------------------------------------------------- - - @Override - public WorkItem schedule(Work work) throws WorkException, IllegalArgumentException { - return obtainWorkManager().schedule(work); - } - - @Override - public WorkItem schedule(Work work, WorkListener workListener) throws WorkException { - return obtainWorkManager().schedule(work, workListener); - } - - @Override - @SuppressWarnings("rawtypes") - public boolean waitForAll(Collection workItems, long timeout) throws InterruptedException { - return obtainWorkManager().waitForAll(workItems, timeout); - } - - @Override - @SuppressWarnings("rawtypes") - public Collection waitForAny(Collection workItems, long timeout) throws InterruptedException { - return obtainWorkManager().waitForAny(workItems, timeout); - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/package-info.java b/spring-context-support/src/main/java/org/springframework/scheduling/commonj/package-info.java deleted file mode 100644 index ca0fbead6816..000000000000 --- a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Convenience classes for scheduling based on the CommonJ WorkManager/TimerManager - * facility, as supported by IBM WebSphere 6.0+ and BEA WebLogic 9.0+. - */ -@NonNullApi -@NonNullFields -package org.springframework.scheduling.commonj; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheCacheManagerTests.java b/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheCacheManagerTests.java deleted file mode 100644 index fd33777c4bbf..000000000000 --- a/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheCacheManagerTests.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.ehcache; - -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.config.CacheConfiguration; -import net.sf.ehcache.config.Configuration; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; - -import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManagerTests; - -/** - * @author Stephane Nicoll - */ -public class EhCacheCacheManagerTests extends AbstractTransactionSupportingCacheManagerTests { - - private CacheManager nativeCacheManager; - - private EhCacheCacheManager cacheManager; - - private EhCacheCacheManager transactionalCacheManager; - - - @BeforeEach - public void setup() { - nativeCacheManager = new CacheManager(new Configuration().name("EhCacheCacheManagerTests") - .defaultCache(new CacheConfiguration("default", 100))); - addNativeCache(CACHE_NAME); - - cacheManager = new EhCacheCacheManager(nativeCacheManager); - cacheManager.setTransactionAware(false); - cacheManager.afterPropertiesSet(); - - transactionalCacheManager = new EhCacheCacheManager(nativeCacheManager); - transactionalCacheManager.setTransactionAware(true); - transactionalCacheManager.afterPropertiesSet(); - } - - @AfterEach - public void shutdown() { - nativeCacheManager.shutdown(); - } - - - @Override - protected EhCacheCacheManager getCacheManager(boolean transactionAware) { - if (transactionAware) { - return transactionalCacheManager; - } - else { - return cacheManager; - } - } - - @Override - protected Class getCacheType() { - return EhCacheCache.class; - } - - @Override - protected void addNativeCache(String cacheName) { - nativeCacheManager.addCache(cacheName); - } - - @Override - protected void removeNativeCache(String cacheName) { - nativeCacheManager.removeCache(cacheName); - } - -} diff --git a/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java b/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java deleted file mode 100644 index b9bb1cc8542a..000000000000 --- a/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.ehcache; - -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.Ehcache; -import net.sf.ehcache.Element; -import net.sf.ehcache.config.CacheConfiguration; -import net.sf.ehcache.config.Configuration; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.context.testfixture.cache.AbstractCacheTests; -import org.springframework.core.testfixture.EnabledForTestGroups; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING; - -/** - * @author Costin Leau - * @author Stephane Nicoll - * @author Juergen Hoeller - */ -public class EhCacheCacheTests extends AbstractCacheTests { - - private CacheManager cacheManager; - - private Ehcache nativeCache; - - private EhCacheCache cache; - - - @BeforeEach - public void setup() { - cacheManager = new CacheManager(new Configuration().name("EhCacheCacheTests") - .defaultCache(new CacheConfiguration("default", 100))); - nativeCache = new net.sf.ehcache.Cache(new CacheConfiguration(CACHE_NAME, 100)); - cacheManager.addCache(nativeCache); - - cache = new EhCacheCache(nativeCache); - } - - @AfterEach - public void shutdown() { - cacheManager.shutdown(); - } - - - @Override - protected EhCacheCache getCache() { - return cache; - } - - @Override - protected Ehcache getNativeCache() { - return nativeCache; - } - - - @Test - @EnabledForTestGroups(LONG_RUNNING) - public void testExpiredElements() throws Exception { - String key = "brancusi"; - String value = "constantin"; - Element brancusi = new Element(key, value); - // ttl = 10s - brancusi.setTimeToLive(3); - nativeCache.put(brancusi); - - assertThat(cache.get(key).get()).isEqualTo(value); - // wait for the entry to expire - Thread.sleep(5 * 1000); - assertThat(cache.get(key)).isNull(); - } - -} diff --git a/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java b/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java deleted file mode 100644 index c663b0fba335..000000000000 --- a/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.ehcache; - -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheException; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.Ehcache; -import net.sf.ehcache.config.CacheConfiguration; -import net.sf.ehcache.constructs.blocking.BlockingCache; -import net.sf.ehcache.constructs.blocking.SelfPopulatingCache; -import net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory; -import net.sf.ehcache.constructs.blocking.UpdatingSelfPopulatingCache; -import org.junit.jupiter.api.Test; - -import org.springframework.core.io.ClassPathResource; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * @author Juergen Hoeller - * @author Dmitriy Kopylenko - * @since 27.09.2004 - */ -public class EhCacheSupportTests { - - @Test - public void testBlankCacheManager() { - EhCacheManagerFactoryBean cacheManagerFb = new EhCacheManagerFactoryBean(); - cacheManagerFb.setCacheManagerName("myCacheManager"); - assertThat(cacheManagerFb.getObjectType()).isEqualTo(CacheManager.class); - assertThat(cacheManagerFb.isSingleton()).as("Singleton property").isTrue(); - cacheManagerFb.afterPropertiesSet(); - try { - CacheManager cm = cacheManagerFb.getObject(); - assertThat(cm.getCacheNames().length == 0).as("Loaded CacheManager with no caches").isTrue(); - Cache myCache1 = cm.getCache("myCache1"); - assertThat(myCache1 == null).as("No myCache1 defined").isTrue(); - } - finally { - cacheManagerFb.destroy(); - } - } - - @Test - public void testCacheManagerConflict() { - EhCacheManagerFactoryBean cacheManagerFb = new EhCacheManagerFactoryBean(); - try { - cacheManagerFb.setCacheManagerName("myCacheManager"); - assertThat(cacheManagerFb.getObjectType()).isEqualTo(CacheManager.class); - assertThat(cacheManagerFb.isSingleton()).as("Singleton property").isTrue(); - cacheManagerFb.afterPropertiesSet(); - CacheManager cm = cacheManagerFb.getObject(); - assertThat(cm.getCacheNames().length == 0).as("Loaded CacheManager with no caches").isTrue(); - Cache myCache1 = cm.getCache("myCache1"); - assertThat(myCache1 == null).as("No myCache1 defined").isTrue(); - - EhCacheManagerFactoryBean cacheManagerFb2 = new EhCacheManagerFactoryBean(); - cacheManagerFb2.setCacheManagerName("myCacheManager"); - assertThatExceptionOfType(CacheException.class).as("because of naming conflict").isThrownBy( - cacheManagerFb2::afterPropertiesSet); - } - finally { - cacheManagerFb.destroy(); - } - } - - @Test - public void testAcceptExistingCacheManager() { - EhCacheManagerFactoryBean cacheManagerFb = new EhCacheManagerFactoryBean(); - cacheManagerFb.setCacheManagerName("myCacheManager"); - assertThat(cacheManagerFb.getObjectType()).isEqualTo(CacheManager.class); - assertThat(cacheManagerFb.isSingleton()).as("Singleton property").isTrue(); - cacheManagerFb.afterPropertiesSet(); - try { - CacheManager cm = cacheManagerFb.getObject(); - assertThat(cm.getCacheNames().length == 0).as("Loaded CacheManager with no caches").isTrue(); - Cache myCache1 = cm.getCache("myCache1"); - assertThat(myCache1 == null).as("No myCache1 defined").isTrue(); - - EhCacheManagerFactoryBean cacheManagerFb2 = new EhCacheManagerFactoryBean(); - cacheManagerFb2.setCacheManagerName("myCacheManager"); - cacheManagerFb2.setAcceptExisting(true); - cacheManagerFb2.afterPropertiesSet(); - CacheManager cm2 = cacheManagerFb2.getObject(); - assertThat(cm2).isSameAs(cm); - cacheManagerFb2.destroy(); - } - finally { - cacheManagerFb.destroy(); - } - } - - public void testCacheManagerFromConfigFile() { - EhCacheManagerFactoryBean cacheManagerFb = new EhCacheManagerFactoryBean(); - cacheManagerFb.setConfigLocation(new ClassPathResource("testEhcache.xml", getClass())); - cacheManagerFb.setCacheManagerName("myCacheManager"); - cacheManagerFb.afterPropertiesSet(); - try { - CacheManager cm = cacheManagerFb.getObject(); - assertThat(cm.getCacheNames().length == 1).as("Correct number of caches loaded").isTrue(); - Cache myCache1 = cm.getCache("myCache1"); - assertThat(myCache1.getCacheConfiguration().isEternal()).as("myCache1 is not eternal").isFalse(); - assertThat(myCache1.getCacheConfiguration().getMaxEntriesLocalHeap() == 300).as("myCache1.maxElements == 300").isTrue(); - } - finally { - cacheManagerFb.destroy(); - } - } - - @Test - public void testEhCacheFactoryBeanWithDefaultCacheManager() { - doTestEhCacheFactoryBean(false); - } - - @Test - public void testEhCacheFactoryBeanWithExplicitCacheManager() { - doTestEhCacheFactoryBean(true); - } - - private void doTestEhCacheFactoryBean(boolean useCacheManagerFb) { - Cache cache; - EhCacheManagerFactoryBean cacheManagerFb = null; - boolean cacheManagerFbInitialized = false; - try { - EhCacheFactoryBean cacheFb = new EhCacheFactoryBean(); - Class objectType = cacheFb.getObjectType(); - assertThat(Ehcache.class.isAssignableFrom(objectType)).isTrue(); - assertThat(cacheFb.isSingleton()).as("Singleton property").isTrue(); - if (useCacheManagerFb) { - cacheManagerFb = new EhCacheManagerFactoryBean(); - cacheManagerFb.setConfigLocation(new ClassPathResource("testEhcache.xml", getClass())); - cacheManagerFb.setCacheManagerName("cache"); - cacheManagerFb.afterPropertiesSet(); - cacheManagerFbInitialized = true; - cacheFb.setCacheManager(cacheManagerFb.getObject()); - } - - cacheFb.setCacheName("myCache1"); - cacheFb.afterPropertiesSet(); - cache = (Cache) cacheFb.getObject(); - Class objectType2 = cacheFb.getObjectType(); - assertThat(objectType2).isSameAs(objectType); - CacheConfiguration config = cache.getCacheConfiguration(); - assertThat(cache.getName()).isEqualTo("myCache1"); - if (useCacheManagerFb){ - assertThat(config.getMaxEntriesLocalHeap()).as("myCache1.maxElements").isEqualTo(300); - } - else { - assertThat(config.getMaxEntriesLocalHeap()).as("myCache1.maxElements").isEqualTo(10000); - } - - // Cache region is not defined. Should create one with default properties. - cacheFb = new EhCacheFactoryBean(); - if (useCacheManagerFb) { - cacheFb.setCacheManager(cacheManagerFb.getObject()); - } - cacheFb.setCacheName("undefinedCache"); - cacheFb.afterPropertiesSet(); - cache = (Cache) cacheFb.getObject(); - config = cache.getCacheConfiguration(); - assertThat(cache.getName()).isEqualTo("undefinedCache"); - assertThat(config.getMaxEntriesLocalHeap() == 10000).as("default maxElements is correct").isTrue(); - assertThat(config.isEternal()).as("default eternal is correct").isFalse(); - assertThat(config.getTimeToLiveSeconds() == 120).as("default timeToLive is correct").isTrue(); - assertThat(config.getTimeToIdleSeconds() == 120).as("default timeToIdle is correct").isTrue(); - assertThat(config.getDiskExpiryThreadIntervalSeconds() == 120).as("default diskExpiryThreadIntervalSeconds is correct").isTrue(); - - // overriding the default properties - cacheFb = new EhCacheFactoryBean(); - if (useCacheManagerFb) { - cacheFb.setCacheManager(cacheManagerFb.getObject()); - } - cacheFb.setBeanName("undefinedCache2"); - cacheFb.setMaxEntriesLocalHeap(5); - cacheFb.setTimeToLive(8); - cacheFb.setTimeToIdle(7); - cacheFb.setDiskExpiryThreadIntervalSeconds(10); - cacheFb.afterPropertiesSet(); - cache = (Cache) cacheFb.getObject(); - config = cache.getCacheConfiguration(); - - assertThat(cache.getName()).isEqualTo("undefinedCache2"); - assertThat(config.getMaxEntriesLocalHeap() == 5).as("overridden maxElements is correct").isTrue(); - assertThat(config.getTimeToLiveSeconds() == 8).as("default timeToLive is correct").isTrue(); - assertThat(config.getTimeToIdleSeconds() == 7).as("default timeToIdle is correct").isTrue(); - assertThat(config.getDiskExpiryThreadIntervalSeconds() == 10).as("overridden diskExpiryThreadIntervalSeconds is correct").isTrue(); - } - finally { - if (cacheManagerFbInitialized) { - cacheManagerFb.destroy(); - } - else { - CacheManager.getInstance().shutdown(); - } - } - } - - @Test - public void testEhCacheFactoryBeanWithBlockingCache() { - EhCacheManagerFactoryBean cacheManagerFb = new EhCacheManagerFactoryBean(); - cacheManagerFb.afterPropertiesSet(); - try { - CacheManager cm = cacheManagerFb.getObject(); - EhCacheFactoryBean cacheFb = new EhCacheFactoryBean(); - cacheFb.setCacheManager(cm); - cacheFb.setCacheName("myCache1"); - cacheFb.setBlocking(true); - assertThat(BlockingCache.class).isEqualTo(cacheFb.getObjectType()); - cacheFb.afterPropertiesSet(); - Ehcache myCache1 = cm.getEhcache("myCache1"); - boolean condition = myCache1 instanceof BlockingCache; - assertThat(condition).isTrue(); - } - finally { - cacheManagerFb.destroy(); - } - } - - @Test - public void testEhCacheFactoryBeanWithSelfPopulatingCache() { - EhCacheManagerFactoryBean cacheManagerFb = new EhCacheManagerFactoryBean(); - cacheManagerFb.afterPropertiesSet(); - try { - CacheManager cm = cacheManagerFb.getObject(); - EhCacheFactoryBean cacheFb = new EhCacheFactoryBean(); - cacheFb.setCacheManager(cm); - cacheFb.setCacheName("myCache1"); - cacheFb.setCacheEntryFactory(key -> key); - assertThat(SelfPopulatingCache.class).isEqualTo(cacheFb.getObjectType()); - cacheFb.afterPropertiesSet(); - Ehcache myCache1 = cm.getEhcache("myCache1"); - boolean condition = myCache1 instanceof SelfPopulatingCache; - assertThat(condition).isTrue(); - assertThat(myCache1.get("myKey1").getObjectValue()).isEqualTo("myKey1"); - } - finally { - cacheManagerFb.destroy(); - } - } - - @Test - public void testEhCacheFactoryBeanWithUpdatingSelfPopulatingCache() { - EhCacheManagerFactoryBean cacheManagerFb = new EhCacheManagerFactoryBean(); - cacheManagerFb.afterPropertiesSet(); - try { - CacheManager cm = cacheManagerFb.getObject(); - EhCacheFactoryBean cacheFb = new EhCacheFactoryBean(); - cacheFb.setCacheManager(cm); - cacheFb.setCacheName("myCache1"); - cacheFb.setCacheEntryFactory(new UpdatingCacheEntryFactory() { - @Override - public Object createEntry(Object key) { - return key; - } - @Override - public void updateEntryValue(Object key, Object value) { - } - }); - assertThat(UpdatingSelfPopulatingCache.class).isEqualTo(cacheFb.getObjectType()); - cacheFb.afterPropertiesSet(); - Ehcache myCache1 = cm.getEhcache("myCache1"); - boolean condition = myCache1 instanceof UpdatingSelfPopulatingCache; - assertThat(condition).isTrue(); - assertThat(myCache1.get("myKey1").getObjectValue()).isEqualTo("myKey1"); - } - finally { - cacheManagerFb.destroy(); - } - } - -} diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCache3AnnotationTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCache3AnnotationTests.java deleted file mode 100644 index 105e4e620995..000000000000 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCache3AnnotationTests.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.jcache; - -import javax.cache.Caching; -import javax.cache.spi.CachingProvider; - -/** - * Just here to be run against EHCache 3, whereas the original JCacheEhCacheAnnotationTests - * runs against EhCache 2.x with the EhCache-JCache add-on. - * - * @author Juergen Hoeller - */ -public class JCacheEhCache3AnnotationTests extends JCacheEhCacheAnnotationTests { - - @Override - protected CachingProvider getCachingProvider() { - return Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider"); - } - -} diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCache3ApiTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCache3ApiTests.java deleted file mode 100644 index 32a2585c9f85..000000000000 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCache3ApiTests.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.jcache; - -import javax.cache.Caching; -import javax.cache.spi.CachingProvider; - -/** - * Just here to be run against EHCache 3, whereas the original JCacheEhCacheAnnotationTests - * runs against EhCache 2.x with the EhCache-JCache add-on. - * - * @author Stephane Nicoll - */ -public class JCacheEhCache3ApiTests extends JCacheEhCacheApiTests { - - @Override - protected CachingProvider getCachingProvider() { - return Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider"); - } - -} diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCacheAnnotationTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCacheAnnotationTests.java index 188cc293c974..88a6ba2cf481 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCacheAnnotationTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCacheAnnotationTests.java @@ -64,7 +64,7 @@ protected ConfigurableApplicationContext getApplicationContext() { } protected CachingProvider getCachingProvider() { - return Caching.getCachingProvider("org.ehcache.jcache.JCacheCachingProvider"); + return Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider"); } @AfterEach diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCacheApiTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCacheApiTests.java index b826e2a3fb37..3f56f2e06c5a 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCacheApiTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/JCacheEhCacheApiTests.java @@ -54,7 +54,7 @@ public void setup() { } protected CachingProvider getCachingProvider() { - return Caching.getCachingProvider("org.ehcache.jcache.JCacheCachingProvider"); + return Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider"); } @AfterEach diff --git a/spring-context-support/src/test/java/org/springframework/mail/javamail/JavaMailSenderTests.java b/spring-context-support/src/test/java/org/springframework/mail/javamail/JavaMailSenderTests.java index 3bd467b9106e..d400341aae43 100644 --- a/spring-context-support/src/test/java/org/springframework/mail/javamail/JavaMailSenderTests.java +++ b/spring-context-support/src/test/java/org/springframework/mail/javamail/JavaMailSenderTests.java @@ -24,18 +24,17 @@ import java.util.List; import java.util.Properties; -import javax.activation.FileTypeMap; -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.NoSuchProviderException; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.URLName; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; - +import jakarta.activation.FileTypeMap; +import jakarta.mail.Address; +import jakarta.mail.Message; +import jakarta.mail.MessagingException; +import jakarta.mail.NoSuchProviderException; +import jakarta.mail.Session; +import jakarta.mail.Transport; +import jakarta.mail.URLName; +import jakarta.mail.internet.AddressException; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeMessage; import org.junit.jupiter.api.Test; import org.springframework.mail.MailParseException; diff --git a/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/BeanValidationPostProcessorTests.java b/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/BeanValidationPostProcessorTests.java deleted file mode 100644 index c5da1e4b1521..000000000000 --- a/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/BeanValidationPostProcessorTests.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation2; - -import javax.annotation.PostConstruct; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.beans.testfixture.beans.TestBean; -import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.validation.beanvalidation.BeanValidationPostProcessor; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * @author Juergen Hoeller - */ -public class BeanValidationPostProcessorTests { - - @Test - public void testNotNullConstraint() { - GenericApplicationContext ac = new GenericApplicationContext(); - ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); - ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); - ac.registerBeanDefinition("bean", new RootBeanDefinition(NotNullConstrainedBean.class)); - assertThatExceptionOfType(BeanCreationException.class) - .isThrownBy(ac::refresh) - .havingRootCause() - .withMessageContainingAll("testBean", "invalid"); - ac.close(); - } - - @Test - public void testNotNullConstraintSatisfied() { - GenericApplicationContext ac = new GenericApplicationContext(); - ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); - ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); - RootBeanDefinition bd = new RootBeanDefinition(NotNullConstrainedBean.class); - bd.getPropertyValues().add("testBean", new TestBean()); - ac.registerBeanDefinition("bean", bd); - ac.refresh(); - ac.close(); - } - - @Test - public void testNotNullConstraintAfterInitialization() { - GenericApplicationContext ac = new GenericApplicationContext(); - RootBeanDefinition bvpp = new RootBeanDefinition(BeanValidationPostProcessor.class); - bvpp.getPropertyValues().add("afterInitialization", true); - ac.registerBeanDefinition("bvpp", bvpp); - ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); - ac.registerBeanDefinition("bean", new RootBeanDefinition(AfterInitConstraintBean.class)); - ac.refresh(); - ac.close(); - } - - @Test - public void testSizeConstraint() { - GenericApplicationContext ac = new GenericApplicationContext(); - ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); - RootBeanDefinition bd = new RootBeanDefinition(NotNullConstrainedBean.class); - bd.getPropertyValues().add("testBean", new TestBean()); - bd.getPropertyValues().add("stringValue", "s"); - ac.registerBeanDefinition("bean", bd); - assertThatExceptionOfType(BeanCreationException.class) - .isThrownBy(ac::refresh) - .havingRootCause() - .withMessageContainingAll("stringValue", "invalid"); - ac.close(); - } - - @Test - public void testSizeConstraintSatisfied() { - GenericApplicationContext ac = new GenericApplicationContext(); - ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); - RootBeanDefinition bd = new RootBeanDefinition(NotNullConstrainedBean.class); - bd.getPropertyValues().add("testBean", new TestBean()); - bd.getPropertyValues().add("stringValue", "ss"); - ac.registerBeanDefinition("bean", bd); - ac.refresh(); - ac.close(); - } - - - public static class NotNullConstrainedBean { - - @NotNull - private TestBean testBean; - - @Size(min = 2) - private String stringValue; - - public TestBean getTestBean() { - return testBean; - } - - public void setTestBean(TestBean testBean) { - this.testBean = testBean; - } - - public String getStringValue() { - return stringValue; - } - - public void setStringValue(String stringValue) { - this.stringValue = stringValue; - } - - @PostConstruct - public void init() { - assertThat(this.testBean).as("Shouldn't be here after constraint checking").isNotNull(); - } - } - - - public static class AfterInitConstraintBean { - - @NotNull - private TestBean testBean; - - public TestBean getTestBean() { - return testBean; - } - - public void setTestBean(TestBean testBean) { - this.testBean = testBean; - } - - @PostConstruct - public void init() { - this.testBean = new TestBean(); - } - } - -} diff --git a/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/MethodValidationTests.java b/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/MethodValidationTests.java deleted file mode 100644 index 763bc156f684..000000000000 --- a/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/MethodValidationTests.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation2; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -import javax.validation.ValidationException; -import javax.validation.Validator; -import javax.validation.constraints.Max; -import javax.validation.constraints.NotNull; -import javax.validation.groups.Default; - -import org.junit.jupiter.api.Test; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.MutablePropertyValues; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; -import org.springframework.context.support.StaticApplicationContext; -import org.springframework.scheduling.annotation.Async; -import org.springframework.scheduling.annotation.AsyncAnnotationAdvisor; -import org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor; -import org.springframework.validation.annotation.Validated; -import org.springframework.validation.beanvalidation.CustomValidatorBean; -import org.springframework.validation.beanvalidation.MethodValidationInterceptor; -import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * @author Juergen Hoeller - */ -public class MethodValidationTests { - - @Test - @SuppressWarnings("unchecked") - public void testMethodValidationInterceptor() { - MyValidBean bean = new MyValidBean(); - ProxyFactory proxyFactory = new ProxyFactory(bean); - proxyFactory.addAdvice(new MethodValidationInterceptor()); - proxyFactory.addAdvisor(new AsyncAnnotationAdvisor()); - doTestProxyValidation((MyValidInterface) proxyFactory.getProxy()); - } - - @Test - @SuppressWarnings("unchecked") - public void testMethodValidationPostProcessor() { - StaticApplicationContext ac = new StaticApplicationContext(); - ac.registerSingleton("mvpp", MethodValidationPostProcessor.class); - MutablePropertyValues pvs = new MutablePropertyValues(); - pvs.add("beforeExistingAdvisors", false); - ac.registerSingleton("aapp", AsyncAnnotationBeanPostProcessor.class, pvs); - ac.registerSingleton("bean", MyValidBean.class); - ac.refresh(); - doTestProxyValidation(ac.getBean("bean", MyValidInterface.class)); - ac.close(); - } - - private void doTestProxyValidation(MyValidInterface proxy) { - assertThat(proxy.myValidMethod("value", 5)).isNotNull(); - assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> - proxy.myValidMethod("value", 15)); - assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> - proxy.myValidMethod(null, 5)); - assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> - proxy.myValidMethod("value", 0)); - proxy.myValidAsyncMethod("value", 5); - assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> - proxy.myValidAsyncMethod("value", 15)); - assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> - proxy.myValidAsyncMethod(null, 5)); - assertThat(proxy.myGenericMethod("myValue")).isEqualTo("myValue"); - assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> - proxy.myGenericMethod(null)); - } - - @Test - public void testLazyValidatorForMethodValidation() { - @SuppressWarnings("resource") - AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext( - LazyMethodValidationConfig.class, CustomValidatorBean.class, - MyValidBean.class, MyValidFactoryBean.class); - ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5)); - } - - @Test - public void testLazyValidatorForMethodValidationWithProxyTargetClass() { - @SuppressWarnings("resource") - AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext( - LazyMethodValidationConfigWithProxyTargetClass.class, CustomValidatorBean.class, - MyValidBean.class, MyValidFactoryBean.class); - ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5)); - } - - - @MyStereotype - public static class MyValidBean implements MyValidInterface { - - @Override - public Object myValidMethod(String arg1, int arg2) { - return (arg2 == 0 ? null : "value"); - } - - @Override - public void myValidAsyncMethod(String arg1, int arg2) { - } - - @Override - public String myGenericMethod(String value) { - return value; - } - } - - - @MyStereotype - public static class MyValidFactoryBean implements FactoryBean, MyValidInterface { - - @Override - public String getObject() { - return null; - } - - @Override - public Class getObjectType() { - return String.class; - } - - @Override - public Object myValidMethod(String arg1, int arg2) { - return (arg2 == 0 ? null : "value"); - } - - @Override - public void myValidAsyncMethod(String arg1, int arg2) { - } - - @Override - public String myGenericMethod(String value) { - return value; - } - } - - - public interface MyValidInterface { - - @NotNull Object myValidMethod(@NotNull(groups = MyGroup.class) String arg1, @Max(10) int arg2); - - @MyValid - @Async void myValidAsyncMethod(@NotNull(groups = OtherGroup.class) String arg1, @Max(10) int arg2); - - T myGenericMethod(@NotNull T value); - } - - - public interface MyGroup { - } - - - public interface OtherGroup { - } - - - @Validated({MyGroup.class, Default.class}) - @Retention(RetentionPolicy.RUNTIME) - public @interface MyStereotype { - } - - - @Validated({OtherGroup.class, Default.class}) - @Retention(RetentionPolicy.RUNTIME) - public @interface MyValid { - } - - - @Configuration - public static class LazyMethodValidationConfig { - - @Bean - public static MethodValidationPostProcessor methodValidationPostProcessor(@Lazy Validator validator) { - MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor(); - postProcessor.setValidator(validator); - return postProcessor; - } - } - - - @Configuration - public static class LazyMethodValidationConfigWithProxyTargetClass { - - @Bean - public static MethodValidationPostProcessor methodValidationPostProcessor(@Lazy Validator validator) { - MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor(); - postProcessor.setValidator(validator); - postProcessor.setProxyTargetClass(true); - return postProcessor; - } - } - -} diff --git a/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/SpringValidatorAdapterTests.java b/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/SpringValidatorAdapterTests.java deleted file mode 100644 index 813111adb05c..000000000000 --- a/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/SpringValidatorAdapterTests.java +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation2; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import javax.validation.Constraint; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; -import javax.validation.ConstraintViolation; -import javax.validation.Payload; -import javax.validation.Valid; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.BeanWrapper; -import org.springframework.beans.BeanWrapperImpl; -import org.springframework.context.support.StaticMessageSource; -import org.springframework.core.testfixture.io.SerializationTestUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.validation.BeanPropertyBindingResult; -import org.springframework.validation.FieldError; -import org.springframework.validation.beanvalidation.SpringValidatorAdapter; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Kazuki Shimizu - * @author Juergen Hoeller - */ -public class SpringValidatorAdapterTests { - - private final Validator nativeValidator = Validation.buildDefaultValidatorFactory().getValidator(); - - private final SpringValidatorAdapter validatorAdapter = new SpringValidatorAdapter(nativeValidator); - - private final StaticMessageSource messageSource = new StaticMessageSource(); - - - @BeforeEach - public void setupSpringValidatorAdapter() { - messageSource.addMessage("Size", Locale.ENGLISH, "Size of {0} must be between {2} and {1}"); - messageSource.addMessage("Same", Locale.ENGLISH, "{2} must be same value as {1}"); - messageSource.addMessage("password", Locale.ENGLISH, "Password"); - messageSource.addMessage("confirmPassword", Locale.ENGLISH, "Password(Confirm)"); - } - - - @Test - public void testUnwrap() { - Validator nativeValidator = validatorAdapter.unwrap(Validator.class); - assertThat(nativeValidator).isSameAs(this.nativeValidator); - } - - @Test // SPR-13406 - public void testNoStringArgumentValue() throws Exception { - TestBean testBean = new TestBean(); - testBean.setPassword("pass"); - testBean.setConfirmPassword("pass"); - - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(testBean, "testBean"); - validatorAdapter.validate(testBean, errors); - - assertThat(errors.getFieldErrorCount("password")).isEqualTo(1); - assertThat(errors.getFieldValue("password")).isEqualTo("pass"); - FieldError error = errors.getFieldError("password"); - assertThat(error).isNotNull(); - assertThat(messageSource.getMessage(error, Locale.ENGLISH)).isEqualTo("Size of Password must be between 8 and 128"); - assertThat(error.contains(ConstraintViolation.class)).isTrue(); - assertThat(error.unwrap(ConstraintViolation.class).getPropertyPath().toString()).isEqualTo("password"); - assertThat(SerializationTestUtils.serializeAndDeserialize(error.toString())).isEqualTo(error.toString()); - } - - @Test // SPR-13406 - public void testApplyMessageSourceResolvableToStringArgumentValueWithResolvedLogicalFieldName() throws Exception { - TestBean testBean = new TestBean(); - testBean.setPassword("password"); - testBean.setConfirmPassword("PASSWORD"); - - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(testBean, "testBean"); - validatorAdapter.validate(testBean, errors); - - assertThat(errors.getFieldErrorCount("password")).isEqualTo(1); - assertThat(errors.getFieldValue("password")).isEqualTo("password"); - FieldError error = errors.getFieldError("password"); - assertThat(error).isNotNull(); - assertThat(messageSource.getMessage(error, Locale.ENGLISH)).isEqualTo("Password must be same value as Password(Confirm)"); - assertThat(error.contains(ConstraintViolation.class)).isTrue(); - assertThat(error.unwrap(ConstraintViolation.class).getPropertyPath().toString()).isEqualTo("password"); - assertThat(SerializationTestUtils.serializeAndDeserialize(error.toString())).isEqualTo(error.toString()); - } - - @Test // SPR-13406 - public void testApplyMessageSourceResolvableToStringArgumentValueWithUnresolvedLogicalFieldName() { - TestBean testBean = new TestBean(); - testBean.setEmail("test@example.com"); - testBean.setConfirmEmail("TEST@EXAMPLE.IO"); - - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(testBean, "testBean"); - validatorAdapter.validate(testBean, errors); - - assertThat(errors.getFieldErrorCount("email")).isEqualTo(1); - assertThat(errors.getFieldValue("email")).isEqualTo("test@example.com"); - assertThat(errors.getFieldErrorCount("confirmEmail")).isEqualTo(1); - FieldError error1 = errors.getFieldError("email"); - FieldError error2 = errors.getFieldError("confirmEmail"); - assertThat(error1).isNotNull(); - assertThat(error2).isNotNull(); - assertThat(messageSource.getMessage(error1, Locale.ENGLISH)).isEqualTo("email must be same value as confirmEmail"); - assertThat(messageSource.getMessage(error2, Locale.ENGLISH)).isEqualTo("Email required"); - assertThat(error1.contains(ConstraintViolation.class)).isTrue(); - assertThat(error1.unwrap(ConstraintViolation.class).getPropertyPath().toString()).isEqualTo("email"); - assertThat(error2.contains(ConstraintViolation.class)).isTrue(); - assertThat(error2.unwrap(ConstraintViolation.class).getPropertyPath().toString()).isEqualTo("confirmEmail"); - } - - @Test // SPR-15123 - public void testApplyMessageSourceResolvableToStringArgumentValueWithAlwaysUseMessageFormat() { - messageSource.setAlwaysUseMessageFormat(true); - - TestBean testBean = new TestBean(); - testBean.setEmail("test@example.com"); - testBean.setConfirmEmail("TEST@EXAMPLE.IO"); - - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(testBean, "testBean"); - validatorAdapter.validate(testBean, errors); - - assertThat(errors.getFieldErrorCount("email")).isEqualTo(1); - assertThat(errors.getFieldValue("email")).isEqualTo("test@example.com"); - assertThat(errors.getFieldErrorCount("confirmEmail")).isEqualTo(1); - FieldError error1 = errors.getFieldError("email"); - FieldError error2 = errors.getFieldError("confirmEmail"); - assertThat(error1).isNotNull(); - assertThat(error2).isNotNull(); - assertThat(messageSource.getMessage(error1, Locale.ENGLISH)).isEqualTo("email must be same value as confirmEmail"); - assertThat(messageSource.getMessage(error2, Locale.ENGLISH)).isEqualTo("Email required"); - assertThat(error1.contains(ConstraintViolation.class)).isTrue(); - assertThat(error1.unwrap(ConstraintViolation.class).getPropertyPath().toString()).isEqualTo("email"); - assertThat(error2.contains(ConstraintViolation.class)).isTrue(); - assertThat(error2.unwrap(ConstraintViolation.class).getPropertyPath().toString()).isEqualTo("confirmEmail"); - } - - @Test - public void testPatternMessage() { - TestBean testBean = new TestBean(); - testBean.setEmail("X"); - testBean.setConfirmEmail("X"); - - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(testBean, "testBean"); - validatorAdapter.validate(testBean, errors); - - assertThat(errors.getFieldErrorCount("email")).isEqualTo(1); - assertThat(errors.getFieldValue("email")).isEqualTo("X"); - FieldError error = errors.getFieldError("email"); - assertThat(error).isNotNull(); - assertThat(messageSource.getMessage(error, Locale.ENGLISH)).contains("[\\w.'-]{1,}@[\\w.'-]{1,}"); - assertThat(error.contains(ConstraintViolation.class)).isTrue(); - assertThat(error.unwrap(ConstraintViolation.class).getPropertyPath().toString()).isEqualTo("email"); - } - - @Test // SPR-16177 - public void testWithList() { - Parent parent = new Parent(); - parent.setName("Parent whit list"); - parent.getChildList().addAll(createChildren(parent)); - - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(parent, "parent"); - validatorAdapter.validate(parent, errors); - - assertThat(errors.getErrorCount() > 0).isTrue(); - } - - @Test // SPR-16177 - public void testWithSet() { - Parent parent = new Parent(); - parent.setName("Parent with set"); - parent.getChildSet().addAll(createChildren(parent)); - - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(parent, "parent"); - validatorAdapter.validate(parent, errors); - - assertThat(errors.getErrorCount() > 0).isTrue(); - } - - private List createChildren(Parent parent) { - Child child1 = new Child(); - child1.setName("Child1"); - child1.setAge(null); - child1.setParent(parent); - - Child child2 = new Child(); - child2.setName(null); - child2.setAge(17); - child2.setParent(parent); - - return Arrays.asList(child1, child2); - } - - @Test // SPR-15839 - public void testListElementConstraint() { - BeanWithListElementConstraint bean = new BeanWithListElementConstraint(); - bean.setProperty(Arrays.asList("no", "element", "can", "be", null)); - - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(bean, "bean"); - validatorAdapter.validate(bean, errors); - - assertThat(errors.getFieldErrorCount("property[4]")).isEqualTo(1); - assertThat(errors.getFieldValue("property[4]")).isNull(); - } - - @Test // SPR-15839 - public void testMapValueConstraint() { - Map property = new HashMap<>(); - property.put("no value can be", null); - - BeanWithMapEntryConstraint bean = new BeanWithMapEntryConstraint(); - bean.setProperty(property); - - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(bean, "bean"); - validatorAdapter.validate(bean, errors); - - assertThat(errors.getFieldErrorCount("property[no value can be]")).isEqualTo(1); - assertThat(errors.getFieldValue("property[no value can be]")).isNull(); - } - - @Test // SPR-15839 - public void testMapEntryConstraint() { - Map property = new HashMap<>(); - property.put(null, null); - - BeanWithMapEntryConstraint bean = new BeanWithMapEntryConstraint(); - bean.setProperty(property); - - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(bean, "bean"); - validatorAdapter.validate(bean, errors); - - assertThat(errors.hasFieldErrors("property[]")).isTrue(); - assertThat(errors.getFieldValue("property[]")).isNull(); - } - - - @Same(field = "password", comparingField = "confirmPassword") - @Same(field = "email", comparingField = "confirmEmail") - static class TestBean { - - @Size(min = 8, max = 128) - private String password; - - private String confirmPassword; - - @Pattern(regexp = "[\\w.'-]{1,}@[\\w.'-]{1,}") - private String email; - - @Pattern(regexp = "[\\p{L} -]*", message = "Email required") - private String confirmEmail; - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getConfirmPassword() { - return confirmPassword; - } - - public void setConfirmPassword(String confirmPassword) { - this.confirmPassword = confirmPassword; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getConfirmEmail() { - return confirmEmail; - } - - public void setConfirmEmail(String confirmEmail) { - this.confirmEmail = confirmEmail; - } - } - - - @Documented - @Constraint(validatedBy = {SameValidator.class}) - @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) - @Retention(RetentionPolicy.RUNTIME) - @Repeatable(SameGroup.class) - @interface Same { - - String message() default "{org.springframework.validation.beanvalidation.Same.message}"; - - Class[] groups() default {}; - - Class[] payload() default {}; - - String field(); - - String comparingField(); - - @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @interface List { - Same[] value(); - } - } - - - @Documented - @Inherited - @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) - @Retention(RetentionPolicy.RUNTIME) - @interface SameGroup { - - Same[] value(); - } - - - public static class SameValidator implements ConstraintValidator { - - private String field; - - private String comparingField; - - private String message; - - @Override - public void initialize(Same constraintAnnotation) { - field = constraintAnnotation.field(); - comparingField = constraintAnnotation.comparingField(); - message = constraintAnnotation.message(); - } - - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { - BeanWrapper beanWrapper = new BeanWrapperImpl(value); - Object fieldValue = beanWrapper.getPropertyValue(field); - Object comparingFieldValue = beanWrapper.getPropertyValue(comparingField); - boolean matched = ObjectUtils.nullSafeEquals(fieldValue, comparingFieldValue); - if (matched) { - return true; - } - else { - context.disableDefaultConstraintViolation(); - context.buildConstraintViolationWithTemplate(message) - .addPropertyNode(field) - .addConstraintViolation(); - return false; - } - } - } - - - public static class Parent { - - private Integer id; - - @NotNull - private String name; - - @Valid - private Set childSet = new LinkedHashSet<>(); - - @Valid - private List childList = new ArrayList<>(); - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Set getChildSet() { - return childSet; - } - - public void setChildSet(Set childSet) { - this.childSet = childSet; - } - - public List getChildList() { - return childList; - } - - public void setChildList(List childList) { - this.childList = childList; - } - } - - - @AnythingValid - public static class Child { - - private Integer id; - - @NotNull - private String name; - - @NotNull - private Integer age; - - @NotNull - private Parent parent; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Integer getAge() { - return age; - } - - public void setAge(Integer age) { - this.age = age; - } - - public Parent getParent() { - return parent; - } - - public void setParent(Parent parent) { - this.parent = parent; - } - } - - - @Constraint(validatedBy = AnythingValidator.class) - @Retention(RetentionPolicy.RUNTIME) - public @interface AnythingValid { - - String message() default "{AnythingValid.message}"; - - Class[] groups() default {}; - - Class[] payload() default {}; - } - - - public static class AnythingValidator implements ConstraintValidator { - - private static final String ID = "id"; - - @Override - public void initialize(AnythingValid constraintAnnotation) { - } - - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { - List fieldsErrors = new ArrayList<>(); - Arrays.asList(value.getClass().getDeclaredFields()).forEach(field -> { - field.setAccessible(true); - try { - if (!field.getName().equals(ID) && field.get(value) == null) { - fieldsErrors.add(field); - context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()) - .addPropertyNode(field.getName()) - .addConstraintViolation(); - } - } - catch (IllegalAccessException ex) { - throw new IllegalStateException(ex); - } - }); - return fieldsErrors.isEmpty(); - } - } - - - public class BeanWithListElementConstraint { - - @Valid - private List<@NotNull String> property; - - public List getProperty() { - return property; - } - - public void setProperty(List property) { - this.property = property; - } - } - - - public class BeanWithMapEntryConstraint { - - @Valid - private Map<@NotNull String, @NotNull String> property; - - public Map getProperty() { - return property; - } - - public void setProperty(Map property) { - this.property = property; - } - } - -} diff --git a/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/ValidatorFactoryTests.java b/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/ValidatorFactoryTests.java deleted file mode 100644 index a383ae5f8bf7..000000000000 --- a/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/ValidatorFactoryTests.java +++ /dev/null @@ -1,505 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation2; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import javax.validation.Constraint; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; -import javax.validation.ConstraintViolation; -import javax.validation.Payload; -import javax.validation.Valid; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; -import javax.validation.constraints.NotNull; - -import org.hibernate.validator.HibernateValidator; -import org.hibernate.validator.HibernateValidatorFactory; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.core.convert.support.DefaultConversionService; -import org.springframework.core.env.Environment; -import org.springframework.validation.BeanPropertyBindingResult; -import org.springframework.validation.Errors; -import org.springframework.validation.FieldError; -import org.springframework.validation.ObjectError; -import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Juergen Hoeller - */ -@SuppressWarnings("resource") -public class ValidatorFactoryTests { - - @Test - @SuppressWarnings("cast") - public void testSimpleValidation() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - Set> result = validator.validate(person); - assertThat(result.size()).isEqualTo(2); - for (ConstraintViolation cv : result) { - String path = cv.getPropertyPath().toString(); - assertThat(path).matches(actual -> "name".equals(actual) || "address.street".equals(actual)); - assertThat(cv.getConstraintDescriptor().getAnnotation()).isInstanceOf(NotNull.class); - } - - Validator nativeValidator = validator.unwrap(Validator.class); - assertThat(nativeValidator.getClass().getName().startsWith("org.hibernate")).isTrue(); - assertThat(validator.unwrap(ValidatorFactory.class) instanceof HibernateValidatorFactory).isTrue(); - assertThat(validator.unwrap(HibernateValidatorFactory.class) instanceof HibernateValidatorFactory).isTrue(); - - validator.destroy(); - } - - @Test - @SuppressWarnings("cast") - public void testSimpleValidationWithCustomProvider() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.setProviderClass(HibernateValidator.class); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - Set> result = validator.validate(person); - assertThat(result.size()).isEqualTo(2); - for (ConstraintViolation cv : result) { - String path = cv.getPropertyPath().toString(); - assertThat(path).matches(actual -> "name".equals(actual) || "address.street".equals(actual)); - assertThat(cv.getConstraintDescriptor().getAnnotation()).isInstanceOf(NotNull.class); - } - - Validator nativeValidator = validator.unwrap(Validator.class); - assertThat(nativeValidator.getClass().getName().startsWith("org.hibernate")).isTrue(); - assertThat(validator.unwrap(ValidatorFactory.class) instanceof HibernateValidatorFactory).isTrue(); - assertThat(validator.unwrap(HibernateValidatorFactory.class) instanceof HibernateValidatorFactory).isTrue(); - - validator.destroy(); - } - - @Test - public void testSimpleValidationWithClassLevel() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - person.setName("Juergen"); - person.getAddress().setStreet("Juergen's Street"); - Set> result = validator.validate(person); - assertThat(result.size()).isEqualTo(1); - Iterator> iterator = result.iterator(); - ConstraintViolation cv = iterator.next(); - assertThat(cv.getPropertyPath().toString()).isEqualTo(""); - assertThat(cv.getConstraintDescriptor().getAnnotation() instanceof NameAddressValid).isTrue(); - } - - @Test - public void testSpringValidationFieldType() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - person.setName("Phil"); - person.getAddress().setStreet("Phil's Street"); - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, errors); - assertThat(errors.getErrorCount()).isEqualTo(1); - assertThat(errors.getFieldError("address").getRejectedValue()).isInstanceOf(ValidAddress.class); - } - - @Test - public void testSpringValidation() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertThat(result.getErrorCount()).isEqualTo(2); - FieldError fieldError = result.getFieldError("name"); - assertThat(fieldError.getField()).isEqualTo("name"); - List errorCodes = Arrays.asList(fieldError.getCodes()); - assertThat(errorCodes.size()).isEqualTo(4); - assertThat(errorCodes.contains("NotNull.person.name")).isTrue(); - assertThat(errorCodes.contains("NotNull.name")).isTrue(); - assertThat(errorCodes.contains("NotNull.java.lang.String")).isTrue(); - assertThat(errorCodes.contains("NotNull")).isTrue(); - fieldError = result.getFieldError("address.street"); - assertThat(fieldError.getField()).isEqualTo("address.street"); - errorCodes = Arrays.asList(fieldError.getCodes()); - assertThat(errorCodes.size()).isEqualTo(5); - assertThat(errorCodes.contains("NotNull.person.address.street")).isTrue(); - assertThat(errorCodes.contains("NotNull.address.street")).isTrue(); - assertThat(errorCodes.contains("NotNull.street")).isTrue(); - assertThat(errorCodes.contains("NotNull.java.lang.String")).isTrue(); - assertThat(errorCodes.contains("NotNull")).isTrue(); - } - - @Test - public void testSpringValidationWithClassLevel() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - person.setName("Juergen"); - person.getAddress().setStreet("Juergen's Street"); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertThat(result.getErrorCount()).isEqualTo(1); - ObjectError globalError = result.getGlobalError(); - List errorCodes = Arrays.asList(globalError.getCodes()); - assertThat(errorCodes.size()).isEqualTo(2); - assertThat(errorCodes.contains("NameAddressValid.person")).isTrue(); - assertThat(errorCodes.contains("NameAddressValid")).isTrue(); - } - - @Test - public void testSpringValidationWithAutowiredValidator() { - ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext( - LocalValidatorFactoryBean.class); - LocalValidatorFactoryBean validator = ctx.getBean(LocalValidatorFactoryBean.class); - - ValidPerson person = new ValidPerson(); - person.expectsAutowiredValidator = true; - person.setName("Juergen"); - person.getAddress().setStreet("Juergen's Street"); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertThat(result.getErrorCount()).isEqualTo(1); - ObjectError globalError = result.getGlobalError(); - List errorCodes = Arrays.asList(globalError.getCodes()); - assertThat(errorCodes.size()).isEqualTo(2); - assertThat(errorCodes.contains("NameAddressValid.person")).isTrue(); - assertThat(errorCodes.contains("NameAddressValid")).isTrue(); - ctx.close(); - } - - @Test - public void testSpringValidationWithErrorInListElement() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - person.getAddressList().add(new ValidAddress()); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertThat(result.getErrorCount()).isEqualTo(3); - FieldError fieldError = result.getFieldError("name"); - assertThat(fieldError.getField()).isEqualTo("name"); - fieldError = result.getFieldError("address.street"); - assertThat(fieldError.getField()).isEqualTo("address.street"); - fieldError = result.getFieldError("addressList[0].street"); - assertThat(fieldError.getField()).isEqualTo("addressList[0].street"); - } - - @Test - public void testSpringValidationWithErrorInSetElement() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ValidPerson person = new ValidPerson(); - person.getAddressSet().add(new ValidAddress()); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertThat(result.getErrorCount()).isEqualTo(3); - FieldError fieldError = result.getFieldError("name"); - assertThat(fieldError.getField()).isEqualTo("name"); - fieldError = result.getFieldError("address.street"); - assertThat(fieldError.getField()).isEqualTo("address.street"); - fieldError = result.getFieldError("addressSet[].street"); - assertThat(fieldError.getField()).isEqualTo("addressSet[].street"); - } - - @Test - public void testInnerBeanValidation() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - MainBean mainBean = new MainBean(); - Errors errors = new BeanPropertyBindingResult(mainBean, "mainBean"); - validator.validate(mainBean, errors); - Object rejected = errors.getFieldValue("inner.value"); - assertThat(rejected).isNull(); - } - - @Test - public void testValidationWithOptionalField() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - MainBeanWithOptional mainBean = new MainBeanWithOptional(); - Errors errors = new BeanPropertyBindingResult(mainBean, "mainBean"); - validator.validate(mainBean, errors); - Object rejected = errors.getFieldValue("inner.value"); - assertThat(rejected).isNull(); - } - - @Test - public void testListValidation() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - - ListContainer listContainer = new ListContainer(); - listContainer.addString("A"); - listContainer.addString("X"); - - BeanPropertyBindingResult errors = new BeanPropertyBindingResult(listContainer, "listContainer"); - errors.initConversion(new DefaultConversionService()); - validator.validate(listContainer, errors); - - FieldError fieldError = errors.getFieldError("list[1]"); - assertThat(fieldError).isNotNull(); - assertThat(fieldError.getRejectedValue()).isEqualTo("X"); - assertThat(errors.getFieldValue("list[1]")).isEqualTo("X"); - } - - - @NameAddressValid - public static class ValidPerson { - - @NotNull - private String name; - - @Valid - private ValidAddress address = new ValidAddress(); - - @Valid - private List addressList = new ArrayList<>(); - - @Valid - private Set addressSet = new LinkedHashSet<>(); - - public boolean expectsAutowiredValidator = false; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public ValidAddress getAddress() { - return address; - } - - public void setAddress(ValidAddress address) { - this.address = address; - } - - public List getAddressList() { - return addressList; - } - - public void setAddressList(List addressList) { - this.addressList = addressList; - } - - public Set getAddressSet() { - return addressSet; - } - - public void setAddressSet(Set addressSet) { - this.addressSet = addressSet; - } - } - - - public static class ValidAddress { - - @NotNull - private String street; - - public String getStreet() { - return street; - } - - public void setStreet(String street) { - this.street = street; - } - } - - - @Target(ElementType.TYPE) - @Retention(RetentionPolicy.RUNTIME) - @Constraint(validatedBy = NameAddressValidator.class) - public @interface NameAddressValid { - - String message() default "Street must not contain name"; - - Class[] groups() default {}; - - Class[] payload() default {}; - } - - - public static class NameAddressValidator implements ConstraintValidator { - - @Autowired - private Environment environment; - - @Override - public void initialize(NameAddressValid constraintAnnotation) { - } - - @Override - public boolean isValid(ValidPerson value, ConstraintValidatorContext context) { - if (value.expectsAutowiredValidator) { - assertThat(this.environment).isNotNull(); - } - boolean valid = (value.name == null || !value.address.street.contains(value.name)); - if (!valid && "Phil".equals(value.name)) { - context.buildConstraintViolationWithTemplate( - context.getDefaultConstraintMessageTemplate()).addPropertyNode("address").addConstraintViolation().disableDefaultConstraintViolation(); - } - return valid; - } - } - - - public static class MainBean { - - @InnerValid - private InnerBean inner = new InnerBean(); - - public InnerBean getInner() { - return inner; - } - } - - - public static class MainBeanWithOptional { - - @InnerValid - private InnerBean inner = new InnerBean(); - - public Optional getInner() { - return Optional.ofNullable(inner); - } - } - - - public static class InnerBean { - - private String value; - - public String getValue() { - return value; - } - public void setValue(String value) { - this.value = value; - } - } - - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - @Constraint(validatedBy=InnerValidator.class) - public static @interface InnerValid { - - String message() default "NOT VALID"; - - Class[] groups() default { }; - - Class[] payload() default {}; - } - - - public static class InnerValidator implements ConstraintValidator { - - @Override - public void initialize(InnerValid constraintAnnotation) { - } - - @Override - public boolean isValid(InnerBean bean, ConstraintValidatorContext context) { - context.disableDefaultConstraintViolation(); - if (bean.getValue() == null) { - context.buildConstraintViolationWithTemplate("NULL").addPropertyNode("value").addConstraintViolation(); - return false; - } - return true; - } - } - - - public static class ListContainer { - - @NotXList - private List list = new ArrayList<>(); - - public void addString(String value) { - list.add(value); - } - - public List getList() { - return list; - } - } - - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - @Constraint(validatedBy = NotXListValidator.class) - public @interface NotXList { - - String message() default "Should not be X"; - - Class[] groups() default {}; - - Class[] payload() default {}; - } - - - public static class NotXListValidator implements ConstraintValidator> { - - @Override - public void initialize(NotXList constraintAnnotation) { - } - - @Override - public boolean isValid(List list, ConstraintValidatorContext context) { - context.disableDefaultConstraintViolation(); - boolean valid = true; - for (int i = 0; i < list.size(); i++) { - if ("X".equals(list.get(i))) { - context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()).addBeanNode().inIterable().atIndex(i).addConstraintViolation(); - valid = false; - } - } - return valid; - } - } - -} diff --git a/spring-context/spring-context.gradle b/spring-context/spring-context.gradle index 221e0f12fe1a..9e4cf72ca954 100644 --- a/spring-context/spring-context.gradle +++ b/spring-context/spring-context.gradle @@ -9,20 +9,18 @@ dependencies { api(project(":spring-core")) api(project(":spring-expression")) optional(project(":spring-instrument")) - optional("javax.annotation:javax.annotation-api") - optional("javax.ejb:javax.ejb-api") - optional("javax.enterprise.concurrent:javax.enterprise.concurrent-api") - optional("javax.inject:javax.inject") - optional("javax.interceptor:javax.interceptor-api") + optional("jakarta.annotation:jakarta.annotation-api") + optional("jakarta.ejb:jakarta.ejb-api") + optional("jakarta.enterprise.concurrent:jakarta.enterprise.concurrent-api") + optional("jakarta.inject:jakarta.inject-api") + optional("jakarta.interceptor:jakarta.interceptor-api") optional("javax.money:money-api") - // Overriding 2.0.1.Final due to Bean Validation 1.1 compatibility in LocalValidatorFactoryBean - optional("javax.validation:validation-api:1.1.0.Final") - optional("javax.xml.ws:jaxws-api") + optional("jakarta.validation:jakarta.validation-api") + optional("jakarta.xml.ws:jakarta.xml.ws-api") optional("org.aspectj:aspectjweaver") optional("org.codehaus.groovy:groovy") optional("org.apache-extras.beanshell:bsh") - optional("joda-time:joda-time") - optional("org.hibernate:hibernate-validator:5.4.3.Final") + optional("org.hibernate:hibernate-validator") optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") optional("org.reactivestreams:reactive-streams") @@ -34,10 +32,10 @@ dependencies { testImplementation("org.codehaus.groovy:groovy-test") testImplementation("org.codehaus.groovy:groovy-xml") testImplementation("org.apache.commons:commons-pool2") - testImplementation("javax.inject:javax.inject-tck") + testImplementation("jakarta.inject:jakarta.inject-tck") testImplementation("org.awaitility:awaitility") - testRuntimeOnly("javax.xml.bind:jaxb-api") - testRuntimeOnly("org.glassfish:javax.el") + testRuntimeOnly("jakarta.xml.bind:jakarta.xml.bind-api") + testRuntimeOnly("org.glassfish:jakarta.el") // Substitute for javax.management:jmxremote_optional:1.0.1_04 (not available on Maven Central) testRuntimeOnly("org.glassfish.external:opendmk_jmxremote_optional_jar") testRuntimeOnly("org.javamoney:moneta") diff --git a/spring-context/src/jmh/java/org/springframework/context/annotation/AnnotationProcessorBenchmark.java b/spring-context/src/jmh/java/org/springframework/context/annotation/AnnotationProcessorBenchmark.java index c00cf0ddfaec..3e19ca7e9781 100644 --- a/spring-context/src/jmh/java/org/springframework/context/annotation/AnnotationProcessorBenchmark.java +++ b/spring-context/src/jmh/java/org/springframework/context/annotation/AnnotationProcessorBenchmark.java @@ -16,8 +16,7 @@ package org.springframework.context.annotation; -import javax.annotation.Resource; - +import jakarta.annotation.Resource; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java index a589a92335ac..c12647a3ca6c 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java @@ -41,8 +41,8 @@ * {@link org.springframework.stereotype.Repository @Repository}) are * themselves annotated with {@code @Component}. * - *

    Also supports Java EE 6's {@link javax.annotation.ManagedBean} and - * JSR-330's {@link javax.inject.Named} annotations, if available. Note that + *

    Also supports Jakarta EE's {@link jakarta.annotation.ManagedBean} and + * JSR-330's {@link jakarta.inject.Named} annotations, if available. Note that * Spring component annotations always override such standard annotations. * *

    If the annotation's value doesn't indicate a bean name, an appropriate @@ -58,7 +58,7 @@ * @see org.springframework.stereotype.Repository#value() * @see org.springframework.stereotype.Service#value() * @see org.springframework.stereotype.Controller#value() - * @see javax.inject.Named#value() + * @see jakarta.inject.Named#value() * @see FullyQualifiedAnnotationBeanNameGenerator */ public class AnnotationBeanNameGenerator implements BeanNameGenerator { @@ -136,8 +136,8 @@ protected boolean isStereotypeWithNameValue(String annotationType, boolean isStereotype = annotationType.equals(COMPONENT_ANNOTATION_CLASSNAME) || metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME) || - annotationType.equals("javax.annotation.ManagedBean") || - annotationType.equals("javax.inject.Named"); + annotationType.equals("jakarta.annotation.ManagedBean") || + annotationType.equals("jakarta.inject.Named"); return (isStereotype && attributes != null && attributes.containsKey("value")); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigApplicationContext.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigApplicationContext.java index 86ea5feb7335..b2d29bca5592 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigApplicationContext.java @@ -32,7 +32,7 @@ * Standalone application context, accepting component classes as input — * in particular {@link Configuration @Configuration}-annotated classes, but also plain * {@link org.springframework.stereotype.Component @Component} types and JSR-330 compliant - * classes using {@code javax.inject} annotations. + * classes using {@code jakarta.inject} annotations. * *

    Allows for registering classes one by one using {@link #register(Class...)} * as well as for classpath scanning using {@link #scan(String...)}. diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java index 91b1719b7083..9c253124eea9 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java @@ -123,8 +123,8 @@ public abstract class AnnotationConfigUtils { static { ClassLoader classLoader = AnnotationConfigUtils.class.getClassLoader(); - jsr250Present = ClassUtils.isPresent("javax.annotation.Resource", classLoader); - jpaPresent = ClassUtils.isPresent("javax.persistence.EntityManagerFactory", classLoader) && + jsr250Present = ClassUtils.isPresent("jakarta.annotation.Resource", classLoader); + jpaPresent = ClassUtils.isPresent("jakarta.persistence.EntityManagerFactory", classLoader) && ClassUtils.isPresent(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, classLoader); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Bean.java b/spring-context/src/main/java/org/springframework/context/annotation/Bean.java index a723b02c3508..2f254d5a7117 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/Bean.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/Bean.java @@ -99,7 +99,7 @@ *

    NOTE: {@code @Order} values may influence priorities at injection points, * but please be aware that they do not influence singleton startup order which is an * orthogonal concern determined by dependency relationships and {@code @DependsOn} - * declarations as mentioned above. Also, {@link javax.annotation.Priority} is not + * declarations as mentioned above. Also, {@link jakarta.annotation.Priority} is not * available at this level since it cannot be declared on methods; its semantics can * be modeled through {@code @Order} values in combination with {@code @Primary} on * a single bean per type. diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ClassPathBeanDefinitionScanner.java b/spring-context/src/main/java/org/springframework/context/annotation/ClassPathBeanDefinitionScanner.java index 65cbb9bdb9f2..bafdd032f009 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ClassPathBeanDefinitionScanner.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ClassPathBeanDefinitionScanner.java @@ -47,8 +47,8 @@ * {@link org.springframework.stereotype.Service @Service}, or * {@link org.springframework.stereotype.Controller @Controller} stereotype. * - *

    Also supports Java EE 6's {@link javax.annotation.ManagedBean} and - * JSR-330's {@link javax.inject.Named} annotations, if available. + *

    Also supports Jakarta EE's {@link jakarta.annotation.ManagedBean} and + * JSR-330's {@link jakarta.inject.Named} annotations, if available. * * @author Mark Fisher * @author Juergen Hoeller diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java b/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java index 05ea7a5159a5..5be6cb914b44 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java @@ -197,8 +197,8 @@ public void resetFilters(boolean useDefaultFilters) { * {@link Component @Component} meta-annotation including the * {@link Repository @Repository}, {@link Service @Service}, and * {@link Controller @Controller} stereotype annotations. - *

    Also supports Java EE 6's {@link javax.annotation.ManagedBean} and - * JSR-330's {@link javax.inject.Named} annotations, if available. + *

    Also supports Jakarta EE's {@link jakarta.annotation.ManagedBean} and + * JSR-330's {@link jakarta.inject.Named} annotations, if available. * */ @SuppressWarnings("unchecked") @@ -207,16 +207,16 @@ protected void registerDefaultFilters() { ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { this.includeFilters.add(new AnnotationTypeFilter( - ((Class) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false)); - logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning"); + ((Class) ClassUtils.forName("jakarta.annotation.ManagedBean", cl)), false)); + logger.trace("JSR-250 'jakarta.annotation.ManagedBean' found and supported for component scanning"); } catch (ClassNotFoundException ex) { - // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip. + // JSR-250 1.1 API (as included in Jakarta EE) not available - simply skip. } try { this.includeFilters.add(new AnnotationTypeFilter( - ((Class) ClassUtils.forName("javax.inject.Named", cl)), false)); - logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning"); + ((Class) ClassUtils.forName("jakarta.inject.Named", cl)), false)); + logger.trace("JSR-330 'jakarta.inject.Named' annotation found and supported for component scanning"); } catch (ClassNotFoundException ex) { // JSR-330 API not available - simply skip. diff --git a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java index d9acb722b08d..75b7d08afec6 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java @@ -37,14 +37,15 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.annotation.Resource; -import javax.ejb.EJB; import javax.xml.namespace.QName; -import javax.xml.ws.Service; -import javax.xml.ws.WebServiceClient; -import javax.xml.ws.WebServiceRef; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; +import jakarta.annotation.Resource; +import jakarta.ejb.EJB; +import jakarta.xml.ws.Service; +import jakarta.xml.ws.WebServiceClient; +import jakarta.xml.ws.WebServiceRef; import org.springframework.aop.TargetSource; import org.springframework.aop.framework.ProxyFactory; @@ -77,36 +78,32 @@ /** * {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation * that supports common Java annotations out of the box, in particular the JSR-250 - * annotations in the {@code javax.annotation} package. These common Java - * annotations are supported in many Java EE 5 technologies (e.g. JSF 1.2), + * annotations in the {@code jakarta.annotation} package. These common Java + * annotations are supported in many Jakarta EE technologies (e.g. JSF 1.2), * as well as in Java 6's JAX-WS. * - *

    This post-processor includes support for the {@link javax.annotation.PostConstruct} - * and {@link javax.annotation.PreDestroy} annotations - as init annotation + *

    This post-processor includes support for the {@link jakarta.annotation.PostConstruct} + * and {@link jakarta.annotation.PreDestroy} annotations - as init annotation * and destroy annotation, respectively - through inheriting from * {@link InitDestroyAnnotationBeanPostProcessor} with pre-configured annotation types. * - *

    The central element is the {@link javax.annotation.Resource} annotation + *

    The central element is the {@link jakarta.annotation.Resource} annotation * for annotation-driven injection of named beans, by default from the containing * Spring BeanFactory, with only {@code mappedName} references resolved in JNDI. * The {@link #setAlwaysUseJndiLookup "alwaysUseJndiLookup" flag} enforces JNDI lookups - * equivalent to standard Java EE 5 resource injection for {@code name} references + * equivalent to standard Jakarta EE resource injection for {@code name} references * and default names as well. The target beans can be simple POJOs, with no special * requirements other than the type having to match. * *

    The JAX-WS {@link javax.xml.ws.WebServiceRef} annotation is supported too, - * analogous to {@link javax.annotation.Resource} but with the capability of creating + * analogous to {@link jakarta.annotation.Resource} but with the capability of creating * specific JAX-WS service endpoints. This may either point to an explicitly defined * resource by name or operate on a locally specified JAX-WS service class. Finally, - * this post-processor also supports the EJB 3 {@link javax.ejb.EJB} annotation, - * analogous to {@link javax.annotation.Resource} as well, with the capability to + * this post-processor also supports the EJB 3 {@link jakarta.ejb.EJB} annotation, + * analogous to {@link jakarta.annotation.Resource} as well, with the capability to * specify both a local bean name and a global JNDI name for fallback retrieval. * The target beans can be plain POJOs as well as EJB 3 Session Beans in this case. * - *

    The common annotations supported by this post-processor are available in - * Java 6 (JDK 1.6) as well as in Java EE 5/6 (which provides a standalone jar for - * its common annotations as well, allowing for use in any Java 5 based application). - * *

    For default usage, resolving resource names as Spring bean names, * simply define the following in your application context: * @@ -114,7 +111,7 @@ * <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/> * * For direct JNDI access, resolving resource names as JNDI resource references - * within the Java EE application's "java:comp/env/" namespace, use the following: + * within the Jakarta EE application's "java:comp/env/" namespace, use the following: * *

      * <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
    @@ -156,7 +153,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
     
     	static {
     		webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef");
    -		ejbClass = loadAnnotationType("javax.ejb.EJB");
    +		ejbClass = loadAnnotationType("jakarta.ejb.EJB");
     
     		resourceAnnotationTypes.add(Resource.class);
     		if (webServiceRefClass != null) {
    @@ -191,7 +188,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
     	/**
     	 * Create a new CommonAnnotationBeanPostProcessor,
     	 * with the init and destroy annotation types set to
    -	 * {@link javax.annotation.PostConstruct} and {@link javax.annotation.PreDestroy},
    +	 * {@link jakarta.annotation.PostConstruct} and {@link jakarta.annotation.PreDestroy},
     	 * respectively.
     	 */
     	public CommonAnnotationBeanPostProcessor() {
    @@ -229,11 +226,11 @@ public void setFallbackToDefaultTypeMatch(boolean fallbackToDefaultTypeMatch) {
     	}
     
     	/**
    -	 * Set whether to always use JNDI lookups equivalent to standard Java EE 5 resource
    +	 * Set whether to always use JNDI lookups equivalent to standard Jakarta EE resource
     	 * injection, even for {@code name} attributes and default names.
     	 * 

    Default is "false": Resource names are used for Spring bean lookups in the * containing BeanFactory; only {@code mappedName} attributes point directly - * into JNDI. Switch this flag to "true" for enforcing Java EE style JNDI lookups + * into JNDI. Switch this flag to "true" for enforcing Jakarta EE style JNDI lookups * in any case, even for {@code name} attributes and default names. * @see #setJndiFactory * @see #setResourceFactory @@ -249,7 +246,7 @@ public void setAlwaysUseJndiLookup(boolean alwaysUseJndiLookup) { * This factory will also be used if "alwaysUseJndiLookup" is set to "true" in order * to enforce JNDI lookups even for {@code name} attributes and default names. *

    The default is a {@link org.springframework.jndi.support.SimpleJndiBeanFactory} - * for JNDI lookup behavior equivalent to standard Java EE 5 resource injection. + * for JNDI lookup behavior equivalent to standard Jakarta EE resource injection. * @see #setResourceFactory * @see #setAlwaysUseJndiLookup */ @@ -266,7 +263,7 @@ public void setJndiFactory(BeanFactory jndiFactory) { * if any, looking up resource names as Spring bean names. Specify the resource * factory explicitly for programmatic usage of this post-processor. *

    Specifying Spring's {@link org.springframework.jndi.support.SimpleJndiBeanFactory} - * leads to JNDI lookup behavior equivalent to standard Java EE 5 resource injection, + * leads to JNDI lookup behavior equivalent to standard Jakarta EE resource injection, * even for {@code name} attributes and default names. This is the same behavior * that the "alwaysUseJndiLookup" flag enables. * @see #setAlwaysUseJndiLookup diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java b/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java index 725999d89c82..0826d1904a8b 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java @@ -86,7 +86,7 @@ *

    {@code @Configuration} is meta-annotated with {@link Component @Component}, therefore * {@code @Configuration} classes are candidates for component scanning (typically using * Spring XML's {@code } element) and therefore may also take - * advantage of {@link Autowired @Autowired}/{@link javax.inject.Inject @Inject} + * advantage of {@link Autowired @Autowired}/{@link jakarta.inject.Inject @Inject} * like any regular {@code @Component}. In particular, if a single constructor is present * autowiring semantics will be applied transparently for that constructor: * diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Jsr330ScopeMetadataResolver.java b/spring-context/src/main/java/org/springframework/context/annotation/Jsr330ScopeMetadataResolver.java index d9e033a83389..7dc65574f4cd 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/Jsr330ScopeMetadataResolver.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/Jsr330ScopeMetadataResolver.java @@ -26,7 +26,7 @@ /** * Simple {@link ScopeMetadataResolver} implementation that follows JSR-330 scoping rules: - * defaulting to prototype scope unless {@link javax.inject.Singleton} is present. + * defaulting to prototype scope unless {@link jakarta.inject.Singleton} is present. * *

    This scope resolver can be used with {@link ClassPathBeanDefinitionScanner} and * {@link AnnotatedBeanDefinitionReader} for standard JSR-330 compliance. However, @@ -46,7 +46,7 @@ public class Jsr330ScopeMetadataResolver implements ScopeMetadataResolver { public Jsr330ScopeMetadataResolver() { - registerScope("javax.inject.Singleton", BeanDefinition.SCOPE_SINGLETON); + registerScope("jakarta.inject.Singleton", BeanDefinition.SCOPE_SINGLETON); } @@ -93,7 +93,7 @@ public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) { String found = null; for (String annType : annTypes) { Set metaAnns = annDef.getMetadata().getMetaAnnotationTypes(annType); - if (metaAnns.contains("javax.inject.Scope")) { + if (metaAnns.contains("jakarta.inject.Scope")) { if (found != null) { throw new IllegalStateException("Found ambiguous scope annotations on bean class [" + definition.getBeanClassName() + "]: " + found + ", " + annType); diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Lazy.java b/spring-context/src/main/java/org/springframework/context/annotation/Lazy.java index 9d04a9df26ee..e708f36b31fb 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/Lazy.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/Lazy.java @@ -44,9 +44,9 @@ * *

    In addition to its role for component initialization, this annotation may also be placed * on injection points marked with {@link org.springframework.beans.factory.annotation.Autowired} - * or {@link javax.inject.Inject}: In that context, it leads to the creation of a + * or {@link jakarta.inject.Inject}: In that context, it leads to the creation of a * lazy-resolution proxy for all affected dependencies, as an alternative to using - * {@link org.springframework.beans.factory.ObjectFactory} or {@link javax.inject.Provider}. + * {@link org.springframework.beans.factory.ObjectFactory} or {@link jakarta.inject.Provider}. * * @author Chris Beams * @author Juergen Hoeller diff --git a/spring-context/src/main/java/org/springframework/context/annotation/MBeanExportConfiguration.java b/spring-context/src/main/java/org/springframework/context/annotation/MBeanExportConfiguration.java index ea4f5b64a67c..25715f82cad7 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/MBeanExportConfiguration.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/MBeanExportConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ import java.util.Map; import javax.management.MBeanServer; -import javax.naming.NamingException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -28,14 +27,10 @@ import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.jmx.MBeanServerNotFoundException; import org.springframework.jmx.export.annotation.AnnotationMBeanExporter; import org.springframework.jmx.support.RegistrationPolicy; -import org.springframework.jmx.support.WebSphereMBeanServerFactoryBean; -import org.springframework.jndi.JndiLocatorDelegate; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; /** @@ -116,15 +111,6 @@ private void setupServer(AnnotationMBeanExporter exporter, AnnotationAttributes Assert.state(this.beanFactory != null, "No BeanFactory set"); exporter.setServer(this.beanFactory.getBean(server, MBeanServer.class)); } - else { - SpecificPlatform specificPlatform = SpecificPlatform.get(); - if (specificPlatform != null) { - MBeanServer mbeanServer = specificPlatform.getMBeanServer(); - if (mbeanServer != null) { - exporter.setServer(mbeanServer); - } - } - } } private void setupRegistrationPolicy(AnnotationMBeanExporter exporter, AnnotationAttributes enableMBeanExport) { @@ -132,58 +118,4 @@ private void setupRegistrationPolicy(AnnotationMBeanExporter exporter, Annotatio exporter.setRegistrationPolicy(registrationPolicy); } - - /** - * Specific platforms that might need custom MBean handling. - */ - public enum SpecificPlatform { - - /** - * Weblogic. - */ - WEBLOGIC("weblogic.management.Helper") { - @Override - public MBeanServer getMBeanServer() { - try { - return new JndiLocatorDelegate().lookup("java:comp/env/jmx/runtime", MBeanServer.class); - } - catch (NamingException ex) { - throw new MBeanServerNotFoundException("Failed to retrieve WebLogic MBeanServer from JNDI", ex); - } - } - }, - - /** - * Websphere. - */ - WEBSPHERE("com.ibm.websphere.management.AdminServiceFactory") { - @Override - public MBeanServer getMBeanServer() { - WebSphereMBeanServerFactoryBean fb = new WebSphereMBeanServerFactoryBean(); - fb.afterPropertiesSet(); - return fb.getObject(); - } - }; - - private final String identifyingClass; - - SpecificPlatform(String identifyingClass) { - this.identifyingClass = identifyingClass; - } - - @Nullable - public abstract MBeanServer getMBeanServer(); - - @Nullable - public static SpecificPlatform get() { - ClassLoader classLoader = MBeanExportConfiguration.class.getClassLoader(); - for (SpecificPlatform environment : values()) { - if (ClassUtils.isPresent(environment.identifyingClass, classLoader)) { - return environment; - } - } - return null; - } - } - } diff --git a/spring-context/src/main/java/org/springframework/context/config/MBeanExportBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/context/config/MBeanExportBeanDefinitionParser.java index e1bba29d3305..14caba9b4a23 100644 --- a/spring-context/src/main/java/org/springframework/context/config/MBeanExportBeanDefinitionParser.java +++ b/spring-context/src/main/java/org/springframework/context/config/MBeanExportBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,12 +76,6 @@ protected AbstractBeanDefinition parseInternal(Element element, ParserContext pa if (StringUtils.hasText(serverBeanName)) { builder.addPropertyReference("server", serverBeanName); } - else { - AbstractBeanDefinition specialServer = MBeanServerBeanDefinitionParser.findServerForSpecialEnvironment(); - if (specialServer != null) { - builder.addPropertyValue("server", specialServer); - } - } String registration = element.getAttribute(REGISTRATION_ATTRIBUTE); RegistrationPolicy registrationPolicy = RegistrationPolicy.FAIL_ON_EXISTING; diff --git a/spring-context/src/main/java/org/springframework/context/config/MBeanServerBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/context/config/MBeanServerBeanDefinitionParser.java index 78062b65835e..89114cf23628 100644 --- a/spring-context/src/main/java/org/springframework/context/config/MBeanServerBeanDefinitionParser.java +++ b/spring-context/src/main/java/org/springframework/context/config/MBeanServerBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,10 +24,6 @@ import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.jmx.support.MBeanServerFactoryBean; -import org.springframework.jmx.support.WebSphereMBeanServerFactoryBean; -import org.springframework.jndi.JndiObjectFactoryBean; -import org.springframework.lang.Nullable; -import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; /** @@ -49,17 +45,6 @@ class MBeanServerBeanDefinitionParser extends AbstractBeanDefinitionParser { private static final String AGENT_ID_ATTRIBUTE = "agent-id"; - private static final boolean weblogicPresent; - - private static final boolean webspherePresent; - - static { - ClassLoader classLoader = MBeanServerBeanDefinitionParser.class.getClassLoader(); - weblogicPresent = ClassUtils.isPresent("weblogic.management.Helper", classLoader); - webspherePresent = ClassUtils.isPresent("com.ibm.websphere.management.AdminServiceFactory", classLoader); - } - - @Override protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) { String id = element.getAttribute(ID_ATTRIBUTE); @@ -74,10 +59,7 @@ protected AbstractBeanDefinition parseInternal(Element element, ParserContext pa bd.getPropertyValues().add("agentId", agentId); return bd; } - AbstractBeanDefinition specialServer = findServerForSpecialEnvironment(); - if (specialServer != null) { - return specialServer; - } + RootBeanDefinition bd = new RootBeanDefinition(MBeanServerFactoryBean.class); bd.getPropertyValues().add("locateExistingServerIfPossible", Boolean.TRUE); @@ -87,19 +69,4 @@ protected AbstractBeanDefinition parseInternal(Element element, ParserContext pa return bd; } - @Nullable - static AbstractBeanDefinition findServerForSpecialEnvironment() { - if (weblogicPresent) { - RootBeanDefinition bd = new RootBeanDefinition(JndiObjectFactoryBean.class); - bd.getPropertyValues().add("jndiName", "java:comp/env/jmx/runtime"); - return bd; - } - else if (webspherePresent) { - return new RootBeanDefinition(WebSphereMBeanServerFactoryBean.class); - } - else { - return null; - } - } - } diff --git a/spring-context/src/main/java/org/springframework/context/weaving/DefaultContextLoadTimeWeaver.java b/spring-context/src/main/java/org/springframework/context/weaving/DefaultContextLoadTimeWeaver.java index 5820735ce041..11072d21a095 100644 --- a/spring-context/src/main/java/org/springframework/context/weaving/DefaultContextLoadTimeWeaver.java +++ b/spring-context/src/main/java/org/springframework/context/weaving/DefaultContextLoadTimeWeaver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,8 +30,6 @@ import org.springframework.instrument.classloading.glassfish.GlassFishLoadTimeWeaver; import org.springframework.instrument.classloading.jboss.JBossLoadTimeWeaver; import org.springframework.instrument.classloading.tomcat.TomcatLoadTimeWeaver; -import org.springframework.instrument.classloading.weblogic.WebLogicLoadTimeWeaver; -import org.springframework.instrument.classloading.websphere.WebSphereLoadTimeWeaver; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -45,10 +43,9 @@ * on a {@code @Configuration} class. * *

    This class implements a runtime environment check for obtaining the - * appropriate weaver implementation. As of Spring Framework 5.0, it detects - * Oracle WebLogic 10+, GlassFish 4+, Tomcat 8+, WildFly 8+, IBM WebSphere 8.5+, - * {@link InstrumentationSavingAgent Spring's VM agent}, and any {@link ClassLoader} - * supported by Spring's {@link ReflectiveLoadTimeWeaver} (such as Liberty's). + * appropriate weaver implementation, including + * {@link InstrumentationSavingAgent Spring's VM agent} and any {@link ClassLoader} + * supported by Spring's {@link ReflectiveLoadTimeWeaver}. * * @author Juergen Hoeller * @author Ramnivas Laddad @@ -120,12 +117,6 @@ else if (name.startsWith("org.glassfish")) { else if (name.startsWith("org.jboss.modules")) { return new JBossLoadTimeWeaver(classLoader); } - else if (name.startsWith("com.ibm.ws.classloader")) { - return new WebSphereLoadTimeWeaver(classLoader); - } - else if (name.startsWith("weblogic")) { - return new WebLogicLoadTimeWeaver(classLoader); - } } catch (Exception ex) { if (logger.isInfoEnabled()) { diff --git a/spring-context/src/main/java/org/springframework/ejb/access/AbstractRemoteSlsbInvokerInterceptor.java b/spring-context/src/main/java/org/springframework/ejb/access/AbstractRemoteSlsbInvokerInterceptor.java deleted file mode 100644 index 1a294ffc9ae3..000000000000 --- a/spring-context/src/main/java/org/springframework/ejb/access/AbstractRemoteSlsbInvokerInterceptor.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ejb.access; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.rmi.RemoteException; - -import javax.ejb.EJBHome; -import javax.ejb.EJBObject; -import javax.naming.NamingException; - -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.lang.Nullable; -import org.springframework.remoting.RemoteConnectFailureException; -import org.springframework.remoting.RemoteLookupFailureException; - -/** - * Base class for interceptors proxying remote Stateless Session Beans. - * Designed for EJB 2.x, but works for EJB 3 Session Beans as well. - * - *

    Such an interceptor must be the last interceptor in the advice chain. - * In this case, there is no target object. - * - * @author Rod Johnson - * @author Juergen Hoeller - */ -public abstract class AbstractRemoteSlsbInvokerInterceptor extends AbstractSlsbInvokerInterceptor { - - private boolean refreshHomeOnConnectFailure = false; - - private volatile boolean homeAsComponent; - - - - /** - * Set whether to refresh the EJB home on connect failure. - * Default is "false". - *

    Can be turned on to allow for hot restart of the EJB server. - * If a cached EJB home throws an RMI exception that indicates a - * remote connect failure, a fresh home will be fetched and the - * invocation will be retried. - * @see java.rmi.ConnectException - * @see java.rmi.ConnectIOException - * @see java.rmi.NoSuchObjectException - */ - public void setRefreshHomeOnConnectFailure(boolean refreshHomeOnConnectFailure) { - this.refreshHomeOnConnectFailure = refreshHomeOnConnectFailure; - } - - @Override - protected boolean isHomeRefreshable() { - return this.refreshHomeOnConnectFailure; - } - - - /** - * Check for EJB3-style home object that serves as EJB component directly. - */ - @Override - protected Method getCreateMethod(Object home) throws EjbAccessException { - if (this.homeAsComponent) { - return null; - } - if (!(home instanceof EJBHome)) { - // An EJB3 Session Bean... - this.homeAsComponent = true; - return null; - } - return super.getCreateMethod(home); - } - - - /** - * Fetches an EJB home object and delegates to {@code doInvoke}. - *

    If configured to refresh on connect failure, it will call - * {@link #refreshAndRetry} on corresponding RMI exceptions. - * @see #getHome - * @see #doInvoke - * @see #refreshAndRetry - */ - @Override - @Nullable - public Object invokeInContext(MethodInvocation invocation) throws Throwable { - try { - return doInvoke(invocation); - } - catch (RemoteConnectFailureException ex) { - return handleRemoteConnectFailure(invocation, ex); - } - catch (RemoteException ex) { - if (isConnectFailure(ex)) { - return handleRemoteConnectFailure(invocation, ex); - } - else { - throw ex; - } - } - } - - /** - * Determine whether the given RMI exception indicates a connect failure. - *

    The default implementation delegates to RmiClientInterceptorUtils. - * @param ex the RMI exception to check - * @return whether the exception should be treated as connect failure - * @see org.springframework.remoting.rmi.RmiClientInterceptorUtils#isConnectFailure - */ - @SuppressWarnings("deprecation") - protected boolean isConnectFailure(RemoteException ex) { - return org.springframework.remoting.rmi.RmiClientInterceptorUtils.isConnectFailure(ex); - } - - @Nullable - private Object handleRemoteConnectFailure(MethodInvocation invocation, Exception ex) throws Throwable { - if (this.refreshHomeOnConnectFailure) { - if (logger.isDebugEnabled()) { - logger.debug("Could not connect to remote EJB [" + getJndiName() + "] - retrying", ex); - } - else if (logger.isWarnEnabled()) { - logger.warn("Could not connect to remote EJB [" + getJndiName() + "] - retrying"); - } - return refreshAndRetry(invocation); - } - else { - throw ex; - } - } - - /** - * Refresh the EJB home object and retry the given invocation. - * Called by invoke on connect failure. - * @param invocation the AOP method invocation - * @return the invocation result, if any - * @throws Throwable in case of invocation failure - * @see #invoke - */ - @Nullable - protected Object refreshAndRetry(MethodInvocation invocation) throws Throwable { - try { - refreshHome(); - } - catch (NamingException ex) { - throw new RemoteLookupFailureException("Failed to locate remote EJB [" + getJndiName() + "]", ex); - } - return doInvoke(invocation); - } - - - /** - * Perform the given invocation on the current EJB home. - * Template method to be implemented by subclasses. - * @param invocation the AOP method invocation - * @return the invocation result, if any - * @throws Throwable in case of invocation failure - * @see #getHome - * @see #newSessionBeanInstance - */ - @Nullable - protected abstract Object doInvoke(MethodInvocation invocation) throws Throwable; - - - /** - * Return a new instance of the stateless session bean. - * To be invoked by concrete remote SLSB invoker subclasses. - *

    Can be overridden to change the algorithm. - * @throws NamingException if thrown by JNDI - * @throws InvocationTargetException if thrown by the create method - * @see #create - */ - protected Object newSessionBeanInstance() throws NamingException, InvocationTargetException { - if (logger.isDebugEnabled()) { - logger.debug("Trying to create reference to remote EJB"); - } - Object ejbInstance = create(); - if (logger.isDebugEnabled()) { - logger.debug("Obtained reference to remote EJB: " + ejbInstance); - } - return ejbInstance; - } - - /** - * Remove the given EJB instance. - * To be invoked by concrete remote SLSB invoker subclasses. - * @param ejb the EJB instance to remove - * @see javax.ejb.EJBObject#remove - */ - protected void removeSessionBeanInstance(@Nullable EJBObject ejb) { - if (ejb != null && !this.homeAsComponent) { - try { - ejb.remove(); - } - catch (Throwable ex) { - logger.warn("Could not invoke 'remove' on remote EJB proxy", ex); - } - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/ejb/access/AbstractSlsbInvokerInterceptor.java b/spring-context/src/main/java/org/springframework/ejb/access/AbstractSlsbInvokerInterceptor.java deleted file mode 100644 index 06657499d6e4..000000000000 --- a/spring-context/src/main/java/org/springframework/ejb/access/AbstractSlsbInvokerInterceptor.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ejb.access; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import javax.naming.Context; -import javax.naming.NamingException; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.jndi.JndiObjectLocator; -import org.springframework.lang.Nullable; - -/** - * Base class for AOP interceptors invoking local or remote Stateless Session Beans. - * Designed for EJB 2.x, but works for EJB 3 Session Beans as well. - * - *

    Such an interceptor must be the last interceptor in the advice chain. - * In this case, there is no direct target object: The call is handled in a - * special way, getting executed on an EJB instance retrieved via an EJB home. - * - * @author Rod Johnson - * @author Juergen Hoeller - */ -public abstract class AbstractSlsbInvokerInterceptor extends JndiObjectLocator - implements MethodInterceptor { - - private boolean lookupHomeOnStartup = true; - - private boolean cacheHome = true; - - private boolean exposeAccessContext = false; - - /** - * The EJB's home object, potentially cached. - * The type must be Object as it could be either EJBHome or EJBLocalHome. - */ - @Nullable - private Object cachedHome; - - /** - * The no-arg create() method required on EJB homes, potentially cached. - */ - @Nullable - private Method createMethod; - - private final Object homeMonitor = new Object(); - - - /** - * Set whether to look up the EJB home object on startup. - * Default is "true". - *

    Can be turned off to allow for late start of the EJB server. - * In this case, the EJB home object will be fetched on first access. - * @see #setCacheHome - */ - public void setLookupHomeOnStartup(boolean lookupHomeOnStartup) { - this.lookupHomeOnStartup = lookupHomeOnStartup; - } - - /** - * Set whether to cache the EJB home object once it has been located. - * Default is "true". - *

    Can be turned off to allow for hot restart of the EJB server. - * In this case, the EJB home object will be fetched for each invocation. - * @see #setLookupHomeOnStartup - */ - public void setCacheHome(boolean cacheHome) { - this.cacheHome = cacheHome; - } - - /** - * Set whether to expose the JNDI environment context for all access to the target - * EJB, i.e. for all method invocations on the exposed object reference. - *

    Default is "false", i.e. to only expose the JNDI context for object lookup. - * Switch this flag to "true" in order to expose the JNDI environment (including - * the authorization context) for each EJB invocation, as needed by WebLogic - * for EJBs with authorization requirements. - */ - public void setExposeAccessContext(boolean exposeAccessContext) { - this.exposeAccessContext = exposeAccessContext; - } - - - /** - * Fetches EJB home on startup, if necessary. - * @see #setLookupHomeOnStartup - * @see #refreshHome - */ - @Override - public void afterPropertiesSet() throws NamingException { - super.afterPropertiesSet(); - if (this.lookupHomeOnStartup) { - // look up EJB home and create method - refreshHome(); - } - } - - /** - * Refresh the cached home object, if applicable. - * Also caches the create method on the home object. - * @throws NamingException if thrown by the JNDI lookup - * @see #lookup - * @see #getCreateMethod - */ - protected void refreshHome() throws NamingException { - synchronized (this.homeMonitor) { - Object home = lookup(); - if (this.cacheHome) { - this.cachedHome = home; - this.createMethod = getCreateMethod(home); - } - } - } - - /** - * Determine the create method of the given EJB home object. - * @param home the EJB home object - * @return the create method - * @throws EjbAccessException if the method couldn't be retrieved - */ - @Nullable - protected Method getCreateMethod(Object home) throws EjbAccessException { - try { - // Cache the EJB create() method that must be declared on the home interface. - return home.getClass().getMethod("create"); - } - catch (NoSuchMethodException ex) { - throw new EjbAccessException("EJB home [" + home + "] has no no-arg create() method"); - } - } - - /** - * Return the EJB home object to use. Called for each invocation. - *

    Default implementation returns the home created on initialization, - * if any; else, it invokes lookup to get a new proxy for each invocation. - *

    Can be overridden in subclasses, for example to cache a home object - * for a given amount of time before recreating it, or to test the home - * object whether it is still alive. - * @return the EJB home object to use for an invocation - * @throws NamingException if proxy creation failed - * @see #lookup - * @see #getCreateMethod - */ - protected Object getHome() throws NamingException { - if (!this.cacheHome || (this.lookupHomeOnStartup && !isHomeRefreshable())) { - return (this.cachedHome != null ? this.cachedHome : lookup()); - } - else { - synchronized (this.homeMonitor) { - if (this.cachedHome == null) { - this.cachedHome = lookup(); - this.createMethod = getCreateMethod(this.cachedHome); - } - return this.cachedHome; - } - } - } - - /** - * Return whether the cached EJB home object is potentially - * subject to on-demand refreshing. Default is "false". - */ - protected boolean isHomeRefreshable() { - return false; - } - - - /** - * Prepares the thread context if necessary, and delegates to - * {@link #invokeInContext}. - */ - @Override - @Nullable - public Object invoke(MethodInvocation invocation) throws Throwable { - Context ctx = (this.exposeAccessContext ? getJndiTemplate().getContext() : null); - try { - return invokeInContext(invocation); - } - finally { - getJndiTemplate().releaseContext(ctx); - } - } - - /** - * Perform the given invocation on the current EJB home, - * within the thread context being prepared accordingly. - * Template method to be implemented by subclasses. - * @param invocation the AOP method invocation - * @return the invocation result, if any - * @throws Throwable in case of invocation failure - */ - @Nullable - protected abstract Object invokeInContext(MethodInvocation invocation) throws Throwable; - - - /** - * Invokes the {@code create()} method on the cached EJB home object. - * @return a new EJBObject or EJBLocalObject - * @throws NamingException if thrown by JNDI - * @throws InvocationTargetException if thrown by the create method - */ - protected Object create() throws NamingException, InvocationTargetException { - try { - Object home = getHome(); - Method createMethodToUse = this.createMethod; - if (createMethodToUse == null) { - createMethodToUse = getCreateMethod(home); - } - if (createMethodToUse == null) { - return home; - } - // Invoke create() method on EJB home object. - return createMethodToUse.invoke(home, (Object[]) null); - } - catch (IllegalAccessException ex) { - throw new EjbAccessException("Could not access EJB home create() method", ex); - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/ejb/access/EjbAccessException.java b/spring-context/src/main/java/org/springframework/ejb/access/EjbAccessException.java deleted file mode 100644 index 50f18064c71f..000000000000 --- a/spring-context/src/main/java/org/springframework/ejb/access/EjbAccessException.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ejb.access; - -import org.springframework.core.NestedRuntimeException; - -/** - * Exception that gets thrown when an EJB stub cannot be accessed properly. - * - * @author Juergen Hoeller - * @since 2.0 - */ -@SuppressWarnings("serial") -public class EjbAccessException extends NestedRuntimeException { - - /** - * Constructor for EjbAccessException. - * @param msg the detail message - */ - public EjbAccessException(String msg) { - super(msg); - } - - /** - * Constructor for EjbAccessException. - * @param msg the detail message - * @param cause the root cause - */ - public EjbAccessException(String msg, Throwable cause) { - super(msg, cause); - } - -} diff --git a/spring-context/src/main/java/org/springframework/ejb/access/LocalSlsbInvokerInterceptor.java b/spring-context/src/main/java/org/springframework/ejb/access/LocalSlsbInvokerInterceptor.java deleted file mode 100644 index 027b7ef87368..000000000000 --- a/spring-context/src/main/java/org/springframework/ejb/access/LocalSlsbInvokerInterceptor.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ejb.access; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import javax.ejb.CreateException; -import javax.ejb.EJBLocalHome; -import javax.ejb.EJBLocalObject; -import javax.naming.NamingException; - -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.lang.Nullable; - -/** - * Invoker for a local Stateless Session Bean. - * Designed for EJB 2.x, but works for EJB 3 Session Beans as well. - * - *

    Caches the home object, since a local EJB home can never go stale. - * See {@link org.springframework.jndi.JndiObjectLocator} for info on - * how to specify the JNDI location of the target EJB. - * - *

    In a bean container, this class is normally best used as a singleton. However, - * if that bean container pre-instantiates singletons (as do the XML ApplicationContext - * variants) you may have a problem if the bean container is loaded before the EJB - * container loads the target EJB. That is because by default the JNDI lookup will be - * performed in the init method of this class and cached, but the EJB will not have been - * bound at the target location yet. The best solution is to set the lookupHomeOnStartup - * property to false, in which case the home will be fetched on first access to the EJB. - * (This flag is only true by default for backwards compatibility reasons). - * - * @author Rod Johnson - * @author Juergen Hoeller - * @see AbstractSlsbInvokerInterceptor#setLookupHomeOnStartup - * @see AbstractSlsbInvokerInterceptor#setCacheHome - */ -public class LocalSlsbInvokerInterceptor extends AbstractSlsbInvokerInterceptor { - - private volatile boolean homeAsComponent; - - - /** - * This implementation "creates" a new EJB instance for each invocation. - * Can be overridden for custom invocation strategies. - *

    Alternatively, override {@link #getSessionBeanInstance} and - * {@link #releaseSessionBeanInstance} to change EJB instance creation, - * for example to hold a single shared EJB instance. - */ - @Override - @Nullable - public Object invokeInContext(MethodInvocation invocation) throws Throwable { - Object ejb = null; - try { - ejb = getSessionBeanInstance(); - Method method = invocation.getMethod(); - if (method.getDeclaringClass().isInstance(ejb)) { - // directly implemented - return method.invoke(ejb, invocation.getArguments()); - } - else { - // not directly implemented - Method ejbMethod = ejb.getClass().getMethod(method.getName(), method.getParameterTypes()); - return ejbMethod.invoke(ejb, invocation.getArguments()); - } - } - catch (InvocationTargetException ex) { - Throwable targetEx = ex.getTargetException(); - if (logger.isDebugEnabled()) { - logger.debug("Method of local EJB [" + getJndiName() + "] threw exception", targetEx); - } - if (targetEx instanceof CreateException) { - throw new EjbAccessException("Could not create local EJB [" + getJndiName() + "]", targetEx); - } - else { - throw targetEx; - } - } - catch (NamingException ex) { - throw new EjbAccessException("Failed to locate local EJB [" + getJndiName() + "]", ex); - } - catch (IllegalAccessException ex) { - throw new EjbAccessException("Could not access method [" + invocation.getMethod().getName() + - "] of local EJB [" + getJndiName() + "]", ex); - } - finally { - if (ejb instanceof EJBLocalObject) { - releaseSessionBeanInstance((EJBLocalObject) ejb); - } - } - } - - /** - * Check for EJB3-style home object that serves as EJB component directly. - */ - @Override - protected Method getCreateMethod(Object home) throws EjbAccessException { - if (this.homeAsComponent) { - return null; - } - if (!(home instanceof EJBLocalHome)) { - // An EJB3 Session Bean... - this.homeAsComponent = true; - return null; - } - return super.getCreateMethod(home); - } - - /** - * Return an EJB instance to delegate the call to. - * Default implementation delegates to newSessionBeanInstance. - * @throws NamingException if thrown by JNDI - * @throws InvocationTargetException if thrown by the create method - * @see #newSessionBeanInstance - */ - protected Object getSessionBeanInstance() throws NamingException, InvocationTargetException { - return newSessionBeanInstance(); - } - - /** - * Release the given EJB instance. - * Default implementation delegates to removeSessionBeanInstance. - * @param ejb the EJB instance to release - * @see #removeSessionBeanInstance - */ - protected void releaseSessionBeanInstance(EJBLocalObject ejb) { - removeSessionBeanInstance(ejb); - } - - /** - * Return a new instance of the stateless session bean. - * Can be overridden to change the algorithm. - * @throws NamingException if thrown by JNDI - * @throws InvocationTargetException if thrown by the create method - * @see #create - */ - protected Object newSessionBeanInstance() throws NamingException, InvocationTargetException { - if (logger.isDebugEnabled()) { - logger.debug("Trying to create reference to local EJB"); - } - Object ejbInstance = create(); - if (logger.isDebugEnabled()) { - logger.debug("Obtained reference to local EJB: " + ejbInstance); - } - return ejbInstance; - } - - /** - * Remove the given EJB instance. - * @param ejb the EJB instance to remove - * @see javax.ejb.EJBLocalObject#remove() - */ - protected void removeSessionBeanInstance(@Nullable EJBLocalObject ejb) { - if (ejb != null && !this.homeAsComponent) { - try { - ejb.remove(); - } - catch (Throwable ex) { - logger.warn("Could not invoke 'remove' on local EJB proxy", ex); - } - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/ejb/access/LocalStatelessSessionProxyFactoryBean.java b/spring-context/src/main/java/org/springframework/ejb/access/LocalStatelessSessionProxyFactoryBean.java deleted file mode 100644 index 1b780af7258f..000000000000 --- a/spring-context/src/main/java/org/springframework/ejb/access/LocalStatelessSessionProxyFactoryBean.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ejb.access; - -import javax.naming.NamingException; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.lang.Nullable; -import org.springframework.util.ClassUtils; - -/** - * Convenient {@link FactoryBean} for local Stateless Session Bean (SLSB) proxies. - * Designed for EJB 2.x, but works for EJB 3 Session Beans as well. - * - *

    See {@link org.springframework.jndi.JndiObjectLocator} for info on - * how to specify the JNDI location of the target EJB. - * - *

    If you want control over interceptor chaining, use an AOP ProxyFactoryBean - * with LocalSlsbInvokerInterceptor rather than rely on this class. - * - *

    In a bean container, this class is normally best used as a singleton. However, - * if that bean container pre-instantiates singletons (as do the XML ApplicationContext - * variants) you may have a problem if the bean container is loaded before the EJB - * container loads the target EJB. That is because by default the JNDI lookup will be - * performed in the init method of this class and cached, but the EJB will not have been - * bound at the target location yet. The best solution is to set the "lookupHomeOnStartup" - * property to "false", in which case the home will be fetched on first access to the EJB. - * (This flag is only true by default for backwards compatibility reasons). - * - * @author Rod Johnson - * @author Colin Sampaleanu - * @since 09.05.2003 - * @see AbstractSlsbInvokerInterceptor#setLookupHomeOnStartup - * @see AbstractSlsbInvokerInterceptor#setCacheHome - */ -public class LocalStatelessSessionProxyFactoryBean extends LocalSlsbInvokerInterceptor - implements FactoryBean, BeanClassLoaderAware { - - /** The business interface of the EJB we're proxying. */ - @Nullable - private Class businessInterface; - - @Nullable - private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); - - /** EJBLocalObject. */ - @Nullable - private Object proxy; - - - /** - * Set the business interface of the EJB we're proxying. - * This will normally be a super-interface of the EJB local component interface. - * Using a business methods interface is a best practice when implementing EJBs. - * @param businessInterface set the business interface of the EJB - */ - public void setBusinessInterface(@Nullable Class businessInterface) { - this.businessInterface = businessInterface; - } - - /** - * Return the business interface of the EJB we're proxying. - */ - @Nullable - public Class getBusinessInterface() { - return this.businessInterface; - } - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } - - @Override - public void afterPropertiesSet() throws NamingException { - super.afterPropertiesSet(); - if (this.businessInterface == null) { - throw new IllegalArgumentException("businessInterface is required"); - } - this.proxy = new ProxyFactory(this.businessInterface, this).getProxy(this.beanClassLoader); - } - - - @Override - @Nullable - public Object getObject() { - return this.proxy; - } - - @Override - public Class getObjectType() { - return this.businessInterface; - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-context/src/main/java/org/springframework/ejb/access/SimpleRemoteSlsbInvokerInterceptor.java b/spring-context/src/main/java/org/springframework/ejb/access/SimpleRemoteSlsbInvokerInterceptor.java deleted file mode 100644 index 292ddb640937..000000000000 --- a/spring-context/src/main/java/org/springframework/ejb/access/SimpleRemoteSlsbInvokerInterceptor.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ejb.access; - -import java.lang.reflect.InvocationTargetException; -import java.rmi.RemoteException; - -import javax.ejb.CreateException; -import javax.ejb.EJBObject; -import javax.naming.NamingException; - -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.lang.Nullable; -import org.springframework.remoting.RemoteLookupFailureException; - -/** - * Basic invoker for a remote Stateless Session Bean. - * Designed for EJB 2.x, but works for EJB 3 Session Beans as well. - * - *

    "Creates" a new EJB instance for each invocation, or caches the session - * bean instance for all invocations (see {@link #setCacheSessionBean}). - * See {@link org.springframework.jndi.JndiObjectLocator} for info on - * how to specify the JNDI location of the target EJB. - * - *

    In a bean container, this class is normally best used as a singleton. However, - * if that bean container pre-instantiates singletons (as do the XML ApplicationContext - * variants) you may have a problem if the bean container is loaded before the EJB - * container loads the target EJB. That is because by default the JNDI lookup will be - * performed in the init method of this class and cached, but the EJB will not have been - * bound at the target location yet. The best solution is to set the "lookupHomeOnStartup" - * property to "false", in which case the home will be fetched on first access to the EJB. - * (This flag is only true by default for backwards compatibility reasons). - * - *

    This invoker is typically used with an RMI business interface, which serves - * as super-interface of the EJB component interface. Alternatively, this invoker - * can also proxy a remote SLSB with a matching non-RMI business interface, i.e. an - * interface that mirrors the EJB business methods but does not declare RemoteExceptions. - * In the latter case, RemoteExceptions thrown by the EJB stub will automatically get - * converted to Spring's unchecked RemoteAccessException. - * - * @author Rod Johnson - * @author Juergen Hoeller - * @since 09.05.2003 - * @see org.springframework.remoting.RemoteAccessException - * @see AbstractSlsbInvokerInterceptor#setLookupHomeOnStartup - * @see AbstractSlsbInvokerInterceptor#setCacheHome - * @see AbstractRemoteSlsbInvokerInterceptor#setRefreshHomeOnConnectFailure - */ -public class SimpleRemoteSlsbInvokerInterceptor extends AbstractRemoteSlsbInvokerInterceptor - implements DisposableBean { - - private boolean cacheSessionBean = false; - - @Nullable - private Object beanInstance; - - private final Object beanInstanceMonitor = new Object(); - - - /** - * Set whether to cache the actual session bean object. - *

    Off by default for standard EJB compliance. Turn this flag - * on to optimize session bean access for servers that are - * known to allow for caching the actual session bean object. - * @see #setCacheHome - */ - public void setCacheSessionBean(boolean cacheSessionBean) { - this.cacheSessionBean = cacheSessionBean; - } - - - /** - * This implementation "creates" a new EJB instance for each invocation. - * Can be overridden for custom invocation strategies. - *

    Alternatively, override {@link #getSessionBeanInstance} and - * {@link #releaseSessionBeanInstance} to change EJB instance creation, - * for example to hold a single shared EJB component instance. - */ - @Override - @Nullable - @SuppressWarnings("deprecation") - protected Object doInvoke(MethodInvocation invocation) throws Throwable { - Object ejb = null; - try { - ejb = getSessionBeanInstance(); - return org.springframework.remoting.rmi.RmiClientInterceptorUtils.invokeRemoteMethod(invocation, ejb); - } - catch (NamingException ex) { - throw new RemoteLookupFailureException("Failed to locate remote EJB [" + getJndiName() + "]", ex); - } - catch (InvocationTargetException ex) { - Throwable targetEx = ex.getTargetException(); - if (targetEx instanceof RemoteException) { - RemoteException rex = (RemoteException) targetEx; - throw org.springframework.remoting.rmi.RmiClientInterceptorUtils.convertRmiAccessException( - invocation.getMethod(), rex, isConnectFailure(rex), getJndiName()); - } - else if (targetEx instanceof CreateException) { - throw org.springframework.remoting.rmi.RmiClientInterceptorUtils.convertRmiAccessException( - invocation.getMethod(), targetEx, "Could not create remote EJB [" + getJndiName() + "]"); - } - throw targetEx; - } - finally { - if (ejb instanceof EJBObject) { - releaseSessionBeanInstance((EJBObject) ejb); - } - } - } - - /** - * Return an EJB component instance to delegate the call to. - *

    The default implementation delegates to {@link #newSessionBeanInstance}. - * @return the EJB component instance - * @throws NamingException if thrown by JNDI - * @throws InvocationTargetException if thrown by the create method - * @see #newSessionBeanInstance - */ - protected Object getSessionBeanInstance() throws NamingException, InvocationTargetException { - if (this.cacheSessionBean) { - synchronized (this.beanInstanceMonitor) { - if (this.beanInstance == null) { - this.beanInstance = newSessionBeanInstance(); - } - return this.beanInstance; - } - } - else { - return newSessionBeanInstance(); - } - } - - /** - * Release the given EJB instance. - *

    The default implementation delegates to {@link #removeSessionBeanInstance}. - * @param ejb the EJB component instance to release - * @see #removeSessionBeanInstance - */ - protected void releaseSessionBeanInstance(EJBObject ejb) { - if (!this.cacheSessionBean) { - removeSessionBeanInstance(ejb); - } - } - - /** - * Reset the cached session bean instance, if necessary. - */ - @Override - protected void refreshHome() throws NamingException { - super.refreshHome(); - if (this.cacheSessionBean) { - synchronized (this.beanInstanceMonitor) { - this.beanInstance = null; - } - } - } - - /** - * Remove the cached session bean instance, if necessary. - */ - @Override - public void destroy() { - if (this.cacheSessionBean) { - synchronized (this.beanInstanceMonitor) { - if (this.beanInstance instanceof EJBObject) { - removeSessionBeanInstance((EJBObject) this.beanInstance); - } - } - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/ejb/access/SimpleRemoteStatelessSessionProxyFactoryBean.java b/spring-context/src/main/java/org/springframework/ejb/access/SimpleRemoteStatelessSessionProxyFactoryBean.java deleted file mode 100644 index 2cf93ad81fa5..000000000000 --- a/spring-context/src/main/java/org/springframework/ejb/access/SimpleRemoteStatelessSessionProxyFactoryBean.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ejb.access; - -import javax.naming.NamingException; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.lang.Nullable; -import org.springframework.util.ClassUtils; - -/** - * Convenient {@link FactoryBean} for remote SLSB proxies. - * Designed for EJB 2.x, but works for EJB 3 Session Beans as well. - * - *

    See {@link org.springframework.jndi.JndiObjectLocator} for info on - * how to specify the JNDI location of the target EJB. - * - *

    If you want control over interceptor chaining, use an AOP ProxyFactoryBean - * with SimpleRemoteSlsbInvokerInterceptor rather than rely on this class. - * - *

    In a bean container, this class is normally best used as a singleton. However, - * if that bean container pre-instantiates singletons (as do the XML ApplicationContext - * variants) you may have a problem if the bean container is loaded before the EJB - * container loads the target EJB. That is because by default the JNDI lookup will be - * performed in the init method of this class and cached, but the EJB will not have been - * bound at the target location yet. The best solution is to set the lookupHomeOnStartup - * property to false, in which case the home will be fetched on first access to the EJB. - * (This flag is only true by default for backwards compatibility reasons). - * - *

    This proxy factory is typically used with an RMI business interface, which serves - * as super-interface of the EJB component interface. Alternatively, this factory - * can also proxy a remote SLSB with a matching non-RMI business interface, i.e. an - * interface that mirrors the EJB business methods but does not declare RemoteExceptions. - * In the latter case, RemoteExceptions thrown by the EJB stub will automatically get - * converted to Spring's unchecked RemoteAccessException. - * - * @author Rod Johnson - * @author Colin Sampaleanu - * @author Juergen Hoeller - * @since 09.05.2003 - * @see org.springframework.remoting.RemoteAccessException - * @see AbstractSlsbInvokerInterceptor#setLookupHomeOnStartup - * @see AbstractSlsbInvokerInterceptor#setCacheHome - * @see AbstractRemoteSlsbInvokerInterceptor#setRefreshHomeOnConnectFailure - */ -public class SimpleRemoteStatelessSessionProxyFactoryBean extends SimpleRemoteSlsbInvokerInterceptor - implements FactoryBean, BeanClassLoaderAware { - - /** The business interface of the EJB we're proxying. */ - @Nullable - private Class businessInterface; - - @Nullable - private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); - - /** EJBObject. */ - @Nullable - private Object proxy; - - - /** - * Set the business interface of the EJB we're proxying. - * This will normally be a super-interface of the EJB remote component interface. - * Using a business methods interface is a best practice when implementing EJBs. - *

    You can also specify a matching non-RMI business interface, i.e. an interface - * that mirrors the EJB business methods but does not declare RemoteExceptions. - * In this case, RemoteExceptions thrown by the EJB stub will automatically get - * converted to Spring's generic RemoteAccessException. - * @param businessInterface the business interface of the EJB - */ - public void setBusinessInterface(@Nullable Class businessInterface) { - this.businessInterface = businessInterface; - } - - /** - * Return the business interface of the EJB we're proxying. - */ - @Nullable - public Class getBusinessInterface() { - return this.businessInterface; - } - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } - - @Override - public void afterPropertiesSet() throws NamingException { - super.afterPropertiesSet(); - if (this.businessInterface == null) { - throw new IllegalArgumentException("businessInterface is required"); - } - this.proxy = new ProxyFactory(this.businessInterface, this).getProxy(this.beanClassLoader); - } - - - @Override - @Nullable - public Object getObject() { - return this.proxy; - } - - @Override - public Class getObjectType() { - return this.businessInterface; - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-context/src/main/java/org/springframework/ejb/access/package-info.java b/spring-context/src/main/java/org/springframework/ejb/access/package-info.java deleted file mode 100644 index 54011fa2eccb..000000000000 --- a/spring-context/src/main/java/org/springframework/ejb/access/package-info.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This package contains classes that allow easy access to EJBs. - * The basis are AOP interceptors run before and after the EJB invocation. - * In particular, the classes in this package allow transparent access - * to stateless session beans (SLSBs) with local interfaces, avoiding - * the need for application code using them to use EJB-specific APIs - * and JNDI lookups, and work with business interfaces that could be - * implemented without using EJB. This provides a valuable decoupling - * of client (such as web components) and business objects (which may - * or may not be EJBs). This gives us the choice of introducing EJB - * into an application (or removing EJB from an application) without - * affecting code using business objects. - * - *

    The motivation for the classes in this package is discussed in Chapter 11 of - * Expert One-On-One J2EE Design and Development - * by Rod Johnson (Wrox, 2002). - * - *

    However, the implementation and naming of classes in this package has changed. - * It now uses FactoryBeans and AOP, rather than the custom bean definitions described in - * Expert One-on-One J2EE. - */ -@NonNullApi -@NonNullFields -package org.springframework.ejb.access; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-context/src/main/java/org/springframework/ejb/config/LocalStatelessSessionBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/ejb/config/LocalStatelessSessionBeanDefinitionParser.java index 5027c4aa2876..035fad6581f5 100644 --- a/spring-context/src/main/java/org/springframework/ejb/config/LocalStatelessSessionBeanDefinitionParser.java +++ b/spring-context/src/main/java/org/springframework/ejb/config/LocalStatelessSessionBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,12 @@ import org.w3c.dom.Element; -import org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean; +import org.springframework.jndi.JndiObjectFactoryBean; /** * {@link org.springframework.beans.factory.xml.BeanDefinitionParser} * implementation for parsing '{@code local-slsb}' tags and - * creating {@link LocalStatelessSessionProxyFactoryBean} definitions. + * creating plain {@link JndiObjectFactoryBean} definitions. * * @author Rob Harrop * @author Juergen Hoeller @@ -32,8 +32,8 @@ class LocalStatelessSessionBeanDefinitionParser extends AbstractJndiLocatingBeanDefinitionParser { @Override - protected String getBeanClassName(Element element) { - return "org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean"; + protected Class getBeanClass(Element element) { + return JndiObjectFactoryBean.class; } } diff --git a/spring-context/src/main/java/org/springframework/ejb/config/RemoteStatelessSessionBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/ejb/config/RemoteStatelessSessionBeanDefinitionParser.java index 15883bdb14ca..a88c5f646189 100644 --- a/spring-context/src/main/java/org/springframework/ejb/config/RemoteStatelessSessionBeanDefinitionParser.java +++ b/spring-context/src/main/java/org/springframework/ejb/config/RemoteStatelessSessionBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,12 @@ import org.w3c.dom.Element; -import org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean; +import org.springframework.jndi.JndiObjectFactoryBean; /** * {@link org.springframework.beans.factory.xml.BeanDefinitionParser} * implementation for parsing '{@code remote-slsb}' tags and - * creating {@link SimpleRemoteStatelessSessionProxyFactoryBean} definitions. + * creating plain {@link JndiObjectFactoryBean} definitions. * * @author Rob Harrop * @author Juergen Hoeller @@ -32,8 +32,8 @@ class RemoteStatelessSessionBeanDefinitionParser extends AbstractJndiLocatingBeanDefinitionParser { @Override - protected String getBeanClassName(Element element) { - return "org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean"; + protected Class getBeanClass(Element element) { + return JndiObjectFactoryBean.class; } } diff --git a/spring-context/src/main/java/org/springframework/ejb/config/package-info.java b/spring-context/src/main/java/org/springframework/ejb/config/package-info.java index a5442d93e90d..501900852b51 100644 --- a/spring-context/src/main/java/org/springframework/ejb/config/package-info.java +++ b/spring-context/src/main/java/org/springframework/ejb/config/package-info.java @@ -1,5 +1,5 @@ /** - * Support package for EJB/Java EE-related configuration, + * Support package for EJB/Jakarta EE-related configuration, * with XML schema being the primary configuration format. */ @NonNullApi diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/WebLogicClassLoaderAdapter.java b/spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/WebLogicClassLoaderAdapter.java deleted file mode 100644 index 1e4e0cd05bb5..000000000000 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/WebLogicClassLoaderAdapter.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.instrument.classloading.weblogic; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -import org.springframework.util.Assert; - -/** - * Reflective wrapper around a WebLogic 10 class loader. Used to - * encapsulate the classloader-specific methods (discovered and - * called through reflection) from the load-time weaver. - * - * @author Costin Leau - * @author Juergen Hoeller - * @since 2.5 - */ -class WebLogicClassLoaderAdapter { - - private static final String GENERIC_CLASS_LOADER_NAME = "weblogic.utils.classloaders.GenericClassLoader"; - - private static final String CLASS_PRE_PROCESSOR_NAME = "weblogic.utils.classloaders.ClassPreProcessor"; - - - private final ClassLoader classLoader; - - private final Class wlPreProcessorClass; - - private final Method addPreProcessorMethod; - - private final Method getClassFinderMethod; - - private final Method getParentMethod; - - private final Constructor wlGenericClassLoaderConstructor; - - - public WebLogicClassLoaderAdapter(ClassLoader classLoader) { - Class wlGenericClassLoaderClass; - try { - wlGenericClassLoaderClass = classLoader.loadClass(GENERIC_CLASS_LOADER_NAME); - this.wlPreProcessorClass = classLoader.loadClass(CLASS_PRE_PROCESSOR_NAME); - this.addPreProcessorMethod = classLoader.getClass().getMethod( - "addInstanceClassPreProcessor", this.wlPreProcessorClass); - this.getClassFinderMethod = classLoader.getClass().getMethod("getClassFinder"); - this.getParentMethod = classLoader.getClass().getMethod("getParent"); - this.wlGenericClassLoaderConstructor = wlGenericClassLoaderClass.getConstructor( - this.getClassFinderMethod.getReturnType(), ClassLoader.class); - } - catch (Throwable ex) { - throw new IllegalStateException( - "Could not initialize WebLogic LoadTimeWeaver because WebLogic 10 API classes are not available", ex); - } - - if (!wlGenericClassLoaderClass.isInstance(classLoader)) { - throw new IllegalArgumentException( - "ClassLoader must be an instance of [" + wlGenericClassLoaderClass.getName() + "]: " + classLoader); - } - this.classLoader = classLoader; - } - - - public void addTransformer(ClassFileTransformer transformer) { - Assert.notNull(transformer, "ClassFileTransformer must not be null"); - try { - InvocationHandler adapter = new WebLogicClassPreProcessorAdapter(transformer, this.classLoader); - Object adapterInstance = Proxy.newProxyInstance(this.wlPreProcessorClass.getClassLoader(), - new Class[] {this.wlPreProcessorClass}, adapter); - this.addPreProcessorMethod.invoke(this.classLoader, adapterInstance); - } - catch (InvocationTargetException ex) { - throw new IllegalStateException("WebLogic addInstanceClassPreProcessor method threw exception", ex.getCause()); - } - catch (Throwable ex) { - throw new IllegalStateException("Could not invoke WebLogic addInstanceClassPreProcessor method", ex); - } - } - - public ClassLoader getClassLoader() { - return this.classLoader; - } - - public ClassLoader getThrowawayClassLoader() { - try { - Object classFinder = this.getClassFinderMethod.invoke(this.classLoader); - Object parent = this.getParentMethod.invoke(this.classLoader); - // arguments for 'clone'-like method - return (ClassLoader) this.wlGenericClassLoaderConstructor.newInstance(classFinder, parent); - } - catch (InvocationTargetException ex) { - throw new IllegalStateException("WebLogic GenericClassLoader constructor failed", ex.getCause()); - } - catch (Throwable ex) { - throw new IllegalStateException("Could not construct WebLogic GenericClassLoader", ex); - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/WebLogicClassPreProcessorAdapter.java b/spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/WebLogicClassPreProcessorAdapter.java deleted file mode 100644 index 36c8834412e9..000000000000 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/WebLogicClassPreProcessorAdapter.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.instrument.classloading.weblogic; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.IllegalClassFormatException; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.util.Hashtable; - -import org.springframework.lang.Nullable; - -/** - * Adapter that implements WebLogic ClassPreProcessor interface, delegating to a - * standard JDK {@link ClassFileTransformer} underneath. - * - *

    To avoid compile time checks again the vendor API, a dynamic proxy is - * being used. - * - * @author Costin Leau - * @author Juergen Hoeller - * @since 2.5 - */ -class WebLogicClassPreProcessorAdapter implements InvocationHandler { - - private final ClassFileTransformer transformer; - - private final ClassLoader loader; - - - /** - * Construct a new {@link WebLogicClassPreProcessorAdapter}. - */ - public WebLogicClassPreProcessorAdapter(ClassFileTransformer transformer, ClassLoader loader) { - this.transformer = transformer; - this.loader = loader; - } - - - @Override - @Nullable - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - String name = method.getName(); - if ("equals".equals(name)) { - return (proxy == args[0]); - } - else if ("hashCode".equals(name)) { - return hashCode(); - } - else if ("toString".equals(name)) { - return toString(); - } - else if ("initialize".equals(name)) { - initialize((Hashtable) args[0]); - return null; - } - else if ("preProcess".equals(name)) { - return preProcess((String) args[0], (byte[]) args[1]); - } - else { - throw new IllegalArgumentException("Unknown method: " + method); - } - } - - public void initialize(Hashtable params) { - } - - public byte[] preProcess(String className, byte[] classBytes) { - try { - byte[] result = this.transformer.transform(this.loader, className, null, null, classBytes); - return (result != null ? result : classBytes); - } - catch (IllegalClassFormatException ex) { - throw new IllegalStateException("Cannot transform due to illegal class format", ex); - } - } - - @Override - public String toString() { - return getClass().getName() + " for transformer: " + this.transformer; - } - -} diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/WebLogicLoadTimeWeaver.java b/spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/WebLogicLoadTimeWeaver.java deleted file mode 100644 index 9ca2b222b480..000000000000 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/WebLogicLoadTimeWeaver.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.instrument.classloading.weblogic; - -import java.lang.instrument.ClassFileTransformer; - -import org.springframework.core.OverridingClassLoader; -import org.springframework.instrument.classloading.LoadTimeWeaver; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * {@link LoadTimeWeaver} implementation for WebLogic's instrumentable - * ClassLoader. - * - *

    NOTE: Requires BEA WebLogic version 10 or higher. - * - * @author Costin Leau - * @author Juergen Hoeller - * @since 2.5 - */ -public class WebLogicLoadTimeWeaver implements LoadTimeWeaver { - - private final WebLogicClassLoaderAdapter classLoader; - - - /** - * Creates a new instance of the {@link WebLogicLoadTimeWeaver} class using - * the default {@link ClassLoader class loader}. - * @see org.springframework.util.ClassUtils#getDefaultClassLoader() - */ - public WebLogicLoadTimeWeaver() { - this(ClassUtils.getDefaultClassLoader()); - } - - /** - * Creates a new instance of the {@link WebLogicLoadTimeWeaver} class using - * the supplied {@link ClassLoader}. - * @param classLoader the {@code ClassLoader} to delegate to for weaving - */ - public WebLogicLoadTimeWeaver(@Nullable ClassLoader classLoader) { - Assert.notNull(classLoader, "ClassLoader must not be null"); - this.classLoader = new WebLogicClassLoaderAdapter(classLoader); - } - - - @Override - public void addTransformer(ClassFileTransformer transformer) { - this.classLoader.addTransformer(transformer); - } - - @Override - public ClassLoader getInstrumentableClassLoader() { - return this.classLoader.getClassLoader(); - } - - @Override - public ClassLoader getThrowawayClassLoader() { - return new OverridingClassLoader(this.classLoader.getClassLoader(), - this.classLoader.getThrowawayClassLoader()); - } - -} diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/package-info.java b/spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/package-info.java deleted file mode 100644 index 9335b6934192..000000000000 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/weblogic/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Support for class instrumentation on BEA WebLogic 10+. - */ -@NonNullApi -@NonNullFields -package org.springframework.instrument.classloading.weblogic; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassLoaderAdapter.java b/spring-context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassLoaderAdapter.java deleted file mode 100644 index bb68f0748e6f..000000000000 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassLoaderAdapter.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.instrument.classloading.websphere; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.List; - -import org.springframework.util.Assert; - -/** - * Reflective wrapper around a WebSphere 7+ class loader. Used to - * encapsulate the classloader-specific methods (discovered and - * called through reflection) from the load-time weaver. - * - * @author Costin Leau - * @author Juergen Hoeller - * @since 3.1 - */ -class WebSphereClassLoaderAdapter { - - private static final String COMPOUND_CLASS_LOADER_NAME = "com.ibm.ws.classloader.CompoundClassLoader"; - - private static final String CLASS_PRE_PROCESSOR_NAME = "com.ibm.websphere.classloader.ClassLoaderInstancePreDefinePlugin"; - - private static final String PLUGINS_FIELD = "preDefinePlugins"; - - - private ClassLoader classLoader; - - private Class wsPreProcessorClass; - - private Method addPreDefinePlugin; - - private Constructor cloneConstructor; - - private Field transformerList; - - - public WebSphereClassLoaderAdapter(ClassLoader classLoader) { - Class wsCompoundClassLoaderClass; - try { - wsCompoundClassLoaderClass = classLoader.loadClass(COMPOUND_CLASS_LOADER_NAME); - this.cloneConstructor = classLoader.getClass().getDeclaredConstructor(wsCompoundClassLoaderClass); - this.cloneConstructor.setAccessible(true); - - this.wsPreProcessorClass = classLoader.loadClass(CLASS_PRE_PROCESSOR_NAME); - this.addPreDefinePlugin = classLoader.getClass().getMethod("addPreDefinePlugin", this.wsPreProcessorClass); - this.transformerList = wsCompoundClassLoaderClass.getDeclaredField(PLUGINS_FIELD); - this.transformerList.setAccessible(true); - } - catch (Throwable ex) { - throw new IllegalStateException( - "Could not initialize WebSphere LoadTimeWeaver because WebSphere API classes are not available", ex); - } - - if (!wsCompoundClassLoaderClass.isInstance(classLoader)) { - throw new IllegalArgumentException( - "ClassLoader must be an instance of [" + COMPOUND_CLASS_LOADER_NAME + "]: " + classLoader); - } - this.classLoader = classLoader; - } - - - public ClassLoader getClassLoader() { - return this.classLoader; - } - - public void addTransformer(ClassFileTransformer transformer) { - Assert.notNull(transformer, "ClassFileTransformer must not be null"); - try { - InvocationHandler adapter = new WebSphereClassPreDefinePlugin(transformer); - Object adapterInstance = Proxy.newProxyInstance(this.wsPreProcessorClass.getClassLoader(), - new Class[] {this.wsPreProcessorClass}, adapter); - this.addPreDefinePlugin.invoke(this.classLoader, adapterInstance); - } - catch (InvocationTargetException ex) { - throw new IllegalStateException("WebSphere addPreDefinePlugin method threw exception", ex.getCause()); - } - catch (Throwable ex) { - throw new IllegalStateException("Could not invoke WebSphere addPreDefinePlugin method", ex); - } - } - - public ClassLoader getThrowawayClassLoader() { - try { - ClassLoader loader = this.cloneConstructor.newInstance(getClassLoader()); - // Clear out the transformers (copied as well) - List list = (List) this.transformerList.get(loader); - list.clear(); - return loader; - } - catch (InvocationTargetException ex) { - throw new IllegalStateException("WebSphere CompoundClassLoader constructor failed", ex.getCause()); - } - catch (Throwable ex) { - throw new IllegalStateException("Could not construct WebSphere CompoundClassLoader", ex); - } - } - -} diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassPreDefinePlugin.java b/spring-context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassPreDefinePlugin.java deleted file mode 100644 index c2d96a6ab9aa..000000000000 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassPreDefinePlugin.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.instrument.classloading.websphere; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.security.CodeSource; - -import org.springframework.util.FileCopyUtils; - -/** - * Adapter that implements WebSphere 7.0 ClassPreProcessPlugin interface, - * delegating to a standard JDK {@link ClassFileTransformer} underneath. - * - *

    To avoid compile time checks again the vendor API, a dynamic proxy is - * being used. - * - * @author Costin Leau - * @since 3.1 - */ -class WebSphereClassPreDefinePlugin implements InvocationHandler { - - private final ClassFileTransformer transformer; - - - /** - * Create a new {@link WebSphereClassPreDefinePlugin}. - * @param transformer the {@link ClassFileTransformer} to be adapted - * (must not be {@code null}) - */ - public WebSphereClassPreDefinePlugin(ClassFileTransformer transformer) { - this.transformer = transformer; - ClassLoader classLoader = transformer.getClass().getClassLoader(); - - // First force the full class loading of the weaver by invoking transformation on a dummy class - try { - String dummyClass = Dummy.class.getName().replace('.', '/'); - byte[] bytes = FileCopyUtils.copyToByteArray(classLoader.getResourceAsStream(dummyClass + ".class")); - transformer.transform(classLoader, dummyClass, null, null, bytes); - } - catch (Throwable ex) { - throw new IllegalArgumentException("Cannot load transformer", ex); - } - } - - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - switch (method.getName()) { - case "equals": - return (proxy == args[0]); - case "hashCode": - return hashCode(); - case "toString": - return toString(); - case "transformClass": - return transform((String) args[0], (byte[]) args[1], (CodeSource) args[2], (ClassLoader) args[3]); - default: - throw new IllegalArgumentException("Unknown method: " + method); - } - } - - protected byte[] transform(String className, byte[] classfileBuffer, CodeSource codeSource, ClassLoader classLoader) - throws Exception { - - // NB: WebSphere passes className as "." without class while the transformer expects a VM "/" format - byte[] result = this.transformer.transform(classLoader, className.replace('.', '/'), null, null, classfileBuffer); - return (result != null ? result : classfileBuffer); - } - - @Override - public String toString() { - return getClass().getName() + " for transformer: " + this.transformer; - } - - - private static class Dummy { - } - -} diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereLoadTimeWeaver.java b/spring-context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereLoadTimeWeaver.java deleted file mode 100644 index 0160aefe1604..000000000000 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereLoadTimeWeaver.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.instrument.classloading.websphere; - -import java.lang.instrument.ClassFileTransformer; - -import org.springframework.core.OverridingClassLoader; -import org.springframework.instrument.classloading.LoadTimeWeaver; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * {@link LoadTimeWeaver} implementation for WebSphere's instrumentable ClassLoader. - * Compatible with WebSphere 7 as well as 8 and 9. - * - * @author Costin Leau - * @since 3.1 - */ -public class WebSphereLoadTimeWeaver implements LoadTimeWeaver { - - private final WebSphereClassLoaderAdapter classLoader; - - - /** - * Create a new instance of the {@link WebSphereLoadTimeWeaver} class using - * the default {@link ClassLoader class loader}. - * @see org.springframework.util.ClassUtils#getDefaultClassLoader() - */ - public WebSphereLoadTimeWeaver() { - this(ClassUtils.getDefaultClassLoader()); - } - - /** - * Create a new instance of the {@link WebSphereLoadTimeWeaver} class using - * the supplied {@link ClassLoader}. - * @param classLoader the {@code ClassLoader} to delegate to for weaving - */ - public WebSphereLoadTimeWeaver(@Nullable ClassLoader classLoader) { - Assert.notNull(classLoader, "ClassLoader must not be null"); - this.classLoader = new WebSphereClassLoaderAdapter(classLoader); - } - - - @Override - public void addTransformer(ClassFileTransformer transformer) { - this.classLoader.addTransformer(transformer); - } - - @Override - public ClassLoader getInstrumentableClassLoader() { - return this.classLoader.getClassLoader(); - } - - @Override - public ClassLoader getThrowawayClassLoader() { - return new OverridingClassLoader(this.classLoader.getClassLoader(), - this.classLoader.getThrowawayClassLoader()); - } - -} diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/websphere/package-info.java b/spring-context/src/main/java/org/springframework/instrument/classloading/websphere/package-info.java deleted file mode 100644 index 7bf0ff58b9be..000000000000 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/websphere/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Support for class instrumentation on IBM WebSphere Application Server 7+. - */ -@NonNullApi -@NonNullFields -package org.springframework.instrument.classloading.websphere; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-context/src/main/java/org/springframework/jmx/support/WebSphereMBeanServerFactoryBean.java b/spring-context/src/main/java/org/springframework/jmx/support/WebSphereMBeanServerFactoryBean.java deleted file mode 100644 index fc0d4b8c5350..000000000000 --- a/spring-context/src/main/java/org/springframework/jmx/support/WebSphereMBeanServerFactoryBean.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jmx.support; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import javax.management.MBeanServer; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.jmx.MBeanServerNotFoundException; -import org.springframework.lang.Nullable; - -/** - * {@link FactoryBean} that obtains a WebSphere {@link javax.management.MBeanServer} - * reference through WebSphere's proprietary {@code AdminServiceFactory} API, - * available on WebSphere 5.1 and higher. - * - *

    Exposes the {@code MBeanServer} for bean references. - * - *

    This {@code FactoryBean} is a direct alternative to {@link MBeanServerFactoryBean}, - * which uses standard JMX 1.2 API to access the platform's {@link MBeanServer}. - * - *

    See the javadocs for WebSphere's - * {@code AdminServiceFactory} - * and - * {@code MBeanFactory}. - * - * @author Juergen Hoeller - * @author Rob Harrop - * @since 2.0.3 - * @see javax.management.MBeanServer - * @see MBeanServerFactoryBean - */ -public class WebSphereMBeanServerFactoryBean implements FactoryBean, InitializingBean { - - private static final String ADMIN_SERVICE_FACTORY_CLASS = "com.ibm.websphere.management.AdminServiceFactory"; - - private static final String GET_MBEAN_FACTORY_METHOD = "getMBeanFactory"; - - private static final String GET_MBEAN_SERVER_METHOD = "getMBeanServer"; - - - @Nullable - private MBeanServer mbeanServer; - - - @Override - public void afterPropertiesSet() throws MBeanServerNotFoundException { - try { - /* - * this.mbeanServer = AdminServiceFactory.getMBeanFactory().getMBeanServer(); - */ - Class adminServiceClass = getClass().getClassLoader().loadClass(ADMIN_SERVICE_FACTORY_CLASS); - Method getMBeanFactoryMethod = adminServiceClass.getMethod(GET_MBEAN_FACTORY_METHOD); - Object mbeanFactory = getMBeanFactoryMethod.invoke(null); - Method getMBeanServerMethod = mbeanFactory.getClass().getMethod(GET_MBEAN_SERVER_METHOD); - this.mbeanServer = (MBeanServer) getMBeanServerMethod.invoke(mbeanFactory); - } - catch (ClassNotFoundException ex) { - throw new MBeanServerNotFoundException("Could not find WebSphere's AdminServiceFactory class", ex); - } - catch (InvocationTargetException ex) { - throw new MBeanServerNotFoundException( - "WebSphere's AdminServiceFactory.getMBeanFactory/getMBeanServer method failed", ex.getTargetException()); - } - catch (Exception ex) { - throw new MBeanServerNotFoundException( - "Could not access WebSphere's AdminServiceFactory.getMBeanFactory/getMBeanServer method", ex); - } - } - - - @Override - @Nullable - public MBeanServer getObject() { - return this.mbeanServer; - } - - @Override - public Class getObjectType() { - return (this.mbeanServer != null ? this.mbeanServer.getClass() : MBeanServer.class); - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-context/src/main/java/org/springframework/jndi/JndiLocatorDelegate.java b/spring-context/src/main/java/org/springframework/jndi/JndiLocatorDelegate.java index 7b0c0f2f2f95..640bdc81f28f 100644 --- a/spring-context/src/main/java/org/springframework/jndi/JndiLocatorDelegate.java +++ b/spring-context/src/main/java/org/springframework/jndi/JndiLocatorDelegate.java @@ -77,7 +77,7 @@ public static JndiLocatorDelegate createDefaultResourceRefLocator() { } /** - * Check whether a default JNDI environment, as in a Java EE environment, + * Check whether a default JNDI environment, as in a Jakarta EE environment, * is available on this JVM. * @return {@code true} if a default InitialContext can be used, * {@code false} if not diff --git a/spring-context/src/main/java/org/springframework/jndi/JndiLocatorSupport.java b/spring-context/src/main/java/org/springframework/jndi/JndiLocatorSupport.java index be910152a377..5b901f6c415d 100644 --- a/spring-context/src/main/java/org/springframework/jndi/JndiLocatorSupport.java +++ b/spring-context/src/main/java/org/springframework/jndi/JndiLocatorSupport.java @@ -27,7 +27,7 @@ * bean properties. * *

    JNDI names may or may not include the "java:comp/env/" prefix expected - * by Java EE applications when accessing a locally mapped (ENC - Environmental + * by Jakarta EE applications when accessing a locally mapped (ENC - Environmental * Naming Context) resource. If it doesn't, the "java:comp/env/" prefix will * be prepended if the "resourceRef" property is true (the default is * false) and no other scheme (e.g. "java:") is given. @@ -40,7 +40,7 @@ */ public abstract class JndiLocatorSupport extends JndiAccessor { - /** JNDI prefix used in a Java EE container. */ + /** JNDI prefix used in a Jakarta EE container. */ public static final String CONTAINER_PREFIX = "java:comp/env/"; @@ -48,7 +48,7 @@ public abstract class JndiLocatorSupport extends JndiAccessor { /** - * Set whether the lookup occurs in a Java EE container, i.e. if the prefix + * Set whether the lookup occurs in a Jakarta EE container, i.e. if the prefix * "java:comp/env/" needs to be added if the JNDI name doesn't already * contain it. Default is "false". *

    Note: Will only get applied if no other scheme (e.g. "java:") is given. @@ -58,7 +58,7 @@ public void setResourceRef(boolean resourceRef) { } /** - * Return whether the lookup occurs in a Java EE container. + * Return whether the lookup occurs in a Jakarta EE container. */ public boolean isResourceRef() { return this.resourceRef; diff --git a/spring-context/src/main/java/org/springframework/jndi/JndiObjectLocator.java b/spring-context/src/main/java/org/springframework/jndi/JndiObjectLocator.java index 7de88c4432c1..ff2a0ffb5a0d 100644 --- a/spring-context/src/main/java/org/springframework/jndi/JndiObjectLocator.java +++ b/spring-context/src/main/java/org/springframework/jndi/JndiObjectLocator.java @@ -28,7 +28,7 @@ * providing configurable lookup of a specific JNDI resource. * *

    Exposes a {@link #setJndiName "jndiName"} property. This may or may not - * include the "java:comp/env/" prefix expected by Java EE applications when + * include the "java:comp/env/" prefix expected by Jakarta EE applications when * accessing a locally mapped (Environmental Naming Context) resource. If it * doesn't, the "java:comp/env/" prefix will be prepended if the "resourceRef" * property is true (the default is false) and no other scheme diff --git a/spring-context/src/main/java/org/springframework/jndi/JndiObjectTargetSource.java b/spring-context/src/main/java/org/springframework/jndi/JndiObjectTargetSource.java index 83da60219dab..21b1e0cdae65 100644 --- a/spring-context/src/main/java/org/springframework/jndi/JndiObjectTargetSource.java +++ b/spring-context/src/main/java/org/springframework/jndi/JndiObjectTargetSource.java @@ -39,7 +39,7 @@ * </bean> * * <bean id="queueConnectionFactory" class="org.springframework.aop.framework.ProxyFactoryBean"> - * <property name="proxyInterfaces" value="javax.jms.QueueConnectionFactory"/> + * <property name="proxyInterfaces" value="jakarta.jms.QueueConnectionFactory"/> * <property name="targetSource" ref="queueConnectionFactoryTarget"/> * </bean> * diff --git a/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java b/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java index 06bb11db5b56..25249087720f 100644 --- a/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java +++ b/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java @@ -44,7 +44,7 @@ * the {@link org.springframework.beans.factory.ListableBeanFactory} interface. * *

    This factory resolves given bean names as JNDI names within the - * Java EE application's "java:comp/env/" namespace. It caches the resolved + * Jakarta EE application's "java:comp/env/" namespace. It caches the resolved * types for all obtained objects, and optionally also caches shareable * objects (if they are explicitly marked as * {@link #addShareableResource shareable resource}. diff --git a/spring-context/src/main/java/org/springframework/scheduling/TaskScheduler.java b/spring-context/src/main/java/org/springframework/scheduling/TaskScheduler.java index 326923d10d47..ad81312237e7 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/TaskScheduler.java +++ b/spring-context/src/main/java/org/springframework/scheduling/TaskScheduler.java @@ -39,7 +39,7 @@ * and adding extended trigger capabilities. * *

    This interface is roughly equivalent to a JSR-236 - * {@code ManagedScheduledExecutorService} as supported in Java EE 7 + * {@code ManagedScheduledExecutorService} as supported in Jakarta EE * environments but aligned with Spring's {@code TaskExecutor} model. * * @author Juergen Hoeller diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java index 496afa98119f..40e572f0e8cc 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java @@ -41,7 +41,7 @@ * {@code Future} that can be used to track the result of the asynchronous method * execution. However, since the target method needs to implement the same signature, * it will have to return a temporary {@code Future} handle that just passes a value - * through: e.g. Spring's {@link AsyncResult}, EJB 3.1's {@link javax.ejb.AsyncResult}, + * through: e.g. Spring's {@link AsyncResult}, EJB 3.1's {@link jakarta.ejb.AsyncResult}, * or {@link java.util.concurrent.CompletableFuture#completedFuture(Object)}. * * @author Juergen Hoeller diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java index c5636f2daa00..9b97ccfa6eca 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java @@ -42,7 +42,7 @@ * annotation. This annotation can be used at the method and type level in * implementation classes as well as in service interfaces. * - *

    This advisor detects the EJB 3.1 {@code javax.ejb.Asynchronous} + *

    This advisor detects the EJB 3.1 {@code jakarta.ejb.Asynchronous} * annotation as well, treating it exactly like Spring's own {@code Async}. * Furthermore, a custom async annotation type may get specified through the * {@link #setAsyncAnnotationType "asyncAnnotationType"} property. @@ -99,7 +99,7 @@ public AsyncAnnotationAdvisor( asyncAnnotationTypes.add(Async.class); try { asyncAnnotationTypes.add((Class) - ClassUtils.forName("javax.ejb.Asynchronous", AsyncAnnotationAdvisor.class.getClassLoader())); + ClassUtils.forName("jakarta.ejb.Asynchronous", AsyncAnnotationAdvisor.class.getClassLoader())); } catch (ClassNotFoundException ex) { // If EJB 3.1 API not present, simply ignore. @@ -112,7 +112,7 @@ public AsyncAnnotationAdvisor( /** * Set the 'async' annotation type. *

    The default async annotation type is the {@link Async} annotation, as well - * as the EJB 3.1 {@code javax.ejb.Asynchronous} annotation (if present). + * as the EJB 3.1 {@code jakarta.ejb.Asynchronous} annotation (if present). *

    This setter property exists so that developers can provide their own * (non-Spring-specific) annotation type to indicate that a method is to * be executed asynchronously. diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java index 1e7d9bb49302..54d66d2f8be6 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java @@ -42,7 +42,7 @@ * be provided as well as the annotation type that indicates a method should be * invoked asynchronously. If no annotation type is specified, this post- * processor will detect both Spring's {@link Async @Async} annotation as well - * as the EJB 3.1 {@code javax.ejb.Asynchronous} annotation. + * as the EJB 3.1 {@code jakarta.ejb.Asynchronous} annotation. * *

    For methods having a {@code void} return type, any exception thrown * during the asynchronous method invocation cannot be accessed by the @@ -130,7 +130,7 @@ public void setExceptionHandler(AsyncUncaughtExceptionHandler exceptionHandler) /** * Set the 'async' annotation type to be detected at either class or method * level. By default, both the {@link Async} annotation and the EJB 3.1 - * {@code javax.ejb.Asynchronous} annotation will be detected. + * {@code jakarta.ejb.Asynchronous} annotation will be detected. *

    This setter property exists so that developers can provide their own * (non-Spring-specific) annotation type to indicate that a method (or all * methods of a given class) should be invoked asynchronously. diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/EnableAsync.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/EnableAsync.java index 71f3f03c6dc1..5e394ae7c75e 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/EnableAsync.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/EnableAsync.java @@ -43,7 +43,7 @@ * } * * {@code MyAsyncBean} is a user-defined type with one or more methods annotated with - * either Spring's {@code @Async} annotation, the EJB 3.1 {@code @javax.ejb.Asynchronous} + * either Spring's {@code @Async} annotation, the EJB 3.1 {@code @jakarta.ejb.Asynchronous} * annotation, or any custom annotation specified via the {@link #annotation} attribute. * The aspect is added transparently for any registered bean, for instance via this * configuration: @@ -166,7 +166,7 @@ * Indicate the 'async' annotation type to be detected at either class * or method level. *

    By default, both Spring's @{@link Async} annotation and the EJB 3.1 - * {@code @javax.ejb.Asynchronous} annotation will be detected. + * {@code @jakarta.ejb.Asynchronous} annotation will be detected. *

    This attribute exists so that developers can provide their own * custom annotation type to indicate that a method (or all methods of * a given class) should be invoked asynchronously. diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java index 0b976d3f00a3..1161c453303f 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java @@ -23,8 +23,8 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; -import javax.enterprise.concurrent.ManagedExecutors; -import javax.enterprise.concurrent.ManagedTask; +import jakarta.enterprise.concurrent.ManagedExecutors; +import jakarta.enterprise.concurrent.ManagedTask; import org.springframework.core.task.AsyncListenableTaskExecutor; import org.springframework.core.task.TaskDecorator; @@ -41,11 +41,11 @@ * Also detects an extended {@code java.util.concurrent.ExecutorService}, adapting * the {@link org.springframework.core.task.AsyncTaskExecutor} interface accordingly. * - *

    Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedExecutorService} - * in order to expose {@link javax.enterprise.concurrent.ManagedTask} adapters for it, + *

    Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedExecutorService} + * in order to expose {@link jakarta.enterprise.concurrent.ManagedTask} adapters for it, * exposing a long-running hint based on {@link SchedulingAwareRunnable} and an identity * name based on the given Runnable/Callable's {@code toString()}. For JSR-236 style - * lookup in a Java EE 7 environment, consider using {@link DefaultManagedTaskExecutor}. + * lookup in a Jakarta EE environment, consider using {@link DefaultManagedTaskExecutor}. * *

    Note that there is a pre-built {@link ThreadPoolTaskExecutor} that allows * for defining a {@link java.util.concurrent.ThreadPoolExecutor} in bean style, @@ -70,7 +70,7 @@ public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, Sche static { try { managedExecutorServiceClass = ClassUtils.forName( - "javax.enterprise.concurrent.ManagedExecutorService", + "jakarta.enterprise.concurrent.ManagedExecutorService", ConcurrentTaskScheduler.class.getClassLoader()); } catch (ClassNotFoundException ex) { @@ -95,8 +95,8 @@ public ConcurrentTaskExecutor() { /** * Create a new ConcurrentTaskExecutor, using the given {@link java.util.concurrent.Executor}. - *

    Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedExecutorService} - * in order to expose {@link javax.enterprise.concurrent.ManagedTask} adapters for it. + *

    Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedExecutorService} + * in order to expose {@link jakarta.enterprise.concurrent.ManagedTask} adapters for it. * @param executor the {@link java.util.concurrent.Executor} to delegate to */ public ConcurrentTaskExecutor(@Nullable Executor executor) { @@ -107,8 +107,8 @@ public ConcurrentTaskExecutor(@Nullable Executor executor) { /** * Specify the {@link java.util.concurrent.Executor} to delegate to. - *

    Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedExecutorService} - * in order to expose {@link javax.enterprise.concurrent.ManagedTask} adapters for it. + *

    Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedExecutorService} + * in order to expose {@link jakarta.enterprise.concurrent.ManagedTask} adapters for it. */ public final void setConcurrentExecutor(@Nullable Executor executor) { this.concurrentExecutor = (executor != null ? executor : Executors.newSingleThreadExecutor()); diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java index 887c3f596518..ca16b976e172 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java @@ -25,8 +25,8 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import javax.enterprise.concurrent.LastExecution; -import javax.enterprise.concurrent.ManagedScheduledExecutorService; +import jakarta.enterprise.concurrent.LastExecution; +import jakarta.enterprise.concurrent.ManagedScheduledExecutorService; import org.springframework.core.task.TaskRejectedException; import org.springframework.lang.Nullable; @@ -44,11 +44,11 @@ * Extends {@link ConcurrentTaskExecutor} in order to implement the * {@link org.springframework.scheduling.SchedulingTaskExecutor} interface as well. * - *

    Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedScheduledExecutorService} + *

    Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedScheduledExecutorService} * in order to use it for trigger-based scheduling if possible, instead of Spring's * local trigger management which ends up delegating to regular delay-based scheduling * against the {@code java.util.concurrent.ScheduledExecutorService} API. For JSR-236 style - * lookup in a Java EE 7 environment, consider using {@link DefaultManagedTaskScheduler}. + * lookup in a Jakarta EE environment, consider using {@link DefaultManagedTaskScheduler}. * *

    Note that there is a pre-built {@link ThreadPoolTaskScheduler} that allows for * defining a {@link java.util.concurrent.ScheduledThreadPoolExecutor} in bean style, @@ -73,7 +73,7 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T static { try { managedScheduledExecutorServiceClass = ClassUtils.forName( - "javax.enterprise.concurrent.ManagedScheduledExecutorService", + "jakarta.enterprise.concurrent.ManagedScheduledExecutorService", ConcurrentTaskScheduler.class.getClassLoader()); } catch (ClassNotFoundException ex) { @@ -106,7 +106,7 @@ public ConcurrentTaskScheduler() { /** * Create a new ConcurrentTaskScheduler, using the given * {@link java.util.concurrent.ScheduledExecutorService} as shared delegate. - *

    Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedScheduledExecutorService} + *

    Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedScheduledExecutorService} * in order to use it for trigger-based scheduling if possible, * instead of Spring's local trigger management. * @param scheduledExecutor the {@link java.util.concurrent.ScheduledExecutorService} @@ -121,7 +121,7 @@ public ConcurrentTaskScheduler(ScheduledExecutorService scheduledExecutor) { /** * Create a new ConcurrentTaskScheduler, using the given {@link java.util.concurrent.Executor} * and {@link java.util.concurrent.ScheduledExecutorService} as delegates. - *

    Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedScheduledExecutorService} + *

    Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedScheduledExecutorService} * in order to use it for trigger-based scheduling if possible, * instead of Spring's local trigger management. * @param concurrentExecutor the {@link java.util.concurrent.Executor} to delegate to @@ -150,7 +150,7 @@ private ScheduledExecutorService initScheduledExecutor(@Nullable ScheduledExecut /** * Specify the {@link java.util.concurrent.ScheduledExecutorService} to delegate to. - *

    Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedScheduledExecutorService} + *

    Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedScheduledExecutorService} * in order to use it for trigger-based scheduling if possible, * instead of Spring's local trigger management. *

    Note: This will only apply to {@link TaskScheduler} invocations. @@ -275,7 +275,7 @@ private class EnterpriseConcurrentTriggerScheduler { public ScheduledFuture schedule(Runnable task, final Trigger trigger) { ManagedScheduledExecutorService executor = (ManagedScheduledExecutorService) scheduledExecutor; - return executor.schedule(task, new javax.enterprise.concurrent.Trigger() { + return executor.schedule(task, new jakarta.enterprise.concurrent.Trigger() { @Override @Nullable public Date getNextRunTime(@Nullable LastExecution le, Date taskScheduledTime) { diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedAwareThreadFactory.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedAwareThreadFactory.java index ab1871578365..d52b92ed7597 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedAwareThreadFactory.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedAwareThreadFactory.java @@ -31,10 +31,10 @@ /** * JNDI-based variant of {@link CustomizableThreadFactory}, performing a default lookup - * for JSR-236's "java:comp/DefaultManagedThreadFactory" in a Java EE 7 environment, + * for JSR-236's "java:comp/DefaultManagedThreadFactory" in a Jakarta EE environment, * falling back to the local {@link CustomizableThreadFactory} setup if not found. * - *

    This is a convenient way to use managed threads when running in a Java EE 7 + *

    This is a convenient way to use managed threads when running in a Jakarta EE * environment, simply using regular local threads otherwise - without conditional * setup (i.e. without profiles). * @@ -77,7 +77,7 @@ public void setJndiEnvironment(Properties jndiEnvironment) { } /** - * Set whether the lookup occurs in a Java EE container, i.e. if the prefix + * Set whether the lookup occurs in a Jakarta EE container, i.e. if the prefix * "java:comp/env/" needs to be added if the JNDI name doesn't already * contain it. PersistenceAnnotationBeanPostProcessor's default is "true". * @see org.springframework.jndi.JndiLocatorSupport#setResourceRef diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedTaskExecutor.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedTaskExecutor.java index 62cb3dd9fb1f..bf40a15f3dd2 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedTaskExecutor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedTaskExecutor.java @@ -28,16 +28,16 @@ /** * JNDI-based variant of {@link ConcurrentTaskExecutor}, performing a default lookup for - * JSR-236's "java:comp/DefaultManagedExecutorService" in a Java EE 7/8 environment. + * JSR-236's "java:comp/DefaultManagedExecutorService" in a Jakarta EE/8 environment. * *

    Note: This class is not strictly JSR-236 based; it can work with any regular * {@link java.util.concurrent.Executor} that can be found in JNDI. - * The actual adapting to {@link javax.enterprise.concurrent.ManagedExecutorService} + * The actual adapting to {@link jakarta.enterprise.concurrent.ManagedExecutorService} * happens in the base class {@link ConcurrentTaskExecutor} itself. * * @author Juergen Hoeller * @since 4.0 - * @see javax.enterprise.concurrent.ManagedExecutorService + * @see jakarta.enterprise.concurrent.ManagedExecutorService */ public class DefaultManagedTaskExecutor extends ConcurrentTaskExecutor implements InitializingBean { @@ -64,7 +64,7 @@ public void setJndiEnvironment(Properties jndiEnvironment) { } /** - * Set whether the lookup occurs in a Java EE container, i.e. if the prefix + * Set whether the lookup occurs in a Jakarta EE container, i.e. if the prefix * "java:comp/env/" needs to be added if the JNDI name doesn't already * contain it. PersistenceAnnotationBeanPostProcessor's default is "true". * @see org.springframework.jndi.JndiLocatorSupport#setResourceRef diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedTaskScheduler.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedTaskScheduler.java index 133527ed7712..b1845b563c17 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedTaskScheduler.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedTaskScheduler.java @@ -28,16 +28,16 @@ /** * JNDI-based variant of {@link ConcurrentTaskScheduler}, performing a default lookup for - * JSR-236's "java:comp/DefaultManagedScheduledExecutorService" in a Java EE 7 environment. + * JSR-236's "java:comp/DefaultManagedScheduledExecutorService" in a Jakarta EE environment. * *

    Note: This class is not strictly JSR-236 based; it can work with any regular * {@link java.util.concurrent.ScheduledExecutorService} that can be found in JNDI. - * The actual adapting to {@link javax.enterprise.concurrent.ManagedScheduledExecutorService} + * The actual adapting to {@link jakarta.enterprise.concurrent.ManagedScheduledExecutorService} * happens in the base class {@link ConcurrentTaskScheduler} itself. * * @author Juergen Hoeller * @since 4.0 - * @see javax.enterprise.concurrent.ManagedScheduledExecutorService + * @see jakarta.enterprise.concurrent.ManagedScheduledExecutorService */ public class DefaultManagedTaskScheduler extends ConcurrentTaskScheduler implements InitializingBean { @@ -64,7 +64,7 @@ public void setJndiEnvironment(Properties jndiEnvironment) { } /** - * Set whether the lookup occurs in a Java EE container, i.e. if the prefix + * Set whether the lookup occurs in a Jakarta EE container, i.e. if the prefix * "java:comp/env/" needs to be added if the JNDI name doesn't already * contain it. PersistenceAnnotationBeanPostProcessor's default is "true". * @see org.springframework.jndi.JndiLocatorSupport#setResourceRef diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java index 559890ef5096..dc9a249bdd9f 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java @@ -71,7 +71,7 @@ public abstract class ExecutorConfigurationSupport extends CustomizableThreadFac /** * Set the ThreadFactory to use for the ExecutorService's thread pool. * Default is the underlying ExecutorService's default thread factory. - *

    In a Java EE 7 or other managed environment with JSR-236 support, + *

    In a Jakarta EE or other managed environment with JSR-236 support, * consider specifying a JNDI-located ManagedThreadFactory: by default, * to be found at "java:comp/DefaultManagedThreadFactory". * Use the "jee:jndi-lookup" namespace element in XML or the programmatic @@ -79,7 +79,7 @@ public abstract class ExecutorConfigurationSupport extends CustomizableThreadFac * Alternatively, consider using Spring's {@link DefaultManagedAwareThreadFactory} * with its fallback to local threads in case of no managed thread factory found. * @see java.util.concurrent.Executors#defaultThreadFactory() - * @see javax.enterprise.concurrent.ManagedThreadFactory + * @see jakarta.enterprise.concurrent.ManagedThreadFactory * @see DefaultManagedAwareThreadFactory */ public void setThreadFactory(@Nullable ThreadFactory threadFactory) { diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/package-info.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/package-info.java index a8ea96ee4eeb..7caa0796d908 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/package-info.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/package-info.java @@ -1,6 +1,6 @@ /** * Scheduling convenience classes for the {@code java.util.concurrent} - * and {@code javax.enterprise.concurrent} packages, allowing to set up a + * and {@code jakarta.enterprise.concurrent} packages, allowing to set up a * ThreadPoolExecutor or ScheduledThreadPoolExecutor as a bean in a Spring * context. Provides support for the native {@code java.util.concurrent} * interfaces as well as the Spring {@code TaskExecutor} mechanism. diff --git a/spring-context/src/main/java/org/springframework/stereotype/Repository.java b/spring-context/src/main/java/org/springframework/stereotype/Repository.java index 97cb1358080b..68f668e80afa 100644 --- a/spring-context/src/main/java/org/springframework/stereotype/Repository.java +++ b/spring-context/src/main/java/org/springframework/stereotype/Repository.java @@ -29,7 +29,7 @@ * Domain-Driven Design (Evans, 2003) as "a mechanism for encapsulating storage, * retrieval, and search behavior which emulates a collection of objects". * - *

    Teams implementing traditional Java EE patterns such as "Data Access Object" + *

    Teams implementing traditional Jakarta EE patterns such as "Data Access Object" * may also apply this stereotype to DAO classes, though care should be taken to * understand the distinction between Data Access Object and DDD-style repositories * before doing so. This annotation is a general-purpose stereotype and individual teams diff --git a/spring-context/src/main/java/org/springframework/validation/ObjectError.java b/spring-context/src/main/java/org/springframework/validation/ObjectError.java index 227cd0839529..0a02d714a763 100644 --- a/spring-context/src/main/java/org/springframework/validation/ObjectError.java +++ b/spring-context/src/main/java/org/springframework/validation/ObjectError.java @@ -76,7 +76,7 @@ public String getObjectName() { /** * Preserve the source behind this error: possibly an {@link Exception} * (typically {@link org.springframework.beans.PropertyAccessException}) - * or a Bean Validation {@link javax.validation.ConstraintViolation}. + * or a Bean Validation {@link jakarta.validation.ConstraintViolation}. *

    Note that any such source object is being stored as transient: * that is, it won't be part of a serialized error representation. * @param source the source object @@ -92,7 +92,7 @@ public void wrap(Object source) { /** * Unwrap the source behind this error: possibly an {@link Exception} * (typically {@link org.springframework.beans.PropertyAccessException}) - * or a Bean Validation {@link javax.validation.ConstraintViolation}. + * or a Bean Validation {@link jakarta.validation.ConstraintViolation}. *

    The cause of the outermost exception will be introspected as well, * e.g. the underlying conversion exception or exception thrown from a setter * (instead of having to unwrap the {@code PropertyAccessException} in turn). @@ -117,7 +117,7 @@ else if (this.source instanceof Throwable) { /** * Check the source behind this error: possibly an {@link Exception} * (typically {@link org.springframework.beans.PropertyAccessException}) - * or a Bean Validation {@link javax.validation.ConstraintViolation}. + * or a Bean Validation {@link jakarta.validation.ConstraintViolation}. *

    The cause of the outermost exception will be introspected as well, * e.g. the underlying conversion exception or exception thrown from a setter * (instead of having to unwrap the {@code PropertyAccessException} in turn). diff --git a/spring-context/src/main/java/org/springframework/validation/SmartValidator.java b/spring-context/src/main/java/org/springframework/validation/SmartValidator.java index 4cc17002964b..36ad9f588d60 100644 --- a/spring-context/src/main/java/org/springframework/validation/SmartValidator.java +++ b/spring-context/src/main/java/org/springframework/validation/SmartValidator.java @@ -42,7 +42,7 @@ public interface SmartValidator extends Validator { * @param target the object that is to be validated * @param errors contextual state about the validation process * @param validationHints one or more hint objects to be passed to the validation engine - * @see javax.validation.Validator#validate(Object, Class[]) + * @see jakarta.validation.Validator#validate(Object, Class[]) */ void validate(Object target, Errors errors, Object... validationHints); @@ -56,7 +56,7 @@ public interface SmartValidator extends Validator { * @param errors contextual state about the validation process * @param validationHints one or more hint objects to be passed to the validation engine * @since 5.1 - * @see javax.validation.Validator#validateValue(Class, String, Object, Class[]) + * @see jakarta.validation.Validator#validateValue(Class, String, Object, Class[]) */ default void validateValue( Class targetType, String fieldName, @Nullable Object value, Errors errors, Object... validationHints) { diff --git a/spring-context/src/main/java/org/springframework/validation/annotation/Validated.java b/spring-context/src/main/java/org/springframework/validation/annotation/Validated.java index a5939a3b16d0..02a651ac8fef 100644 --- a/spring-context/src/main/java/org/springframework/validation/annotation/Validated.java +++ b/spring-context/src/main/java/org/springframework/validation/annotation/Validated.java @@ -23,7 +23,7 @@ import java.lang.annotation.Target; /** - * Variant of JSR-303's {@link javax.validation.Valid}, supporting the + * Variant of JSR-303's {@link jakarta.validation.Valid}, supporting the * specification of validation groups. Designed for convenient use with * Spring's JSR-303 support but not JSR-303 specific. * @@ -43,7 +43,7 @@ * * @author Juergen Hoeller * @since 3.1 - * @see javax.validation.Validator#validate(Object, Class[]) + * @see jakarta.validation.Validator#validate(Object, Class[]) * @see org.springframework.validation.SmartValidator#validate(Object, org.springframework.validation.Errors, Object...) * @see org.springframework.validation.beanvalidation.SpringValidatorAdapter * @see org.springframework.validation.beanvalidation.MethodValidationPostProcessor diff --git a/spring-context/src/main/java/org/springframework/validation/annotation/ValidationAnnotationUtils.java b/spring-context/src/main/java/org/springframework/validation/annotation/ValidationAnnotationUtils.java index 196f6fc6c74e..a5309bcb02c2 100644 --- a/spring-context/src/main/java/org/springframework/validation/annotation/ValidationAnnotationUtils.java +++ b/spring-context/src/main/java/org/springframework/validation/annotation/ValidationAnnotationUtils.java @@ -34,7 +34,7 @@ public abstract class ValidationAnnotationUtils { /** * Determine any validation hints by the given annotation. - *

    This implementation checks for {@code @javax.validation.Valid}, + *

    This implementation checks for {@code @jakarta.validation.Valid}, * Spring's {@link org.springframework.validation.annotation.Validated}, * and custom annotations whose name starts with "Valid". * @param ann the annotation (potentially a validation annotation) @@ -45,7 +45,7 @@ public abstract class ValidationAnnotationUtils { public static Object[] determineValidationHints(Annotation ann) { Class annotationType = ann.annotationType(); String annotationName = annotationType.getName(); - if ("javax.validation.Valid".equals(annotationName)) { + if ("jakarta.validation.Valid".equals(annotationName)) { return EMPTY_OBJECT_ARRAY; } Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class); diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessor.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessor.java index 11dccd32aa9b..77c7966a0ed1 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessor.java @@ -19,10 +19,10 @@ import java.util.Iterator; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.springframework.aop.framework.AopProxyUtils; import org.springframework.beans.BeansException; @@ -60,7 +60,7 @@ public void setValidator(Validator validator) { * Set the JSR-303 ValidatorFactory to delegate to for validating beans, * using its default Validator. *

    Default is the default ValidatorFactory's default Validator. - * @see javax.validation.ValidatorFactory#getValidator() + * @see jakarta.validation.ValidatorFactory#getValidator() */ public void setValidatorFactory(ValidatorFactory validatorFactory) { this.validator = validatorFactory.getValidator(); @@ -105,7 +105,7 @@ public Object postProcessAfterInitialization(Object bean, String beanName) throw /** * Perform validation of the given bean. * @param bean the bean instance to validate - * @see javax.validation.Validator#validate + * @see jakarta.validation.Validator#validate */ protected void doValidate(Object bean) { Assert.state(this.validator != null, "No Validator set"); diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/CustomValidatorBean.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/CustomValidatorBean.java index b9c074fb24e5..37800c7df5f4 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/CustomValidatorBean.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/CustomValidatorBean.java @@ -16,12 +16,12 @@ package org.springframework.validation.beanvalidation; -import javax.validation.MessageInterpolator; -import javax.validation.TraversableResolver; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorContext; -import javax.validation.ValidatorFactory; +import jakarta.validation.MessageInterpolator; +import jakarta.validation.TraversableResolver; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorContext; +import jakarta.validation.ValidatorFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.lang.Nullable; @@ -48,7 +48,7 @@ public class CustomValidatorBean extends SpringValidatorAdapter implements Valid /** * Set the ValidatorFactory to obtain the target Validator from. - *

    Default is {@link javax.validation.Validation#buildDefaultValidatorFactory()}. + *

    Default is {@link jakarta.validation.Validation#buildDefaultValidatorFactory()}. */ public void setValidatorFactory(ValidatorFactory validatorFactory) { this.validatorFactory = validatorFactory; diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java index 73ec646bead7..58bc3c2f60ef 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java @@ -27,20 +27,20 @@ import java.util.Map; import java.util.Properties; -import javax.validation.Configuration; -import javax.validation.ConstraintValidatorFactory; -import javax.validation.MessageInterpolator; -import javax.validation.ParameterNameProvider; -import javax.validation.TraversableResolver; -import javax.validation.Validation; -import javax.validation.ValidationException; -import javax.validation.ValidationProviderResolver; -import javax.validation.Validator; -import javax.validation.ValidatorContext; -import javax.validation.ValidatorFactory; -import javax.validation.bootstrap.GenericBootstrap; -import javax.validation.bootstrap.ProviderSpecificBootstrap; - +import jakarta.validation.ClockProvider; +import jakarta.validation.Configuration; +import jakarta.validation.ConstraintValidatorFactory; +import jakarta.validation.MessageInterpolator; +import jakarta.validation.ParameterNameProvider; +import jakarta.validation.TraversableResolver; +import jakarta.validation.Validation; +import jakarta.validation.ValidationException; +import jakarta.validation.ValidationProviderResolver; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorContext; +import jakarta.validation.ValidatorFactory; +import jakarta.validation.bootstrap.GenericBootstrap; +import jakarta.validation.bootstrap.ProviderSpecificBootstrap; import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; import org.springframework.beans.factory.DisposableBean; @@ -57,11 +57,11 @@ import org.springframework.util.ReflectionUtils; /** - * This is the central class for {@code javax.validation} (JSR-303) setup in a Spring - * application context: It bootstraps a {@code javax.validation.ValidationFactory} and + * This is the central class for {@code jakarta.validation} (JSR-303) setup in a Spring + * application context: It bootstraps a {@code jakarta.validation.ValidationFactory} and * exposes it through the Spring {@link org.springframework.validation.Validator} interface - * as well as through the JSR-303 {@link javax.validation.Validator} interface and the - * {@link javax.validation.ValidatorFactory} interface itself. + * as well as through the JSR-303 {@link jakarta.validation.Validator} interface and the + * {@link jakarta.validation.ValidatorFactory} interface itself. * *

    When talking to an instance of this bean through the Spring or JSR-303 Validator interfaces, * you'll be talking to the default Validator of the underlying ValidatorFactory. This is very @@ -69,22 +69,15 @@ * you will almost always use the default Validator anyway. This can also be injected directly * into any target dependency of type {@link org.springframework.validation.Validator}! * - *

    As of Spring 5.0, this class requires Bean Validation 1.1+, with special support - * for Hibernate Validator 5.x (see {@link #setValidationMessageSource}). - * This class is also runtime-compatible with Bean Validation 2.0 and Hibernate Validator 6.0, - * with one special note: If you'd like to call BV 2.0's {@code getClockProvider()} method, - * obtain the native {@code ValidatorFactory} through {@code #unwrap(ValidatorFactory.class)} - * and call the {@code getClockProvider()} method on the returned native reference there. - * *

    This class is also being used by Spring's MVC configuration namespace, in case of the - * {@code javax.validation} API being present but no explicit Validator having been configured. + * {@code jakarta.validation} API being present but no explicit Validator having been configured. * * @author Juergen Hoeller * @since 3.0 - * @see javax.validation.ValidatorFactory - * @see javax.validation.Validator - * @see javax.validation.Validation#buildDefaultValidatorFactory() - * @see javax.validation.ValidatorFactory#getValidator() + * @see jakarta.validation.ValidatorFactory + * @see jakarta.validation.Validator + * @see jakarta.validation.Validation#buildDefaultValidatorFactory() + * @see jakarta.validation.ValidatorFactory#getValidator() */ public class LocalValidatorFactoryBean extends SpringValidatorAdapter implements ValidatorFactory, ApplicationContextAware, InitializingBean, DisposableBean { @@ -123,8 +116,8 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter /** * Specify the desired provider class, if any. *

    If not specified, JSR-303's default search mechanism will be used. - * @see javax.validation.Validation#byProvider(Class) - * @see javax.validation.Validation#byDefaultProvider() + * @see jakarta.validation.Validation#byProvider(Class) + * @see jakarta.validation.Validation#byDefaultProvider() */ @SuppressWarnings("rawtypes") public void setProviderClass(Class providerClass) { @@ -208,7 +201,7 @@ public void setMappingLocations(Resource... mappingLocations) { * Specify bean validation properties to be passed to the validation provider. *

    Can be populated with a String "value" (parsed via PropertiesEditor) * or a "props" element in XML bean definitions. - * @see javax.validation.Configuration#addProperty(String, String) + * @see jakarta.validation.Configuration#addProperty(String, String) */ public void setValidationProperties(Properties jpaProperties) { CollectionUtils.mergePropertiesIntoMap(jpaProperties, this.validationPropertyMap); @@ -217,7 +210,7 @@ public void setValidationProperties(Properties jpaProperties) { /** * Specify bean validation properties to be passed to the validation provider as a Map. *

    Can be populated with a "map" or "props" element in XML bean definitions. - * @see javax.validation.Configuration#addProperty(String, String) + * @see jakarta.validation.Configuration#addProperty(String, String) */ public void setValidationPropertyMap(@Nullable Map validationProperties) { if (validationProperties != null) { @@ -400,18 +393,11 @@ public ParameterNameProvider getParameterNameProvider() { return this.validatorFactory.getParameterNameProvider(); } - // Bean Validation 2.0: currently not implemented here since it would imply - // a hard dependency on the new javax.validation.ClockProvider interface. - // To be resolved once Spring Framework requires Bean Validation 2.0+. - // Obtain the native ValidatorFactory through unwrap(ValidatorFactory.class) - // instead which will fully support a getClockProvider() call as well. - /* @Override - public javax.validation.ClockProvider getClockProvider() { + public ClockProvider getClockProvider() { Assert.notNull(this.validatorFactory, "No target ValidatorFactory set"); return this.validatorFactory.getClockProvider(); } - */ @Override @SuppressWarnings("unchecked") diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocaleContextMessageInterpolator.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocaleContextMessageInterpolator.java index 40854bc3b1d0..0a97ba2c7800 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocaleContextMessageInterpolator.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocaleContextMessageInterpolator.java @@ -18,7 +18,7 @@ import java.util.Locale; -import javax.validation.MessageInterpolator; +import jakarta.validation.MessageInterpolator; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.util.Assert; diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java index 8baf92adbfcb..6e68a740583a 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java @@ -19,13 +19,12 @@ import java.lang.reflect.Method; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.ConstraintViolationException; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; -import javax.validation.executable.ExecutableValidator; - +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; +import jakarta.validation.executable.ExecutableValidator; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; @@ -57,7 +56,7 @@ * @author Juergen Hoeller * @since 3.1 * @see MethodValidationPostProcessor - * @see javax.validation.executable.ExecutableValidator + * @see jakarta.validation.executable.ExecutableValidator */ public class MethodValidationInterceptor implements MethodInterceptor { diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationPostProcessor.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationPostProcessor.java index 45e5d13a5fb6..e24c9a02288d 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationPostProcessor.java @@ -18,9 +18,8 @@ import java.lang.annotation.Annotation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; - +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.aopalliance.aop.Advice; import org.springframework.aop.Pointcut; @@ -55,7 +54,7 @@ * @author Juergen Hoeller * @since 3.1 * @see MethodValidationInterceptor - * @see javax.validation.executable.ExecutableValidator + * @see jakarta.validation.executable.ExecutableValidator */ @SuppressWarnings("serial") public class MethodValidationPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor @@ -101,7 +100,7 @@ else if (validator instanceof SpringValidatorAdapter) { * Set the JSR-303 ValidatorFactory to delegate to for validating methods, * using its default Validator. *

    Default is the default ValidatorFactory's default Validator. - * @see javax.validation.ValidatorFactory#getValidator() + * @see jakarta.validation.ValidatorFactory#getValidator() */ public void setValidatorFactory(ValidatorFactory validatorFactory) { this.validator = validatorFactory.getValidator(); diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/OptionalValidatorFactoryBean.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/OptionalValidatorFactoryBean.java index 6d306943b08a..a2991e556333 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/OptionalValidatorFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/OptionalValidatorFactoryBean.java @@ -16,8 +16,7 @@ package org.springframework.validation.beanvalidation; -import javax.validation.ValidationException; - +import jakarta.validation.ValidationException; import org.apache.commons.logging.LogFactory; /** @@ -26,7 +25,7 @@ * in case of no Bean Validation provider being available. * *

    This is the actual class used by Spring's MVC configuration namespace, - * in case of the {@code javax.validation} API being present but no explicit + * in case of the {@code jakarta.validation} API being present but no explicit * Validator having been configured. * * @author Juergen Hoeller diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringConstraintValidatorFactory.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringConstraintValidatorFactory.java index 5b68f0728351..f26a033a8aba 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringConstraintValidatorFactory.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringConstraintValidatorFactory.java @@ -16,8 +16,8 @@ package org.springframework.validation.beanvalidation; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorFactory; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorFactory; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.util.Assert; diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java index cf41fed3b29d..de02082dffe7 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java @@ -25,13 +25,13 @@ import java.util.Set; import java.util.TreeMap; -import javax.validation.ConstraintViolation; -import javax.validation.ElementKind; -import javax.validation.Path; -import javax.validation.ValidationException; -import javax.validation.executable.ExecutableValidator; -import javax.validation.metadata.BeanDescriptor; -import javax.validation.metadata.ConstraintDescriptor; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ElementKind; +import jakarta.validation.Path; +import jakarta.validation.ValidationException; +import jakarta.validation.executable.ExecutableValidator; +import jakarta.validation.metadata.BeanDescriptor; +import jakarta.validation.metadata.ConstraintDescriptor; import org.springframework.beans.NotReadablePropertyException; import org.springframework.context.MessageSourceResolvable; @@ -63,7 +63,7 @@ * @see CustomValidatorBean * @see LocalValidatorFactoryBean */ -public class SpringValidatorAdapter implements SmartValidator, javax.validation.Validator { +public class SpringValidatorAdapter implements SmartValidator, jakarta.validation.Validator { private static final Set internalAnnotationAttributes = new HashSet<>(4); @@ -74,14 +74,14 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation. } @Nullable - private javax.validation.Validator targetValidator; + private jakarta.validation.Validator targetValidator; /** * Create a new SpringValidatorAdapter for the given JSR-303 Validator. * @param targetValidator the JSR-303 Validator to wrap */ - public SpringValidatorAdapter(javax.validation.Validator targetValidator) { + public SpringValidatorAdapter(jakarta.validation.Validator targetValidator) { Assert.notNull(targetValidator, "Target Validator must not be null"); this.targetValidator = targetValidator; } @@ -89,7 +89,7 @@ public SpringValidatorAdapter(javax.validation.Validator targetValidator) { SpringValidatorAdapter() { } - void setTargetValidator(javax.validation.Validator targetValidator) { + void setTargetValidator(jakarta.validation.Validator targetValidator) { this.targetValidator = targetValidator; } @@ -199,7 +199,7 @@ protected void processConstraintViolations(Set> viol * @param violation the current JSR-303 ConstraintViolation * @return the Spring-reported field (for use with {@link Errors}) * @since 4.2 - * @see javax.validation.ConstraintViolation#getPropertyPath() + * @see jakarta.validation.ConstraintViolation#getPropertyPath() * @see org.springframework.validation.FieldError#getField() */ protected String determineField(ConstraintViolation violation) { @@ -239,7 +239,7 @@ protected String determineField(ConstraintViolation violation) { * @param descriptor the JSR-303 ConstraintDescriptor for the current violation * @return a corresponding error code (for use with {@link Errors}) * @since 4.2 - * @see javax.validation.metadata.ConstraintDescriptor#getAnnotation() + * @see jakarta.validation.metadata.ConstraintDescriptor#getAnnotation() * @see org.springframework.validation.MessageCodesResolver */ protected String determineErrorCode(ConstraintDescriptor descriptor) { @@ -305,7 +305,7 @@ protected MessageSourceResolvable getResolvableField(String objectName, String f * which contains the current field's value * @return the invalid value to expose as part of the field error * @since 4.2 - * @see javax.validation.ConstraintViolation#getInvalidValue() + * @see jakarta.validation.ConstraintViolation#getInvalidValue() * @see org.springframework.validation.FieldError#getRejectedValue() */ @Nullable @@ -387,7 +387,7 @@ public T unwrap(@Nullable Class type) { } catch (ValidationException ex) { // Ignore if just being asked for plain JSR-303 Validator - if (javax.validation.Validator.class == type) { + if (jakarta.validation.Validator.class == type) { return (T) this.targetValidator; } throw ex; diff --git a/spring-context/src/main/resources/org/springframework/ejb/config/spring-jee.xsd b/spring-context/src/main/resources/org/springframework/ejb/config/spring-jee.xsd index ad681b198dad..283e803db813 100644 --- a/spring-context/src/main/resources/org/springframework/ejb/config/spring-jee.xsd +++ b/spring-context/src/main/resources/org/springframework/ejb/config/spring-jee.xsd @@ -13,7 +13,7 @@ @@ -95,62 +95,23 @@ - + - - + - - - - - - - - - - - - - - - - - - - - - - - - + @@ -178,7 +139,7 @@ @@ -186,7 +147,7 @@ @@ -222,37 +183,6 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-context/src/test/java/example/scannable/AutowiredQualifierFooService.java b/spring-context/src/test/java/example/scannable/AutowiredQualifierFooService.java index fc59dcf58d51..72232fb83115 100644 --- a/spring-context/src/test/java/example/scannable/AutowiredQualifierFooService.java +++ b/spring-context/src/test/java/example/scannable/AutowiredQualifierFooService.java @@ -18,7 +18,7 @@ import java.util.concurrent.Future; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; diff --git a/spring-context/src/test/java/example/scannable/FooServiceImpl.java b/spring-context/src/test/java/example/scannable/FooServiceImpl.java index de062761fac8..2b5425f8ecfc 100644 --- a/spring-context/src/test/java/example/scannable/FooServiceImpl.java +++ b/spring-context/src/test/java/example/scannable/FooServiceImpl.java @@ -20,7 +20,7 @@ import java.util.List; import java.util.concurrent.Future; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.ListableBeanFactory; diff --git a/spring-context/src/test/java/org/springframework/beans/factory/annotation/BridgeMethodAutowiringTests.java b/spring-context/src/test/java/org/springframework/beans/factory/annotation/BridgeMethodAutowiringTests.java index 0be289d07b47..d0d555ca5b11 100644 --- a/spring-context/src/test/java/org/springframework/beans/factory/annotation/BridgeMethodAutowiringTests.java +++ b/spring-context/src/test/java/org/springframework/beans/factory/annotation/BridgeMethodAutowiringTests.java @@ -16,9 +16,8 @@ package org.springframework.beans.factory.annotation; -import javax.inject.Inject; -import javax.inject.Named; - +import jakarta.inject.Inject; +import jakarta.inject.Named; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; diff --git a/spring-context/src/test/java/org/springframework/beans/factory/support/InjectAnnotationAutowireContextTests.java b/spring-context/src/test/java/org/springframework/beans/factory/support/InjectAnnotationAutowireContextTests.java index b36639ad7de4..f2f3e2af9e18 100644 --- a/spring-context/src/test/java/org/springframework/beans/factory/support/InjectAnnotationAutowireContextTests.java +++ b/spring-context/src/test/java/org/springframework/beans/factory/support/InjectAnnotationAutowireContextTests.java @@ -21,10 +21,9 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Qualifier; - +import jakarta.inject.Inject; +import jakarta.inject.Named; +import jakarta.inject.Qualifier; import org.junit.jupiter.api.Test; import org.springframework.aop.scope.ScopedProxyUtils; @@ -40,7 +39,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** - * Integration tests for handling JSR-303 {@link javax.inject.Qualifier} annotations. + * Integration tests for handling JSR-303 {@link jakarta.inject.Qualifier} annotations. * * @author Juergen Hoeller * @since 3.0 diff --git a/spring-context/src/test/java/org/springframework/context/annotation/AutoProxyLazyInitTests.java b/spring-context/src/test/java/org/springframework/context/annotation/AutoProxyLazyInitTests.java index c73ddf7ad59e..0f73a07a1fa0 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/AutoProxyLazyInitTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/AutoProxyLazyInitTests.java @@ -16,8 +16,7 @@ package org.springframework.context.annotation; -import javax.annotation.PreDestroy; - +import jakarta.annotation.PreDestroy; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java index 3d300b71dbe0..14ae10d2b319 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java @@ -18,11 +18,10 @@ import java.util.Properties; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.annotation.Resource; -import javax.ejb.EJB; - +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; +import jakarta.annotation.Resource; +import jakarta.ejb.EJB; import org.junit.jupiter.api.Test; import org.springframework.beans.BeansException; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostConstructAndAutowiringTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostConstructAndAutowiringTests.java index 0aaf4c00a069..a63a94be1872 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostConstructAndAutowiringTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostConstructAndAutowiringTests.java @@ -16,8 +16,7 @@ package org.springframework.context.annotation; -import javax.annotation.PostConstruct; - +import jakarta.annotation.PostConstruct; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java index 3b1f1a7f0dd9..d8e78ee153f3 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java @@ -23,8 +23,7 @@ import java.util.List; import java.util.Map; -import javax.annotation.PostConstruct; - +import jakarta.annotation.PostConstruct; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/PrimitiveBeanLookupAndAutowiringTests.java b/spring-context/src/test/java/org/springframework/context/annotation/PrimitiveBeanLookupAndAutowiringTests.java index 31a2d7c631d7..342573f7397e 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/PrimitiveBeanLookupAndAutowiringTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/PrimitiveBeanLookupAndAutowiringTests.java @@ -16,8 +16,7 @@ package org.springframework.context.annotation; -import javax.annotation.Resource; - +import jakarta.annotation.Resource; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/PropertySourceAnnotationTests.java b/spring-context/src/test/java/org/springframework/context/annotation/PropertySourceAnnotationTests.java index faada752fdb3..8b73c760ee10 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/PropertySourceAnnotationTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/PropertySourceAnnotationTests.java @@ -26,8 +26,7 @@ import java.util.Iterator; import java.util.Properties; -import javax.inject.Inject; - +import jakarta.inject.Inject; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanDefinitionStoreException; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/Spr3775InitDestroyLifecycleTests.java b/spring-context/src/test/java/org/springframework/context/annotation/Spr3775InitDestroyLifecycleTests.java index 0fb249595f43..82caf5254e98 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/Spr3775InitDestroyLifecycleTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/Spr3775InitDestroyLifecycleTests.java @@ -20,9 +20,8 @@ import java.util.Arrays; import java.util.List; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.Test; @@ -49,8 +48,8 @@ *
  • {@link InitializingBean} & {@link DisposableBean} interfaces
  • *
  • Custom {@link RootBeanDefinition#getInitMethodName() init} & * {@link RootBeanDefinition#getDestroyMethodName() destroy} methods
  • - *
  • JSR 250's {@link javax.annotation.PostConstruct @PostConstruct} & - * {@link javax.annotation.PreDestroy @PreDestroy} annotations
  • + *
  • JSR 250's {@link jakarta.annotation.PostConstruct @PostConstruct} & + * {@link jakarta.annotation.PreDestroy @PreDestroy} annotations
  • * * * @author Sam Brannen diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java index fa9052002566..2a8eca47d36e 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java @@ -22,8 +22,7 @@ import java.util.List; import java.util.Optional; -import javax.inject.Provider; - +import jakarta.inject.Provider; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanFactory; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java index 89da3b916225..ddc5db678c6c 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java @@ -22,9 +22,8 @@ import java.util.Set; import java.util.function.Supplier; -import javax.annotation.Resource; -import javax.inject.Provider; - +import jakarta.annotation.Resource; +import jakarta.inject.Provider; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanClassLoaderAware; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/Spr12526Tests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/Spr12526Tests.java index 8c069e16add0..5c4f58d5063e 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/Spr12526Tests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/Spr12526Tests.java @@ -16,8 +16,7 @@ package org.springframework.context.annotation.configuration; -import javax.annotation.Resource; - +import jakarta.annotation.Resource; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; diff --git a/spring-context/src/test/java/org/springframework/context/annotation6/Jsr330NamedForScanning.java b/spring-context/src/test/java/org/springframework/context/annotation6/Jsr330NamedForScanning.java index d474a99d4a44..e84bad2a5288 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation6/Jsr330NamedForScanning.java +++ b/spring-context/src/test/java/org/springframework/context/annotation6/Jsr330NamedForScanning.java @@ -16,7 +16,7 @@ package org.springframework.context.annotation6; -import javax.inject.Named; +import jakarta.inject.Named; @Named public class Jsr330NamedForScanning { diff --git a/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java b/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java index c493f075b1ae..8c51dd29420b 100644 --- a/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java +++ b/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java @@ -30,9 +30,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import javax.annotation.PostConstruct; -import javax.inject.Inject; - +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; diff --git a/spring-context/src/test/java/org/springframework/ejb/access/LocalSlsbInvokerInterceptorTests.java b/spring-context/src/test/java/org/springframework/ejb/access/LocalSlsbInvokerInterceptorTests.java deleted file mode 100644 index f34897711754..000000000000 --- a/spring-context/src/test/java/org/springframework/ejb/access/LocalSlsbInvokerInterceptorTests.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ejb.access; - -import javax.ejb.CreateException; -import javax.ejb.EJBLocalHome; -import javax.ejb.EJBLocalObject; -import javax.naming.Context; -import javax.naming.NamingException; - -import org.junit.jupiter.api.Test; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.jndi.JndiTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * @author Rod Johnson - * @author Juergen Hoeller - * @author Chris Beams -*/ -public class LocalSlsbInvokerInterceptorTests { - - /** - * Test that it performs the correct lookup. - */ - @Test - public void testPerformsLookup() throws Exception { - LocalInterfaceWithBusinessMethods ejb = mock(LocalInterfaceWithBusinessMethods.class); - - String jndiName= "foobar"; - Context mockContext = mockContext(jndiName, ejb); - - configuredInterceptor(mockContext, jndiName); - - verify(mockContext).close(); - } - - @Test - public void testLookupFailure() throws Exception { - final NamingException nex = new NamingException(); - final String jndiName= "foobar"; - JndiTemplate jt = new JndiTemplate() { - @Override - public Object lookup(String name) throws NamingException { - assertThat(jndiName.equals(name)).isTrue(); - throw nex; - } - }; - - LocalSlsbInvokerInterceptor si = new LocalSlsbInvokerInterceptor(); - si.setJndiName("foobar"); - // default resourceRef=false should cause this to fail, as java:/comp/env will not - // automatically be added - si.setJndiTemplate(jt); - assertThatExceptionOfType(NamingException.class) - .isThrownBy(si::afterPropertiesSet) - .isSameAs(nex); - } - - @Test - public void testInvokesMethodOnEjbInstance() throws Exception { - Object retVal = new Object(); - LocalInterfaceWithBusinessMethods ejb = mock(LocalInterfaceWithBusinessMethods.class); - given(ejb.targetMethod()).willReturn(retVal); - - String jndiName= "foobar"; - Context mockContext = mockContext(jndiName, ejb); - - LocalSlsbInvokerInterceptor si = configuredInterceptor(mockContext, jndiName); - - ProxyFactory pf = new ProxyFactory(new Class[] { BusinessMethods.class }); - pf.addAdvice(si); - BusinessMethods target = (BusinessMethods) pf.getProxy(); - - assertThat(target.targetMethod() == retVal).isTrue(); - - verify(mockContext).close(); - verify(ejb).remove(); - } - - @Test - public void testInvokesMethodOnEjbInstanceWithSeparateBusinessMethods() throws Exception { - Object retVal = new Object(); - LocalInterface ejb = mock(LocalInterface.class); - given(ejb.targetMethod()).willReturn(retVal); - - String jndiName= "foobar"; - Context mockContext = mockContext(jndiName, ejb); - - LocalSlsbInvokerInterceptor si = configuredInterceptor(mockContext, jndiName); - - ProxyFactory pf = new ProxyFactory(new Class[] { BusinessMethods.class }); - pf.addAdvice(si); - BusinessMethods target = (BusinessMethods) pf.getProxy(); - - assertThat(target.targetMethod() == retVal).isTrue(); - - verify(mockContext).close(); - verify(ejb).remove(); - } - - private void testException(Exception expected) throws Exception { - LocalInterfaceWithBusinessMethods ejb = mock(LocalInterfaceWithBusinessMethods.class); - given(ejb.targetMethod()).willThrow(expected); - - String jndiName= "foobar"; - Context mockContext = mockContext(jndiName, ejb); - - LocalSlsbInvokerInterceptor si = configuredInterceptor(mockContext, jndiName); - - ProxyFactory pf = new ProxyFactory(new Class[] { LocalInterfaceWithBusinessMethods.class }); - pf.addAdvice(si); - LocalInterfaceWithBusinessMethods target = (LocalInterfaceWithBusinessMethods) pf.getProxy(); - - assertThatExceptionOfType(Exception.class) - .isThrownBy(target::targetMethod) - .isSameAs(expected); - - verify(mockContext).close(); - } - - @Test - public void testApplicationException() throws Exception { - testException(new ApplicationException()); - } - - protected Context mockContext(final String jndiName, final Object ejbInstance) - throws Exception { - SlsbHome mockHome = mock(SlsbHome.class); - given(mockHome.create()).willReturn((LocalInterface)ejbInstance); - Context mockCtx = mock(Context.class); - given(mockCtx.lookup("java:comp/env/" + jndiName)).willReturn(mockHome); - return mockCtx; - } - - protected LocalSlsbInvokerInterceptor configuredInterceptor(final Context mockCtx, final String jndiName) - throws Exception { - - LocalSlsbInvokerInterceptor si = new LocalSlsbInvokerInterceptor(); - si.setJndiTemplate(new JndiTemplate() { - @Override - protected Context createInitialContext() throws NamingException { - return mockCtx; - } - }); - si.setJndiName(jndiName); - si.setResourceRef(true); - si.afterPropertiesSet(); - - return si; - } - - - /** - * Needed so that we can mock the create() method. - */ - private interface SlsbHome extends EJBLocalHome { - - LocalInterface create() throws CreateException; - } - - - private interface BusinessMethods { - - Object targetMethod() throws ApplicationException; - } - - - private interface LocalInterface extends EJBLocalObject { - - Object targetMethod() throws ApplicationException; - } - - - private interface LocalInterfaceWithBusinessMethods extends LocalInterface, BusinessMethods { - } - - - @SuppressWarnings("serial") - private class ApplicationException extends Exception { - - public ApplicationException() { - super("appException"); - } - } - -} diff --git a/spring-context/src/test/java/org/springframework/ejb/access/LocalStatelessSessionProxyFactoryBeanTests.java b/spring-context/src/test/java/org/springframework/ejb/access/LocalStatelessSessionProxyFactoryBeanTests.java deleted file mode 100644 index 545e6c288af7..000000000000 --- a/spring-context/src/test/java/org/springframework/ejb/access/LocalStatelessSessionProxyFactoryBeanTests.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ejb.access; - -import java.lang.reflect.Proxy; - -import javax.ejb.CreateException; -import javax.ejb.EJBLocalHome; -import javax.ejb.EJBLocalObject; -import javax.naming.NamingException; - -import org.junit.jupiter.api.Test; - -import org.springframework.jndi.JndiTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; - -/** - * @author Rod Johnson - * @author Juergen Hoeller - * @author Chris Beams - * @since 21.05.2003 - */ -public class LocalStatelessSessionProxyFactoryBeanTests { - - @Test - public void testInvokesMethod() throws Exception { - final int value = 11; - final String jndiName = "foo"; - - MyEjb myEjb = mock(MyEjb.class); - given(myEjb.getValue()).willReturn(value); - - final MyHome home = mock(MyHome.class); - given(home.create()).willReturn(myEjb); - - JndiTemplate jt = new JndiTemplate() { - @Override - public Object lookup(String name) throws NamingException { - // parameterize - assertThat(name.equals("java:comp/env/" + jndiName)).isTrue(); - return home; - } - }; - - LocalStatelessSessionProxyFactoryBean fb = new LocalStatelessSessionProxyFactoryBean(); - fb.setJndiName(jndiName); - fb.setResourceRef(true); - fb.setBusinessInterface(MyBusinessMethods.class); - fb.setJndiTemplate(jt); - - // Need lifecycle methods - fb.afterPropertiesSet(); - - MyBusinessMethods mbm = (MyBusinessMethods) fb.getObject(); - assertThat(Proxy.isProxyClass(mbm.getClass())).isTrue(); - assertThat(mbm.getValue() == value).isTrue(); - verify(myEjb).remove(); - } - - @Test - public void testInvokesMethodOnEjb3StyleBean() throws Exception { - final int value = 11; - final String jndiName = "foo"; - - final MyEjb myEjb = mock(MyEjb.class); - given(myEjb.getValue()).willReturn(value); - - JndiTemplate jt = new JndiTemplate() { - @Override - public Object lookup(String name) throws NamingException { - // parameterize - assertThat(name.equals("java:comp/env/" + jndiName)).isTrue(); - return myEjb; - } - }; - - LocalStatelessSessionProxyFactoryBean fb = new LocalStatelessSessionProxyFactoryBean(); - fb.setJndiName(jndiName); - fb.setResourceRef(true); - fb.setBusinessInterface(MyBusinessMethods.class); - fb.setJndiTemplate(jt); - - // Need lifecycle methods - fb.afterPropertiesSet(); - - MyBusinessMethods mbm = (MyBusinessMethods) fb.getObject(); - assertThat(Proxy.isProxyClass(mbm.getClass())).isTrue(); - assertThat(mbm.getValue() == value).isTrue(); - } - - @Test - public void testCreateException() throws Exception { - final String jndiName = "foo"; - - final CreateException cex = new CreateException(); - final MyHome home = mock(MyHome.class); - given(home.create()).willThrow(cex); - - JndiTemplate jt = new JndiTemplate() { - @Override - public Object lookup(String name) throws NamingException { - // parameterize - assertThat(name.equals(jndiName)).isTrue(); - return home; - } - }; - - LocalStatelessSessionProxyFactoryBean fb = new LocalStatelessSessionProxyFactoryBean(); - fb.setJndiName(jndiName); - fb.setResourceRef(false); // no java:comp/env prefix - fb.setBusinessInterface(MyBusinessMethods.class); - assertThat(MyBusinessMethods.class).isEqualTo(fb.getBusinessInterface()); - fb.setJndiTemplate(jt); - - // Need lifecycle methods - fb.afterPropertiesSet(); - - MyBusinessMethods mbm = (MyBusinessMethods) fb.getObject(); - assertThat(Proxy.isProxyClass(mbm.getClass())).isTrue(); - - assertThatExceptionOfType(EjbAccessException.class).isThrownBy( - mbm::getValue) - .withCause(cex); - } - - @Test - public void testNoBusinessInterfaceSpecified() throws Exception { - // Will do JNDI lookup to get home but won't call create - // Could actually try to figure out interface from create? - final String jndiName = "foo"; - - final MyHome home = mock(MyHome.class); - - JndiTemplate jt = new JndiTemplate() { - @Override - public Object lookup(String name) throws NamingException { - // parameterize - assertThat(name.equals("java:comp/env/" + jndiName)).isTrue(); - return home; - } - }; - - LocalStatelessSessionProxyFactoryBean fb = new LocalStatelessSessionProxyFactoryBean(); - fb.setJndiName(jndiName); - fb.setResourceRef(true); - // Don't set business interface - fb.setJndiTemplate(jt); - - // Check it's a singleton - assertThat(fb.isSingleton()).isTrue(); - - assertThatIllegalArgumentException().isThrownBy( - fb::afterPropertiesSet) - .withMessageContaining("businessInterface"); - - // Expect no methods on home - verifyNoInteractions(home); - } - - - public interface MyHome extends EJBLocalHome { - - MyBusinessMethods create() throws CreateException; - } - - - public interface MyBusinessMethods { - - int getValue(); - } - - - public interface MyEjb extends EJBLocalObject, MyBusinessMethods { - } - -} diff --git a/spring-context/src/test/java/org/springframework/ejb/access/SimpleRemoteSlsbInvokerInterceptorTests.java b/spring-context/src/test/java/org/springframework/ejb/access/SimpleRemoteSlsbInvokerInterceptorTests.java deleted file mode 100644 index 3397cb05ee05..000000000000 --- a/spring-context/src/test/java/org/springframework/ejb/access/SimpleRemoteSlsbInvokerInterceptorTests.java +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ejb.access; - -import java.rmi.ConnectException; -import java.rmi.RemoteException; - -import javax.ejb.CreateException; -import javax.ejb.EJBHome; -import javax.ejb.EJBObject; -import javax.naming.Context; -import javax.naming.NamingException; - -import org.junit.jupiter.api.Test; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.jndi.JndiTemplate; -import org.springframework.remoting.RemoteAccessException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * @author Rod Johnson - * @author Juergen Hoeller - * @author Chris Beams - */ -public class SimpleRemoteSlsbInvokerInterceptorTests { - - private Context mockContext( - String jndiName, RemoteInterface ejbInstance) - throws Exception { - SlsbHome mockHome = mock(SlsbHome.class); - given(mockHome.create()).willReturn(ejbInstance); - Context mockCtx = mock(Context.class); - given(mockCtx.lookup("java:comp/env/" + jndiName)).willReturn(mockHome); - return mockCtx; - } - - private SimpleRemoteSlsbInvokerInterceptor configuredInterceptor( - final Context mockCtx, String jndiName) throws Exception { - - SimpleRemoteSlsbInvokerInterceptor si = createInterceptor(); - si.setJndiTemplate(new JndiTemplate() { - @Override - protected Context createInitialContext() { - return mockCtx; - } - }); - si.setResourceRef(true); - si.setJndiName(jndiName); - - return si; - } - - protected SimpleRemoteSlsbInvokerInterceptor createInterceptor() { - return new SimpleRemoteSlsbInvokerInterceptor(); - } - - protected Object configuredProxy(SimpleRemoteSlsbInvokerInterceptor si, Class ifc) throws NamingException { - si.afterPropertiesSet(); - ProxyFactory pf = new ProxyFactory(new Class[] {ifc}); - pf.addAdvice(si); - return pf.getProxy(); - } - - - @Test - public void testPerformsLookup() throws Exception { - RemoteInterface ejb = mock(RemoteInterface.class); - - String jndiName= "foobar"; - Context mockContext = mockContext(jndiName, ejb); - - SimpleRemoteSlsbInvokerInterceptor si = configuredInterceptor(mockContext, jndiName); - configuredProxy(si, RemoteInterface.class); - - verify(mockContext).close(); - } - - @Test - public void testPerformsLookupWithAccessContext() throws Exception { - RemoteInterface ejb = mock(RemoteInterface.class); - - String jndiName= "foobar"; - Context mockContext = mockContext(jndiName, ejb); - - SimpleRemoteSlsbInvokerInterceptor si = configuredInterceptor(mockContext, jndiName); - si.setExposeAccessContext(true); - RemoteInterface target = (RemoteInterface) configuredProxy(si, RemoteInterface.class); - assertThat(target.targetMethod()).isNull(); - - verify(mockContext, times(2)).close(); - verify(ejb).targetMethod(); - - } - - @Test - public void testLookupFailure() throws Exception { - final NamingException nex = new NamingException(); - final String jndiName = "foobar"; - JndiTemplate jt = new JndiTemplate() { - @Override - public Object lookup(String name) throws NamingException { - assertThat(jndiName.equals(name)).isTrue(); - throw nex; - } - }; - - SimpleRemoteSlsbInvokerInterceptor si = new SimpleRemoteSlsbInvokerInterceptor(); - si.setJndiName("foobar"); - // default resourceRef=false should cause this to fail, as java:/comp/env will not - // automatically be added - si.setJndiTemplate(jt); - assertThatExceptionOfType(NamingException.class) - .isThrownBy(si::afterPropertiesSet) - .isSameAs(nex); - } - - @Test - public void testInvokesMethodOnEjbInstance() throws Exception { - doTestInvokesMethodOnEjbInstance(true, true); - } - - @Test - public void testInvokesMethodOnEjbInstanceWithLazyLookup() throws Exception { - doTestInvokesMethodOnEjbInstance(false, true); - } - - @Test - public void testInvokesMethodOnEjbInstanceWithLazyLookupAndNoCache() throws Exception { - doTestInvokesMethodOnEjbInstance(false, false); - } - - @Test - public void testInvokesMethodOnEjbInstanceWithNoCache() throws Exception { - doTestInvokesMethodOnEjbInstance(true, false); - } - - private void doTestInvokesMethodOnEjbInstance(boolean lookupHomeOnStartup, boolean cacheHome) throws Exception { - Object retVal = new Object(); - final RemoteInterface ejb = mock(RemoteInterface.class); - given(ejb.targetMethod()).willReturn(retVal); - - int lookupCount = 1; - if (!cacheHome) { - lookupCount++; - if (lookupHomeOnStartup) { - lookupCount++; - } - } - - final String jndiName= "foobar"; - Context mockContext = mockContext(jndiName, ejb); - - SimpleRemoteSlsbInvokerInterceptor si = configuredInterceptor(mockContext, jndiName); - si.setLookupHomeOnStartup(lookupHomeOnStartup); - si.setCacheHome(cacheHome); - - RemoteInterface target = (RemoteInterface) configuredProxy(si, RemoteInterface.class); - assertThat(target.targetMethod() == retVal).isTrue(); - assertThat(target.targetMethod() == retVal).isTrue(); - - verify(mockContext, times(lookupCount)).close(); - verify(ejb, times(2)).remove(); - } - - @Test - public void testInvokesMethodOnEjbInstanceWithRemoteException() throws Exception { - final RemoteInterface ejb = mock(RemoteInterface.class); - given(ejb.targetMethod()).willThrow(new RemoteException()); - ejb.remove(); - - final String jndiName= "foobar"; - Context mockContext = mockContext(jndiName, ejb); - - SimpleRemoteSlsbInvokerInterceptor si = configuredInterceptor(mockContext, jndiName); - - RemoteInterface target = (RemoteInterface) configuredProxy(si, RemoteInterface.class); - assertThatExceptionOfType(RemoteException.class).isThrownBy( - target::targetMethod); - - verify(mockContext).close(); - verify(ejb, times(2)).remove(); - } - - @Test - public void testInvokesMethodOnEjbInstanceWithConnectExceptionWithRefresh() throws Exception { - doTestInvokesMethodOnEjbInstanceWithConnectExceptionWithRefresh(true, true); - } - - @Test - public void testInvokesMethodOnEjbInstanceWithConnectExceptionWithRefreshAndLazyLookup() throws Exception { - doTestInvokesMethodOnEjbInstanceWithConnectExceptionWithRefresh(false, true); - } - - @Test - public void testInvokesMethodOnEjbInstanceWithConnectExceptionWithRefreshAndLazyLookupAndNoCache() throws Exception { - doTestInvokesMethodOnEjbInstanceWithConnectExceptionWithRefresh(false, false); - } - - @Test - public void testInvokesMethodOnEjbInstanceWithConnectExceptionWithRefreshAndNoCache() throws Exception { - doTestInvokesMethodOnEjbInstanceWithConnectExceptionWithRefresh(true, false); - } - - private void doTestInvokesMethodOnEjbInstanceWithConnectExceptionWithRefresh( - boolean lookupHomeOnStartup, boolean cacheHome) throws Exception { - - final RemoteInterface ejb = mock(RemoteInterface.class); - given(ejb.targetMethod()).willThrow(new ConnectException("")); - - int lookupCount = 2; - if (!cacheHome) { - lookupCount++; - if (lookupHomeOnStartup) { - lookupCount++; - } - } - - final String jndiName= "foobar"; - Context mockContext = mockContext(jndiName, ejb); - - SimpleRemoteSlsbInvokerInterceptor si = configuredInterceptor(mockContext, jndiName); - si.setRefreshHomeOnConnectFailure(true); - si.setLookupHomeOnStartup(lookupHomeOnStartup); - si.setCacheHome(cacheHome); - - RemoteInterface target = (RemoteInterface) configuredProxy(si, RemoteInterface.class); - assertThatExceptionOfType(ConnectException.class).isThrownBy( - target::targetMethod); - - verify(mockContext, times(lookupCount)).close(); - verify(ejb, times(2)).remove(); - } - - @Test - public void testInvokesMethodOnEjbInstanceWithBusinessInterface() throws Exception { - Object retVal = new Object(); - final RemoteInterface ejb = mock(RemoteInterface.class); - given(ejb.targetMethod()).willReturn(retVal); - - final String jndiName= "foobar"; - Context mockContext = mockContext(jndiName, ejb); - - SimpleRemoteSlsbInvokerInterceptor si = configuredInterceptor(mockContext, jndiName); - - BusinessInterface target = (BusinessInterface) configuredProxy(si, BusinessInterface.class); - assertThat(target.targetMethod() == retVal).isTrue(); - - verify(mockContext).close(); - verify(ejb).remove(); - } - - @Test - public void testInvokesMethodOnEjbInstanceWithBusinessInterfaceWithRemoteException() throws Exception { - final RemoteInterface ejb = mock(RemoteInterface.class); - given(ejb.targetMethod()).willThrow(new RemoteException()); - - final String jndiName= "foobar"; - Context mockContext = mockContext(jndiName, ejb); - - SimpleRemoteSlsbInvokerInterceptor si = configuredInterceptor(mockContext, jndiName); - - BusinessInterface target = (BusinessInterface) configuredProxy(si, BusinessInterface.class); - assertThatExceptionOfType(RemoteAccessException.class).isThrownBy( - target::targetMethod); - - verify(mockContext).close(); - verify(ejb).remove(); - } - - @Test - public void testApplicationException() throws Exception { - doTestException(new ApplicationException()); - } - - @Test - public void testRemoteException() throws Exception { - doTestException(new RemoteException()); - } - - private void doTestException(Exception expected) throws Exception { - final RemoteInterface ejb = mock(RemoteInterface.class); - given(ejb.targetMethod()).willThrow(expected); - - final String jndiName= "foobar"; - Context mockContext = mockContext(jndiName, ejb); - - SimpleRemoteSlsbInvokerInterceptor si = configuredInterceptor(mockContext, jndiName); - - RemoteInterface target = (RemoteInterface) configuredProxy(si, RemoteInterface.class); - assertThatExceptionOfType(Exception.class) - .isThrownBy(target::targetMethod) - .isSameAs(expected); - verify(mockContext).close(); - verify(ejb).remove(); - } - - - /** - * Needed so that we can mock create() method. - */ - protected interface SlsbHome extends EJBHome { - - EJBObject create() throws RemoteException, CreateException; - } - - - protected interface RemoteInterface extends EJBObject { - - // Also business exception!? - Object targetMethod() throws RemoteException, ApplicationException; - } - - - protected interface BusinessInterface { - - Object targetMethod() throws ApplicationException; - } - - - @SuppressWarnings("serial") - protected class ApplicationException extends Exception { - - public ApplicationException() { - super("appException"); - } - } - -} diff --git a/spring-context/src/test/java/org/springframework/ejb/access/SimpleRemoteStatelessSessionProxyFactoryBeanTests.java b/spring-context/src/test/java/org/springframework/ejb/access/SimpleRemoteStatelessSessionProxyFactoryBeanTests.java deleted file mode 100644 index cc5dd44b693d..000000000000 --- a/spring-context/src/test/java/org/springframework/ejb/access/SimpleRemoteStatelessSessionProxyFactoryBeanTests.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ejb.access; - -import java.lang.reflect.Proxy; -import java.rmi.RemoteException; - -import javax.ejb.CreateException; -import javax.ejb.EJBHome; -import javax.ejb.EJBObject; -import javax.naming.NamingException; - -import org.junit.jupiter.api.Test; - -import org.springframework.jndi.JndiTemplate; -import org.springframework.remoting.RemoteAccessException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; - -/** - * @author Rod Johnson - * @author Juergen Hoeller - * @since 21.05.2003 - */ -public class SimpleRemoteStatelessSessionProxyFactoryBeanTests extends SimpleRemoteSlsbInvokerInterceptorTests { - - @Override - protected SimpleRemoteSlsbInvokerInterceptor createInterceptor() { - return new SimpleRemoteStatelessSessionProxyFactoryBean(); - } - - @Override - protected Object configuredProxy(SimpleRemoteSlsbInvokerInterceptor si, Class ifc) throws NamingException { - SimpleRemoteStatelessSessionProxyFactoryBean fb = (SimpleRemoteStatelessSessionProxyFactoryBean) si; - fb.setBusinessInterface(ifc); - fb.afterPropertiesSet(); - return fb.getObject(); - } - - @Test - public void testInvokesMethod() throws Exception { - final int value = 11; - final String jndiName = "foo"; - - MyEjb myEjb = mock(MyEjb.class); - given(myEjb.getValue()).willReturn(value); - - final MyHome home = mock(MyHome.class); - given(home.create()).willReturn(myEjb); - - JndiTemplate jt = new JndiTemplate() { - @Override - public Object lookup(String name) { - // parameterize - assertThat(name.equals("java:comp/env/" + jndiName)).isTrue(); - return home; - } - }; - - SimpleRemoteStatelessSessionProxyFactoryBean fb = new SimpleRemoteStatelessSessionProxyFactoryBean(); - fb.setJndiName(jndiName); - fb.setResourceRef(true); - fb.setBusinessInterface(MyBusinessMethods.class); - fb.setJndiTemplate(jt); - - // Need lifecycle methods - fb.afterPropertiesSet(); - - MyBusinessMethods mbm = (MyBusinessMethods) fb.getObject(); - assertThat(Proxy.isProxyClass(mbm.getClass())).isTrue(); - assertThat(mbm.getValue()).as("Returns expected value").isEqualTo(value); - verify(myEjb).remove(); - } - - @Test - public void testInvokesMethodOnEjb3StyleBean() throws Exception { - final int value = 11; - final String jndiName = "foo"; - - final MyEjb myEjb = mock(MyEjb.class); - given(myEjb.getValue()).willReturn(value); - - JndiTemplate jt = new JndiTemplate() { - @Override - public Object lookup(String name) { - // parameterize - assertThat(name.equals("java:comp/env/" + jndiName)).isTrue(); - return myEjb; - } - }; - - SimpleRemoteStatelessSessionProxyFactoryBean fb = new SimpleRemoteStatelessSessionProxyFactoryBean(); - fb.setJndiName(jndiName); - fb.setResourceRef(true); - fb.setBusinessInterface(MyBusinessMethods.class); - fb.setJndiTemplate(jt); - - // Need lifecycle methods - fb.afterPropertiesSet(); - - MyBusinessMethods mbm = (MyBusinessMethods) fb.getObject(); - assertThat(Proxy.isProxyClass(mbm.getClass())).isTrue(); - assertThat(mbm.getValue()).as("Returns expected value").isEqualTo(value); - } - - @Override - @Test - public void testRemoteException() throws Exception { - final RemoteException rex = new RemoteException(); - final String jndiName = "foo"; - - MyEjb myEjb = mock(MyEjb.class); - given(myEjb.getValue()).willThrow(rex); - // TODO might want to control this behaviour... - // Do we really want to call remove after a remote exception? - - final MyHome home = mock(MyHome.class); - given(home.create()).willReturn(myEjb); - - JndiTemplate jt = new JndiTemplate() { - @Override - public Object lookup(String name) { - // parameterize - assertThat(name.equals("java:comp/env/" + jndiName)).isTrue(); - return home; - } - }; - - SimpleRemoteStatelessSessionProxyFactoryBean fb = new SimpleRemoteStatelessSessionProxyFactoryBean(); - fb.setJndiName(jndiName); - fb.setResourceRef(true); - fb.setBusinessInterface(MyBusinessMethods.class); - fb.setJndiTemplate(jt); - - // Need lifecycle methods - fb.afterPropertiesSet(); - - MyBusinessMethods mbm = (MyBusinessMethods) fb.getObject(); - assertThat(Proxy.isProxyClass(mbm.getClass())).isTrue(); - assertThatExceptionOfType(RemoteException.class) - .isThrownBy(mbm::getValue) - .isSameAs(rex); - verify(myEjb).remove(); - } - - @Test - public void testCreateException() throws Exception { - final String jndiName = "foo"; - - final CreateException cex = new CreateException(); - final MyHome home = mock(MyHome.class); - given(home.create()).willThrow(cex); - - JndiTemplate jt = new JndiTemplate() { - @Override - public Object lookup(String name) { - // parameterize - assertThat(name.equals(jndiName)).isTrue(); - return home; - } - }; - - SimpleRemoteStatelessSessionProxyFactoryBean fb = new SimpleRemoteStatelessSessionProxyFactoryBean(); - fb.setJndiName(jndiName); - // rely on default setting of resourceRef=false, no auto addition of java:/comp/env prefix - fb.setBusinessInterface(MyBusinessMethods.class); - assertThat(MyBusinessMethods.class).isEqualTo(fb.getBusinessInterface()); - fb.setJndiTemplate(jt); - - // Need lifecycle methods - fb.afterPropertiesSet(); - - MyBusinessMethods mbm = (MyBusinessMethods) fb.getObject(); - assertThat(Proxy.isProxyClass(mbm.getClass())).isTrue(); - assertThatExceptionOfType(RemoteException.class).isThrownBy(mbm::getValue); - } - - @Test - public void testCreateExceptionWithLocalBusinessInterface() throws Exception { - final String jndiName = "foo"; - - final CreateException cex = new CreateException(); - final MyHome home = mock(MyHome.class); - given(home.create()).willThrow(cex); - - JndiTemplate jt = new JndiTemplate() { - @Override - public Object lookup(String name) { - // parameterize - assertThat(name.equals(jndiName)).isTrue(); - return home; - } - }; - - SimpleRemoteStatelessSessionProxyFactoryBean fb = new SimpleRemoteStatelessSessionProxyFactoryBean(); - fb.setJndiName(jndiName); - // rely on default setting of resourceRef=false, no auto addition of java:/comp/env prefix - fb.setBusinessInterface(MyLocalBusinessMethods.class); - assertThat(MyLocalBusinessMethods.class).isEqualTo(fb.getBusinessInterface()); - fb.setJndiTemplate(jt); - - // Need lifecycle methods - fb.afterPropertiesSet(); - - MyLocalBusinessMethods mbm = (MyLocalBusinessMethods) fb.getObject(); - assertThat(Proxy.isProxyClass(mbm.getClass())).isTrue(); - assertThatExceptionOfType(RemoteAccessException.class).isThrownBy( - mbm::getValue) - .withCause(cex); - } - - @Test - public void testNoBusinessInterfaceSpecified() throws Exception { - // Will do JNDI lookup to get home but won't call create - // Could actually try to figure out interface from create? - final String jndiName = "foo"; - - final MyHome home = mock(MyHome.class); - - JndiTemplate jt = new JndiTemplate() { - @Override - public Object lookup(String name) throws NamingException { - // parameterize - assertThat(name.equals(jndiName)).isTrue(); - return home; - } - }; - - SimpleRemoteStatelessSessionProxyFactoryBean fb = new SimpleRemoteStatelessSessionProxyFactoryBean(); - fb.setJndiName(jndiName); - // rely on default setting of resourceRef=false, no auto addition of java:/comp/env prefix - // Don't set business interface - fb.setJndiTemplate(jt); - - // Check it's a singleton - assertThat(fb.isSingleton()).isTrue(); - - assertThatIllegalArgumentException().isThrownBy( - fb::afterPropertiesSet) - .withMessageContaining("businessInterface"); - - // Expect no methods on home - verifyNoInteractions(home); - } - - - protected interface MyHome extends EJBHome { - - MyBusinessMethods create() throws CreateException, RemoteException; - } - - - protected interface MyBusinessMethods { - - int getValue() throws RemoteException; - } - - - protected interface MyLocalBusinessMethods { - - int getValue(); - } - - - protected interface MyEjb extends EJBObject, MyBusinessMethods { - } - -} diff --git a/spring-context/src/test/java/org/springframework/ejb/config/JeeNamespaceHandlerEventTests.java b/spring-context/src/test/java/org/springframework/ejb/config/JeeNamespaceHandlerEventTests.java index dc0e81943f33..71692278a41e 100644 --- a/spring-context/src/test/java/org/springframework/ejb/config/JeeNamespaceHandlerEventTests.java +++ b/spring-context/src/test/java/org/springframework/ejb/config/JeeNamespaceHandlerEventTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,20 +35,21 @@ */ public class JeeNamespaceHandlerEventTests { - private CollectingReaderEventListener eventListener = new CollectingReaderEventListener(); + private final CollectingReaderEventListener eventListener = new CollectingReaderEventListener(); - private XmlBeanDefinitionReader reader; + private final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); - private DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + private XmlBeanDefinitionReader reader; @BeforeEach - public void setUp() throws Exception { + public void setup() throws Exception { this.reader = new XmlBeanDefinitionReader(this.beanFactory); this.reader.setEventListener(this.eventListener); this.reader.loadBeanDefinitions(new ClassPathResource("jeeNamespaceHandlerTests.xml", getClass())); } + @Test public void testJndiLookupComponentEventReceived() { ComponentDefinition component = this.eventListener.getComponentDefinition("simple"); diff --git a/spring-context/src/test/java/org/springframework/ejb/config/JeeNamespaceHandlerTests.java b/spring-context/src/test/java/org/springframework/ejb/config/JeeNamespaceHandlerTests.java index ec9662810e6b..65292d305730 100644 --- a/spring-context/src/test/java/org/springframework/ejb/config/JeeNamespaceHandlerTests.java +++ b/spring-context/src/test/java/org/springframework/ejb/config/JeeNamespaceHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,8 +26,6 @@ import org.springframework.beans.testfixture.beans.ITestBean; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.io.ClassPathResource; -import org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean; -import org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean; import org.springframework.jndi.JndiObjectFactoryBean; import static org.assertj.core.api.Assertions.assertThat; @@ -93,44 +91,15 @@ public void testWithReferencedEnvironment() { @Test public void testSimpleLocalSlsb() { BeanDefinition beanDefinition = this.beanFactory.getMergedBeanDefinition("simpleLocalEjb"); - assertThat(beanDefinition.getBeanClassName()).isEqualTo(LocalStatelessSessionProxyFactoryBean.class.getName()); - assertPropertyValue(beanDefinition, "businessInterface", ITestBean.class.getName()); + assertThat(beanDefinition.getBeanClassName()).isEqualTo(JndiObjectFactoryBean.class.getName()); assertPropertyValue(beanDefinition, "jndiName", "ejb/MyLocalBean"); } @Test public void testSimpleRemoteSlsb() { BeanDefinition beanDefinition = this.beanFactory.getMergedBeanDefinition("simpleRemoteEjb"); - assertThat(beanDefinition.getBeanClassName()).isEqualTo(SimpleRemoteStatelessSessionProxyFactoryBean.class.getName()); - assertPropertyValue(beanDefinition, "businessInterface", ITestBean.class.getName()); - assertPropertyValue(beanDefinition, "jndiName", "ejb/MyRemoteBean"); - } - - @Test - public void testComplexLocalSlsb() { - BeanDefinition beanDefinition = this.beanFactory.getMergedBeanDefinition("complexLocalEjb"); - assertThat(beanDefinition.getBeanClassName()).isEqualTo(LocalStatelessSessionProxyFactoryBean.class.getName()); - assertPropertyValue(beanDefinition, "businessInterface", ITestBean.class.getName()); - assertPropertyValue(beanDefinition, "jndiName", "ejb/MyLocalBean"); - assertPropertyValue(beanDefinition, "cacheHome", "true"); - assertPropertyValue(beanDefinition, "lookupHomeOnStartup", "true"); - assertPropertyValue(beanDefinition, "resourceRef", "true"); - assertPropertyValue(beanDefinition, "jndiEnvironment", "foo=bar"); - } - - @Test - public void testComplexRemoteSlsb() { - BeanDefinition beanDefinition = this.beanFactory.getMergedBeanDefinition("complexRemoteEjb"); - assertThat(beanDefinition.getBeanClassName()).isEqualTo(SimpleRemoteStatelessSessionProxyFactoryBean.class.getName()); - assertPropertyValue(beanDefinition, "businessInterface", ITestBean.class.getName()); + assertThat(beanDefinition.getBeanClassName()).isEqualTo(JndiObjectFactoryBean.class.getName()); assertPropertyValue(beanDefinition, "jndiName", "ejb/MyRemoteBean"); - assertPropertyValue(beanDefinition, "cacheHome", "true"); - assertPropertyValue(beanDefinition, "lookupHomeOnStartup", "true"); - assertPropertyValue(beanDefinition, "resourceRef", "true"); - assertPropertyValue(beanDefinition, "jndiEnvironment", "foo=bar"); - assertPropertyValue(beanDefinition, "homeInterface", "org.springframework.beans.testfixture.beans.ITestBean"); - assertPropertyValue(beanDefinition, "refreshHomeOnConnectFailure", "true"); - assertPropertyValue(beanDefinition, "cacheSessionBean", "true"); } @Test diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessorTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessorTests.java index 4ec8ce0c59d9..cc6b89e9db87 100644 --- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessorTests.java @@ -16,10 +16,9 @@ package org.springframework.validation.beanvalidation; -import javax.annotation.PostConstruct; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - +import jakarta.annotation.PostConstruct; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import org.junit.jupiter.api.Test; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; @@ -99,7 +98,7 @@ public void testSizeConstraint() { bd.getPropertyValues().add("stringValue", "s"); ac.registerBeanDefinition("bean", bd); assertThatExceptionOfType(BeanCreationException.class) - .isThrownBy(() -> ac.refresh()) + .isThrownBy(ac::refresh) .havingRootCause() .withMessageContainingAll("stringValue", "invalid"); ac.close(); diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java index bdfa8705d36c..974f431462a2 100644 --- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java +++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java @@ -19,12 +19,11 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import javax.validation.ValidationException; -import javax.validation.Validator; -import javax.validation.constraints.Max; -import javax.validation.constraints.NotNull; -import javax.validation.groups.Default; - +import jakarta.validation.ValidationException; +import jakarta.validation.Validator; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.groups.Default; import org.junit.jupiter.api.Test; import org.springframework.aop.framework.ProxyFactory; @@ -49,15 +48,17 @@ public class MethodValidationTests { @Test + @SuppressWarnings("unchecked") public void testMethodValidationInterceptor() { MyValidBean bean = new MyValidBean(); ProxyFactory proxyFactory = new ProxyFactory(bean); proxyFactory.addAdvice(new MethodValidationInterceptor()); proxyFactory.addAdvisor(new AsyncAnnotationAdvisor()); - doTestProxyValidation((MyValidInterface) proxyFactory.getProxy()); + doTestProxyValidation((MyValidInterface) proxyFactory.getProxy()); } @Test + @SuppressWarnings("unchecked") public void testMethodValidationPostProcessor() { StaticApplicationContext ac = new StaticApplicationContext(); ac.registerSingleton("mvpp", MethodValidationPostProcessor.class); @@ -70,8 +71,7 @@ public void testMethodValidationPostProcessor() { ac.close(); } - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void doTestProxyValidation(MyValidInterface proxy) { + private void doTestProxyValidation(MyValidInterface proxy) { assertThat(proxy.myValidMethod("value", 5)).isNotNull(); assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidMethod("value", 15)); @@ -90,8 +90,8 @@ private void doTestProxyValidation(MyValidInterface proxy) { } @Test - @SuppressWarnings("resource") public void testLazyValidatorForMethodValidation() { + @SuppressWarnings("resource") AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext( LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class, MyValidFactoryBean.class); @@ -99,8 +99,8 @@ public void testLazyValidatorForMethodValidation() { } @Test - @SuppressWarnings("resource") public void testLazyValidatorForMethodValidationWithProxyTargetClass() { + @SuppressWarnings("resource") AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext( LazyMethodValidationConfigWithProxyTargetClass.class, CustomValidatorBean.class, MyValidBean.class, MyValidFactoryBean.class); diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/SpringValidatorAdapterTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/SpringValidatorAdapterTests.java index fe5f62b59848..83138f4344f9 100644 --- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/SpringValidatorAdapterTests.java +++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/SpringValidatorAdapterTests.java @@ -26,23 +26,24 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Set; -import javax.validation.Constraint; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; -import javax.validation.ConstraintViolation; -import javax.validation.Payload; -import javax.validation.Valid; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; - +import jakarta.validation.Constraint; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Payload; +import jakarta.validation.Valid; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -228,6 +229,48 @@ private List createChildren(Parent parent) { return Arrays.asList(child1, child2); } + @Test // SPR-15839 + public void testListElementConstraint() { + BeanWithListElementConstraint bean = new BeanWithListElementConstraint(); + bean.setProperty(Arrays.asList("no", "element", "can", "be", null)); + + BeanPropertyBindingResult errors = new BeanPropertyBindingResult(bean, "bean"); + validatorAdapter.validate(bean, errors); + + assertThat(errors.getFieldErrorCount("property[4]")).isEqualTo(1); + assertThat(errors.getFieldValue("property[4]")).isNull(); + } + + @Test // SPR-15839 + public void testMapValueConstraint() { + Map property = new HashMap<>(); + property.put("no value can be", null); + + BeanWithMapEntryConstraint bean = new BeanWithMapEntryConstraint(); + bean.setProperty(property); + + BeanPropertyBindingResult errors = new BeanPropertyBindingResult(bean, "bean"); + validatorAdapter.validate(bean, errors); + + assertThat(errors.getFieldErrorCount("property[no value can be]")).isEqualTo(1); + assertThat(errors.getFieldValue("property[no value can be]")).isNull(); + } + + @Test // SPR-15839 + public void testMapEntryConstraint() { + Map property = new HashMap<>(); + property.put(null, null); + + BeanWithMapEntryConstraint bean = new BeanWithMapEntryConstraint(); + bean.setProperty(property); + + BeanPropertyBindingResult errors = new BeanPropertyBindingResult(bean, "bean"); + validatorAdapter.validate(bean, errors); + + assertThat(errors.hasFieldErrors("property[]")).isTrue(); + assertThat(errors.getFieldValue("property[]")).isNull(); + } + @Same(field = "password", comparingField = "confirmPassword") @Same(field = "email", comparingField = "confirmEmail") @@ -485,4 +528,34 @@ public boolean isValid(Object value, ConstraintValidatorContext context) { } } + + public class BeanWithListElementConstraint { + + @Valid + private List<@NotNull String> property; + + public List getProperty() { + return property; + } + + public void setProperty(List property) { + this.property = property; + } + } + + + public class BeanWithMapEntryConstraint { + + @Valid + private Map<@NotNull String, @NotNull String> property; + + public Map getProperty() { + return property; + } + + public void setProperty(Map property) { + this.property = property; + } + } + } diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java index a8ae01122e36..29c485dc7722 100644 --- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java +++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java @@ -28,16 +28,15 @@ import java.util.Optional; import java.util.Set; -import javax.validation.Constraint; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; -import javax.validation.ConstraintViolation; -import javax.validation.Payload; -import javax.validation.Valid; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; -import javax.validation.constraints.NotNull; - +import jakarta.validation.Constraint; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Payload; +import jakarta.validation.Valid; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; +import jakarta.validation.constraints.NotNull; import org.hibernate.validator.HibernateValidator; import org.hibernate.validator.HibernateValidatorFactory; import org.junit.jupiter.api.Test; diff --git a/spring-context/src/test/resources/org/springframework/ejb/config/jeeNamespaceHandlerTests.xml b/spring-context/src/test/resources/org/springframework/ejb/config/jeeNamespaceHandlerTests.xml index 6d0dc55e40ed..e8a47157a877 100644 --- a/spring-context/src/test/resources/org/springframework/ejb/config/jeeNamespaceHandlerTests.xml +++ b/spring-context/src/test/resources/org/springframework/ejb/config/jeeNamespaceHandlerTests.xml @@ -40,39 +40,14 @@ - - - - foo=bar - + - - - - foo=bar - + - - - + + + diff --git a/spring-context/src/testFixtures/java/org/springframework/context/testfixture/jndi/SimpleNamingContextBuilder.java b/spring-context/src/testFixtures/java/org/springframework/context/testfixture/jndi/SimpleNamingContextBuilder.java index d686261d1a57..d0a014175fdd 100644 --- a/spring-context/src/testFixtures/java/org/springframework/context/testfixture/jndi/SimpleNamingContextBuilder.java +++ b/spring-context/src/testFixtures/java/org/springframework/context/testfixture/jndi/SimpleNamingContextBuilder.java @@ -42,7 +42,7 @@ * configure JNDI appropriately, so that {@code new InitialContext()} * will expose the required objects. Also usable for standalone applications, * e.g. for binding a JDBC DataSource to a well-known JNDI location, to be - * able to use traditional Java EE data access code outside of a Java EE + * able to use traditional Jakarta EE data access code outside of a Jakarta EE * container. * *

    There are various choices for DataSource implementations: diff --git a/spring-core/spring-core.gradle b/spring-core/spring-core.gradle index a6e5e309b073..de0f6a756e08 100644 --- a/spring-core/spring-core.gradle +++ b/spring-core/spring-core.gradle @@ -52,8 +52,8 @@ dependencies { optional("io.netty:netty-buffer") testImplementation("io.projectreactor:reactor-test") testImplementation("com.google.code.findbugs:jsr305") - testImplementation("javax.annotation:javax.annotation-api") - testImplementation("javax.xml.bind:jaxb-api") + testImplementation("jakarta.annotation:jakarta.annotation-api") + testImplementation("jakarta.xml.bind:jakarta.xml.bind-api") testImplementation("com.fasterxml.woodstox:woodstox-core") testImplementation("org.xmlunit:xmlunit-assertj") testImplementation("org.xmlunit:xmlunit-matchers") diff --git a/spring-core/src/main/java/org/springframework/core/MethodParameter.java b/spring-core/src/main/java/org/springframework/core/MethodParameter.java index 42a0dfca93fc..3ec9549cb60f 100644 --- a/spring-core/src/main/java/org/springframework/core/MethodParameter.java +++ b/spring-core/src/main/java/org/springframework/core/MethodParameter.java @@ -409,7 +409,7 @@ public boolean isOptional() { /** * Check whether this method parameter is annotated with any variant of a - * {@code Nullable} annotation, e.g. {@code javax.annotation.Nullable} or + * {@code Nullable} annotation, e.g. {@code jakarta.annotation.Nullable} or * {@code edu.umd.cs.findbugs.annotations.Nullable}. */ private boolean hasNullableAnnotation() { diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAwareOrderComparator.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAwareOrderComparator.java index 1fe06d42d7f5..a57a0179c3e9 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAwareOrderComparator.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAwareOrderComparator.java @@ -29,7 +29,7 @@ * {@code AnnotationAwareOrderComparator} is an extension of * {@link OrderComparator} that supports Spring's * {@link org.springframework.core.Ordered} interface as well as the - * {@link Order @Order} and {@link javax.annotation.Priority @Priority} + * {@link Order @Order} and {@link jakarta.annotation.Priority @Priority} * annotations, with an order value provided by an {@code Ordered} * instance overriding a statically defined annotation value (if any). * @@ -42,7 +42,7 @@ * @since 2.0.1 * @see org.springframework.core.Ordered * @see org.springframework.core.annotation.Order - * @see javax.annotation.Priority + * @see jakarta.annotation.Priority */ public class AnnotationAwareOrderComparator extends OrderComparator { @@ -54,7 +54,7 @@ public class AnnotationAwareOrderComparator extends OrderComparator { /** * This implementation checks for {@link Order @Order} or - * {@link javax.annotation.Priority @Priority} on various kinds of + * {@link jakarta.annotation.Priority @Priority} on various kinds of * elements, in addition to the {@link org.springframework.core.Ordered} * check in the superclass. */ @@ -80,7 +80,7 @@ private Integer findOrderFromAnnotation(Object obj) { } /** - * This implementation retrieves an @{@link javax.annotation.Priority} + * This implementation retrieves an @{@link jakarta.annotation.Priority} * value, allowing for additional semantics over the regular @{@link Order} * annotation: typically, selecting one object over another in case of * multiple matches but only one object to be returned. diff --git a/spring-core/src/main/java/org/springframework/core/annotation/Order.java b/spring-core/src/main/java/org/springframework/core/annotation/Order.java index a60a439bc618..84f8d067e7c3 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/Order.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/Order.java @@ -40,7 +40,7 @@ * order which is an orthogonal concern determined by dependency relationships and * {@code @DependsOn} declarations (influencing a runtime-determined dependency graph). * - *

    Since Spring 4.1, the standard {@link javax.annotation.Priority} annotation + *

    Since Spring 4.1, the standard {@link jakarta.annotation.Priority} annotation * can be used as a drop-in replacement for this annotation in ordering scenarios. * Note that {@code @Priority} may have additional semantics when a single element * has to be picked (see {@link AnnotationAwareOrderComparator#getPriority}). @@ -58,7 +58,7 @@ * @see org.springframework.core.Ordered * @see AnnotationAwareOrderComparator * @see OrderUtils - * @see javax.annotation.Priority + * @see jakarta.annotation.Priority */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) diff --git a/spring-core/src/main/java/org/springframework/core/annotation/OrderUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/OrderUtils.java index 25acbc848161..46d196e5d2d1 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/OrderUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/OrderUtils.java @@ -25,20 +25,20 @@ /** * General utility for determining the order of an object based on its type declaration. - * Handles Spring's {@link Order} annotation as well as {@link javax.annotation.Priority}. + * Handles Spring's {@link Order} annotation as well as {@link jakarta.annotation.Priority}. * * @author Stephane Nicoll * @author Juergen Hoeller * @since 4.1 * @see Order - * @see javax.annotation.Priority + * @see jakarta.annotation.Priority */ public abstract class OrderUtils { /** Cache marker for a non-annotated Class. */ private static final Object NOT_ANNOTATED = new Object(); - private static final String JAVAX_PRIORITY_ANNOTATION = "javax.annotation.Priority"; + private static final String JAVAX_PRIORITY_ANNOTATION = "jakarta.annotation.Priority"; /** Cache for @Order value (or NOT_ANNOTATED marker) per Class. */ private static final Map orderCache = new ConcurrentReferenceHashMap<>(64); @@ -47,7 +47,7 @@ public abstract class OrderUtils { /** * Return the order on the specified {@code type}, or the specified * default value if none can be found. - *

    Takes care of {@link Order @Order} and {@code @javax.annotation.Priority}. + *

    Takes care of {@link Order @Order} and {@code @jakarta.annotation.Priority}. * @param type the type to handle * @return the priority value, or the specified default order if none can be found * @since 5.0 @@ -61,7 +61,7 @@ public static int getOrder(Class type, int defaultOrder) { /** * Return the order on the specified {@code type}, or the specified * default value if none can be found. - *

    Takes care of {@link Order @Order} and {@code @javax.annotation.Priority}. + *

    Takes care of {@link Order @Order} and {@code @jakarta.annotation.Priority}. * @param type the type to handle * @return the priority value, or the specified default order if none can be found * @see #getPriority(Class) @@ -74,7 +74,7 @@ public static Integer getOrder(Class type, @Nullable Integer defaultOrder) { /** * Return the order on the specified {@code type}. - *

    Takes care of {@link Order @Order} and {@code @javax.annotation.Priority}. + *

    Takes care of {@link Order @Order} and {@code @jakarta.annotation.Priority}. * @param type the type to handle * @return the order value, or {@code null} if none can be found * @see #getPriority(Class) @@ -86,7 +86,7 @@ public static Integer getOrder(Class type) { /** * Return the order declared on the specified {@code element}. - *

    Takes care of {@link Order @Order} and {@code @javax.annotation.Priority}. + *

    Takes care of {@link Order @Order} and {@code @jakarta.annotation.Priority}. * @param element the annotated element (e.g. type or method) * @return the order value, or {@code null} if none can be found * @since 5.3 @@ -99,7 +99,7 @@ public static Integer getOrder(AnnotatedElement element) { /** * Return the order from the specified annotations collection. *

    Takes care of {@link Order @Order} and - * {@code @javax.annotation.Priority}. + * {@code @jakarta.annotation.Priority}. * @param element the source element * @param annotations the annotation to consider * @return the order value, or {@code null} if none can be found @@ -132,7 +132,7 @@ private static Integer findOrder(MergedAnnotations annotations) { } /** - * Return the value of the {@code javax.annotation.Priority} annotation + * Return the value of the {@code jakarta.annotation.Priority} annotation * declared on the specified type, or {@code null} if none. * @param type the type to handle * @return the priority value if the annotation is declared, or {@code null} if none diff --git a/spring-core/src/main/java/org/springframework/core/io/ContextResource.java b/spring-core/src/main/java/org/springframework/core/io/ContextResource.java index f5df62938b18..30f75e00c334 100644 --- a/spring-core/src/main/java/org/springframework/core/io/ContextResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/ContextResource.java @@ -18,7 +18,7 @@ /** * Extended interface for a resource that is loaded from an enclosing - * 'context', e.g. from a {@link javax.servlet.ServletContext} but also + * 'context', e.g. from a {@link jakarta.servlet.ServletContext} but also * from plain classpath paths or relative file system paths (specified * without an explicit prefix, hence applying relative to the local * {@link ResourceLoader}'s context). diff --git a/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java b/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java index 7d96032ad80b..fe0104f58982 100644 --- a/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java +++ b/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java @@ -102,7 +102,7 @@ public SimpleAsyncTaskExecutor(ThreadFactory threadFactory) { * Specify an external factory to use for creating new Threads, * instead of relying on the local properties of this executor. *

    You may specify an inner ThreadFactory bean or also a ThreadFactory reference - * obtained from JNDI (on a Java EE 6 server) or some other lookup mechanism. + * obtained from JNDI (on a Jakarta EE server) or some other lookup mechanism. * @see #setThreadNamePrefix * @see #setThreadPriority */ diff --git a/spring-core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java b/spring-core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java index 3297ff16e11e..0c22b7651b31 100644 --- a/spring-core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java +++ b/spring-core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java @@ -30,12 +30,12 @@ *

    This is primarily for adapting to client components that communicate via the * {@code java.util.concurrent.ExecutorService} API. It can also be used as * common ground between a local Spring {@code TaskExecutor} backend and a - * JNDI-located {@code ManagedExecutorService} in a Java EE 7 environment. + * JNDI-located {@code ManagedExecutorService} in a Jakarta EE environment. * *

    NOTE: This ExecutorService adapter does not support the * lifecycle methods in the {@code java.util.concurrent.ExecutorService} API * ("shutdown()" etc), similar to a server-wide {@code ManagedExecutorService} - * in a Java EE 7 environment. The lifecycle is always up to the backend pool, + * in a Jakarta EE environment. The lifecycle is always up to the backend pool, * with this adapter acting as an access-only proxy for that target pool. * * @author Juergen Hoeller diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java index 2957f31863c8..99b10db9b7eb 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java @@ -32,9 +32,9 @@ import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; -import javax.annotation.Resource; import javax.annotation.meta.When; +import jakarta.annotation.Resource; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationAwareOrderComparatorTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationAwareOrderComparatorTests.java index afe0bcc76200..97ff1aabb516 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationAwareOrderComparatorTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationAwareOrderComparatorTests.java @@ -19,8 +19,7 @@ import java.util.ArrayList; import java.util.List; -import javax.annotation.Priority; - +import jakarta.annotation.Priority; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java index e9e3586bb6a4..f0502a9687d1 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java @@ -35,8 +35,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.annotation.Resource; - +import jakarta.annotation.Resource; import org.junit.jupiter.api.Test; import org.springframework.core.Ordered; @@ -3011,14 +3010,14 @@ public void handleMappedWithDifferentPathAndValueAttributes() { } /** - * Mimics javax.persistence.Id + * Mimics jakarta.persistence.Id */ @Retention(RUNTIME) @interface Id { } /** - * Mimics javax.persistence.GeneratedValue + * Mimics jakarta.persistence.GeneratedValue */ @Retention(RUNTIME) @interface GeneratedValue { diff --git a/spring-core/src/test/java/org/springframework/core/annotation/OrderUtilsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/OrderUtilsTests.java index 08d980baf00b..35c96f2ada67 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/OrderUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/OrderUtilsTests.java @@ -16,8 +16,7 @@ package org.springframework.core.annotation; -import javax.annotation.Priority; - +import jakarta.annotation.Priority; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-core/src/test/java/org/springframework/util/Base64UtilsTests.java b/spring-core/src/test/java/org/springframework/util/Base64UtilsTests.java index 593d81eb6847..17f07b407317 100644 --- a/spring-core/src/test/java/org/springframework/util/Base64UtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/Base64UtilsTests.java @@ -18,8 +18,7 @@ import java.io.UnsupportedEncodingException; -import javax.xml.bind.DatatypeConverter; - +import jakarta.xml.bind.DatatypeConverter; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-jdbc/spring-jdbc.gradle b/spring-jdbc/spring-jdbc.gradle index 41aa3f198720..389462f3bb41 100644 --- a/spring-jdbc/spring-jdbc.gradle +++ b/spring-jdbc/spring-jdbc.gradle @@ -7,7 +7,7 @@ dependencies { api(project(":spring-core")) api(project(":spring-tx")) optional(project(":spring-context")) // for JndiDataSourceLookup - optional("javax.transaction:javax.transaction-api") + optional("jakarta.transaction:jakarta.transaction-api") optional("org.hsqldb:hsqldb") optional("com.h2database:h2") optional("org.apache.derby:derby") diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java index d2f619a4d176..2c84c34014f8 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java @@ -52,14 +52,14 @@ * *

    Application code is required to retrieve the JDBC Connection via * {@link DataSourceUtils#getConnection(DataSource)} instead of a standard - * Java EE-style {@link DataSource#getConnection()} call. Spring classes such as + * Jakarta EE-style {@link DataSource#getConnection()} call. Spring classes such as * {@link org.springframework.jdbc.core.JdbcTemplate} use this strategy implicitly. * If not used in combination with this transaction manager, the * {@link DataSourceUtils} lookup strategy behaves exactly like the native * DataSource lookup; it can thus be used in a portable fashion. * *

    Alternatively, you can allow application code to work with the standard - * Java EE-style lookup pattern {@link DataSource#getConnection()}, for example for + * Jakarta EE-style lookup pattern {@link DataSource#getConnection()}, for example for * legacy code that is not aware of Spring at all. In that case, define a * {@link TransactionAwareDataSourceProxy} for your target DataSource, and pass * that proxy DataSource to your DAOs, which will automatically participate in diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DriverManagerDataSource.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DriverManagerDataSource.java index f803cd46770c..875ac1e88715 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DriverManagerDataSource.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DriverManagerDataSource.java @@ -34,7 +34,7 @@ * connection pool, implementing the same standard interface, but creating new * Connections on every call. * - *

    Useful for test or standalone environments outside of a Java EE container, either + *

    Useful for test or standalone environments outside of a Jakarta EE container, either * as a DataSource bean in a corresponding ApplicationContext or in conjunction with * a simple JNDI environment. Pool-assuming {@code Connection.close()} calls will * simply close the Connection, so any DataSource-aware persistence code should work. @@ -44,7 +44,7 @@ * loading issues with the JDBC DriverManager that be resolved through direct Driver * usage (which is exactly what SimpleDriverDataSource does). * - *

    In a Java EE container, it is recommended to use a JNDI DataSource provided by + *

    In a Jakarta EE container, it is recommended to use a JNDI DataSource provided by * the container. Such a DataSource can be exposed as a DataSource bean in a Spring * ApplicationContext via {@link org.springframework.jndi.JndiObjectFactoryBean}, * for seamless switching to and from a local DataSource bean like this class. diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java index e22d47de3723..6ca3f9f1880b 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java @@ -57,7 +57,7 @@ * without paying a performance penalty if no actual data access happens. * *

    This DataSource proxy gives you behavior analogous to JTA and a - * transactional JNDI DataSource (as provided by the Java EE server), even + * transactional JNDI DataSource (as provided by the Jakarta EE server), even * with a local transaction strategy like DataSourceTransactionManager or * HibernateTransactionManager. It does not add value with Spring's * JtaTransactionManager as transaction strategy. diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java index 09e813d13afa..55b75e02bf73 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java @@ -35,7 +35,7 @@ * connection pool, implementing the same standard interface, but creating new * Connections on every call. * - *

    In a Java EE container, it is recommended to use a JNDI DataSource provided by + *

    In a Jakarta EE container, it is recommended to use a JNDI DataSource provided by * the container. Such a DataSource can be exposed as a DataSource bean in a Spring * ApplicationContext via {@link org.springframework.jndi.JndiObjectFactoryBean}, * for seamless switching to and from a local DataSource bean like this class. diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java index aed3ddb54b4c..9edaca7857a4 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java @@ -32,7 +32,7 @@ /** * Proxy for a target JDBC {@link javax.sql.DataSource}, adding awareness of * Spring-managed transactions. Similar to a transactional JNDI DataSource - * as provided by a Java EE server. + * as provided by a Jakarta EE server. * *

    Data access code that should remain unaware of Spring's data access support * can work with this proxy to seamlessly participate in Spring-managed transactions. @@ -52,7 +52,7 @@ * Connection. If not within a transaction, normal DataSource behavior applies. * *

    This proxy allows data access code to work with the plain JDBC API and still - * participate in Spring-managed transactions, similar to JDBC code in a Java EE/JTA + * participate in Spring-managed transactions, similar to JDBC code in a Jakarta EE/JTA * environment. However, if possible, use Spring's DataSourceUtils, JdbcTemplate or * JDBC operation objects to get transaction participation even without a proxy for * the target DataSource, avoiding the need to define such a proxy in the first place. diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/WebSphereDataSourceAdapter.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/WebSphereDataSourceAdapter.java deleted file mode 100644 index 95e7a2daada5..000000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/WebSphereDataSourceAdapter.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jdbc.datasource; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.sql.Connection; -import java.sql.SQLException; - -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -/** - * {@link DataSource} implementation that delegates all calls to a WebSphere - * target {@link DataSource}, typically obtained from JNDI, applying a current - * isolation level and/or current user credentials to every Connection obtained - * from it. - * - *

    Uses IBM-specific API to get a JDBC Connection with a specific isolation - * level (and read-only flag) from a WebSphere DataSource - * (IBM code example). - * Supports the transaction-specific isolation level exposed by - * {@link org.springframework.transaction.support.TransactionSynchronizationManager#getCurrentTransactionIsolationLevel()}. - * It's also possible to specify a default isolation level, to be applied when the - * current Spring-managed transaction does not define a specific isolation level. - * - *

    Usage example, defining the target DataSource as an inner-bean JNDI lookup - * (of course, you can link to any WebSphere DataSource through a bean reference): - * - *

    - * <bean id="myDataSource" class="org.springframework.jdbc.datasource.WebSphereDataSourceAdapter">
    - *   <property name="targetDataSource">
    - *     <bean class="org.springframework.jndi.JndiObjectFactoryBean">
    - *       <property name="jndiName" value="jdbc/myds"/>
    - *     </bean>
    - *   </property>
    - * </bean>
    - * - * Thanks to Ricardo Olivieri for submitting the original implementation - * of this approach! - * - * @author Juergen Hoeller - * @author Lari Hotari - * @author Ricardo N. Olivieri - * @since 2.0.3 - * @see com.ibm.websphere.rsadapter.JDBCConnectionSpec - * @see com.ibm.websphere.rsadapter.WSDataSource#getConnection(com.ibm.websphere.rsadapter.JDBCConnectionSpec) - * @see org.springframework.transaction.support.TransactionSynchronizationManager#getCurrentTransactionIsolationLevel() - * @see org.springframework.transaction.support.TransactionSynchronizationManager#isCurrentTransactionReadOnly() - */ -public class WebSphereDataSourceAdapter extends IsolationLevelDataSourceAdapter { - - protected final Log logger = LogFactory.getLog(getClass()); - - private Class wsDataSourceClass; - - private Method newJdbcConnSpecMethod; - - private Method wsDataSourceGetConnectionMethod; - - private Method setTransactionIsolationMethod; - - private Method setReadOnlyMethod; - - private Method setUserNameMethod; - - private Method setPasswordMethod; - - - /** - * This constructor retrieves the WebSphere JDBC connection spec API, - * so we can get obtain specific WebSphere Connections using reflection. - */ - public WebSphereDataSourceAdapter() { - try { - this.wsDataSourceClass = getClass().getClassLoader().loadClass("com.ibm.websphere.rsadapter.WSDataSource"); - Class jdbcConnSpecClass = getClass().getClassLoader().loadClass("com.ibm.websphere.rsadapter.JDBCConnectionSpec"); - Class wsrraFactoryClass = getClass().getClassLoader().loadClass("com.ibm.websphere.rsadapter.WSRRAFactory"); - this.newJdbcConnSpecMethod = wsrraFactoryClass.getMethod("createJDBCConnectionSpec"); - this.wsDataSourceGetConnectionMethod = - this.wsDataSourceClass.getMethod("getConnection", jdbcConnSpecClass); - this.setTransactionIsolationMethod = - jdbcConnSpecClass.getMethod("setTransactionIsolation", int.class); - this.setReadOnlyMethod = jdbcConnSpecClass.getMethod("setReadOnly", Boolean.class); - this.setUserNameMethod = jdbcConnSpecClass.getMethod("setUserName", String.class); - this.setPasswordMethod = jdbcConnSpecClass.getMethod("setPassword", String.class); - } - catch (Exception ex) { - throw new IllegalStateException( - "Could not initialize WebSphereDataSourceAdapter because WebSphere API classes are not available: " + ex); - } - } - - /** - * Checks that the specified 'targetDataSource' actually is - * a WebSphere WSDataSource. - */ - @Override - public void afterPropertiesSet() { - super.afterPropertiesSet(); - - if (!this.wsDataSourceClass.isInstance(getTargetDataSource())) { - throw new IllegalStateException( - "Specified 'targetDataSource' is not a WebSphere WSDataSource: " + getTargetDataSource()); - } - } - - - /** - * Builds a WebSphere JDBCConnectionSpec object for the current settings - * and calls {@code WSDataSource.getConnection(JDBCConnectionSpec)}. - * @see #createConnectionSpec - * @see com.ibm.websphere.rsadapter.WSDataSource#getConnection(com.ibm.websphere.rsadapter.JDBCConnectionSpec) - */ - @Override - protected Connection doGetConnection(@Nullable String username, @Nullable String password) throws SQLException { - // Create JDBCConnectionSpec using current isolation level value and read-only flag. - Object connSpec = createConnectionSpec( - getCurrentIsolationLevel(), getCurrentReadOnlyFlag(), username, password); - if (logger.isDebugEnabled()) { - logger.debug("Obtaining JDBC Connection from WebSphere DataSource [" + - getTargetDataSource() + "], using ConnectionSpec [" + connSpec + "]"); - } - // Create Connection through invoking WSDataSource.getConnection(JDBCConnectionSpec) - Connection con = (Connection) invokeJdbcMethod( - this.wsDataSourceGetConnectionMethod, obtainTargetDataSource(), connSpec); - Assert.state(con != null, "No Connection"); - return con; - } - - /** - * Create a WebSphere {@code JDBCConnectionSpec} object for the given characteristics. - *

    The default implementation uses reflection to apply the given settings. - * Can be overridden in subclasses to customize the JDBCConnectionSpec object - * (JDBCConnectionSpec javadoc; - * IBM developerWorks article). - * @param isolationLevel the isolation level to apply (or {@code null} if none) - * @param readOnlyFlag the read-only flag to apply (or {@code null} if none) - * @param username the username to apply ({@code null} or empty indicates the default) - * @param password the password to apply (may be {@code null} or empty) - * @throws SQLException if thrown by JDBCConnectionSpec API methods - * @see com.ibm.websphere.rsadapter.JDBCConnectionSpec - */ - protected Object createConnectionSpec(@Nullable Integer isolationLevel, @Nullable Boolean readOnlyFlag, - @Nullable String username, @Nullable String password) throws SQLException { - - Object connSpec = invokeJdbcMethod(this.newJdbcConnSpecMethod, null); - Assert.state(connSpec != null, "No JDBCConnectionSpec"); - if (isolationLevel != null) { - invokeJdbcMethod(this.setTransactionIsolationMethod, connSpec, isolationLevel); - } - if (readOnlyFlag != null) { - invokeJdbcMethod(this.setReadOnlyMethod, connSpec, readOnlyFlag); - } - // If the username is empty, we'll simply let the target DataSource - // use its default credentials. - if (StringUtils.hasLength(username)) { - invokeJdbcMethod(this.setUserNameMethod, connSpec, username); - invokeJdbcMethod(this.setPasswordMethod, connSpec, password); - } - return connSpec; - } - - - @Nullable - private static Object invokeJdbcMethod(Method method, @Nullable Object target, @Nullable Object... args) - throws SQLException { - try { - return method.invoke(target, args); - } - catch (IllegalAccessException ex) { - ReflectionUtils.handleReflectionException(ex); - } - catch (InvocationTargetException ex) { - if (ex.getTargetException() instanceof SQLException) { - throw (SQLException) ex.getTargetException(); - } - ReflectionUtils.handleInvocationTargetException(ex); - } - throw new IllegalStateException("Should never get here"); - } - -} diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceJtaTransactionTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceJtaTransactionTests.java index 13e87b621bcd..dfd67268392b 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceJtaTransactionTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceJtaTransactionTests.java @@ -23,13 +23,13 @@ import java.util.Map; import javax.sql.DataSource; -import javax.transaction.RollbackException; -import javax.transaction.Status; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; -import javax.transaction.UserTransaction; +import jakarta.transaction.RollbackException; +import jakarta.transaction.Status; +import jakarta.transaction.SystemException; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; +import jakarta.transaction.UserTransaction; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-jms/spring-jms.gradle b/spring-jms/spring-jms.gradle index 32485dff84ba..6757f90eca2c 100644 --- a/spring-jms/spring-jms.gradle +++ b/spring-jms/spring-jms.gradle @@ -5,15 +5,14 @@ dependencies { api(project(":spring-core")) api(project(":spring-messaging")) api(project(":spring-tx")) - compileOnly("javax.jms:javax.jms-api") + compileOnly("jakarta.jms:jakarta.jms-api") optional(project(":spring-aop")) optional(project(":spring-context")) optional(project(":spring-oxm")) - optional("javax.resource:javax.resource-api") - optional("javax.transaction:javax.transaction-api") + optional("jakarta.resource:jakarta.resource-api") + optional("jakarta.transaction:jakarta.transaction-api") optional("com.fasterxml.jackson.core:jackson-databind") testImplementation(testFixtures(project(":spring-beans"))) testImplementation(testFixtures(project(":spring-tx"))) - testImplementation("org.apache.activemq:activemq-broker") - testImplementation("javax.jms:javax.jms-api") + testImplementation("jakarta.jms:jakarta.jms-api") } diff --git a/spring-jms/src/main/java/org/springframework/jms/IllegalStateException.java b/spring-jms/src/main/java/org/springframework/jms/IllegalStateException.java index 1b6d7924f057..87c9192e0605 100644 --- a/spring-jms/src/main/java/org/springframework/jms/IllegalStateException.java +++ b/spring-jms/src/main/java/org/springframework/jms/IllegalStateException.java @@ -21,12 +21,12 @@ * * @author Mark Pollack * @since 1.1 - * @see javax.jms.IllegalStateException + * @see jakarta.jms.IllegalStateException */ @SuppressWarnings("serial") public class IllegalStateException extends JmsException { - public IllegalStateException(javax.jms.IllegalStateException cause) { + public IllegalStateException(jakarta.jms.IllegalStateException cause) { super(cause); } diff --git a/spring-jms/src/main/java/org/springframework/jms/InvalidClientIDException.java b/spring-jms/src/main/java/org/springframework/jms/InvalidClientIDException.java index 25f915971488..d4e84a4bb834 100644 --- a/spring-jms/src/main/java/org/springframework/jms/InvalidClientIDException.java +++ b/spring-jms/src/main/java/org/springframework/jms/InvalidClientIDException.java @@ -21,12 +21,12 @@ * * @author Mark Pollack * @since 1.1 - * @see javax.jms.InvalidClientIDException + * @see jakarta.jms.InvalidClientIDException */ @SuppressWarnings("serial") public class InvalidClientIDException extends JmsException { - public InvalidClientIDException(javax.jms.InvalidClientIDException cause) { + public InvalidClientIDException(jakarta.jms.InvalidClientIDException cause) { super(cause); } diff --git a/spring-jms/src/main/java/org/springframework/jms/InvalidDestinationException.java b/spring-jms/src/main/java/org/springframework/jms/InvalidDestinationException.java index a40434a23161..b1ac9001ebbf 100644 --- a/spring-jms/src/main/java/org/springframework/jms/InvalidDestinationException.java +++ b/spring-jms/src/main/java/org/springframework/jms/InvalidDestinationException.java @@ -21,12 +21,12 @@ * * @author Mark Pollack * @since 1.1 - * @see javax.jms.InvalidDestinationException + * @see jakarta.jms.InvalidDestinationException */ @SuppressWarnings("serial") public class InvalidDestinationException extends JmsException { - public InvalidDestinationException(javax.jms.InvalidDestinationException cause) { + public InvalidDestinationException(jakarta.jms.InvalidDestinationException cause) { super(cause); } diff --git a/spring-jms/src/main/java/org/springframework/jms/InvalidSelectorException.java b/spring-jms/src/main/java/org/springframework/jms/InvalidSelectorException.java index da4c6df92c58..a065af5f8730 100644 --- a/spring-jms/src/main/java/org/springframework/jms/InvalidSelectorException.java +++ b/spring-jms/src/main/java/org/springframework/jms/InvalidSelectorException.java @@ -21,12 +21,12 @@ * * @author Mark Pollack * @since 1.1 - * @see javax.jms.InvalidSelectorException + * @see jakarta.jms.InvalidSelectorException */ @SuppressWarnings("serial") public class InvalidSelectorException extends JmsException { - public InvalidSelectorException(javax.jms.InvalidSelectorException cause) { + public InvalidSelectorException(jakarta.jms.InvalidSelectorException cause) { super(cause); } diff --git a/spring-jms/src/main/java/org/springframework/jms/JmsException.java b/spring-jms/src/main/java/org/springframework/jms/JmsException.java index 0c847adea3e1..77a712e6ed60 100644 --- a/spring-jms/src/main/java/org/springframework/jms/JmsException.java +++ b/spring-jms/src/main/java/org/springframework/jms/JmsException.java @@ -16,7 +16,7 @@ package org.springframework.jms; -import javax.jms.JMSException; +import jakarta.jms.JMSException; import org.springframework.core.NestedRuntimeException; import org.springframework.lang.Nullable; @@ -44,7 +44,7 @@ public JmsException(String msg) { * Constructor that takes a message and a root cause. * @param msg the detail message * @param cause the cause of the exception. This argument is generally - * expected to be a proper subclass of {@link javax.jms.JMSException}, + * expected to be a proper subclass of {@link jakarta.jms.JMSException}, * but can also be a JNDI NamingException or the like. */ public JmsException(String msg, @Nullable Throwable cause) { @@ -53,9 +53,9 @@ public JmsException(String msg, @Nullable Throwable cause) { /** * Constructor that takes a plain root cause, intended for - * subclasses mirroring corresponding {@code javax.jms} exceptions. + * subclasses mirroring corresponding {@code jakarta.jms} exceptions. * @param cause the cause of the exception. This argument is generally - * expected to be a proper subclass of {@link javax.jms.JMSException}. + * expected to be a proper subclass of {@link jakarta.jms.JMSException}. */ public JmsException(@Nullable Throwable cause) { super(cause != null ? cause.getMessage() : null, cause); @@ -80,7 +80,7 @@ public String getErrorCode() { /** * Return the detail message, including the message from the linked exception * if there is one. - * @see javax.jms.JMSException#getLinkedException() + * @see jakarta.jms.JMSException#getLinkedException() */ @Override @Nullable diff --git a/spring-jms/src/main/java/org/springframework/jms/JmsSecurityException.java b/spring-jms/src/main/java/org/springframework/jms/JmsSecurityException.java index a55352d9d56b..1db9307340d9 100644 --- a/spring-jms/src/main/java/org/springframework/jms/JmsSecurityException.java +++ b/spring-jms/src/main/java/org/springframework/jms/JmsSecurityException.java @@ -21,12 +21,12 @@ * * @author Mark Pollack * @since 1.1 - * @see javax.jms.JMSSecurityException + * @see jakarta.jms.JMSSecurityException */ @SuppressWarnings("serial") public class JmsSecurityException extends JmsException { - public JmsSecurityException(javax.jms.JMSSecurityException cause) { + public JmsSecurityException(jakarta.jms.JMSSecurityException cause) { super(cause); } diff --git a/spring-jms/src/main/java/org/springframework/jms/MessageEOFException.java b/spring-jms/src/main/java/org/springframework/jms/MessageEOFException.java index 93cafa81b929..d6f53d1b1b79 100644 --- a/spring-jms/src/main/java/org/springframework/jms/MessageEOFException.java +++ b/spring-jms/src/main/java/org/springframework/jms/MessageEOFException.java @@ -21,12 +21,12 @@ * * @author Mark Pollack * @since 1.1 - * @see javax.jms.MessageEOFException + * @see jakarta.jms.MessageEOFException */ @SuppressWarnings("serial") public class MessageEOFException extends JmsException { - public MessageEOFException(javax.jms.MessageEOFException cause) { + public MessageEOFException(jakarta.jms.MessageEOFException cause) { super(cause); } diff --git a/spring-jms/src/main/java/org/springframework/jms/MessageFormatException.java b/spring-jms/src/main/java/org/springframework/jms/MessageFormatException.java index 5fd26326c543..d70f1fcfb705 100644 --- a/spring-jms/src/main/java/org/springframework/jms/MessageFormatException.java +++ b/spring-jms/src/main/java/org/springframework/jms/MessageFormatException.java @@ -21,12 +21,12 @@ * * @author Mark Pollack * @since 1.1 - * @see javax.jms.MessageFormatException + * @see jakarta.jms.MessageFormatException */ @SuppressWarnings("serial") public class MessageFormatException extends JmsException { - public MessageFormatException(javax.jms.MessageFormatException cause) { + public MessageFormatException(jakarta.jms.MessageFormatException cause) { super(cause); } diff --git a/spring-jms/src/main/java/org/springframework/jms/MessageNotReadableException.java b/spring-jms/src/main/java/org/springframework/jms/MessageNotReadableException.java index d17acc90bf17..04e3221754f6 100644 --- a/spring-jms/src/main/java/org/springframework/jms/MessageNotReadableException.java +++ b/spring-jms/src/main/java/org/springframework/jms/MessageNotReadableException.java @@ -21,12 +21,12 @@ * * @author Mark Pollack * @since 1.1 - * @see javax.jms.MessageNotReadableException + * @see jakarta.jms.MessageNotReadableException */ @SuppressWarnings("serial") public class MessageNotReadableException extends JmsException { - public MessageNotReadableException(javax.jms.MessageNotReadableException cause) { + public MessageNotReadableException(jakarta.jms.MessageNotReadableException cause) { super(cause); } diff --git a/spring-jms/src/main/java/org/springframework/jms/MessageNotWriteableException.java b/spring-jms/src/main/java/org/springframework/jms/MessageNotWriteableException.java index 52aa0223627a..a4a4961577c6 100644 --- a/spring-jms/src/main/java/org/springframework/jms/MessageNotWriteableException.java +++ b/spring-jms/src/main/java/org/springframework/jms/MessageNotWriteableException.java @@ -21,12 +21,12 @@ * * @author Mark Pollack * @since 1.1 - * @see javax.jms.MessageNotWriteableException + * @see jakarta.jms.MessageNotWriteableException */ @SuppressWarnings("serial") public class MessageNotWriteableException extends JmsException { - public MessageNotWriteableException(javax.jms.MessageNotWriteableException cause) { + public MessageNotWriteableException(jakarta.jms.MessageNotWriteableException cause) { super(cause); } diff --git a/spring-jms/src/main/java/org/springframework/jms/ResourceAllocationException.java b/spring-jms/src/main/java/org/springframework/jms/ResourceAllocationException.java index 31ded9822361..d3a1f674553d 100644 --- a/spring-jms/src/main/java/org/springframework/jms/ResourceAllocationException.java +++ b/spring-jms/src/main/java/org/springframework/jms/ResourceAllocationException.java @@ -21,12 +21,12 @@ * * @author Mark Pollack * @since 1.1 - * @see javax.jms.ResourceAllocationException + * @see jakarta.jms.ResourceAllocationException */ @SuppressWarnings("serial") public class ResourceAllocationException extends JmsException { - public ResourceAllocationException(javax.jms.ResourceAllocationException cause) { + public ResourceAllocationException(jakarta.jms.ResourceAllocationException cause) { super(cause); } diff --git a/spring-jms/src/main/java/org/springframework/jms/TransactionInProgressException.java b/spring-jms/src/main/java/org/springframework/jms/TransactionInProgressException.java index 37bab68acdfe..2b271ae13975 100644 --- a/spring-jms/src/main/java/org/springframework/jms/TransactionInProgressException.java +++ b/spring-jms/src/main/java/org/springframework/jms/TransactionInProgressException.java @@ -21,12 +21,12 @@ * * @author Mark Pollack * @since 1.1 - * @see javax.jms.TransactionInProgressException + * @see jakarta.jms.TransactionInProgressException */ @SuppressWarnings("serial") public class TransactionInProgressException extends JmsException { - public TransactionInProgressException(javax.jms.TransactionInProgressException cause) { + public TransactionInProgressException(jakarta.jms.TransactionInProgressException cause) { super(cause); } diff --git a/spring-jms/src/main/java/org/springframework/jms/TransactionRolledBackException.java b/spring-jms/src/main/java/org/springframework/jms/TransactionRolledBackException.java index 3d0cd7501b09..d29b98206c8b 100644 --- a/spring-jms/src/main/java/org/springframework/jms/TransactionRolledBackException.java +++ b/spring-jms/src/main/java/org/springframework/jms/TransactionRolledBackException.java @@ -21,12 +21,12 @@ * * @author Mark Pollack * @since 1.1 - * @see javax.jms.TransactionRolledBackException + * @see jakarta.jms.TransactionRolledBackException */ @SuppressWarnings("serial") public class TransactionRolledBackException extends JmsException { - public TransactionRolledBackException(javax.jms.TransactionRolledBackException cause) { + public TransactionRolledBackException(jakarta.jms.TransactionRolledBackException cause) { super(cause); } diff --git a/spring-jms/src/main/java/org/springframework/jms/UncategorizedJmsException.java b/spring-jms/src/main/java/org/springframework/jms/UncategorizedJmsException.java index ebf07cdf05df..f449cbacd8cb 100644 --- a/spring-jms/src/main/java/org/springframework/jms/UncategorizedJmsException.java +++ b/spring-jms/src/main/java/org/springframework/jms/UncategorizedJmsException.java @@ -37,7 +37,7 @@ public UncategorizedJmsException(String msg) { * Constructor that takes a message and a root cause. * @param msg the detail message * @param cause the cause of the exception. This argument is generally - * expected to be a proper subclass of {@link javax.jms.JMSException}, + * expected to be a proper subclass of {@link jakarta.jms.JMSException}, * but can also be a JNDI NamingException or the like. */ public UncategorizedJmsException(String msg, Throwable cause) { @@ -47,7 +47,7 @@ public UncategorizedJmsException(String msg, Throwable cause) { /** * Constructor that takes a root cause only. * @param cause the cause of the exception. This argument is generally - * expected to be a proper subclass of {@link javax.jms.JMSException}, + * expected to be a proper subclass of {@link jakarta.jms.JMSException}, * but can also be a JNDI NamingException or the like. */ public UncategorizedJmsException(Throwable cause) { diff --git a/spring-jms/src/main/java/org/springframework/jms/annotation/EnableJms.java b/spring-jms/src/main/java/org/springframework/jms/annotation/EnableJms.java index 79c4a3bca051..589e0e8e1380 100644 --- a/spring-jms/src/main/java/org/springframework/jms/annotation/EnableJms.java +++ b/spring-jms/src/main/java/org/springframework/jms/annotation/EnableJms.java @@ -74,8 +74,8 @@ * is set a {@code JmsListenerContainerFactory} bean with name {@code jmsListenerContainerFactory} is * assumed to be present. * - *

    the following configuration would ensure that every time a {@link javax.jms.Message} - * is received on the {@link javax.jms.Destination} named "myQueue", {@code MyService.process()} + *

    the following configuration would ensure that every time a {@link jakarta.jms.Message} + * is received on the {@link jakarta.jms.Destination} named "myQueue", {@code MyService.process()} * is called with the content of the message: * *

    diff --git a/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java b/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java
    index 20847545785b..7fee7e70935c 100644
    --- a/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java
    +++ b/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java
    @@ -47,8 +47,8 @@
      * 

    Annotated JMS listener methods are allowed to have flexible signatures similar * to what {@link MessageMapping} provides: *

      - *
    • {@link javax.jms.Session} to get access to the JMS session
    • - *
    • {@link javax.jms.Message} or one of its subclasses to get access to the raw JMS message
    • + *
    • {@link jakarta.jms.Session} to get access to the JMS session
    • + *
    • {@link jakarta.jms.Message} or one of its subclasses to get access to the raw JMS message
    • *
    • {@link org.springframework.messaging.Message} to use Spring's messaging abstraction counterpart
    • *
    • {@link org.springframework.messaging.handler.annotation.Payload @Payload}-annotated method * arguments, including support for validation
    • diff --git a/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerContainerFactory.java b/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerContainerFactory.java index 39007467a0b9..049aa4bcc061 100644 --- a/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerContainerFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerContainerFactory.java @@ -16,9 +16,8 @@ package org.springframework.jms.config; -import javax.jms.ConnectionFactory; -import javax.jms.ExceptionListener; - +import jakarta.jms.ConnectionFactory; +import jakarta.jms.ExceptionListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerEndpoint.java b/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerEndpoint.java index 2e0fb1a9b4bc..96df64e0e67f 100644 --- a/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerEndpoint.java +++ b/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerEndpoint.java @@ -16,7 +16,7 @@ package org.springframework.jms.config; -import javax.jms.MessageListener; +import jakarta.jms.MessageListener; import org.springframework.jms.listener.AbstractMessageListenerContainer; import org.springframework.jms.listener.MessageListenerContainer; diff --git a/spring-jms/src/main/java/org/springframework/jms/config/AbstractListenerContainerParser.java b/spring-jms/src/main/java/org/springframework/jms/config/AbstractListenerContainerParser.java index a8e66fd602c4..787b0622ca72 100644 --- a/spring-jms/src/main/java/org/springframework/jms/config/AbstractListenerContainerParser.java +++ b/spring-jms/src/main/java/org/springframework/jms/config/AbstractListenerContainerParser.java @@ -16,8 +16,7 @@ package org.springframework.jms.config; -import javax.jms.Session; - +import jakarta.jms.Session; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; diff --git a/spring-jms/src/main/java/org/springframework/jms/config/DefaultJcaListenerContainerFactory.java b/spring-jms/src/main/java/org/springframework/jms/config/DefaultJcaListenerContainerFactory.java index a14af147cfa7..0338478a0864 100644 --- a/spring-jms/src/main/java/org/springframework/jms/config/DefaultJcaListenerContainerFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/config/DefaultJcaListenerContainerFactory.java @@ -16,7 +16,7 @@ package org.springframework.jms.config; -import javax.resource.spi.ResourceAdapter; +import jakarta.resource.spi.ResourceAdapter; import org.springframework.jms.listener.endpoint.JmsActivationSpecConfig; import org.springframework.jms.listener.endpoint.JmsActivationSpecFactory; diff --git a/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerContainerParser.java b/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerContainerParser.java index 0738ecfae1c7..e88259bbdc77 100644 --- a/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerContainerParser.java +++ b/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerContainerParser.java @@ -16,8 +16,7 @@ package org.springframework.jms.config; -import javax.jms.Session; - +import jakarta.jms.Session; import org.w3c.dom.Element; import org.springframework.beans.MutablePropertyValues; diff --git a/spring-jms/src/main/java/org/springframework/jms/config/SimpleJmsListenerEndpoint.java b/spring-jms/src/main/java/org/springframework/jms/config/SimpleJmsListenerEndpoint.java index 33be14be058d..5dfc42ad2883 100644 --- a/spring-jms/src/main/java/org/springframework/jms/config/SimpleJmsListenerEndpoint.java +++ b/spring-jms/src/main/java/org/springframework/jms/config/SimpleJmsListenerEndpoint.java @@ -16,7 +16,7 @@ package org.springframework.jms.config; -import javax.jms.MessageListener; +import jakarta.jms.MessageListener; import org.springframework.jms.listener.MessageListenerContainer; import org.springframework.lang.Nullable; diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/CachedMessageConsumer.java b/spring-jms/src/main/java/org/springframework/jms/connection/CachedMessageConsumer.java index 5f919cc67012..a077dac8d49f 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/CachedMessageConsumer.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/CachedMessageConsumer.java @@ -16,14 +16,14 @@ package org.springframework.jms.connection; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.Queue; -import javax.jms.QueueReceiver; -import javax.jms.Topic; -import javax.jms.TopicSubscriber; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageConsumer; +import jakarta.jms.MessageListener; +import jakarta.jms.Queue; +import jakarta.jms.QueueReceiver; +import jakarta.jms.Topic; +import jakarta.jms.TopicSubscriber; import org.springframework.lang.Nullable; diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/CachedMessageProducer.java b/spring-jms/src/main/java/org/springframework/jms/connection/CachedMessageProducer.java index daae35af0aa9..91f24ccd00a0 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/CachedMessageProducer.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/CachedMessageProducer.java @@ -16,15 +16,15 @@ package org.springframework.jms.connection; -import javax.jms.CompletionListener; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.QueueSender; -import javax.jms.Topic; -import javax.jms.TopicPublisher; +import jakarta.jms.CompletionListener; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageProducer; +import jakarta.jms.Queue; +import jakarta.jms.QueueSender; +import jakarta.jms.Topic; +import jakarta.jms.TopicPublisher; import org.springframework.lang.Nullable; diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java b/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java index d9b8027f1aa3..109762e0888d 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java @@ -30,18 +30,18 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.QueueSession; -import javax.jms.Session; -import javax.jms.TemporaryQueue; -import javax.jms.TemporaryTopic; -import javax.jms.Topic; -import javax.jms.TopicSession; +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.MessageConsumer; +import jakarta.jms.MessageProducer; +import jakarta.jms.QueueSession; +import jakarta.jms.Session; +import jakarta.jms.TemporaryQueue; +import jakarta.jms.TemporaryTopic; +import jakarta.jms.Topic; +import jakarta.jms.TopicSession; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -49,8 +49,8 @@ import org.springframework.util.ObjectUtils; /** - * {@link SingleConnectionFactory} subclass that adds {@link javax.jms.Session} - * caching as well {@link javax.jms.MessageProducer} caching. This ConnectionFactory + * {@link SingleConnectionFactory} subclass that adds {@link jakarta.jms.Session} + * caching as well {@link jakarta.jms.MessageProducer} caching. This ConnectionFactory * also switches the {@link #setReconnectOnException "reconnectOnException" property} * to "true" by default, allowing for automatic recovery of the underlying Connection. * diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/ChainedExceptionListener.java b/spring-jms/src/main/java/org/springframework/jms/connection/ChainedExceptionListener.java index eb5d0beac028..6a7b58ba295e 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/ChainedExceptionListener.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/ChainedExceptionListener.java @@ -19,8 +19,8 @@ import java.util.ArrayList; import java.util.List; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; +import jakarta.jms.ExceptionListener; +import jakarta.jms.JMSException; import org.springframework.util.Assert; diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/ConnectionFactoryUtils.java b/spring-jms/src/main/java/org/springframework/jms/connection/ConnectionFactoryUtils.java index 3de9bc71ffa9..0f7b72fd2e21 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/ConnectionFactoryUtils.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/ConnectionFactoryUtils.java @@ -16,17 +16,16 @@ package org.springframework.jms.connection; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSException; -import javax.jms.QueueConnection; -import javax.jms.QueueConnectionFactory; -import javax.jms.QueueSession; -import javax.jms.Session; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; -import javax.jms.TopicSession; - +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.JMSException; +import jakarta.jms.QueueConnection; +import jakarta.jms.QueueConnectionFactory; +import jakarta.jms.QueueSession; +import jakarta.jms.Session; +import jakarta.jms.TopicConnection; +import jakarta.jms.TopicConnectionFactory; +import jakarta.jms.TopicSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -36,7 +35,7 @@ import org.springframework.util.Assert; /** - * Helper class for managing a JMS {@link javax.jms.ConnectionFactory}, in particular + * Helper class for managing a JMS {@link jakarta.jms.ConnectionFactory}, in particular * for obtaining transactional JMS resources for a given ConnectionFactory. * *

      Mainly for internal use within the framework. Used by @@ -264,7 +263,7 @@ public boolean isSynchedLocalTransactionAllowed() { * JMS resources * @return the transactional Session, or {@code null} if none found * @throws JMSException in case of JMS failure - * @see #doGetTransactionalSession(javax.jms.ConnectionFactory, ResourceFactory, boolean) + * @see #doGetTransactionalSession(jakarta.jms.ConnectionFactory, ResourceFactory, boolean) */ @Nullable public static Session doGetTransactionalSession( diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/DelegatingConnectionFactory.java b/spring-jms/src/main/java/org/springframework/jms/connection/DelegatingConnectionFactory.java index 1cdedc3a61fb..ea72ff38c6ec 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/DelegatingConnectionFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/DelegatingConnectionFactory.java @@ -16,22 +16,22 @@ package org.springframework.jms.connection; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSContext; -import javax.jms.JMSException; -import javax.jms.QueueConnection; -import javax.jms.QueueConnectionFactory; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.JMSContext; +import jakarta.jms.JMSException; +import jakarta.jms.QueueConnection; +import jakarta.jms.QueueConnectionFactory; +import jakarta.jms.TopicConnection; +import jakarta.jms.TopicConnectionFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * {@link javax.jms.ConnectionFactory} implementation that delegates all calls - * to a given target {@link javax.jms.ConnectionFactory}, adapting specific + * {@link jakarta.jms.ConnectionFactory} implementation that delegates all calls + * to a given target {@link jakarta.jms.ConnectionFactory}, adapting specific * {@code create(Queue/Topic)Connection} calls to the target ConnectionFactory * if necessary (e.g. when running JMS 1.0.2 API based code against a generic * JMS 1.1 ConnectionFactory, such as ActiveMQ's PooledConnectionFactory). @@ -126,7 +126,7 @@ public QueueConnection createQueueConnection() throws JMSException { else { Connection con = target.createConnection(); if (!(con instanceof QueueConnection)) { - throw new javax.jms.IllegalStateException("'targetConnectionFactory' is not a QueueConnectionFactory"); + throw new jakarta.jms.IllegalStateException("'targetConnectionFactory' is not a QueueConnectionFactory"); } return (QueueConnection) con; } @@ -141,7 +141,7 @@ public QueueConnection createQueueConnection(String username, String password) t else { Connection con = target.createConnection(username, password); if (!(con instanceof QueueConnection)) { - throw new javax.jms.IllegalStateException("'targetConnectionFactory' is not a QueueConnectionFactory"); + throw new jakarta.jms.IllegalStateException("'targetConnectionFactory' is not a QueueConnectionFactory"); } return (QueueConnection) con; } @@ -156,7 +156,7 @@ public TopicConnection createTopicConnection() throws JMSException { else { Connection con = target.createConnection(); if (!(con instanceof TopicConnection)) { - throw new javax.jms.IllegalStateException("'targetConnectionFactory' is not a TopicConnectionFactory"); + throw new jakarta.jms.IllegalStateException("'targetConnectionFactory' is not a TopicConnectionFactory"); } return (TopicConnection) con; } @@ -171,7 +171,7 @@ public TopicConnection createTopicConnection(String username, String password) t else { Connection con = target.createConnection(username, password); if (!(con instanceof TopicConnection)) { - throw new javax.jms.IllegalStateException("'targetConnectionFactory' is not a TopicConnectionFactory"); + throw new jakarta.jms.IllegalStateException("'targetConnectionFactory' is not a TopicConnectionFactory"); } return (TopicConnection) con; } diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java b/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java index a8e9c86dbe1e..7b43c35152c0 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java @@ -22,12 +22,11 @@ import java.util.HashMap; import java.util.Map; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSException; -import javax.jms.Session; -import javax.jms.TransactionInProgressException; - +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.JMSException; +import jakarta.jms.Session; +import jakarta.jms.TransactionInProgressException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -243,7 +242,7 @@ public void commitAll() throws JMSException { catch (TransactionInProgressException ex) { // Ignore -> can only happen in case of a JTA transaction. } - catch (javax.jms.IllegalStateException ex) { + catch (jakarta.jms.IllegalStateException ex) { if (this.connectionFactory != null) { try { Method getDataSourceMethod = this.connectionFactory.getClass().getMethod("getDataSource"); diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java b/spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java index 28de1e8df06f..2bc43f20da25 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java @@ -16,11 +16,11 @@ package org.springframework.jms.connection; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSException; -import javax.jms.Session; -import javax.jms.TransactionRolledBackException; +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.JMSException; +import jakarta.jms.Session; +import jakarta.jms.TransactionRolledBackException; import org.springframework.beans.factory.InitializingBean; import org.springframework.lang.Nullable; @@ -38,7 +38,7 @@ /** * {@link org.springframework.transaction.PlatformTransactionManager} implementation - * for a single JMS {@link javax.jms.ConnectionFactory}. Binds a JMS + * for a single JMS {@link jakarta.jms.ConnectionFactory}. Binds a JMS * Connection/Session pair from the specified ConnectionFactory to the thread, * potentially allowing for one thread-bound Session per ConnectionFactory. * @@ -52,12 +52,12 @@ * *

      Application code is required to retrieve the transactional JMS Session via * {@link ConnectionFactoryUtils#getTransactionalSession} instead of a standard - * Java EE-style {@link ConnectionFactory#createConnection()} call with subsequent + * Jakarta EE-style {@link ConnectionFactory#createConnection()} call with subsequent * Session creation. Spring's {@link org.springframework.jms.core.JmsTemplate} * will autodetect a thread-bound Session and automatically participate in it. * *

      Alternatively, you can allow application code to work with the standard - * Java EE-style lookup pattern on a ConnectionFactory, for example for legacy code + * Jakarta EE-style lookup pattern on a ConnectionFactory, for example for legacy code * that is not aware of Spring at all. In that case, define a * {@link TransactionAwareConnectionFactoryProxy} for your target ConnectionFactory, * which will automatically participate in Spring-managed transactions. @@ -324,7 +324,7 @@ protected void doCleanupAfterCompletion(Object transaction) { * Create a JMS Connection via this template's ConnectionFactory. *

      This implementation uses JMS 1.1 API. * @return the new JMS Connection - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods */ protected Connection createConnection() throws JMSException { return obtainConnectionFactory().createConnection(); @@ -335,7 +335,7 @@ protected Connection createConnection() throws JMSException { *

      This implementation uses JMS 1.1 API. * @param con the JMS Connection to create a Session for * @return the new JMS Session - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods */ protected Session createSession(Connection con) throws JMSException { return con.createSession(true, Session.AUTO_ACKNOWLEDGE); diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/SessionProxy.java b/spring-jms/src/main/java/org/springframework/jms/connection/SessionProxy.java index f6443252b41b..cd4ccbb5b800 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/SessionProxy.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/SessionProxy.java @@ -16,17 +16,17 @@ package org.springframework.jms.connection; -import javax.jms.Session; +import jakarta.jms.Session; /** - * Subinterface of {@link javax.jms.Session} to be implemented by + * Subinterface of {@link jakarta.jms.Session} to be implemented by * Session proxies. Allows access to the underlying target Session. * * @author Juergen Hoeller * @since 2.0.4 * @see TransactionAwareConnectionFactoryProxy * @see CachingConnectionFactory - * @see ConnectionFactoryUtils#getTargetSession(javax.jms.Session) + * @see ConnectionFactoryUtils#getTargetSession(jakarta.jms.Session) */ public interface SessionProxy extends Session { diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java b/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java index 1a463c3b4fef..0c5e629022a3 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java @@ -25,17 +25,16 @@ import java.util.List; import java.util.Set; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.ExceptionListener; -import javax.jms.JMSContext; -import javax.jms.JMSException; -import javax.jms.QueueConnection; -import javax.jms.QueueConnectionFactory; -import javax.jms.Session; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; - +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.ExceptionListener; +import jakarta.jms.JMSContext; +import jakarta.jms.JMSException; +import jakarta.jms.QueueConnection; +import jakarta.jms.QueueConnectionFactory; +import jakarta.jms.Session; +import jakarta.jms.TopicConnection; +import jakarta.jms.TopicConnectionFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -49,7 +48,7 @@ /** * A JMS ConnectionFactory adapter that returns the same Connection * from all {@link #createConnection()} calls, and ignores calls to - * {@link javax.jms.Connection#close()}. According to the JMS Connection + * {@link jakarta.jms.Connection#close()}. According to the JMS Connection * model, this is perfectly thread-safe (in contrast to e.g. JDBC). The * shared Connection can be automatically recovered in case of an Exception. * @@ -170,7 +169,7 @@ public ConnectionFactory getTargetConnectionFactory() { *

      Note that client IDs need to be unique among all active Connections * of the underlying JMS provider. Furthermore, a client ID can only be * assigned if the original ConnectionFactory hasn't already assigned one. - * @see javax.jms.Connection#setClientID + * @see jakarta.jms.Connection#setClientID * @see #setTargetConnectionFactory */ public void setClientId(@Nullable String clientId) { @@ -245,7 +244,7 @@ public Connection createConnection() throws JMSException { @Override public Connection createConnection(String username, String password) throws JMSException { - throw new javax.jms.IllegalStateException( + throw new jakarta.jms.IllegalStateException( "SingleConnectionFactory does not support custom username and password"); } @@ -257,7 +256,7 @@ public QueueConnection createQueueConnection() throws JMSException { con = createConnection(); } if (!(con instanceof QueueConnection)) { - throw new javax.jms.IllegalStateException( + throw new jakarta.jms.IllegalStateException( "This SingleConnectionFactory does not hold a QueueConnection but rather: " + con); } return ((QueueConnection) con); @@ -265,7 +264,7 @@ public QueueConnection createQueueConnection() throws JMSException { @Override public QueueConnection createQueueConnection(String username, String password) throws JMSException { - throw new javax.jms.IllegalStateException( + throw new jakarta.jms.IllegalStateException( "SingleConnectionFactory does not support custom username and password"); } @@ -277,7 +276,7 @@ public TopicConnection createTopicConnection() throws JMSException { con = createConnection(); } if (!(con instanceof TopicConnection)) { - throw new javax.jms.IllegalStateException( + throw new jakarta.jms.IllegalStateException( "This SingleConnectionFactory does not hold a TopicConnection but rather: " + con); } return ((TopicConnection) con); @@ -285,7 +284,7 @@ public TopicConnection createTopicConnection() throws JMSException { @Override public TopicConnection createTopicConnection(String username, String password) throws JMSException { - throw new javax.jms.IllegalStateException( + throw new jakarta.jms.IllegalStateException( "SingleConnectionFactory does not support custom username and password"); } @@ -319,7 +318,7 @@ private ConnectionFactory obtainTargetConnectionFactory() { /** * Obtain an initialized shared Connection. * @return the Connection (never {@code null}) - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods * @see #initConnection() */ protected Connection getConnection() throws JMSException { @@ -335,7 +334,7 @@ protected Connection getConnection() throws JMSException { * Initialize the underlying shared Connection. *

      Closes and reinitializes the Connection if an underlying * Connection is present already. - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods * @see #prepareConnection */ public void initConnection() throws JMSException { @@ -396,7 +395,7 @@ public void resetConnection() { /** * Create a JMS Connection via this template's ConnectionFactory. * @return the new JMS Connection - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods */ protected Connection doCreateConnection() throws JMSException { ConnectionFactory cf = getTargetConnectionFactory(); @@ -502,7 +501,7 @@ protected void closeConnection(Connection con) { con.close(); } } - catch (javax.jms.IllegalStateException ex) { + catch (jakarta.jms.IllegalStateException ex) { logger.debug("Ignoring Connection state exception - assuming already closed: " + ex); } catch (Throwable ex) { @@ -569,7 +568,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl return null; } else { - throw new javax.jms.IllegalStateException( + throw new jakarta.jms.IllegalStateException( "setClientID call not supported on proxy for shared Connection. " + "Set the 'clientId' property on the SingleConnectionFactory instead."); } @@ -590,7 +589,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl return null; } else { - throw new javax.jms.IllegalStateException( + throw new jakarta.jms.IllegalStateException( "setExceptionListener call not supported on proxy for shared Connection. " + "Set the 'exceptionListener' property on the SingleConnectionFactory instead. " + "Alternatively, activate SingleConnectionFactory's 'reconnectOnException' feature, " + @@ -650,7 +649,7 @@ else if (args.length == 2) { catch (Throwable ex) { logger.trace("Failed to close newly obtained JMS Session", ex); } - throw new javax.jms.IllegalStateException(msg); + throw new jakarta.jms.IllegalStateException(msg); } return session; } diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/SmartConnectionFactory.java b/spring-jms/src/main/java/org/springframework/jms/connection/SmartConnectionFactory.java index 222627a7f327..00eb4c6b1eaa 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/SmartConnectionFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/SmartConnectionFactory.java @@ -16,11 +16,11 @@ package org.springframework.jms.connection; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; /** - * Extension of the {@code javax.jms.ConnectionFactory} interface, + * Extension of the {@code jakarta.jms.ConnectionFactory} interface, * indicating how to release Connections obtained from it. * * @author Juergen Hoeller @@ -32,7 +32,7 @@ public interface SmartConnectionFactory extends ConnectionFactory { * Should we stop the Connection, obtained from this ConnectionFactory? * @param con the Connection to check * @return whether a stop call is necessary - * @see javax.jms.Connection#stop() + * @see jakarta.jms.Connection#stop() */ boolean shouldStop(Connection con); diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/SynchedLocalTransactionFailedException.java b/spring-jms/src/main/java/org/springframework/jms/connection/SynchedLocalTransactionFailedException.java index 311de08a2aa6..a4fbdb961f31 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/SynchedLocalTransactionFailedException.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/SynchedLocalTransactionFailedException.java @@ -16,7 +16,7 @@ package org.springframework.jms.connection; -import javax.jms.JMSException; +import jakarta.jms.JMSException; import org.springframework.jms.JmsException; diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/TransactionAwareConnectionFactoryProxy.java b/spring-jms/src/main/java/org/springframework/jms/connection/TransactionAwareConnectionFactoryProxy.java index 3dbbfb5c7327..2bac2fa55d03 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/TransactionAwareConnectionFactoryProxy.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/TransactionAwareConnectionFactoryProxy.java @@ -23,27 +23,27 @@ import java.util.ArrayList; import java.util.List; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSContext; -import javax.jms.JMSException; -import javax.jms.QueueConnection; -import javax.jms.QueueConnectionFactory; -import javax.jms.QueueSession; -import javax.jms.Session; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; -import javax.jms.TopicSession; -import javax.jms.TransactionInProgressException; +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.JMSContext; +import jakarta.jms.JMSException; +import jakarta.jms.QueueConnection; +import jakarta.jms.QueueConnectionFactory; +import jakarta.jms.QueueSession; +import jakarta.jms.Session; +import jakarta.jms.TopicConnection; +import jakarta.jms.TopicConnectionFactory; +import jakarta.jms.TopicSession; +import jakarta.jms.TransactionInProgressException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; /** - * Proxy for a target JMS {@link javax.jms.ConnectionFactory}, adding awareness of + * Proxy for a target JMS {@link jakarta.jms.ConnectionFactory}, adding awareness of * Spring-managed transactions. Similar to a transactional JNDI ConnectionFactory - * as provided by a Java EE application server. + * as provided by a Jakarta EE application server. * *

      Messaging code which should remain unaware of Spring's JMS support can work with * this proxy to seamlessly participate in Spring-managed transactions. Note that the @@ -164,7 +164,7 @@ public Connection createConnection(String username, String password) throws JMSE public QueueConnection createQueueConnection() throws JMSException { ConnectionFactory target = getTargetConnectionFactory(); if (!(target instanceof QueueConnectionFactory)) { - throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no QueueConnectionFactory"); + throw new jakarta.jms.IllegalStateException("'targetConnectionFactory' is no QueueConnectionFactory"); } QueueConnection targetConnection = ((QueueConnectionFactory) target).createQueueConnection(); return (QueueConnection) getTransactionAwareConnectionProxy(targetConnection); @@ -174,7 +174,7 @@ public QueueConnection createQueueConnection() throws JMSException { public QueueConnection createQueueConnection(String username, String password) throws JMSException { ConnectionFactory target = getTargetConnectionFactory(); if (!(target instanceof QueueConnectionFactory)) { - throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no QueueConnectionFactory"); + throw new jakarta.jms.IllegalStateException("'targetConnectionFactory' is no QueueConnectionFactory"); } QueueConnection targetConnection = ((QueueConnectionFactory) target).createQueueConnection(username, password); return (QueueConnection) getTransactionAwareConnectionProxy(targetConnection); @@ -184,7 +184,7 @@ public QueueConnection createQueueConnection(String username, String password) t public TopicConnection createTopicConnection() throws JMSException { ConnectionFactory target = getTargetConnectionFactory(); if (!(target instanceof TopicConnectionFactory)) { - throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no TopicConnectionFactory"); + throw new jakarta.jms.IllegalStateException("'targetConnectionFactory' is no TopicConnectionFactory"); } TopicConnection targetConnection = ((TopicConnectionFactory) target).createTopicConnection(); return (TopicConnection) getTransactionAwareConnectionProxy(targetConnection); @@ -194,7 +194,7 @@ public TopicConnection createTopicConnection() throws JMSException { public TopicConnection createTopicConnection(String username, String password) throws JMSException { ConnectionFactory target = getTargetConnectionFactory(); if (!(target instanceof TopicConnectionFactory)) { - throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no TopicConnectionFactory"); + throw new jakarta.jms.IllegalStateException("'targetConnectionFactory' is no TopicConnectionFactory"); } TopicConnection targetConnection = ((TopicConnectionFactory) target).createTopicConnection(username, password); return (TopicConnection) getTransactionAwareConnectionProxy(targetConnection); diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java b/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java index f8d2e4b9b42e..ef8dd8585fa9 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java @@ -16,14 +16,14 @@ package org.springframework.jms.connection; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSContext; -import javax.jms.JMSException; -import javax.jms.QueueConnection; -import javax.jms.QueueConnectionFactory; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.JMSContext; +import jakarta.jms.JMSException; +import jakarta.jms.QueueConnection; +import jakarta.jms.QueueConnectionFactory; +import jakarta.jms.TopicConnection; +import jakarta.jms.TopicConnectionFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.NamedThreadLocal; @@ -32,7 +32,7 @@ import org.springframework.util.StringUtils; /** - * An adapter for a target JMS {@link javax.jms.ConnectionFactory}, applying the + * An adapter for a target JMS {@link jakarta.jms.ConnectionFactory}, applying the * given user credentials to every standard {@code createConnection()} call, * that is, implicitly invoking {@code createConnection(username, password)} * on the target. All other methods simply delegate to the corresponding methods @@ -179,8 +179,8 @@ public Connection createConnection(String username, String password) throws JMSE * @param username the username to use * @param password the password to use * @return the Connection - * @see javax.jms.ConnectionFactory#createConnection(String, String) - * @see javax.jms.ConnectionFactory#createConnection() + * @see jakarta.jms.ConnectionFactory#createConnection(String, String) + * @see jakarta.jms.ConnectionFactory#createConnection() */ protected Connection doCreateConnection(@Nullable String username, @Nullable String password) throws JMSException { ConnectionFactory target = obtainTargetConnectionFactory(); @@ -225,15 +225,15 @@ public QueueConnection createQueueConnection(String username, String password) t * @param username the username to use * @param password the password to use * @return the Connection - * @see javax.jms.QueueConnectionFactory#createQueueConnection(String, String) - * @see javax.jms.QueueConnectionFactory#createQueueConnection() + * @see jakarta.jms.QueueConnectionFactory#createQueueConnection(String, String) + * @see jakarta.jms.QueueConnectionFactory#createQueueConnection() */ protected QueueConnection doCreateQueueConnection( @Nullable String username, @Nullable String password) throws JMSException { ConnectionFactory target = obtainTargetConnectionFactory(); if (!(target instanceof QueueConnectionFactory)) { - throw new javax.jms.IllegalStateException("'targetConnectionFactory' is not a QueueConnectionFactory"); + throw new jakarta.jms.IllegalStateException("'targetConnectionFactory' is not a QueueConnectionFactory"); } QueueConnectionFactory queueFactory = (QueueConnectionFactory) target; if (StringUtils.hasLength(username)) { @@ -277,15 +277,15 @@ public TopicConnection createTopicConnection(String username, String password) t * @param username the username to use * @param password the password to use * @return the Connection - * @see javax.jms.TopicConnectionFactory#createTopicConnection(String, String) - * @see javax.jms.TopicConnectionFactory#createTopicConnection() + * @see jakarta.jms.TopicConnectionFactory#createTopicConnection(String, String) + * @see jakarta.jms.TopicConnectionFactory#createTopicConnection() */ protected TopicConnection doCreateTopicConnection( @Nullable String username, @Nullable String password) throws JMSException { ConnectionFactory target = obtainTargetConnectionFactory(); if (!(target instanceof TopicConnectionFactory)) { - throw new javax.jms.IllegalStateException("'targetConnectionFactory' is not a TopicConnectionFactory"); + throw new jakarta.jms.IllegalStateException("'targetConnectionFactory' is not a TopicConnectionFactory"); } TopicConnectionFactory queueFactory = (TopicConnectionFactory) target; if (StringUtils.hasLength(username)) { diff --git a/spring-jms/src/main/java/org/springframework/jms/core/BrowserCallback.java b/spring-jms/src/main/java/org/springframework/jms/core/BrowserCallback.java index 5142cd350801..1a076bad5012 100644 --- a/spring-jms/src/main/java/org/springframework/jms/core/BrowserCallback.java +++ b/spring-jms/src/main/java/org/springframework/jms/core/BrowserCallback.java @@ -16,9 +16,9 @@ package org.springframework.jms.core; -import javax.jms.JMSException; -import javax.jms.QueueBrowser; -import javax.jms.Session; +import jakarta.jms.JMSException; +import jakarta.jms.QueueBrowser; +import jakarta.jms.Session; import org.springframework.lang.Nullable; @@ -39,13 +39,13 @@ public interface BrowserCallback { /** - * Perform operations on the given {@link javax.jms.Session} and - * {@link javax.jms.QueueBrowser}. + * Perform operations on the given {@link jakarta.jms.Session} and + * {@link jakarta.jms.QueueBrowser}. * @param session the JMS {@code Session} object to use * @param browser the JMS {@code QueueBrowser} object to use * @return a result object from working with the {@code Session}, if any * (or {@code null} if none) - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods */ @Nullable T doInJms(Session session, QueueBrowser browser) throws JMSException; diff --git a/spring-jms/src/main/java/org/springframework/jms/core/JmsMessageOperations.java b/spring-jms/src/main/java/org/springframework/jms/core/JmsMessageOperations.java index 50bba1b04ffe..ebb821da62cd 100644 --- a/spring-jms/src/main/java/org/springframework/jms/core/JmsMessageOperations.java +++ b/spring-jms/src/main/java/org/springframework/jms/core/JmsMessageOperations.java @@ -18,7 +18,7 @@ import java.util.Map; -import javax.jms.Destination; +import jakarta.jms.Destination; import org.springframework.lang.Nullable; import org.springframework.messaging.Message; @@ -31,7 +31,7 @@ /** * A specialization of {@link MessageSendingOperations}, {@link MessageReceivingOperations} * and {@link MessageRequestReplyOperations} for JMS related operations that allow to specify - * a destination name rather than the actual {@link javax.jms.Destination}. + * a destination name rather than the actual {@link jakarta.jms.Destination}. * * @author Stephane Nicoll * @since 4.1 diff --git a/spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java b/spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java index 7eaa1bd8d988..0835ae2e9b19 100644 --- a/spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java +++ b/spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java @@ -18,10 +18,10 @@ import java.util.Map; -import javax.jms.ConnectionFactory; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Session; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Session; import org.springframework.beans.factory.InitializingBean; import org.springframework.jms.InvalidDestinationException; @@ -123,7 +123,7 @@ public JmsTemplate getJmsTemplate() { /** * Set the {@link MessageConverter} to use to convert a {@link Message} from - * the messaging to and from a {@link javax.jms.Message}. By default, a + * the messaging to and from a {@link jakarta.jms.Message}. By default, a * {@link MessagingMessageConverter} is defined using a {@link SimpleMessageConverter} * to convert the payload of the message. *

      Consider configuring a {@link MessagingMessageConverter} with a different @@ -139,7 +139,7 @@ public void setJmsMessageConverter(MessageConverter jmsMessageConverter) { /** * Return the {@link MessageConverter} to use to convert a {@link Message} - * from the messaging to and from a {@link javax.jms.Message}. + * from the messaging to and from a {@link jakarta.jms.Message}. */ public MessageConverter getJmsMessageConverter() { return this.jmsMessageConverter; @@ -373,7 +373,7 @@ protected void doSend(String destinationName, Message message) { @Nullable protected Message doReceive(Destination destination) { try { - javax.jms.Message jmsMessage = obtainJmsTemplate().receive(destination); + jakarta.jms.Message jmsMessage = obtainJmsTemplate().receive(destination); return convertJmsMessage(jmsMessage); } catch (JmsException ex) { @@ -384,7 +384,7 @@ protected Message doReceive(Destination destination) { @Nullable protected Message doReceive(String destinationName) { try { - javax.jms.Message jmsMessage = obtainJmsTemplate().receive(destinationName); + jakarta.jms.Message jmsMessage = obtainJmsTemplate().receive(destinationName); return convertJmsMessage(jmsMessage); } catch (JmsException ex) { @@ -396,7 +396,7 @@ protected Message doReceive(String destinationName) { @Nullable protected Message doSendAndReceive(Destination destination, Message requestMessage) { try { - javax.jms.Message jmsMessage = obtainJmsTemplate().sendAndReceive( + jakarta.jms.Message jmsMessage = obtainJmsTemplate().sendAndReceive( destination, createMessageCreator(requestMessage)); return convertJmsMessage(jmsMessage); } @@ -408,7 +408,7 @@ protected Message doSendAndReceive(Destination destination, Message reques @Nullable protected Message doSendAndReceive(String destinationName, Message requestMessage) { try { - javax.jms.Message jmsMessage = obtainJmsTemplate().sendAndReceive( + jakarta.jms.Message jmsMessage = obtainJmsTemplate().sendAndReceive( destinationName, createMessageCreator(requestMessage)); return convertJmsMessage(jmsMessage); } @@ -431,7 +431,7 @@ protected String getRequiredDefaultDestinationName() { } @Nullable - protected Message convertJmsMessage(@Nullable javax.jms.Message message) { + protected Message convertJmsMessage(@Nullable jakarta.jms.Message message) { if (message == null) { return null; } @@ -468,7 +468,7 @@ public MessagingMessageCreator(Message message, MessageConverter messageConve } @Override - public javax.jms.Message createMessage(Session session) throws JMSException { + public jakarta.jms.Message createMessage(Session session) throws JMSException { try { return this.messageConverter.toMessage(this.message, session); } diff --git a/spring-jms/src/main/java/org/springframework/jms/core/JmsOperations.java b/spring-jms/src/main/java/org/springframework/jms/core/JmsOperations.java index 9b2cef401b92..845be02a12e0 100644 --- a/spring-jms/src/main/java/org/springframework/jms/core/JmsOperations.java +++ b/spring-jms/src/main/java/org/springframework/jms/core/JmsOperations.java @@ -16,9 +16,9 @@ package org.springframework.jms.core; -import javax.jms.Destination; -import javax.jms.Message; -import javax.jms.Queue; +import jakarta.jms.Destination; +import jakarta.jms.Message; +import jakarta.jms.Queue; import org.springframework.jms.JmsException; import org.springframework.lang.Nullable; @@ -41,10 +41,10 @@ * @author Stephane Nicoll * @since 1.1 * @see JmsTemplate - * @see javax.jms.Destination - * @see javax.jms.Session - * @see javax.jms.MessageProducer - * @see javax.jms.MessageConsumer + * @see jakarta.jms.Destination + * @see jakarta.jms.Session + * @see jakarta.jms.MessageProducer + * @see jakarta.jms.MessageConsumer */ public interface JmsOperations { diff --git a/spring-jms/src/main/java/org/springframework/jms/core/JmsTemplate.java b/spring-jms/src/main/java/org/springframework/jms/core/JmsTemplate.java index a190fe48dcf2..cdbc1bc0bb55 100644 --- a/spring-jms/src/main/java/org/springframework/jms/core/JmsTemplate.java +++ b/spring-jms/src/main/java/org/springframework/jms/core/JmsTemplate.java @@ -16,18 +16,18 @@ package org.springframework.jms.core; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.DeliveryMode; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.QueueBrowser; -import javax.jms.Session; -import javax.jms.TemporaryQueue; +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.DeliveryMode; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageConsumer; +import jakarta.jms.MessageProducer; +import jakarta.jms.Queue; +import jakarta.jms.QueueBrowser; +import jakarta.jms.Session; +import jakarta.jms.TemporaryQueue; import org.springframework.jms.JmsException; import org.springframework.jms.connection.ConnectionFactoryUtils; @@ -50,7 +50,7 @@ * domain. * *

      Default settings for JMS Sessions are "not transacted" and "auto-acknowledge". - * As defined by the Java EE specification, the transaction and acknowledgement + * As defined by the Jakarta EE specification, the transaction and acknowledgement * parameters are ignored when a JMS Session is created inside an active * transaction, no matter if a JTA transaction or a Spring-managed transaction. * To configure them for native JMS usage, specify appropriate values for @@ -70,7 +70,7 @@ * {@link org.springframework.jms.connection.SingleConnectionFactory} as a * decorator for your target {@code ConnectionFactory}, reusing a single * JMS Connection in a thread-safe fashion; this is often good enough for the - * purpose of sending messages via this template. In a Java EE environment, + * purpose of sending messages via this template. In a Jakarta EE environment, * make sure that the {@code ConnectionFactory} is obtained from the * application's environment naming context via JNDI; application servers * typically expose pooled, transaction-aware factories there. @@ -83,8 +83,8 @@ * @see #setPubSubDomain * @see #setDestinationResolver * @see #setMessageConverter - * @see javax.jms.MessageProducer - * @see javax.jms.MessageConsumer + * @see jakarta.jms.MessageProducer + * @see jakarta.jms.MessageConsumer */ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations { @@ -195,7 +195,7 @@ private Queue getDefaultQueue() { * @see #convertAndSend(Object) * @see #convertAndSend(Object, MessagePostProcessor) * @see #setDestinationResolver - * @see #setDefaultDestination(javax.jms.Destination) + * @see #setDefaultDestination(jakarta.jms.Destination) */ public void setDefaultDestinationName(@Nullable String destinationName) { this.defaultDestination = destinationName; @@ -254,7 +254,7 @@ private MessageConverter getRequiredMessageConverter() throws IllegalStateExcept * Set whether message IDs are enabled. Default is "true". *

      This is only a hint to the JMS producer. * See the JMS javadocs for details. - * @see javax.jms.MessageProducer#setDisableMessageID + * @see jakarta.jms.MessageProducer#setDisableMessageID */ public void setMessageIdEnabled(boolean messageIdEnabled) { this.messageIdEnabled = messageIdEnabled; @@ -271,7 +271,7 @@ public boolean isMessageIdEnabled() { * Set whether message timestamps are enabled. Default is "true". *

      This is only a hint to the JMS producer. * See the JMS javadocs for details. - * @see javax.jms.MessageProducer#setDisableMessageTimestamp + * @see jakarta.jms.MessageProducer#setDisableMessageTimestamp */ public void setMessageTimestampEnabled(boolean messageTimestampEnabled) { this.messageTimestampEnabled = messageTimestampEnabled; @@ -287,7 +287,7 @@ public boolean isMessageTimestampEnabled() { /** * Set whether to inhibit the delivery of messages published by its own connection. * Default is "false". - * @see javax.jms.Session#createConsumer(javax.jms.Destination, String, boolean) + * @see jakarta.jms.Session#createConsumer(jakarta.jms.Destination, String, boolean) */ public void setPubSubNoLocal(boolean pubSubNoLocal) { this.pubSubNoLocal = pubSubNoLocal; @@ -308,9 +308,9 @@ public boolean isPubSubNoLocal() { * to indicate that a receive operation should check if a message is * immediately available without blocking. * @see #receiveFromConsumer(MessageConsumer, long) - * @see javax.jms.MessageConsumer#receive(long) - * @see javax.jms.MessageConsumer#receiveNoWait() - * @see javax.jms.MessageConsumer#receive() + * @see jakarta.jms.MessageConsumer#receive(long) + * @see jakarta.jms.MessageConsumer#receiveNoWait() + * @see jakarta.jms.MessageConsumer#receive() */ public void setReceiveTimeout(long receiveTimeout) { this.receiveTimeout = receiveTimeout; @@ -388,8 +388,8 @@ public void setQosSettings(QosSettings settings) { * mode accordingly, to either "PERSISTENT" (2) or "NON_PERSISTENT" (1). *

      Default is "true" a.k.a. delivery mode "PERSISTENT". * @see #setDeliveryMode(int) - * @see javax.jms.DeliveryMode#PERSISTENT - * @see javax.jms.DeliveryMode#NON_PERSISTENT + * @see jakarta.jms.DeliveryMode#PERSISTENT + * @see jakarta.jms.DeliveryMode#NON_PERSISTENT */ public void setDeliveryPersistent(boolean deliveryPersistent) { this.deliveryMode = (deliveryPersistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT); @@ -402,10 +402,10 @@ public void setDeliveryPersistent(boolean deliveryPersistent) { * this is only used when "isExplicitQosEnabled" equals "true". * @param deliveryMode the delivery mode to use * @see #isExplicitQosEnabled - * @see javax.jms.DeliveryMode#PERSISTENT - * @see javax.jms.DeliveryMode#NON_PERSISTENT - * @see javax.jms.Message#DEFAULT_DELIVERY_MODE - * @see javax.jms.MessageProducer#send(javax.jms.Message, int, int, long) + * @see jakarta.jms.DeliveryMode#PERSISTENT + * @see jakarta.jms.DeliveryMode#NON_PERSISTENT + * @see jakarta.jms.Message#DEFAULT_DELIVERY_MODE + * @see jakarta.jms.MessageProducer#send(jakarta.jms.Message, int, int, long) */ public void setDeliveryMode(int deliveryMode) { this.deliveryMode = deliveryMode; @@ -423,8 +423,8 @@ public int getDeliveryMode() { *

      Since a default value may be defined administratively, * this is only used when "isExplicitQosEnabled" equals "true". * @see #isExplicitQosEnabled - * @see javax.jms.Message#DEFAULT_PRIORITY - * @see javax.jms.MessageProducer#send(javax.jms.Message, int, int, long) + * @see jakarta.jms.Message#DEFAULT_PRIORITY + * @see jakarta.jms.MessageProducer#send(jakarta.jms.Message, int, int, long) */ public void setPriority(int priority) { this.priority = priority; @@ -443,8 +443,8 @@ public int getPriority() { * this is only used when "isExplicitQosEnabled" equals "true". * @param timeToLive the message's lifetime (in milliseconds) * @see #isExplicitQosEnabled - * @see javax.jms.Message#DEFAULT_TIME_TO_LIVE - * @see javax.jms.MessageProducer#send(javax.jms.Message, int, int, long) + * @see jakarta.jms.Message#DEFAULT_TIME_TO_LIVE + * @see jakarta.jms.MessageProducer#send(jakarta.jms.Message, int, int, long) */ public void setTimeToLive(long timeToLive) { this.timeToLive = timeToLive; diff --git a/spring-jms/src/main/java/org/springframework/jms/core/MessageCreator.java b/spring-jms/src/main/java/org/springframework/jms/core/MessageCreator.java index d14ec884a251..80cf2a7e85f7 100644 --- a/spring-jms/src/main/java/org/springframework/jms/core/MessageCreator.java +++ b/spring-jms/src/main/java/org/springframework/jms/core/MessageCreator.java @@ -16,9 +16,9 @@ package org.springframework.jms.core; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.Session; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.Session; /** * Creates a JMS message given a {@link Session}. @@ -27,7 +27,7 @@ * of the {@link JmsTemplate} class. * *

      Implementations do not need to concern themselves with - * checked {@code JMSExceptions} (from the '{@code javax.jms}' + * checked {@code JMSExceptions} (from the '{@code jakarta.jms}' * package) that may be thrown from operations they attempt. The * {@code JmsTemplate} will catch and handle these * {@code JMSExceptions} appropriately. @@ -43,7 +43,7 @@ public interface MessageCreator { * @param session the JMS {@link Session} to be used to create the * {@code Message} (never {@code null}) * @return the {@code Message} to be sent - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods */ Message createMessage(Session session) throws JMSException; diff --git a/spring-jms/src/main/java/org/springframework/jms/core/MessagePostProcessor.java b/spring-jms/src/main/java/org/springframework/jms/core/MessagePostProcessor.java index 84c4c5da9445..962e5caf519f 100644 --- a/spring-jms/src/main/java/org/springframework/jms/core/MessagePostProcessor.java +++ b/spring-jms/src/main/java/org/springframework/jms/core/MessagePostProcessor.java @@ -16,8 +16,8 @@ package org.springframework.jms.core; -import javax.jms.JMSException; -import javax.jms.Message; +import jakarta.jms.JMSException; +import jakarta.jms.Message; /** * To be used with JmsTemplate's send method that converts an object to a message. @@ -30,7 +30,7 @@ * @author Mark Pollack * @since 1.1 * @see JmsTemplate#convertAndSend(String, Object, MessagePostProcessor) - * @see JmsTemplate#convertAndSend(javax.jms.Destination, Object, MessagePostProcessor) + * @see JmsTemplate#convertAndSend(jakarta.jms.Destination, Object, MessagePostProcessor) * @see org.springframework.jms.support.converter.MessageConverter */ @FunctionalInterface @@ -42,7 +42,7 @@ public interface MessagePostProcessor { * @param message the JMS message from the MessageConverter * @return a post-processed variant of the message, or simply the incoming * message; never {@code null} - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods */ Message postProcessMessage(Message message) throws JMSException; diff --git a/spring-jms/src/main/java/org/springframework/jms/core/ProducerCallback.java b/spring-jms/src/main/java/org/springframework/jms/core/ProducerCallback.java index 961ad4aa803d..952d3a6d15a0 100644 --- a/spring-jms/src/main/java/org/springframework/jms/core/ProducerCallback.java +++ b/spring-jms/src/main/java/org/springframework/jms/core/ProducerCallback.java @@ -16,9 +16,9 @@ package org.springframework.jms.core; -import javax.jms.JMSException; -import javax.jms.MessageProducer; -import javax.jms.Session; +import jakarta.jms.JMSException; +import jakarta.jms.MessageProducer; +import jakarta.jms.Session; import org.springframework.lang.Nullable; @@ -36,7 +36,7 @@ * @since 1.1 * @param the result type * @see JmsTemplate#execute(ProducerCallback) - * @see JmsTemplate#execute(javax.jms.Destination, ProducerCallback) + * @see JmsTemplate#execute(jakarta.jms.Destination, ProducerCallback) * @see JmsTemplate#execute(String, ProducerCallback) */ @FunctionalInterface @@ -50,7 +50,7 @@ public interface ProducerCallback { * @param producer the JMS {@code MessageProducer} object to use * @return a result object from working with the {@code Session}, if any * (or {@code null} if none) - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods */ @Nullable T doInJms(Session session, MessageProducer producer) throws JMSException; diff --git a/spring-jms/src/main/java/org/springframework/jms/core/SessionCallback.java b/spring-jms/src/main/java/org/springframework/jms/core/SessionCallback.java index 8bbd1fe31f62..99dfe64b0ca8 100644 --- a/spring-jms/src/main/java/org/springframework/jms/core/SessionCallback.java +++ b/spring-jms/src/main/java/org/springframework/jms/core/SessionCallback.java @@ -16,8 +16,8 @@ package org.springframework.jms.core; -import javax.jms.JMSException; -import javax.jms.Session; +import jakarta.jms.JMSException; +import jakarta.jms.Session; import org.springframework.lang.Nullable; @@ -41,7 +41,7 @@ public interface SessionCallback { * @param session the JMS {@code Session} * @return a result object from working with the {@code Session}, if any * (or {@code null} if none) - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods */ @Nullable T doInJms(Session session) throws JMSException; diff --git a/spring-jms/src/main/java/org/springframework/jms/core/support/JmsGatewaySupport.java b/spring-jms/src/main/java/org/springframework/jms/core/support/JmsGatewaySupport.java index 0ce0650a00c4..f85c3db9925d 100644 --- a/spring-jms/src/main/java/org/springframework/jms/core/support/JmsGatewaySupport.java +++ b/spring-jms/src/main/java/org/springframework/jms/core/support/JmsGatewaySupport.java @@ -16,8 +16,7 @@ package org.springframework.jms.core.support; -import javax.jms.ConnectionFactory; - +import jakarta.jms.ConnectionFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -54,7 +53,7 @@ public abstract class JmsGatewaySupport implements InitializingBean { * Set the JMS connection factory to be used by the gateway. * Will automatically create a JmsTemplate for the given ConnectionFactory. * @see #createJmsTemplate - * @see #setConnectionFactory(javax.jms.ConnectionFactory) + * @see #setConnectionFactory(jakarta.jms.ConnectionFactory) */ public final void setConnectionFactory(ConnectionFactory connectionFactory) { this.jmsTemplate = createJmsTemplate(connectionFactory); @@ -83,7 +82,7 @@ public final ConnectionFactory getConnectionFactory() { /** * Set the JmsTemplate for the gateway. - * @see #setConnectionFactory(javax.jms.ConnectionFactory) + * @see #setConnectionFactory(jakarta.jms.ConnectionFactory) */ public final void setJmsTemplate(@Nullable JmsTemplate jmsTemplate) { this.jmsTemplate = jmsTemplate; diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractJmsListeningContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractJmsListeningContainer.java index b7e1734bb99f..30ee11c812be 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractJmsListeningContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractJmsListeningContainer.java @@ -20,8 +20,8 @@ import java.util.Iterator; import java.util.List; -import javax.jms.Connection; -import javax.jms.JMSException; +import jakarta.jms.Connection; +import jakarta.jms.JMSException; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; @@ -94,7 +94,7 @@ public abstract class AbstractJmsListeningContainer extends JmsDestinationAccess *

      Note that client IDs need to be unique among all active Connections * of the underlying JMS provider. Furthermore, a client ID can only be * assigned if the original ConnectionFactory hasn't already assigned one. - * @see javax.jms.Connection#setClientID + * @see jakarta.jms.Connection#setClientID * @see #setConnectionFactory */ public void setClientId(@Nullable String clientId) { @@ -191,7 +191,7 @@ public void destroy() { /** * Initialize this container. - *

      Creates a JMS Connection, starts the {@link javax.jms.Connection} + *

      Creates a JMS Connection, starts the {@link jakarta.jms.Connection} * (if {@link #setAutoStartup(boolean) "autoStartup"} hasn't been turned off), * and calls {@link #doInitialize()}. * @throws org.springframework.jms.JmsException if startup failed @@ -439,7 +439,7 @@ protected void prepareSharedConnection(Connection connection) throws JMSExceptio /** * Start the shared Connection. * @throws JMSException if thrown by JMS API methods - * @see javax.jms.Connection#start() + * @see jakarta.jms.Connection#start() */ protected void startSharedConnection() throws JMSException { synchronized (this.sharedConnectionMonitor) { @@ -448,7 +448,7 @@ protected void startSharedConnection() throws JMSException { try { this.sharedConnection.start(); } - catch (javax.jms.IllegalStateException ex) { + catch (jakarta.jms.IllegalStateException ex) { logger.debug("Ignoring Connection start exception - assuming already started: " + ex); } } @@ -458,7 +458,7 @@ protected void startSharedConnection() throws JMSException { /** * Stop the shared Connection. * @throws JMSException if thrown by JMS API methods - * @see javax.jms.Connection#start() + * @see jakarta.jms.Connection#start() */ protected void stopSharedConnection() throws JMSException { synchronized (this.sharedConnectionMonitor) { @@ -467,7 +467,7 @@ protected void stopSharedConnection() throws JMSException { try { this.sharedConnection.stop(); } - catch (javax.jms.IllegalStateException ex) { + catch (jakarta.jms.IllegalStateException ex) { logger.debug("Ignoring Connection stop exception - assuming already stopped: " + ex); } } diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractMessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractMessageListenerContainer.java index 534e12285f05..eb4c7e4e46c2 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractMessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractMessageListenerContainer.java @@ -16,16 +16,16 @@ package org.springframework.jms.listener; -import javax.jms.Connection; -import javax.jms.Destination; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.Topic; +import jakarta.jms.Connection; +import jakarta.jms.Destination; +import jakarta.jms.ExceptionListener; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageConsumer; +import jakarta.jms.MessageListener; +import jakarta.jms.Queue; +import jakarta.jms.Session; +import jakarta.jms.Topic; import org.springframework.jms.support.JmsUtils; import org.springframework.jms.support.QosSettings; @@ -35,12 +35,12 @@ /** * Abstract base class for Spring message listener container implementations. - * Can either host a standard JMS {@link javax.jms.MessageListener} or Spring's + * Can either host a standard JMS {@link jakarta.jms.MessageListener} or Spring's * {@link SessionAwareMessageListener} for actual message processing. * *

      Usually holds a single JMS {@link Connection} that all listeners are supposed * to be registered on, which is the standard JMS way of managing listener sessions. - * Can alternatively also be used with a fresh Connection per listener, for Java EE + * Can alternatively also be used with a fresh Connection per listener, for Jakarta EE * style XA-aware JMS messaging. The actual registration process is up to concrete * subclasses. * @@ -99,7 +99,7 @@ * supported by {@link DefaultMessageListenerContainer}, through specifying * an external "transactionManager" (typically a * {@link org.springframework.transaction.jta.JtaTransactionManager}, with - * a corresponding XA-aware JMS {@link javax.jms.ConnectionFactory} passed in + * a corresponding XA-aware JMS {@link jakarta.jms.ConnectionFactory} passed in * as "connectionFactory"). *

    * Note that XA transaction coordination adds significant runtime overhead, @@ -116,7 +116,7 @@ *
  • Alternatively, specify a * {@link org.springframework.transaction.jta.JtaTransactionManager} as * "transactionManager" for a fully XA-aware JMS provider - typically when - * running on a Java EE server, but also for other environments with a JTA + * running on a Jakarta EE server, but also for other environments with a JTA * transaction manager present. This will give full "exactly-once" guarantees * without custom duplicate message checks, at the price of additional * runtime processing overhead. @@ -132,7 +132,7 @@ * @author Stephane Nicoll * @since 2.0 * @see #setMessageListener - * @see javax.jms.MessageListener + * @see jakarta.jms.MessageListener * @see SessionAwareMessageListener * @see #handleListenerException * @see DefaultMessageListenerContainer @@ -222,7 +222,7 @@ public Destination getDestination() { * container picking up the new destination immediately (works e.g. with * DefaultMessageListenerContainer, as long as the cache level is less than * CACHE_CONSUMER). However, this is considered advanced usage; use it with care! - * @see #setDestination(javax.jms.Destination) + * @see #setDestination(jakarta.jms.Destination) */ public void setDestinationName(@Nullable String destinationName) { this.destination = destinationName; @@ -280,7 +280,7 @@ public String getMessageSelector() { * CACHE_CONSUMER). However, this is considered advanced usage; use it with care! * @throws IllegalArgumentException if the supplied listener is not a * {@link MessageListener} or a {@link SessionAwareMessageListener} - * @see javax.jms.MessageListener + * @see jakarta.jms.MessageListener * @see SessionAwareMessageListener */ public void setMessageListener(@Nullable Object messageListener) { @@ -307,7 +307,7 @@ public Object getMessageListener() { * @param messageListener the message listener object to check * @throws IllegalArgumentException if the supplied listener is not a * {@link MessageListener} or a {@link SessionAwareMessageListener} - * @see javax.jms.MessageListener + * @see jakarta.jms.MessageListener * @see SessionAwareMessageListener */ protected void checkMessageListener(@Nullable Object messageListener) { @@ -449,7 +449,7 @@ public String getDurableSubscriptionName() { * Set whether to inhibit the delivery of messages published by its own connection. * Default is "false". * @since 4.1 - * @see javax.jms.Session#createConsumer(javax.jms.Destination, String, boolean) + * @see jakarta.jms.Session#createConsumer(jakarta.jms.Destination, String, boolean) */ public void setPubSubNoLocal(boolean pubSubNoLocal) { this.pubSubNoLocal = pubSubNoLocal; @@ -478,8 +478,8 @@ public void setReplyPubSubDomain(boolean replyPubSubDomain) { } /** - * Return whether the Publish/Subscribe domain ({@link javax.jms.Topic Topics}) is used - * for replies. Otherwise, the Point-to-Point domain ({@link javax.jms.Queue Queues}) + * Return whether the Publish/Subscribe domain ({@link jakarta.jms.Topic Topics}) is used + * for replies. Otherwise, the Point-to-Point domain ({@link jakarta.jms.Queue Queues}) * is used. * @since 4.2 */ @@ -755,7 +755,7 @@ protected void doInvokeListener(SessionAwareMessageListener listener, Session se * @param listener the JMS MessageListener to invoke * @param message the received JMS Message * @throws JMSException if thrown by JMS API methods - * @see javax.jms.MessageListener#onMessage + * @see jakarta.jms.MessageListener#onMessage */ protected void doInvokeListener(MessageListener listener, Message message) throws JMSException { listener.onMessage(message); @@ -765,7 +765,7 @@ protected void doInvokeListener(MessageListener listener, Message message) throw * Perform a commit or message acknowledgement, as appropriate. * @param session the JMS Session to commit * @param message the Message to acknowledge - * @throws javax.jms.JMSException in case of commit failure + * @throws jakarta.jms.JMSException in case of commit failure */ protected void commitIfNecessary(Session session, @Nullable Message message) throws JMSException { // Commit session or acknowledge message. @@ -784,7 +784,7 @@ else if (message != null && isClientAcknowledge(session)) { /** * Perform a rollback, if appropriate. * @param session the JMS Session to rollback - * @throws javax.jms.JMSException in case of a rollback error + * @throws jakarta.jms.JMSException in case of a rollback error */ protected void rollbackIfNecessary(Session session) throws JMSException { if (session.getTransacted()) { @@ -802,7 +802,7 @@ else if (isClientAcknowledge(session)) { * Perform a rollback, handling rollback exceptions properly. * @param session the JMS Session to rollback * @param ex the thrown application exception or error - * @throws javax.jms.JMSException in case of a rollback error + * @throws jakarta.jms.JMSException in case of a rollback error */ protected void rollbackOnExceptionIfNecessary(Session session, Throwable ex) throws JMSException { try { @@ -850,7 +850,7 @@ protected boolean isSessionLocallyTransacted(Session session) { * @param session the JMS Session to create a MessageConsumer for * @param destination the JMS Destination to create a MessageConsumer for * @return the new JMS MessageConsumer - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods */ protected MessageConsumer createConsumer(Session session, Destination destination) throws JMSException { if (isPubSubDomain() && destination instanceof Topic) { diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractPollingMessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractPollingMessageListenerContainer.java index 0a6287169a40..e681aaef1b19 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractPollingMessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractPollingMessageListenerContainer.java @@ -16,12 +16,12 @@ package org.springframework.jms.listener; -import javax.jms.Connection; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.Session; +import jakarta.jms.Connection; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageConsumer; +import jakarta.jms.Session; import org.springframework.jms.connection.ConnectionFactoryUtils; import org.springframework.jms.connection.JmsResourceHolder; @@ -38,7 +38,7 @@ /** * Base class for listener container implementations which are based on polling. - * Provides support for listener handling based on {@link javax.jms.MessageConsumer}, + * Provides support for listener handling based on {@link jakarta.jms.MessageConsumer}, * optionally participating in externally managed transactions. * *

    This listener container variant is built for repeated polling attempts, @@ -48,7 +48,7 @@ * configured through the {@link #setReceiveTimeout "receiveTimeout"} property. * *

    The underlying mechanism is based on standard JMS MessageConsumer handling, - * which is perfectly compatible with both native JMS and JMS in a Java EE environment. + * which is perfectly compatible with both native JMS and JMS in a Jakarta EE environment. * Neither the JMS {@code MessageConsumer.setMessageListener} facility nor the JMS * ServerSessionPool facility is required. A further advantage of this approach is * full control over the listening process, allowing for custom scaling and throttling @@ -59,7 +59,7 @@ * {@link org.springframework.transaction.PlatformTransactionManager} into the * {@link #setTransactionManager "transactionManager"} property. This will usually * be a {@link org.springframework.transaction.jta.JtaTransactionManager} in a - * Java EE environment, in combination with a JTA-aware JMS ConnectionFactory + * Jakarta EE environment, in combination with a JTA-aware JMS ConnectionFactory * obtained from JNDI (check your application server's documentation). * *

    This base class does not assume any specific mechanism for asynchronous @@ -165,9 +165,9 @@ public void setTransactionTimeout(int transactionTimeout) { * discouraged since such a listener container cannot cleanly shut down. * A negative value such as -1 indicates a no-wait receive operation. * @see #receiveFromConsumer(MessageConsumer, long) - * @see javax.jms.MessageConsumer#receive(long) - * @see javax.jms.MessageConsumer#receiveNoWait() - * @see javax.jms.MessageConsumer#receive() + * @see jakarta.jms.MessageConsumer#receive(long) + * @see jakarta.jms.MessageConsumer#receiveNoWait() + * @see jakarta.jms.MessageConsumer#receive() * @see #setTransactionTimeout */ public void setReceiveTimeout(long receiveTimeout) { @@ -211,7 +211,7 @@ public void initialize() { * registering a MessageListener for the specified listener. * @param session the JMS Session to work on * @return the MessageConsumer - * @throws javax.jms.JMSException if thrown by JMS methods + * @throws jakarta.jms.JMSException if thrown by JMS methods * @see #receiveAndExecute */ protected MessageConsumer createListenerConsumer(Session session) throws JMSException { @@ -266,7 +266,7 @@ protected boolean receiveAndExecute( * @param status the TransactionStatus (may be {@code null}) * @return whether a message has been received * @throws JMSException if thrown by JMS methods - * @see #doExecuteListener(javax.jms.Session, javax.jms.Message) + * @see #doExecuteListener(jakarta.jms.Session, jakarta.jms.Message) */ protected boolean doReceiveAndExecute(Object invoker, @Nullable Session session, @Nullable MessageConsumer consumer, @Nullable TransactionStatus status) throws JMSException { diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java index 856be8c914da..41fc11034f65 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java @@ -20,10 +20,10 @@ import java.util.Set; import java.util.concurrent.Executor; -import javax.jms.Connection; -import javax.jms.JMSException; -import javax.jms.MessageConsumer; -import javax.jms.Session; +import jakarta.jms.Connection; +import jakarta.jms.JMSException; +import jakarta.jms.MessageConsumer; +import jakarta.jms.Session; import org.springframework.core.Constants; import org.springframework.core.task.SimpleAsyncTaskExecutor; @@ -45,7 +45,7 @@ * Message listener container variant that uses plain JMS client APIs, specifically * a loop of {@code MessageConsumer.receive()} calls that also allow for * transactional reception of messages (registering them with XA transactions). - * Designed to work in a native JMS environment as well as in a Java EE environment, + * Designed to work in a native JMS environment as well as in a Jakarta EE environment, * with only minimal differences in configuration. * *

    This is a simple but nevertheless powerful form of message listener container. @@ -62,7 +62,7 @@ * abstraction. By default, the specified number of invoker tasks will be created * on startup, according to the {@link #setConcurrentConsumers "concurrentConsumers"} * setting. Specify an alternative {@code TaskExecutor} to integrate with an existing - * thread pool facility (such as a Java EE server's), for example using a + * thread pool facility (such as a Jakarta EE server's), for example using a * {@link org.springframework.scheduling.commonj.WorkManagerTaskExecutor CommonJ WorkManager}. * With a native JMS setup, each of those listener threads is going to use a * cached JMS {@code Session} and {@code MessageConsumer} (only refreshed in case @@ -73,11 +73,11 @@ * {@link org.springframework.transaction.PlatformTransactionManager} into the * {@link #setTransactionManager "transactionManager"} property. This will usually * be a {@link org.springframework.transaction.jta.JtaTransactionManager} in a - * Java EE environment, in combination with a JTA-aware JMS {@code ConnectionFactory} - * obtained from JNDI (check your Java EE server's documentation). Note that this + * Jakarta EE environment, in combination with a JTA-aware JMS {@code ConnectionFactory} + * obtained from JNDI (check your Jakarta EE server's documentation). Note that this * listener container will automatically reobtain all JMS handles for each transaction * in case an external transaction manager is specified, for compatibility with - * all Java EE servers (in particular JBoss). This non-caching behavior can be + * all Jakarta EE servers (in particular JBoss). This non-caching behavior can be * overridden through the {@link #setCacheLevel "cacheLevel"} / * {@link #setCacheLevelName "cacheLevelName"} property, enforcing caching of * the {@code Connection} (or also {@code Session} and {@code MessageConsumer}) @@ -119,7 +119,7 @@ * @since 2.0 * @see #setTransactionManager * @see #setCacheLevel - * @see javax.jms.MessageConsumer#receive(long) + * @see jakarta.jms.MessageConsumer#receive(long) * @see SimpleMessageListenerContainer * @see org.springframework.jms.listener.endpoint.JmsMessageEndpointManager */ @@ -219,7 +219,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe * of concurrent consumers. *

    Specify an alternative {@code TaskExecutor} for integration with an existing * thread pool. Note that this really only adds value if the threads are - * managed in a specific fashion, for example within a Java EE environment. + * managed in a specific fashion, for example within a Jakarta EE environment. * A plain thread pool does not add much value, as this listener container * will occupy a number of threads for its entire lifetime. * @see #setConcurrentConsumers @@ -273,7 +273,7 @@ public void setCacheLevelName(String constantName) throws IllegalArgumentExcepti *

    Default is {@link #CACHE_NONE} if an external transaction manager has been specified * (to reobtain all resources freshly within the scope of the external transaction), * and {@link #CACHE_CONSUMER} otherwise (operating with local JMS resources). - *

    Some Java EE servers only register their JMS resources with an ongoing XA + *

    Some Jakarta EE servers only register their JMS resources with an ongoing XA * transaction in case of a freshly obtained JMS {@code Connection} and {@code Session}, * which is why this listener container by default does not cache any of those. * However, depending on the rules of your server with respect to the caching diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/LocallyExposedJmsResourceHolder.java b/spring-jms/src/main/java/org/springframework/jms/listener/LocallyExposedJmsResourceHolder.java index 2adad4f3cdb4..c0148da51fc5 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/LocallyExposedJmsResourceHolder.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/LocallyExposedJmsResourceHolder.java @@ -16,7 +16,7 @@ package org.springframework.jms.listener; -import javax.jms.Session; +import jakarta.jms.Session; import org.springframework.jms.connection.JmsResourceHolder; diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/MessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/MessageListenerContainer.java index 89bfe78daacc..8610e2f7e4aa 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/MessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/MessageListenerContainer.java @@ -40,7 +40,7 @@ public interface MessageListenerContainer extends SmartLifecycle { /** * Return the {@link MessageConverter} that can be used to - * convert {@link javax.jms.Message}, if any. + * convert {@link jakarta.jms.Message}, if any. */ @Nullable MessageConverter getMessageConverter(); @@ -53,15 +53,15 @@ public interface MessageListenerContainer extends SmartLifecycle { DestinationResolver getDestinationResolver(); /** - * Return whether the Publish/Subscribe domain ({@link javax.jms.Topic Topics}) is used. - * Otherwise, the Point-to-Point domain ({@link javax.jms.Queue Queues}) is used. + * Return whether the Publish/Subscribe domain ({@link jakarta.jms.Topic Topics}) is used. + * Otherwise, the Point-to-Point domain ({@link jakarta.jms.Queue Queues}) is used. */ boolean isPubSubDomain(); /** * Return whether the reply destination uses Publish/Subscribe domain - * ({@link javax.jms.Topic Topics}). Otherwise, the Point-to-Point domain - * ({@link javax.jms.Queue Queues}) is used. + * ({@link jakarta.jms.Topic Topics}). Otherwise, the Point-to-Point domain + * ({@link jakarta.jms.Queue Queues}) is used. *

    By default, the value is identical to {@link #isPubSubDomain()}. */ boolean isReplyPubSubDomain(); diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/SessionAwareMessageListener.java b/spring-jms/src/main/java/org/springframework/jms/listener/SessionAwareMessageListener.java index af07dfae5a65..f2ba17487c0e 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/SessionAwareMessageListener.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/SessionAwareMessageListener.java @@ -16,12 +16,12 @@ package org.springframework.jms.listener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.Session; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.Session; /** - * Variant of the standard JMS {@link javax.jms.MessageListener} interface, + * Variant of the standard JMS {@link jakarta.jms.MessageListener} interface, * offering not only the received Message but also the underlying * JMS Session object. The latter can be used to send reply messages, * without the need to access an external Connection/Session, @@ -40,7 +40,7 @@ * @see DefaultMessageListenerContainer * @see SimpleMessageListenerContainer * @see org.springframework.jms.listener.endpoint.JmsMessageEndpointManager - * @see javax.jms.MessageListener + * @see jakarta.jms.MessageListener */ @FunctionalInterface public interface SessionAwareMessageListener { diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java index 469dfd43c871..b45de7781a6f 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java @@ -20,14 +20,14 @@ import java.util.Set; import java.util.concurrent.Executor; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.Destination; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.Session; +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.Destination; +import jakarta.jms.ExceptionListener; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageConsumer; +import jakarta.jms.Session; import org.springframework.jms.support.JmsUtils; import org.springframework.lang.Nullable; @@ -59,7 +59,7 @@ * * @author Juergen Hoeller * @since 2.0 - * @see javax.jms.MessageConsumer#setMessageListener + * @see jakarta.jms.MessageConsumer#setMessageListener * @see DefaultMessageListenerContainer * @see org.springframework.jms.listener.endpoint.JmsMessageEndpointManager */ @@ -174,7 +174,7 @@ public void setConcurrentConsumers(int concurrentConsumers) { * underlying Session. As a consequence, it is not recommended to use * this setting with a {@link SessionAwareMessageListener}, at least not * if the latter performs actual work on the given Session. A standard - * {@link javax.jms.MessageListener} will work fine, in general. + * {@link jakarta.jms.MessageListener} will work fine, in general. * @see #setConcurrentConsumers * @see org.springframework.core.task.SimpleAsyncTaskExecutor * @see org.springframework.scheduling.commonj.WorkManagerTaskExecutor diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/SubscriptionNameProvider.java b/spring-jms/src/main/java/org/springframework/jms/listener/SubscriptionNameProvider.java index c8622a78c06d..d1178618d9d2 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/SubscriptionNameProvider.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/SubscriptionNameProvider.java @@ -21,7 +21,7 @@ * name for a durable subscription that they might be registered with. Otherwise * the listener class name will be used as a default subscription name. * - *

    Applies to {@link javax.jms.MessageListener} objects as well as to + *

    Applies to {@link jakarta.jms.MessageListener} objects as well as to * {@link SessionAwareMessageListener} objects and plain listener methods * (as supported by {@link org.springframework.jms.listener.adapter.MessageListenerAdapter}. * diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java index e4b9cd442617..0bfec3872626 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java @@ -16,15 +16,14 @@ package org.springframework.jms.listener.adapter; -import javax.jms.BytesMessage; -import javax.jms.Destination; -import javax.jms.InvalidDestinationException; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Session; - +import jakarta.jms.BytesMessage; +import jakarta.jms.Destination; +import jakarta.jms.InvalidDestinationException; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageListener; +import jakarta.jms.MessageProducer; +import jakarta.jms.Session; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -96,7 +95,7 @@ public void setDefaultResponseDestination(Destination destination) { * "JMSReplyTo" field. *

    Alternatively, specify a JMS Destination object as "defaultResponseDestination". * @see #setDestinationResolver - * @see #setDefaultResponseDestination(javax.jms.Destination) + * @see #setDefaultResponseDestination(jakarta.jms.Destination) */ public void setDefaultResponseQueueName(String destinationName) { this.defaultResponseDestination = new DestinationNameHolder(destinationName, false); @@ -108,7 +107,7 @@ public void setDefaultResponseQueueName(String destinationName) { * "JMSReplyTo" field. *

    Alternatively, specify a JMS Destination object as "defaultResponseDestination". * @see #setDestinationResolver - * @see #setDefaultResponseDestination(javax.jms.Destination) + * @see #setDefaultResponseDestination(jakarta.jms.Destination) */ public void setDefaultResponseTopicName(String destinationName) { this.defaultResponseDestination = new DestinationNameHolder(destinationName, true); @@ -139,9 +138,9 @@ protected DestinationResolver getDestinationResolver() { * listener method arguments, and objects returned from listener * methods back to JMS messages. *

    The default converter is a {@link SimpleMessageConverter}, which is able - * to handle {@link javax.jms.BytesMessage BytesMessages}, - * {@link javax.jms.TextMessage TextMessages} and - * {@link javax.jms.ObjectMessage ObjectMessages}. + * to handle {@link jakarta.jms.BytesMessage BytesMessages}, + * {@link jakarta.jms.TextMessage TextMessages} and + * {@link jakarta.jms.ObjectMessage ObjectMessages}. */ public void setMessageConverter(@Nullable MessageConverter messageConverter) { this.messageConverter = messageConverter; @@ -208,7 +207,7 @@ protected QosSettings getResponseQosSettings() { * message listener container) for handling result objects as well. * @param message the incoming JMS message * @see #handleListenerException - * @see #onMessage(javax.jms.Message, javax.jms.Session) + * @see #onMessage(jakarta.jms.Message, jakarta.jms.Session) */ @Override public void onMessage(Message message) { @@ -230,7 +229,7 @@ public void onMessage(Message message) { * In case of the Spring {@link SessionAwareMessageListener} mechanism, * exceptions get handled by the caller instead. * @param ex the exception to handle - * @see #onMessage(javax.jms.Message) + * @see #onMessage(jakarta.jms.Message) */ protected void handleListenerException(Throwable ex) { logger.error("Listener execution failed", ex); @@ -343,7 +342,7 @@ protected Object preProcessResponse(Object result) { * @param request the original incoming JMS message * @param response the outgoing JMS message about to be sent * @throws JMSException if thrown by JMS API methods - * @see javax.jms.Message#setJMSCorrelationID + * @see jakarta.jms.Message#setJMSCorrelationID */ protected void postProcessResponse(Message request, Message response) throws JMSException { String correlation = request.getJMSCorrelationID(); @@ -373,15 +372,15 @@ private Destination getResponseDestination(Message request, Message response, Se * it is returned; if it is {@code null}, then the configured * {@link #resolveDefaultResponseDestination default response destination} * is returned; if this too is {@code null}, then an - * {@link javax.jms.InvalidDestinationException} is thrown. + * {@link jakarta.jms.InvalidDestinationException} is thrown. * @param request the original incoming JMS message * @param response the outgoing JMS message about to be sent * @param session the JMS Session to operate on * @return the response destination (never {@code null}) * @throws JMSException if thrown by JMS API methods - * @throws javax.jms.InvalidDestinationException if no {@link Destination} can be determined + * @throws jakarta.jms.InvalidDestinationException if no {@link Destination} can be determined * @see #setDefaultResponseDestination - * @see javax.jms.Message#getJMSReplyTo() + * @see jakarta.jms.Message#getJMSReplyTo() */ protected Destination getResponseDestination(Message request, Message response, Session session) throws JMSException { @@ -401,7 +400,7 @@ protected Destination getResponseDestination(Message request, Message response, * Resolve the default response destination into a JMS {@link Destination}, using this * accessor's {@link DestinationResolver} in case of a destination name. * @return the located {@link Destination} - * @throws javax.jms.JMSException if resolution failed + * @throws jakarta.jms.JMSException if resolution failed * @see #setDefaultResponseDestination * @see #setDefaultResponseQueueName * @see #setDefaultResponseTopicName @@ -426,8 +425,8 @@ protected Destination resolveDefaultResponseDestination(Session session) throws * @param session the JMS session to operate on * @throws JMSException if thrown by JMS API methods * @see #postProcessProducer - * @see javax.jms.Session#createProducer - * @see javax.jms.MessageProducer#send + * @see jakarta.jms.Session#createProducer + * @see jakarta.jms.MessageProducer#send */ protected void sendResponse(Session session, Destination destination, Message response) throws JMSException { MessageProducer producer = session.createProducer(destination); @@ -460,13 +459,13 @@ protected void postProcessProducer(MessageProducer producer, Message response) t /** * A {@link MessagingMessageConverter} that lazily invokes payload extraction and - * delegates it to {@link #extractMessage(javax.jms.Message)} in order to enforce + * delegates it to {@link #extractMessage(jakarta.jms.Message)} in order to enforce * backward compatibility. */ private class MessagingMessageConverterAdapter extends MessagingMessageConverter { @Override - public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException { + public Object fromMessage(jakarta.jms.Message message) throws JMSException, MessageConversionException { return new LazyResolutionMessage(message); } @@ -505,7 +504,7 @@ protected Message createMessageForPayload(Object payload, Session session, @Null protected class LazyResolutionMessage implements org.springframework.messaging.Message { - private final javax.jms.Message message; + private final jakarta.jms.Message message; @Nullable private Object payload; @@ -513,7 +512,7 @@ protected class LazyResolutionMessage implements org.springframework.messaging.M @Nullable private MessageHeaders headers; - public LazyResolutionMessage(javax.jms.Message message) { + public LazyResolutionMessage(jakarta.jms.Message message) { this.message = message; } diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/JmsResponse.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/JmsResponse.java index a1f425774e56..16564a3b6c2e 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/JmsResponse.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/JmsResponse.java @@ -16,9 +16,9 @@ package org.springframework.jms.listener.adapter; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Session; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Session; import org.springframework.jms.support.destination.DestinationResolver; import org.springframework.lang.Nullable; diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessageListenerAdapter.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessageListenerAdapter.java index 2743b70439c5..1cf7c230d838 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessageListenerAdapter.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessageListenerAdapter.java @@ -18,10 +18,10 @@ import java.lang.reflect.InvocationTargetException; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.Session; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageListener; +import jakarta.jms.Session; import org.springframework.jms.listener.SessionAwareMessageListener; import org.springframework.jms.listener.SubscriptionNameProvider; @@ -51,7 +51,7 @@ * message content type such as {@code String} or byte array), it will get * wrapped in a JMS {@code Message} and sent to the response destination * (either the JMS "reply-to" destination or a - * {@link #setDefaultResponseDestination(javax.jms.Destination) specified default + * {@link #setDefaultResponseDestination(jakarta.jms.Destination) specified default * destination}). * *

    Note: The sending of response messages is only available when @@ -86,7 +86,7 @@ * * This next example illustrates a {@code Message} delegate * that just consumes the {@code String} contents of - * {@link javax.jms.TextMessage TextMessages}. Notice also how the + * {@link jakarta.jms.TextMessage TextMessages}. Notice also how the * name of the {@code Message} handling method is different from the * {@link #ORIGINAL_DEFAULT_LISTENER_METHOD original} (this will have to * be configured in the attendant bean definition). Again, no {@code Message} @@ -98,9 +98,9 @@ * * This final example illustrates a {@code Message} delegate * that just consumes the {@code String} contents of - * {@link javax.jms.TextMessage TextMessages}. Notice how the return type + * {@link jakarta.jms.TextMessage TextMessages}. Notice how the return type * of this method is {@code String}: This will result in the configured - * {@link MessageListenerAdapter} sending a {@link javax.jms.TextMessage} in response. + * {@link MessageListenerAdapter} sending a {@link jakarta.jms.TextMessage} in response. * *

    public interface ResponsiveTextMessageContentDelegate {
      *    String handleMessage(String text);
    diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java
    index 91072e40cb5e..c858d2b1519c 100644
    --- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java
    +++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java
    @@ -16,8 +16,8 @@
     
     package org.springframework.jms.listener.adapter;
     
    -import javax.jms.JMSException;
    -import javax.jms.Session;
    +import jakarta.jms.JMSException;
    +import jakarta.jms.Session;
     
     import org.springframework.core.MethodParameter;
     import org.springframework.jms.support.JmsHeaderMapper;
    @@ -31,14 +31,14 @@
     import org.springframework.util.Assert;
     
     /**
    - * A {@link javax.jms.MessageListener} adapter that invokes a configurable
    + * A {@link jakarta.jms.MessageListener} adapter that invokes a configurable
      * {@link InvocableHandlerMethod}.
      *
    - * 

    Wraps the incoming {@link javax.jms.Message} to Spring's {@link Message} + *

    Wraps the incoming {@link jakarta.jms.Message} to Spring's {@link Message} * abstraction, copying the JMS standard headers using a configurable * {@link JmsHeaderMapper}. * - *

    The original {@link javax.jms.Message} and the {@link javax.jms.Session} + *

    The original {@link jakarta.jms.Message} and the {@link jakarta.jms.Session} * are provided as additional arguments so that these can be injected as * method arguments if necessary. * @@ -56,7 +56,7 @@ public class MessagingMessageListenerAdapter extends AbstractAdaptableMessageLis /** * Set the {@link InvocableHandlerMethod} to use to invoke the method - * processing an incoming {@link javax.jms.Message}. + * processing an incoming {@link jakarta.jms.Message}. */ public void setHandlerMethod(InvocableHandlerMethod handlerMethod) { this.handlerMethod = handlerMethod; @@ -69,7 +69,7 @@ private InvocableHandlerMethod getHandlerMethod() { @Override - public void onMessage(javax.jms.Message jmsMessage, @Nullable Session session) throws JMSException { + public void onMessage(jakarta.jms.Message jmsMessage, @Nullable Session session) throws JMSException { Message message = toMessagingMessage(jmsMessage); if (logger.isDebugEnabled()) { logger.debug("Processing [" + message + "]"); @@ -94,7 +94,7 @@ protected Object preProcessResponse(Object result) { AbstractMessageSendingTemplate.CONVERSION_HINT_HEADER, returnType).build(); } - protected Message toMessagingMessage(javax.jms.Message jmsMessage) { + protected Message toMessagingMessage(jakarta.jms.Message jmsMessage) { try { return (Message) getMessagingMessageConverter().fromMessage(jmsMessage); } @@ -108,7 +108,7 @@ protected Message toMessagingMessage(javax.jms.Message jmsMessage) { * with a dedicated error message. */ @Nullable - private Object invokeHandler(javax.jms.Message jmsMessage, @Nullable Session session, Message message) { + private Object invokeHandler(jakarta.jms.Message jmsMessage, @Nullable Session session, Message message) { InvocableHandlerMethod handlerMethod = getHandlerMethod(); try { return handlerMethod.invoke(message, jmsMessage, session); diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/DefaultJmsActivationSpecFactory.java b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/DefaultJmsActivationSpecFactory.java index 1702070063b0..810d848138c0 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/DefaultJmsActivationSpecFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/DefaultJmsActivationSpecFactory.java @@ -16,9 +16,8 @@ package org.springframework.jms.listener.endpoint; -import javax.jms.Session; -import javax.resource.spi.ResourceAdapter; - +import jakarta.jms.Session; +import jakarta.resource.spi.ResourceAdapter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsActivationSpecConfig.java b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsActivationSpecConfig.java index ba2f6da68a94..9109654e2ff7 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsActivationSpecConfig.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsActivationSpecConfig.java @@ -16,7 +16,7 @@ package org.springframework.jms.listener.endpoint; -import javax.jms.Session; +import jakarta.jms.Session; import org.springframework.core.Constants; import org.springframework.jms.support.QosSettings; @@ -36,11 +36,11 @@ * @since 2.5 * @see JmsActivationSpecFactory * @see JmsMessageEndpointManager#setActivationSpecConfig - * @see javax.resource.spi.ResourceAdapter#endpointActivation + * @see jakarta.resource.spi.ResourceAdapter#endpointActivation */ public class JmsActivationSpecConfig { - /** Constants instance for {@code javax.jms.Session}. */ + /** Constants instance for {@code jakarta.jms.Session}. */ private static final Constants sessionConstants = new Constants(Session.class); @@ -184,10 +184,10 @@ public String getMessageSelector() { * supports "SESSION_TRANSACTED" in the form of RA-managed transactions * (automatically translated by Spring's {@link DefaultJmsActivationSpecFactory}. * @param constantName the name of the {@link Session} acknowledge mode constant - * @see javax.jms.Session#AUTO_ACKNOWLEDGE - * @see javax.jms.Session#CLIENT_ACKNOWLEDGE - * @see javax.jms.Session#DUPS_OK_ACKNOWLEDGE - * @see javax.jms.Session#SESSION_TRANSACTED + * @see jakarta.jms.Session#AUTO_ACKNOWLEDGE + * @see jakarta.jms.Session#CLIENT_ACKNOWLEDGE + * @see jakarta.jms.Session#DUPS_OK_ACKNOWLEDGE + * @see jakarta.jms.Session#SESSION_TRANSACTED * @see StandardJmsActivationSpecFactory * @see DefaultJmsActivationSpecFactory */ @@ -197,10 +197,10 @@ public void setAcknowledgeModeName(String constantName) { /** * Set the JMS acknowledgement mode to use. - * @see javax.jms.Session#AUTO_ACKNOWLEDGE - * @see javax.jms.Session#CLIENT_ACKNOWLEDGE - * @see javax.jms.Session#DUPS_OK_ACKNOWLEDGE - * @see javax.jms.Session#SESSION_TRANSACTED + * @see jakarta.jms.Session#AUTO_ACKNOWLEDGE + * @see jakarta.jms.Session#CLIENT_ACKNOWLEDGE + * @see jakarta.jms.Session#DUPS_OK_ACKNOWLEDGE + * @see jakarta.jms.Session#SESSION_TRANSACTED */ public void setAcknowledgeMode(int acknowledgeMode) { this.acknowledgeMode = acknowledgeMode; diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsActivationSpecFactory.java b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsActivationSpecFactory.java index 2ef3bcbb5d33..2be2e2a20469 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsActivationSpecFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsActivationSpecFactory.java @@ -16,8 +16,8 @@ package org.springframework.jms.listener.endpoint; -import javax.resource.spi.ActivationSpec; -import javax.resource.spi.ResourceAdapter; +import jakarta.resource.spi.ActivationSpec; +import jakarta.resource.spi.ResourceAdapter; /** * Strategy interface for creating JCA 1.5 ActivationSpec objects @@ -32,7 +32,7 @@ * @since 2.5 * @see JmsActivationSpecConfig * @see JmsMessageEndpointManager#setActivationSpecFactory - * @see javax.resource.spi.ResourceAdapter#endpointActivation + * @see jakarta.resource.spi.ResourceAdapter#endpointActivation */ public interface JmsActivationSpecFactory { diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointFactory.java b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointFactory.java index c27867f6f5b3..5151aaa3cb66 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointFactory.java @@ -16,10 +16,10 @@ package org.springframework.jms.listener.endpoint; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.resource.ResourceException; -import javax.resource.spi.UnavailableException; +import jakarta.jms.Message; +import jakarta.jms.MessageListener; +import jakarta.resource.ResourceException; +import jakarta.resource.spi.UnavailableException; import org.springframework.jca.endpoint.AbstractMessageEndpointFactory; import org.springframework.lang.Nullable; @@ -27,9 +27,9 @@ /** * JMS-specific implementation of the JCA 1.7 - * {@link javax.resource.spi.endpoint.MessageEndpointFactory} interface, + * {@link jakarta.resource.spi.endpoint.MessageEndpointFactory} interface, * providing transaction management capabilities for a JMS listener object - * (e.g. a {@link javax.jms.MessageListener} object). + * (e.g. a {@link jakarta.jms.MessageListener} object). * *

    Uses a static endpoint implementation, simply wrapping the * specified message listener object and exposing all of its implemented @@ -38,7 +38,7 @@ *

    Typically used with Spring's {@link JmsMessageEndpointManager}, * but not tied to it. As a consequence, this endpoint factory could * also be used with programmatic endpoint management on a native - * {@link javax.resource.spi.ResourceAdapter} instance. + * {@link jakarta.resource.spi.ResourceAdapter} instance. * * @author Juergen Hoeller * @author Stephane Nicoll diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointManager.java b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointManager.java index 518736f59e20..72a4f99fab31 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointManager.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointManager.java @@ -16,8 +16,8 @@ package org.springframework.jms.listener.endpoint; -import javax.jms.MessageListener; -import javax.resource.ResourceException; +import jakarta.jms.MessageListener; +import jakarta.resource.ResourceException; import org.springframework.beans.factory.BeanNameAware; import org.springframework.jca.endpoint.GenericMessageEndpointManager; @@ -37,15 +37,15 @@ * object for activating the endpoint. * *

    NOTE: This JCA-based endpoint manager supports standard JMS - * {@link javax.jms.MessageListener} endpoints only. It does not support + * {@link jakarta.jms.MessageListener} endpoints only. It does not support * Spring's {@link org.springframework.jms.listener.SessionAwareMessageListener} * variant, simply because the JCA endpoint management contract does not allow - * for obtaining the current JMS {@link javax.jms.Session}. + * for obtaining the current JMS {@link jakarta.jms.Session}. * * @author Juergen Hoeller * @author Stephane Nicoll * @since 2.5 - * @see javax.jms.MessageListener + * @see jakarta.jms.MessageListener * @see #setActivationSpecConfig * @see JmsActivationSpecConfig * @see JmsActivationSpecFactory @@ -86,7 +86,7 @@ public MessageListener getMessageListener() { * invocations, enlisting the endpoint resource in each such transaction. *

    The passed-in object may be a transaction manager which implements * Spring's {@link org.springframework.transaction.jta.TransactionFactory} - * interface, or a plain {@link javax.transaction.TransactionManager}. + * interface, or a plain {@link jakarta.transaction.TransactionManager}. *

    If no transaction manager is specified, the endpoint invocation * will simply not be wrapped in an XA transaction. Consult your * resource provider's ActivationSpec documentation for the local diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/StandardJmsActivationSpecFactory.java b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/StandardJmsActivationSpecFactory.java index 632a12513163..f93eef259521 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/StandardJmsActivationSpecFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/StandardJmsActivationSpecFactory.java @@ -18,12 +18,12 @@ import java.util.Map; -import javax.jms.JMSException; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.Topic; -import javax.resource.spi.ActivationSpec; -import javax.resource.spi.ResourceAdapter; +import jakarta.jms.JMSException; +import jakarta.jms.Queue; +import jakarta.jms.Session; +import jakarta.jms.Topic; +import jakarta.resource.spi.ActivationSpec; +import jakarta.resource.spi.ResourceAdapter; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanWrapper; @@ -193,11 +193,11 @@ else if (config.isSubscriptionDurable()) { * having been requested. * @param bw the BeanWrapper wrapping the ActivationSpec object * @param ackMode the configured acknowledge mode - * (according to the constants in {@link javax.jms.Session} - * @see javax.jms.Session#AUTO_ACKNOWLEDGE - * @see javax.jms.Session#DUPS_OK_ACKNOWLEDGE - * @see javax.jms.Session#CLIENT_ACKNOWLEDGE - * @see javax.jms.Session#SESSION_TRANSACTED + * (according to the constants in {@link jakarta.jms.Session} + * @see jakarta.jms.Session#AUTO_ACKNOWLEDGE + * @see jakarta.jms.Session#DUPS_OK_ACKNOWLEDGE + * @see jakarta.jms.Session#CLIENT_ACKNOWLEDGE + * @see jakarta.jms.Session#SESSION_TRANSACTED */ protected void applyAcknowledgeMode(BeanWrapper bw, int ackMode) { if (ackMode == Session.SESSION_TRANSACTED) { diff --git a/spring-jms/src/main/java/org/springframework/jms/support/JmsAccessor.java b/spring-jms/src/main/java/org/springframework/jms/support/JmsAccessor.java index 305fc824983b..5e8e19c7505f 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/JmsAccessor.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/JmsAccessor.java @@ -16,11 +16,10 @@ package org.springframework.jms.support; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSException; -import javax.jms.Session; - +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.JMSException; +import jakarta.jms.Session; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -47,7 +46,7 @@ */ public abstract class JmsAccessor implements InitializingBean { - /** Constants instance for {@code javax.jms.Session}. */ + /** Constants instance for {@code jakarta.jms.Session}. */ private static final Constants sessionConstants = new Constants(Session.class); @@ -95,7 +94,7 @@ protected final ConnectionFactory obtainConnectionFactory() { * Default is "false". *

    Note that within a JTA transaction, the parameters passed to * {@code create(Queue/Topic)Session(boolean transacted, int acknowledgeMode)} - * method are not taken into account. Depending on the Java EE transaction context, + * method are not taken into account. Depending on the Jakarta EE transaction context, * the container makes its own decisions on these values. Analogously, these * parameters are not taken into account within a locally managed transaction * either, since the accessor operates on an existing JMS Session in this case. @@ -106,7 +105,7 @@ protected final ConnectionFactory obtainConnectionFactory() { * transaction being managed alongside the main transaction (which might * be a native JDBC transaction), with the JMS transaction committing * right after the main transaction. - * @see javax.jms.Connection#createSession(boolean, int) + * @see jakarta.jms.Connection#createSession(boolean, int) */ public void setSessionTransacted(boolean sessionTransacted) { this.sessionTransacted = sessionTransacted; @@ -127,10 +126,10 @@ public boolean isSessionTransacted() { *

    If you want to use vendor-specific extensions to the acknowledgment mode, * use {@link #setSessionAcknowledgeMode(int)} instead. * @param constantName the name of the {@link Session} acknowledge mode constant - * @see javax.jms.Session#AUTO_ACKNOWLEDGE - * @see javax.jms.Session#CLIENT_ACKNOWLEDGE - * @see javax.jms.Session#DUPS_OK_ACKNOWLEDGE - * @see javax.jms.Connection#createSession(boolean, int) + * @see jakarta.jms.Session#AUTO_ACKNOWLEDGE + * @see jakarta.jms.Session#CLIENT_ACKNOWLEDGE + * @see jakarta.jms.Session#DUPS_OK_ACKNOWLEDGE + * @see jakarta.jms.Connection#createSession(boolean, int) */ public void setSessionAcknowledgeModeName(String constantName) { setSessionAcknowledgeMode(sessionConstants.asNumber(constantName).intValue()); @@ -147,10 +146,10 @@ public void setSessionAcknowledgeModeName(String constantName) { * the container makes its own decisions on these values. See section 17.3.5 * of the EJB spec. * @param sessionAcknowledgeMode the acknowledgement mode constant - * @see javax.jms.Session#AUTO_ACKNOWLEDGE - * @see javax.jms.Session#CLIENT_ACKNOWLEDGE - * @see javax.jms.Session#DUPS_OK_ACKNOWLEDGE - * @see javax.jms.Connection#createSession(boolean, int) + * @see jakarta.jms.Session#AUTO_ACKNOWLEDGE + * @see jakarta.jms.Session#CLIENT_ACKNOWLEDGE + * @see jakarta.jms.Session#DUPS_OK_ACKNOWLEDGE + * @see jakarta.jms.Connection#createSession(boolean, int) */ public void setSessionAcknowledgeMode(int sessionAcknowledgeMode) { this.sessionAcknowledgeMode = sessionAcknowledgeMode; @@ -172,7 +171,7 @@ public void afterPropertiesSet() { /** - * Convert the specified checked {@link javax.jms.JMSException JMSException} to + * Convert the specified checked {@link jakarta.jms.JMSException JMSException} to * a Spring runtime {@link org.springframework.jms.JmsException JmsException} * equivalent. *

    The default implementation delegates to the @@ -190,7 +189,7 @@ protected JmsException convertJmsAccessException(JMSException ex) { *

    This implementation uses JMS 1.1 API. * @return the new JMS Connection * @throws JMSException if thrown by JMS API methods - * @see javax.jms.ConnectionFactory#createConnection() + * @see jakarta.jms.ConnectionFactory#createConnection() */ protected Connection createConnection() throws JMSException { return obtainConnectionFactory().createConnection(); @@ -202,7 +201,7 @@ protected Connection createConnection() throws JMSException { * @param con the JMS Connection to create a Session for * @return the new JMS Session * @throws JMSException if thrown by JMS API methods - * @see javax.jms.Connection#createSession(boolean, int) + * @see jakarta.jms.Connection#createSession(boolean, int) */ protected Session createSession(Connection con) throws JMSException { return con.createSession(isSessionTransacted(), getSessionAcknowledgeMode()); @@ -213,9 +212,9 @@ protected Session createSession(Connection con) throws JMSException { *

    This implementation uses JMS 1.1 API. * @param session the JMS Session to check * @return whether the given Session is in client acknowledge mode - * @throws javax.jms.JMSException if thrown by JMS API methods - * @see javax.jms.Session#getAcknowledgeMode() - * @see javax.jms.Session#CLIENT_ACKNOWLEDGE + * @throws jakarta.jms.JMSException if thrown by JMS API methods + * @see jakarta.jms.Session#getAcknowledgeMode() + * @see jakarta.jms.Session#CLIENT_ACKNOWLEDGE */ protected boolean isClientAcknowledge(Session session) throws JMSException { return (session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE); diff --git a/spring-jms/src/main/java/org/springframework/jms/support/JmsHeaderMapper.java b/spring-jms/src/main/java/org/springframework/jms/support/JmsHeaderMapper.java index 3914d61bede5..75e4d4fa3272 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/JmsHeaderMapper.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/JmsHeaderMapper.java @@ -16,13 +16,13 @@ package org.springframework.jms.support; -import javax.jms.Message; +import jakarta.jms.Message; import org.springframework.messaging.support.HeaderMapper; /** * Strategy interface for mapping {@link org.springframework.messaging.Message} - * headers to an outbound JMS {@link javax.jms.Message} (e.g. to configure JMS + * headers to an outbound JMS {@link jakarta.jms.Message} (e.g. to configure JMS * properties) or extracting messaging header values from an inbound JMS Message. * * @author Mark Fisher diff --git a/spring-jms/src/main/java/org/springframework/jms/support/JmsHeaders.java b/spring-jms/src/main/java/org/springframework/jms/support/JmsHeaders.java index f4e5c028e7af..a2e7867e92f7 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/JmsHeaders.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/JmsHeaders.java @@ -37,53 +37,53 @@ public interface JmsHeaders { * Correlation ID for the message. This may be the {@link #MESSAGE_ID} of * the message that this message replies to. It may also be an * application-specific identifier. - * @see javax.jms.Message#getJMSCorrelationID() + * @see jakarta.jms.Message#getJMSCorrelationID() */ String CORRELATION_ID = PREFIX + "correlationId"; /** * Name of the destination (topic or queue) of the message. *

    Read-only value. - * @see javax.jms.Message#getJMSDestination() - * @see javax.jms.Destination - * @see javax.jms.Queue - * @see javax.jms.Topic + * @see jakarta.jms.Message#getJMSDestination() + * @see jakarta.jms.Destination + * @see jakarta.jms.Queue + * @see jakarta.jms.Topic */ String DESTINATION = PREFIX + "destination"; /** * Distribution mode. *

    Read-only value. - * @see javax.jms.Message#getJMSDeliveryMode() - * @see javax.jms.DeliveryMode + * @see jakarta.jms.Message#getJMSDeliveryMode() + * @see jakarta.jms.DeliveryMode */ String DELIVERY_MODE = PREFIX + "deliveryMode"; /** * Message expiration date and time. *

    Read-only value. - * @see javax.jms.Message#getJMSExpiration() + * @see jakarta.jms.Message#getJMSExpiration() */ String EXPIRATION = PREFIX + "expiration"; /** * Unique identifier for a message. *

    Read-only value. - * @see javax.jms.Message#getJMSMessageID() + * @see jakarta.jms.Message#getJMSMessageID() */ String MESSAGE_ID = PREFIX + "messageId"; /** * The message priority level. *

    Read-only value. - * @see javax.jms.Message#getJMSPriority() + * @see jakarta.jms.Message#getJMSPriority() */ String PRIORITY = PREFIX + "priority"; /** * Name of the destination (topic or queue) the message replies should * be sent to. - * @see javax.jms.Message#getJMSReplyTo() + * @see jakarta.jms.Message#getJMSReplyTo() */ String REPLY_TO = PREFIX + "replyTo"; @@ -91,21 +91,21 @@ public interface JmsHeaders { * Specify if the message was resent. This occurs when a message * consumer fails to acknowledge the message reception. *

    Read-only value. - * @see javax.jms.Message#getJMSRedelivered() + * @see jakarta.jms.Message#getJMSRedelivered() */ String REDELIVERED = PREFIX + "redelivered"; /** * Message type label. This type is a string value describing the message * in a functional manner. - * @see javax.jms.Message#getJMSType() + * @see jakarta.jms.Message#getJMSType() */ String TYPE = PREFIX + "type"; /** * Date and time of the message sending operation. *

    Read-only value. - * @see javax.jms.Message#getJMSTimestamp() + * @see jakarta.jms.Message#getJMSTimestamp() */ String TIMESTAMP = PREFIX + "timestamp"; diff --git a/spring-jms/src/main/java/org/springframework/jms/support/JmsMessageHeaderAccessor.java b/spring-jms/src/main/java/org/springframework/jms/support/JmsMessageHeaderAccessor.java index c7ccdf4e96cb..3523c7808ba6 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/JmsMessageHeaderAccessor.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/JmsMessageHeaderAccessor.java @@ -19,7 +19,7 @@ import java.util.List; import java.util.Map; -import javax.jms.Destination; +import jakarta.jms.Destination; import org.springframework.lang.Nullable; import org.springframework.messaging.Message; diff --git a/spring-jms/src/main/java/org/springframework/jms/support/JmsUtils.java b/spring-jms/src/main/java/org/springframework/jms/support/JmsUtils.java index 3f33ba102110..4d6b136264c3 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/JmsUtils.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/JmsUtils.java @@ -16,14 +16,13 @@ package org.springframework.jms.support; -import javax.jms.Connection; -import javax.jms.JMSException; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.QueueBrowser; -import javax.jms.QueueRequestor; -import javax.jms.Session; - +import jakarta.jms.Connection; +import jakarta.jms.JMSException; +import jakarta.jms.MessageConsumer; +import jakarta.jms.MessageProducer; +import jakarta.jms.QueueBrowser; +import jakarta.jms.QueueRequestor; +import jakarta.jms.Session; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -85,7 +84,7 @@ public static void closeConnection(@Nullable Connection con, boolean stop) { con.close(); } } - catch (javax.jms.IllegalStateException ex) { + catch (jakarta.jms.IllegalStateException ex) { logger.debug("Ignoring Connection state exception - assuming already closed: " + ex); } catch (JMSException ex) { @@ -217,7 +216,7 @@ public static void commitIfNecessary(Session session) throws JMSException { try { session.commit(); } - catch (javax.jms.TransactionInProgressException | javax.jms.IllegalStateException ex) { + catch (jakarta.jms.TransactionInProgressException | jakarta.jms.IllegalStateException ex) { // Ignore -> can only happen in case of a JTA transaction. } } @@ -232,7 +231,7 @@ public static void rollbackIfNecessary(Session session) throws JMSException { try { session.rollback(); } - catch (javax.jms.TransactionInProgressException | javax.jms.IllegalStateException ex) { + catch (jakarta.jms.TransactionInProgressException | jakarta.jms.IllegalStateException ex) { // Ignore -> can only happen in case of a JTA transaction. } } @@ -242,7 +241,7 @@ public static void rollbackIfNecessary(Session session) throws JMSException { * incorporating a linked exception's message if appropriate. * @param ex the JMSException to build a message for * @return the descriptive message String - * @see javax.jms.JMSException#getLinkedException() + * @see jakarta.jms.JMSException#getLinkedException() */ public static String buildExceptionMessage(JMSException ex) { String message = ex.getMessage(); @@ -262,7 +261,7 @@ public static String buildExceptionMessage(JMSException ex) { } /** - * Convert the specified checked {@link javax.jms.JMSException JMSException} to a + * Convert the specified checked {@link jakarta.jms.JMSException JMSException} to a * Spring runtime {@link org.springframework.jms.JmsException JmsException} equivalent. * @param ex the original checked JMSException to convert * @return the Spring runtime JmsException wrapping the given exception @@ -270,41 +269,41 @@ public static String buildExceptionMessage(JMSException ex) { public static JmsException convertJmsAccessException(JMSException ex) { Assert.notNull(ex, "JMSException must not be null"); - if (ex instanceof javax.jms.IllegalStateException) { - return new org.springframework.jms.IllegalStateException((javax.jms.IllegalStateException) ex); + if (ex instanceof jakarta.jms.IllegalStateException) { + return new org.springframework.jms.IllegalStateException((jakarta.jms.IllegalStateException) ex); } - if (ex instanceof javax.jms.InvalidClientIDException) { - return new InvalidClientIDException((javax.jms.InvalidClientIDException) ex); + if (ex instanceof jakarta.jms.InvalidClientIDException) { + return new InvalidClientIDException((jakarta.jms.InvalidClientIDException) ex); } - if (ex instanceof javax.jms.InvalidDestinationException) { - return new InvalidDestinationException((javax.jms.InvalidDestinationException) ex); + if (ex instanceof jakarta.jms.InvalidDestinationException) { + return new InvalidDestinationException((jakarta.jms.InvalidDestinationException) ex); } - if (ex instanceof javax.jms.InvalidSelectorException) { - return new InvalidSelectorException((javax.jms.InvalidSelectorException) ex); + if (ex instanceof jakarta.jms.InvalidSelectorException) { + return new InvalidSelectorException((jakarta.jms.InvalidSelectorException) ex); } - if (ex instanceof javax.jms.JMSSecurityException) { - return new JmsSecurityException((javax.jms.JMSSecurityException) ex); + if (ex instanceof jakarta.jms.JMSSecurityException) { + return new JmsSecurityException((jakarta.jms.JMSSecurityException) ex); } - if (ex instanceof javax.jms.MessageEOFException) { - return new MessageEOFException((javax.jms.MessageEOFException) ex); + if (ex instanceof jakarta.jms.MessageEOFException) { + return new MessageEOFException((jakarta.jms.MessageEOFException) ex); } - if (ex instanceof javax.jms.MessageFormatException) { - return new MessageFormatException((javax.jms.MessageFormatException) ex); + if (ex instanceof jakarta.jms.MessageFormatException) { + return new MessageFormatException((jakarta.jms.MessageFormatException) ex); } - if (ex instanceof javax.jms.MessageNotReadableException) { - return new MessageNotReadableException((javax.jms.MessageNotReadableException) ex); + if (ex instanceof jakarta.jms.MessageNotReadableException) { + return new MessageNotReadableException((jakarta.jms.MessageNotReadableException) ex); } - if (ex instanceof javax.jms.MessageNotWriteableException) { - return new MessageNotWriteableException((javax.jms.MessageNotWriteableException) ex); + if (ex instanceof jakarta.jms.MessageNotWriteableException) { + return new MessageNotWriteableException((jakarta.jms.MessageNotWriteableException) ex); } - if (ex instanceof javax.jms.ResourceAllocationException) { - return new ResourceAllocationException((javax.jms.ResourceAllocationException) ex); + if (ex instanceof jakarta.jms.ResourceAllocationException) { + return new ResourceAllocationException((jakarta.jms.ResourceAllocationException) ex); } - if (ex instanceof javax.jms.TransactionInProgressException) { - return new TransactionInProgressException((javax.jms.TransactionInProgressException) ex); + if (ex instanceof jakarta.jms.TransactionInProgressException) { + return new TransactionInProgressException((jakarta.jms.TransactionInProgressException) ex); } - if (ex instanceof javax.jms.TransactionRolledBackException) { - return new TransactionRolledBackException((javax.jms.TransactionRolledBackException) ex); + if (ex instanceof jakarta.jms.TransactionRolledBackException) { + return new TransactionRolledBackException((jakarta.jms.TransactionRolledBackException) ex); } // fallback diff --git a/spring-jms/src/main/java/org/springframework/jms/support/QosSettings.java b/spring-jms/src/main/java/org/springframework/jms/support/QosSettings.java index f19a6970e429..2cd329fff708 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/QosSettings.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/QosSettings.java @@ -16,7 +16,7 @@ package org.springframework.jms.support; -import javax.jms.Message; +import jakarta.jms.Message; import org.springframework.lang.Nullable; @@ -59,10 +59,10 @@ public QosSettings(int deliveryMode, int priority, long timeToLive) { * Set the delivery mode to use when sending a message. * Default is the JMS Message default: "PERSISTENT". * @param deliveryMode the delivery mode to use - * @see javax.jms.DeliveryMode#PERSISTENT - * @see javax.jms.DeliveryMode#NON_PERSISTENT - * @see javax.jms.Message#DEFAULT_DELIVERY_MODE - * @see javax.jms.MessageProducer#send(javax.jms.Message, int, int, long) + * @see jakarta.jms.DeliveryMode#PERSISTENT + * @see jakarta.jms.DeliveryMode#NON_PERSISTENT + * @see jakarta.jms.Message#DEFAULT_DELIVERY_MODE + * @see jakarta.jms.MessageProducer#send(jakarta.jms.Message, int, int, long) */ public void setDeliveryMode(int deliveryMode) { this.deliveryMode = deliveryMode; @@ -77,8 +77,8 @@ public int getDeliveryMode() { /** * Set the priority of a message when sending. - * @see javax.jms.Message#DEFAULT_PRIORITY - * @see javax.jms.MessageProducer#send(javax.jms.Message, int, int, long) + * @see jakarta.jms.Message#DEFAULT_PRIORITY + * @see jakarta.jms.MessageProducer#send(jakarta.jms.Message, int, int, long) */ public void setPriority(int priority) { this.priority = priority; @@ -94,8 +94,8 @@ public int getPriority() { /** * Set the time-to-live of the message when sending. * @param timeToLive the message's lifetime (in milliseconds) - * @see javax.jms.Message#DEFAULT_TIME_TO_LIVE - * @see javax.jms.MessageProducer#send(javax.jms.Message, int, int, long) + * @see jakarta.jms.Message#DEFAULT_TIME_TO_LIVE + * @see jakarta.jms.MessageProducer#send(jakarta.jms.Message, int, int, long) */ public void setTimeToLive(long timeToLive) { this.timeToLive = timeToLive; diff --git a/spring-jms/src/main/java/org/springframework/jms/support/SimpleJmsHeaderMapper.java b/spring-jms/src/main/java/org/springframework/jms/support/SimpleJmsHeaderMapper.java index 36569911c694..43d53cf3ffc3 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/SimpleJmsHeaderMapper.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/SimpleJmsHeaderMapper.java @@ -23,9 +23,9 @@ import java.util.Map; import java.util.Set; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Message; import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.support.AbstractHeaderMapper; @@ -61,7 +61,7 @@ public class SimpleJmsHeaderMapper extends AbstractHeaderMapper impleme @Override - public void fromHeaders(MessageHeaders headers, javax.jms.Message jmsMessage) { + public void fromHeaders(MessageHeaders headers, jakarta.jms.Message jmsMessage) { try { Object jmsCorrelationId = headers.get(JmsHeaders.CORRELATION_ID); if (jmsCorrelationId instanceof Number) { @@ -125,7 +125,7 @@ else if (logger.isDebugEnabled()) { } @Override - public MessageHeaders toHeaders(javax.jms.Message jmsMessage) { + public MessageHeaders toHeaders(jakarta.jms.Message jmsMessage) { Map headers = new HashMap<>(); try { try { diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java index 401f5c0cb5ed..7b6c3370aed1 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java @@ -24,18 +24,17 @@ import java.util.HashMap; import java.util.Map; -import javax.jms.BytesMessage; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.Session; -import javax.jms.TextMessage; - import com.fasterxml.jackson.annotation.JsonView; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; +import jakarta.jms.BytesMessage; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.Session; +import jakarta.jms.TextMessage; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.core.MethodParameter; @@ -212,7 +211,7 @@ public Message toMessage(Object object, Session session, @Nullable Object conver * @param session the Session to use for creating a JMS Message * @param jsonView the view to use to filter the content * @return the JMS Message - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods * @throws MessageConversionException in case of conversion failure * @since 4.3 */ @@ -343,7 +342,7 @@ protected Message mapToMessage(Object object, Session session, ObjectWriter obje * @param object the payload object to set a type id for * @param message the JMS Message on which to set the type id property * @throws JMSException if thrown by JMS methods - * @see #getJavaTypeForMessage(javax.jms.Message) + * @see #getJavaTypeForMessage(jakarta.jms.Message) * @see #setTypeIdPropertyName(String) * @see #setTypeIdMappings(java.util.Map) */ @@ -445,7 +444,7 @@ protected Object convertFromMessage(Message message, JavaType targetJavaType) * a different strategy, e.g. doing some heuristics based on message origin. * @param message the JMS Message from which to get the type id property * @throws JMSException if thrown by JMS methods - * @see #setTypeIdOnMessage(Object, javax.jms.Message) + * @see #setTypeIdOnMessage(Object, jakarta.jms.Message) * @see #setTypeIdPropertyName(String) * @see #setTypeIdMappings(java.util.Map) */ diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java index 99c38631fdac..b420ec92c6b0 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java @@ -22,16 +22,17 @@ import java.io.StringReader; import java.io.StringWriter; -import javax.jms.BytesMessage; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.Session; -import javax.jms.TextMessage; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import jakarta.jms.BytesMessage; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.Session; +import jakarta.jms.TextMessage; + import org.springframework.beans.factory.InitializingBean; import org.springframework.lang.Nullable; import org.springframework.oxm.Marshaller; @@ -144,8 +145,8 @@ public void afterPropertiesSet() { /** - * This implementation marshals the given object to a {@link javax.jms.TextMessage} or - * {@link javax.jms.BytesMessage}. The desired message type can be defined by setting + * This implementation marshals the given object to a {@link jakarta.jms.TextMessage} or + * {@link jakarta.jms.BytesMessage}. The desired message type can be defined by setting * the {@link #setTargetType "marshalTo"} property. * @see #marshalToTextMessage * @see #marshalToBytesMessage diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageConversionException.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageConversionException.java index 837b19bb04cb..e6ba699751d0 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageConversionException.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageConversionException.java @@ -21,7 +21,7 @@ /** * Thrown by {@link MessageConverter} implementations when the conversion - * of an object to/from a {@link javax.jms.Message} fails. + * of an object to/from a {@link jakarta.jms.Message} fails. * * @author Mark Pollack * @since 1.1 diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageConverter.java index b4c75ab02335..433123d19535 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageConverter.java @@ -16,9 +16,9 @@ package org.springframework.jms.support.converter; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.Session; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.Session; /** * Strategy interface that specifies a converter between Java objects and JMS messages. @@ -42,7 +42,7 @@ public interface MessageConverter { * @param object the object to convert * @param session the Session to use for creating a JMS Message * @return the JMS Message - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods * @throws MessageConversionException in case of conversion failure */ Message toMessage(Object object, Session session) throws JMSException, MessageConversionException; @@ -51,7 +51,7 @@ public interface MessageConverter { * Convert from a JMS Message to a Java object. * @param message the message to convert * @return the converted Java object - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods * @throws MessageConversionException in case of conversion failure */ Object fromMessage(Message message) throws JMSException, MessageConversionException; diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageType.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageType.java index edaea0e38cd9..98b46c77bbcf 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageType.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageType.java @@ -18,8 +18,8 @@ /** * Constants that indicate a target message type to convert to: a - * {@link javax.jms.TextMessage}, a {@link javax.jms.BytesMessage}, - * a {@link javax.jms.MapMessage} or an {@link javax.jms.ObjectMessage}. + * {@link jakarta.jms.TextMessage}, a {@link jakarta.jms.BytesMessage}, + * a {@link jakarta.jms.MapMessage} or an {@link jakarta.jms.ObjectMessage}. * * @author Juergen Hoeller * @since 3.0 @@ -28,22 +28,22 @@ public enum MessageType { /** - * A {@link javax.jms.TextMessage}. + * A {@link jakarta.jms.TextMessage}. */ TEXT, /** - * A {@link javax.jms.BytesMessage}. + * A {@link jakarta.jms.BytesMessage}. */ BYTES, /** - * A {@link javax.jms.MapMessage}. + * A {@link jakarta.jms.MapMessage}. */ MAP, /** - * A {@link javax.jms.ObjectMessage}. + * A {@link jakarta.jms.ObjectMessage}. */ OBJECT diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MessagingMessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MessagingMessageConverter.java index 441f306d7289..98e8ad026395 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MessagingMessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MessagingMessageConverter.java @@ -18,8 +18,8 @@ import java.util.Map; -import javax.jms.JMSException; -import javax.jms.Session; +import jakarta.jms.JMSException; +import jakarta.jms.Session; import org.springframework.beans.factory.InitializingBean; import org.springframework.jms.support.JmsHeaderMapper; @@ -33,7 +33,7 @@ /** * Convert a {@link Message} from the messaging abstraction to and from a - * {@link javax.jms.Message} using an underlying {@link MessageConverter} + * {@link jakarta.jms.Message} using an underlying {@link MessageConverter} * for the payload and a {@link org.springframework.jms.support.JmsHeaderMapper} * to map the JMS headers to and from standard message headers. * @@ -100,7 +100,7 @@ public void afterPropertiesSet() { @Override - public javax.jms.Message toMessage(Object object, Session session) throws JMSException, MessageConversionException { + public jakarta.jms.Message toMessage(Object object, Session session) throws JMSException, MessageConversionException { if (!(object instanceof Message)) { throw new IllegalArgumentException("Could not convert [" + object + "] - only [" + Message.class.getName() + "] is handled by this converter"); @@ -108,14 +108,14 @@ public javax.jms.Message toMessage(Object object, Session session) throws JMSExc Message input = (Message) object; MessageHeaders headers = input.getHeaders(); Object conversionHint = headers.get(AbstractMessagingTemplate.CONVERSION_HINT_HEADER); - javax.jms.Message reply = createMessageForPayload(input.getPayload(), session, conversionHint); + jakarta.jms.Message reply = createMessageForPayload(input.getPayload(), session, conversionHint); this.headerMapper.fromHeaders(headers, reply); return reply; } @SuppressWarnings("unchecked") @Override - public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException { + public Object fromMessage(jakarta.jms.Message message) throws JMSException, MessageConversionException { Map mappedHeaders = extractHeaders(message); Object convertedObject = extractPayload(message); MessageBuilder builder = (convertedObject instanceof org.springframework.messaging.Message ? @@ -125,9 +125,9 @@ public Object fromMessage(javax.jms.Message message) throws JMSException, Messag } /** - * Extract the payload of the specified {@link javax.jms.Message}. + * Extract the payload of the specified {@link jakarta.jms.Message}. */ - protected Object extractPayload(javax.jms.Message message) throws JMSException { + protected Object extractPayload(jakarta.jms.Message message) throws JMSException { return this.payloadConverter.fromMessage(message); } @@ -138,13 +138,13 @@ protected Object extractPayload(javax.jms.Message message) throws JMSException { * @since 4.3 * @see MessageConverter#toMessage(Object, Session) */ - protected javax.jms.Message createMessageForPayload( + protected jakarta.jms.Message createMessageForPayload( Object payload, Session session, @Nullable Object conversionHint) throws JMSException { return this.payloadConverter.toMessage(payload, session); } - protected final MessageHeaders extractHeaders(javax.jms.Message message) { + protected final MessageHeaders extractHeaders(jakarta.jms.Message message) { return this.headerMapper.toHeaders(message); } diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/SimpleMessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/SimpleMessageConverter.java index 4c28352000b8..deab9e8677f1 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/SimpleMessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/SimpleMessageConverter.java @@ -21,13 +21,13 @@ import java.util.HashMap; import java.util.Map; -import javax.jms.BytesMessage; -import javax.jms.JMSException; -import javax.jms.MapMessage; -import javax.jms.Message; -import javax.jms.ObjectMessage; -import javax.jms.Session; -import javax.jms.TextMessage; +import jakarta.jms.BytesMessage; +import jakarta.jms.JMSException; +import jakarta.jms.MapMessage; +import jakarta.jms.Message; +import jakarta.jms.ObjectMessage; +import jakarta.jms.Session; +import jakarta.jms.TextMessage; import org.springframework.util.ObjectUtils; @@ -37,9 +37,9 @@ * by {@link org.springframework.jms.core.JmsTemplate}, for * {@code convertAndSend} and {@code receiveAndConvert} operations. * - *

    Converts a String to a {@link javax.jms.TextMessage}, a byte array to a - * {@link javax.jms.BytesMessage}, a Map to a {@link javax.jms.MapMessage}, and - * a Serializable object to a {@link javax.jms.ObjectMessage} (or vice versa). + *

    Converts a String to a {@link jakarta.jms.TextMessage}, a byte array to a + * {@link jakarta.jms.BytesMessage}, a Map to a {@link jakarta.jms.MapMessage}, and + * a Serializable object to a {@link jakarta.jms.ObjectMessage} (or vice versa). * * @author Juergen Hoeller * @since 1.1 @@ -117,7 +117,7 @@ else if (message instanceof ObjectMessage) { * @param session current JMS session * @return the resulting message * @throws JMSException if thrown by JMS methods - * @see javax.jms.Session#createTextMessage + * @see jakarta.jms.Session#createTextMessage */ protected TextMessage createMessageForString(String text, Session session) throws JMSException { return session.createTextMessage(text); @@ -129,7 +129,7 @@ protected TextMessage createMessageForString(String text, Session session) throw * @param session current JMS session * @return the resulting message * @throws JMSException if thrown by JMS methods - * @see javax.jms.Session#createBytesMessage + * @see jakarta.jms.Session#createBytesMessage */ protected BytesMessage createMessageForByteArray(byte[] bytes, Session session) throws JMSException { BytesMessage message = session.createBytesMessage(); @@ -143,7 +143,7 @@ protected BytesMessage createMessageForByteArray(byte[] bytes, Session session) * @param session current JMS session * @return the resulting message * @throws JMSException if thrown by JMS methods - * @see javax.jms.Session#createMapMessage + * @see jakarta.jms.Session#createMapMessage */ protected MapMessage createMessageForMap(Map map, Session session) throws JMSException { MapMessage message = session.createMapMessage(); @@ -164,7 +164,7 @@ protected MapMessage createMessageForMap(Map map, Session session) throws * @param session current JMS session * @return the resulting message * @throws JMSException if thrown by JMS methods - * @see javax.jms.Session#createObjectMessage + * @see jakarta.jms.Session#createObjectMessage */ protected ObjectMessage createMessageForSerializable(Serializable object, Session session) throws JMSException { return session.createObjectMessage(object); diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/SmartMessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/SmartMessageConverter.java index 8ae6a8944847..ab180e4ecebc 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/SmartMessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/SmartMessageConverter.java @@ -16,9 +16,9 @@ package org.springframework.jms.support.converter; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.Session; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.Session; import org.springframework.lang.Nullable; @@ -43,7 +43,7 @@ public interface SmartMessageConverter extends MessageConverter { * @param conversionHint an extra object passed to the {@link MessageConverter}, * e.g. the associated {@code MethodParameter} (may be {@code null}} * @return the JMS Message - * @throws javax.jms.JMSException if thrown by JMS API methods + * @throws jakarta.jms.JMSException if thrown by JMS API methods * @throws MessageConversionException in case of conversion failure * @see #toMessage(Object, Session) */ diff --git a/spring-jms/src/main/java/org/springframework/jms/support/destination/BeanFactoryDestinationResolver.java b/spring-jms/src/main/java/org/springframework/jms/support/destination/BeanFactoryDestinationResolver.java index 0a7d5beaf3d2..291e7a3d0790 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/destination/BeanFactoryDestinationResolver.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/destination/BeanFactoryDestinationResolver.java @@ -16,9 +16,9 @@ package org.springframework.jms.support.destination; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Session; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Session; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; @@ -30,7 +30,7 @@ * {@link DestinationResolver} implementation based on a Spring {@link BeanFactory}. * *

    Will lookup Spring managed beans identified by bean name, - * expecting them to be of type {@code javax.jms.Destination}. + * expecting them to be of type {@code jakarta.jms.Destination}. * * @author Juergen Hoeller * @since 2.5 @@ -57,7 +57,7 @@ public BeanFactoryDestinationResolver() { * replaced by the {@link BeanFactory} that creates it (c.f. the * {@link BeanFactoryAware} contract). So only use this constructor if you * are using this class outside the context of a Spring IoC container. - * @param beanFactory the bean factory to be used to lookup {@link javax.jms.Destination Destination} + * @param beanFactory the bean factory to be used to lookup {@link jakarta.jms.Destination Destination} */ public BeanFactoryDestinationResolver(BeanFactory beanFactory) { Assert.notNull(beanFactory, "BeanFactory is required"); diff --git a/spring-jms/src/main/java/org/springframework/jms/support/destination/DestinationResolver.java b/spring-jms/src/main/java/org/springframework/jms/support/destination/DestinationResolver.java index 7767f3d2ccd9..ddc273729ab6 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/destination/DestinationResolver.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/destination/DestinationResolver.java @@ -16,9 +16,9 @@ package org.springframework.jms.support.destination; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Session; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Session; import org.springframework.lang.Nullable; @@ -51,7 +51,7 @@ public interface DestinationResolver { * @param destinationName the name of the destination * @param pubSubDomain {@code true} if the domain is pub-sub, {@code false} if P2P * @return the JMS destination (either a topic or a queue) - * @throws javax.jms.JMSException if the JMS Session failed to resolve the destination + * @throws jakarta.jms.JMSException if the JMS Session failed to resolve the destination * @throws DestinationResolutionException in case of general destination resolution failure */ Destination resolveDestinationName(@Nullable Session session, String destinationName, boolean pubSubDomain) diff --git a/spring-jms/src/main/java/org/springframework/jms/support/destination/DynamicDestinationResolver.java b/spring-jms/src/main/java/org/springframework/jms/support/destination/DynamicDestinationResolver.java index 80d69145f9ab..0a1d885f7ef5 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/destination/DynamicDestinationResolver.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/destination/DynamicDestinationResolver.java @@ -16,11 +16,11 @@ package org.springframework.jms.support.destination; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.Topic; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Queue; +import jakarta.jms.Session; +import jakarta.jms.Topic; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -31,8 +31,8 @@ * * @author Juergen Hoeller * @since 1.1 - * @see javax.jms.Session#createQueue - * @see javax.jms.Session#createTopic + * @see jakarta.jms.Session#createQueue + * @see jakarta.jms.Session#createTopic */ public class DynamicDestinationResolver implements DestinationResolver { @@ -42,9 +42,9 @@ public class DynamicDestinationResolver implements DestinationResolver { * @param destinationName the name of the destination * @param pubSubDomain {@code true} if the domain is pub-sub, {@code false} if P2P * @return the JMS destination (either a topic or a queue) - * @throws javax.jms.JMSException if resolution failed - * @see #resolveTopic(javax.jms.Session, String) - * @see #resolveQueue(javax.jms.Session, String) + * @throws jakarta.jms.JMSException if resolution failed + * @see #resolveTopic(jakarta.jms.Session, String) + * @see #resolveQueue(jakarta.jms.Session, String) */ @Override public Destination resolveDestinationName(@Nullable Session session, String destinationName, boolean pubSubDomain) @@ -66,7 +66,7 @@ public Destination resolveDestinationName(@Nullable Session session, String dest * @param session the current JMS Session * @param topicName the name of the desired {@link Topic} * @return the JMS {@link Topic} - * @throws javax.jms.JMSException if resolution failed + * @throws jakarta.jms.JMSException if resolution failed * @see Session#createTopic(String) */ protected Topic resolveTopic(Session session, String topicName) throws JMSException { @@ -78,7 +78,7 @@ protected Topic resolveTopic(Session session, String topicName) throws JMSExcept * @param session the current JMS Session * @param queueName the name of the desired {@link Queue} * @return the JMS {@link Queue} - * @throws javax.jms.JMSException if resolution failed + * @throws jakarta.jms.JMSException if resolution failed * @see Session#createQueue(String) */ protected Queue resolveQueue(Session session, String queueName) throws JMSException { diff --git a/spring-jms/src/main/java/org/springframework/jms/support/destination/JmsDestinationAccessor.java b/spring-jms/src/main/java/org/springframework/jms/support/destination/JmsDestinationAccessor.java index 56953b02a7d3..6711e7030f72 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/destination/JmsDestinationAccessor.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/destination/JmsDestinationAccessor.java @@ -16,11 +16,11 @@ package org.springframework.jms.support.destination; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.Session; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageConsumer; +import jakarta.jms.Session; import org.springframework.jms.support.JmsAccessor; import org.springframework.lang.Nullable; @@ -62,7 +62,7 @@ public abstract class JmsDestinationAccessor extends JmsAccessor { /** * Set the {@link DestinationResolver} that is to be used to resolve - * {@link javax.jms.Destination} references for this accessor. + * {@link jakarta.jms.Destination} references for this accessor. *

    The default resolver is a DynamicDestinationResolver. Specify a * JndiDestinationResolver for resolving destination names as JNDI locations. * @see org.springframework.jms.support.destination.DynamicDestinationResolver @@ -85,8 +85,8 @@ public DestinationResolver getDestinationResolver() { * Default is Point-to-Point (Queues). *

    This setting primarily indicates what type of destination to resolve * if dynamic destinations are enabled. - * @param pubSubDomain "true" for the Publish/Subscribe domain ({@link javax.jms.Topic Topics}), - * "false" for the Point-to-Point domain ({@link javax.jms.Queue Queues}) + * @param pubSubDomain "true" for the Publish/Subscribe domain ({@link jakarta.jms.Topic Topics}), + * "false" for the Point-to-Point domain ({@link jakarta.jms.Queue Queues}) * @see #setDestinationResolver */ public void setPubSubDomain(boolean pubSubDomain) { @@ -94,8 +94,8 @@ public void setPubSubDomain(boolean pubSubDomain) { } /** - * Return whether the Publish/Subscribe domain ({@link javax.jms.Topic Topics}) is used. - * Otherwise, the Point-to-Point domain ({@link javax.jms.Queue Queues}) is used. + * Return whether the Publish/Subscribe domain ({@link jakarta.jms.Topic Topics}) is used. + * Otherwise, the Point-to-Point domain ({@link jakarta.jms.Queue Queues}) is used. */ public boolean isPubSubDomain() { return this.pubSubDomain; @@ -108,7 +108,7 @@ public boolean isPubSubDomain() { * @param session the current JMS {@link Session} * @param destinationName the name of the destination * @return the located {@link Destination} - * @throws javax.jms.JMSException if resolution failed + * @throws jakarta.jms.JMSException if resolution failed * @see #setDestinationResolver */ protected Destination resolveDestinationName(Session session, String destinationName) throws JMSException { diff --git a/spring-jms/src/main/java/org/springframework/jms/support/destination/JndiDestinationResolver.java b/spring-jms/src/main/java/org/springframework/jms/support/destination/JndiDestinationResolver.java index 86e0e7da2ad5..b27d883a0884 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/destination/JndiDestinationResolver.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/destination/JndiDestinationResolver.java @@ -19,13 +19,14 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.Topic; import javax.naming.NamingException; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Queue; +import jakarta.jms.Session; +import jakarta.jms.Topic; + import org.springframework.jndi.JndiLocatorSupport; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-jms/src/main/resources/org/springframework/jms/config/spring-jms.xsd b/spring-jms/src/main/resources/org/springframework/jms/config/spring-jms.xsd index f454160fa58c..e38673903d83 100644 --- a/spring-jms/src/main/resources/org/springframework/jms/config/spring-jms.xsd +++ b/spring-jms/src/main/resources/org/springframework/jms/config/spring-jms.xsd @@ -151,7 +151,7 @@ ]]> - + @@ -178,7 +178,7 @@ A reference to the DestinationResolver strategy for resolving destination names. Default is a DynamicDestinationResolver, using the JMS provider's queue/topic name resolution. Alternatively, specify a reference to a JndiDestinationResolver - (typically in a Java EE environment). + (typically in a Jakarta EE environment). ]]> @@ -260,7 +260,7 @@ The cache level for JMS resources: "none", "connection", "session", "consumer" or "auto". By default ("auto"), the cache level will effectively be "consumer", unless an external transaction manager has been specified - in which case the - effective default will be "none" (assuming Java EE-style transaction management + effective default will be "none" (assuming Jakarta EE-style transaction management where the given ConnectionFactory is an XA-aware pool). ]]> @@ -411,7 +411,7 @@ ]]> - + @@ -435,7 +435,7 @@ @@ -516,7 +516,7 @@ diff --git a/spring-jms/src/test/java/org/springframework/jca/StubActivationSpec.java b/spring-jms/src/test/java/org/springframework/jca/StubActivationSpec.java index 41950530e371..f7df15458d5d 100644 --- a/spring-jms/src/test/java/org/springframework/jca/StubActivationSpec.java +++ b/spring-jms/src/test/java/org/springframework/jca/StubActivationSpec.java @@ -16,10 +16,10 @@ package org.springframework.jca; -import javax.resource.ResourceException; -import javax.resource.spi.ActivationSpec; -import javax.resource.spi.InvalidPropertyException; -import javax.resource.spi.ResourceAdapter; +import jakarta.resource.ResourceException; +import jakarta.resource.spi.ActivationSpec; +import jakarta.resource.spi.InvalidPropertyException; +import jakarta.resource.spi.ResourceAdapter; /** * @author Juergen Hoeller diff --git a/spring-jms/src/test/java/org/springframework/jca/StubResourceAdapter.java b/spring-jms/src/test/java/org/springframework/jca/StubResourceAdapter.java index 787f6250a52d..5f751395e1a4 100644 --- a/spring-jms/src/test/java/org/springframework/jca/StubResourceAdapter.java +++ b/spring-jms/src/test/java/org/springframework/jca/StubResourceAdapter.java @@ -16,14 +16,15 @@ package org.springframework.jca; -import javax.resource.ResourceException; -import javax.resource.spi.ActivationSpec; -import javax.resource.spi.BootstrapContext; -import javax.resource.spi.ResourceAdapter; -import javax.resource.spi.ResourceAdapterInternalException; -import javax.resource.spi.endpoint.MessageEndpointFactory; import javax.transaction.xa.XAResource; +import jakarta.resource.ResourceException; +import jakarta.resource.spi.ActivationSpec; +import jakarta.resource.spi.BootstrapContext; +import jakarta.resource.spi.ResourceAdapter; +import jakarta.resource.spi.ResourceAdapterInternalException; +import jakarta.resource.spi.endpoint.MessageEndpointFactory; + /** * @author Juergen Hoeller */ diff --git a/spring-jms/src/test/java/org/springframework/jms/StubConnectionFactory.java b/spring-jms/src/test/java/org/springframework/jms/StubConnectionFactory.java index a8df4ed3774e..a85c43aefe9d 100644 --- a/spring-jms/src/test/java/org/springframework/jms/StubConnectionFactory.java +++ b/spring-jms/src/test/java/org/springframework/jms/StubConnectionFactory.java @@ -16,10 +16,10 @@ package org.springframework.jms; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSContext; -import javax.jms.JMSException; +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.JMSContext; +import jakarta.jms.JMSException; /** * A stub implementation of the JMS ConnectionFactory for testing. diff --git a/spring-jms/src/test/java/org/springframework/jms/StubQueue.java b/spring-jms/src/test/java/org/springframework/jms/StubQueue.java index c529a2c066b5..34e10a51143e 100644 --- a/spring-jms/src/test/java/org/springframework/jms/StubQueue.java +++ b/spring-jms/src/test/java/org/springframework/jms/StubQueue.java @@ -16,10 +16,10 @@ package org.springframework.jms; -import javax.jms.Queue; +import jakarta.jms.Queue; /** - * Stub implementation of the {@link javax.jms.Queue} interface. + * Stub implementation of the {@link jakarta.jms.Queue} interface. * * @author Rick Evans */ diff --git a/spring-jms/src/test/java/org/springframework/jms/StubTextMessage.java b/spring-jms/src/test/java/org/springframework/jms/StubTextMessage.java index cb4d0ee6f121..3276634761b0 100644 --- a/spring-jms/src/test/java/org/springframework/jms/StubTextMessage.java +++ b/spring-jms/src/test/java/org/springframework/jms/StubTextMessage.java @@ -19,9 +19,9 @@ import java.util.Enumeration; import java.util.concurrent.ConcurrentHashMap; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.TextMessage; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.TextMessage; /** * Stub JMS Message implementation intended for testing purposes only. diff --git a/spring-jms/src/test/java/org/springframework/jms/StubTopic.java b/spring-jms/src/test/java/org/springframework/jms/StubTopic.java index 2621b9aea188..c11b925dc49a 100644 --- a/spring-jms/src/test/java/org/springframework/jms/StubTopic.java +++ b/spring-jms/src/test/java/org/springframework/jms/StubTopic.java @@ -16,7 +16,7 @@ package org.springframework.jms; -import javax.jms.Topic; +import jakarta.jms.Topic; /** * Stub implementation of the {@link Topic} interface. diff --git a/spring-jms/src/test/java/org/springframework/jms/annotation/AbstractJmsAnnotationDrivenTests.java b/spring-jms/src/test/java/org/springframework/jms/annotation/AbstractJmsAnnotationDrivenTests.java index d0986f527dcd..8ac5af2c9567 100644 --- a/spring-jms/src/test/java/org/springframework/jms/annotation/AbstractJmsAnnotationDrivenTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/annotation/AbstractJmsAnnotationDrivenTests.java @@ -18,9 +18,8 @@ import java.lang.reflect.Method; -import javax.jms.JMSException; -import javax.jms.Session; - +import jakarta.jms.JMSException; +import jakarta.jms.Session; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; diff --git a/spring-jms/src/test/java/org/springframework/jms/annotation/AnnotationDrivenNamespaceTests.java b/spring-jms/src/test/java/org/springframework/jms/annotation/AnnotationDrivenNamespaceTests.java index f2d84d307b27..e4d28bcd3a4a 100644 --- a/spring-jms/src/test/java/org/springframework/jms/annotation/AnnotationDrivenNamespaceTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/annotation/AnnotationDrivenNamespaceTests.java @@ -16,9 +16,8 @@ package org.springframework.jms.annotation; -import javax.jms.JMSException; -import javax.jms.MessageListener; - +import jakarta.jms.JMSException; +import jakarta.jms.MessageListener; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; diff --git a/spring-jms/src/test/java/org/springframework/jms/annotation/EnableJmsTests.java b/spring-jms/src/test/java/org/springframework/jms/annotation/EnableJmsTests.java index 1bdc0d20c0e4..1a1d61c5235d 100644 --- a/spring-jms/src/test/java/org/springframework/jms/annotation/EnableJmsTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/annotation/EnableJmsTests.java @@ -19,9 +19,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import javax.jms.JMSException; -import javax.jms.MessageListener; - +import jakarta.jms.JMSException; +import jakarta.jms.MessageListener; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanCreationException; diff --git a/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerFactoryIntegrationTests.java b/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerFactoryIntegrationTests.java index f1efec4d74a9..b84fb7060c21 100644 --- a/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerFactoryIntegrationTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerFactoryIntegrationTests.java @@ -20,12 +20,11 @@ import java.util.HashMap; import java.util.Map; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.Session; -import javax.jms.TextMessage; - +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageListener; +import jakarta.jms.Session; +import jakarta.jms.TextMessage; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerFactoryTests.java b/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerFactoryTests.java index 865a0edc08fe..c1cba94e1a76 100644 --- a/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerFactoryTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerContainerFactoryTests.java @@ -16,11 +16,10 @@ package org.springframework.jms.config; -import javax.jms.ConnectionFactory; -import javax.jms.MessageListener; -import javax.jms.Session; -import javax.transaction.TransactionManager; - +import jakarta.jms.ConnectionFactory; +import jakarta.jms.MessageListener; +import jakarta.jms.Session; +import jakarta.transaction.TransactionManager; import org.junit.jupiter.api.Test; import org.springframework.beans.DirectFieldAccessor; diff --git a/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerEndpointTests.java b/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerEndpointTests.java index fa93a7f257c6..0f66f2393a76 100644 --- a/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerEndpointTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/config/JmsListenerEndpointTests.java @@ -16,8 +16,7 @@ package org.springframework.jms.config; -import javax.jms.MessageListener; - +import jakarta.jms.MessageListener; import org.junit.jupiter.api.Test; import org.springframework.beans.DirectFieldAccessor; 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 43b9a1a6ca58..658ecf62ab41 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 @@ -21,11 +21,10 @@ import java.util.Map; import java.util.Set; -import javax.jms.ConnectionFactory; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.TextMessage; - +import jakarta.jms.ConnectionFactory; +import jakarta.jms.Message; +import jakarta.jms.MessageListener; +import jakarta.jms.TextMessage; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-jms/src/test/java/org/springframework/jms/config/MethodJmsListenerEndpointTests.java b/spring-jms/src/test/java/org/springframework/jms/config/MethodJmsListenerEndpointTests.java index 4e74d2dc4090..8e1c3ecd5109 100644 --- a/spring-jms/src/test/java/org/springframework/jms/config/MethodJmsListenerEndpointTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/config/MethodJmsListenerEndpointTests.java @@ -22,14 +22,13 @@ import java.util.HashMap; import java.util.Map; -import javax.jms.Destination; -import javax.jms.InvalidDestinationException; -import javax.jms.JMSException; -import javax.jms.ObjectMessage; -import javax.jms.QueueSender; -import javax.jms.Session; -import javax.jms.TextMessage; - +import jakarta.jms.Destination; +import jakarta.jms.InvalidDestinationException; +import jakarta.jms.JMSException; +import jakarta.jms.ObjectMessage; +import jakarta.jms.QueueSender; +import jakarta.jms.Session; +import jakarta.jms.TextMessage; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; @@ -127,7 +126,7 @@ void setExtraCollaborators() { @Test void resolveMessageAndSession() throws JMSException { - MessagingMessageListenerAdapter listener = createDefaultInstance(javax.jms.Message.class, Session.class); + MessagingMessageListenerAdapter listener = createDefaultInstance(jakarta.jms.Message.class, Session.class); Session session = mock(Session.class); listener.onMessage(createSimpleJmsTextMessage("test"), session); @@ -521,7 +520,7 @@ static class JmsEndpointSampleBean { private final Map invocations = new HashMap<>(); - public void resolveMessageAndSession(javax.jms.Message message, Session session) { + public void resolveMessageAndSession(jakarta.jms.Message message, Session session) { this.invocations.put("resolveMessageAndSession", true); assertThat(message).as("Message not injected").isNotNull(); assertThat(session).as("Session not injected").isNotNull(); diff --git a/spring-jms/src/test/java/org/springframework/jms/config/SimpleJmsListenerEndpointTests.java b/spring-jms/src/test/java/org/springframework/jms/config/SimpleJmsListenerEndpointTests.java index b8ef640a60c9..0ba4c762cb57 100644 --- a/spring-jms/src/test/java/org/springframework/jms/config/SimpleJmsListenerEndpointTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/config/SimpleJmsListenerEndpointTests.java @@ -16,8 +16,7 @@ package org.springframework.jms.config; -import javax.jms.MessageListener; - +import jakarta.jms.MessageListener; import org.junit.jupiter.api.Test; import org.springframework.jms.listener.SimpleMessageListenerContainer; diff --git a/spring-jms/src/test/java/org/springframework/jms/connection/JmsTransactionManagerTests.java b/spring-jms/src/test/java/org/springframework/jms/connection/JmsTransactionManagerTests.java index ae0878a29df6..3b9897df3ff4 100644 --- a/spring-jms/src/test/java/org/springframework/jms/connection/JmsTransactionManagerTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/connection/JmsTransactionManagerTests.java @@ -16,14 +16,13 @@ package org.springframework.jms.connection; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageProducer; -import javax.jms.Session; - +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageProducer; +import jakarta.jms.Session; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; diff --git a/spring-jms/src/test/java/org/springframework/jms/connection/SingleConnectionFactoryTests.java b/spring-jms/src/test/java/org/springframework/jms/connection/SingleConnectionFactoryTests.java index 85a6126dde2e..110ffa2b106e 100644 --- a/spring-jms/src/test/java/org/springframework/jms/connection/SingleConnectionFactoryTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/connection/SingleConnectionFactoryTests.java @@ -16,18 +16,17 @@ package org.springframework.jms.connection; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.QueueConnection; -import javax.jms.QueueConnectionFactory; -import javax.jms.QueueSession; -import javax.jms.Session; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; -import javax.jms.TopicSession; - +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.ExceptionListener; +import jakarta.jms.JMSException; +import jakarta.jms.QueueConnection; +import jakarta.jms.QueueConnectionFactory; +import jakarta.jms.QueueSession; +import jakarta.jms.Session; +import jakarta.jms.TopicConnection; +import jakarta.jms.TopicConnectionFactory; +import jakarta.jms.TopicSession; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-jms/src/test/java/org/springframework/jms/connection/TestConnection.java b/spring-jms/src/test/java/org/springframework/jms/connection/TestConnection.java index 3cef4288d493..99ebfa92ff9c 100644 --- a/spring-jms/src/test/java/org/springframework/jms/connection/TestConnection.java +++ b/spring-jms/src/test/java/org/springframework/jms/connection/TestConnection.java @@ -16,15 +16,15 @@ package org.springframework.jms.connection; -import javax.jms.Connection; -import javax.jms.ConnectionConsumer; -import javax.jms.ConnectionMetaData; -import javax.jms.Destination; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.ServerSessionPool; -import javax.jms.Session; -import javax.jms.Topic; +import jakarta.jms.Connection; +import jakarta.jms.ConnectionConsumer; +import jakarta.jms.ConnectionMetaData; +import jakarta.jms.Destination; +import jakarta.jms.ExceptionListener; +import jakarta.jms.JMSException; +import jakarta.jms.ServerSessionPool; +import jakarta.jms.Session; +import jakarta.jms.Topic; /** * @author Juergen Hoeller diff --git a/spring-jms/src/test/java/org/springframework/jms/connection/TestExceptionListener.java b/spring-jms/src/test/java/org/springframework/jms/connection/TestExceptionListener.java index 57b77ad160ad..1e95a8c98b46 100644 --- a/spring-jms/src/test/java/org/springframework/jms/connection/TestExceptionListener.java +++ b/spring-jms/src/test/java/org/springframework/jms/connection/TestExceptionListener.java @@ -16,8 +16,8 @@ package org.springframework.jms.connection; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; +import jakarta.jms.ExceptionListener; +import jakarta.jms.JMSException; /** * @author Juergen Hoeller diff --git a/spring-jms/src/test/java/org/springframework/jms/core/JmsMessagingTemplateTests.java b/spring-jms/src/test/java/org/springframework/jms/core/JmsMessagingTemplateTests.java index 96148ab15f45..10b633294677 100644 --- a/spring-jms/src/test/java/org/springframework/jms/core/JmsMessagingTemplateTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/core/JmsMessagingTemplateTests.java @@ -20,13 +20,12 @@ import java.util.HashMap; import java.util.Map; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.MessageFormatException; -import javax.jms.MessageNotWriteableException; -import javax.jms.Session; -import javax.jms.TextMessage; - +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.MessageFormatException; +import jakarta.jms.MessageNotWriteableException; +import jakarta.jms.Session; +import jakarta.jms.TextMessage; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -237,7 +236,7 @@ public void convertAndSendNoDefaultSet() throws JMSException { public void convertAndSendCustomJmsMessageConverter() throws JMSException { this.messagingTemplate.setJmsMessageConverter(new SimpleMessageConverter() { @Override - public javax.jms.Message toMessage(Object object, Session session) + public jakarta.jms.Message toMessage(Object object, Session session) throws JMSException, org.springframework.jms.support.converter.MessageConversionException { throw new org.springframework.jms.support.converter.MessageConversionException("Test exception"); } @@ -275,7 +274,7 @@ public void convertAndSendPayloadAndHeadersName() throws JMSException { @Test public void receive() { Destination destination = new Destination() {}; - javax.jms.Message jmsMessage = createJmsTextMessage(); + jakarta.jms.Message jmsMessage = createJmsTextMessage(); given(this.jmsTemplate.receive(destination)).willReturn(jmsMessage); Message message = this.messagingTemplate.receive(destination); @@ -285,7 +284,7 @@ public void receive() { @Test public void receiveName() { - javax.jms.Message jmsMessage = createJmsTextMessage(); + jakarta.jms.Message jmsMessage = createJmsTextMessage(); given(this.jmsTemplate.receive("myQueue")).willReturn(jmsMessage); Message message = this.messagingTemplate.receive("myQueue"); @@ -297,7 +296,7 @@ public void receiveName() { public void receiveDefaultDestination() { Destination destination = new Destination() {}; this.messagingTemplate.setDefaultDestination(destination); - javax.jms.Message jmsMessage = createJmsTextMessage(); + jakarta.jms.Message jmsMessage = createJmsTextMessage(); given(this.jmsTemplate.receive(destination)).willReturn(jmsMessage); Message message = this.messagingTemplate.receive(); @@ -308,7 +307,7 @@ public void receiveDefaultDestination() { @Test public void receiveDefaultDestinationName() { this.messagingTemplate.setDefaultDestinationName("myQueue"); - javax.jms.Message jmsMessage = createJmsTextMessage(); + jakarta.jms.Message jmsMessage = createJmsTextMessage(); given(this.jmsTemplate.receive("myQueue")).willReturn(jmsMessage); Message message = this.messagingTemplate.receive(); @@ -325,7 +324,7 @@ public void receiveNoDefaultSet() { @Test public void receiveAndConvert() { Destination destination = new Destination() {}; - javax.jms.Message jmsMessage = createJmsTextMessage("my Payload"); + jakarta.jms.Message jmsMessage = createJmsTextMessage("my Payload"); given(this.jmsTemplate.receive(destination)).willReturn(jmsMessage); String payload = this.messagingTemplate.receiveAndConvert(destination, String.class); @@ -335,7 +334,7 @@ public void receiveAndConvert() { @Test public void receiveAndConvertName() { - javax.jms.Message jmsMessage = createJmsTextMessage("my Payload"); + jakarta.jms.Message jmsMessage = createJmsTextMessage("my Payload"); given(this.jmsTemplate.receive("myQueue")).willReturn(jmsMessage); String payload = this.messagingTemplate.receiveAndConvert("myQueue", String.class); @@ -347,7 +346,7 @@ public void receiveAndConvertName() { public void receiveAndConvertDefaultDestination() { Destination destination = new Destination() {}; this.messagingTemplate.setDefaultDestination(destination); - javax.jms.Message jmsMessage = createJmsTextMessage("my Payload"); + jakarta.jms.Message jmsMessage = createJmsTextMessage("my Payload"); given(this.jmsTemplate.receive(destination)).willReturn(jmsMessage); String payload = this.messagingTemplate.receiveAndConvert(String.class); @@ -358,7 +357,7 @@ public void receiveAndConvertDefaultDestination() { @Test public void receiveAndConvertDefaultDestinationName() { this.messagingTemplate.setDefaultDestinationName("myQueue"); - javax.jms.Message jmsMessage = createJmsTextMessage("my Payload"); + jakarta.jms.Message jmsMessage = createJmsTextMessage("my Payload"); given(this.jmsTemplate.receive("myQueue")).willReturn(jmsMessage); String payload = this.messagingTemplate.receiveAndConvert(String.class); @@ -368,7 +367,7 @@ public void receiveAndConvertDefaultDestinationName() { @Test public void receiveAndConvertWithConversion() { - javax.jms.Message jmsMessage = createJmsTextMessage("123"); + jakarta.jms.Message jmsMessage = createJmsTextMessage("123"); given(this.jmsTemplate.receive("myQueue")).willReturn(jmsMessage); this.messagingTemplate.setMessageConverter(new GenericMessageConverter()); @@ -380,7 +379,7 @@ public void receiveAndConvertWithConversion() { @Test public void receiveAndConvertNoConverter() { - javax.jms.Message jmsMessage = createJmsTextMessage("Hello"); + jakarta.jms.Message jmsMessage = createJmsTextMessage("Hello"); given(this.jmsTemplate.receive("myQueue")).willReturn(jmsMessage); assertThatExceptionOfType(org.springframework.messaging.converter.MessageConversionException.class).isThrownBy(() -> @@ -398,7 +397,7 @@ public void receiveAndConvertNoInput() { public void sendAndReceive() { Destination destination = new Destination() {}; Message request = createTextMessage(); - javax.jms.Message replyJmsMessage = createJmsTextMessage(); + jakarta.jms.Message replyJmsMessage = createJmsTextMessage(); given(this.jmsTemplate.sendAndReceive(eq(destination), any())).willReturn(replyJmsMessage); Message actual = this.messagingTemplate.sendAndReceive(destination, request); @@ -409,7 +408,7 @@ public void sendAndReceive() { @Test public void sendAndReceiveName() { Message request = createTextMessage(); - javax.jms.Message replyJmsMessage = createJmsTextMessage(); + jakarta.jms.Message replyJmsMessage = createJmsTextMessage(); given(this.jmsTemplate.sendAndReceive(eq("myQueue"), any())).willReturn(replyJmsMessage); Message actual = this.messagingTemplate.sendAndReceive("myQueue", request); @@ -422,7 +421,7 @@ public void sendAndReceiveDefaultDestination() { Destination destination = new Destination() {}; this.messagingTemplate.setDefaultDestination(destination); Message request = createTextMessage(); - javax.jms.Message replyJmsMessage = createJmsTextMessage(); + jakarta.jms.Message replyJmsMessage = createJmsTextMessage(); given(this.jmsTemplate.sendAndReceive(eq(destination), any())).willReturn(replyJmsMessage); Message actual = this.messagingTemplate.sendAndReceive(request); @@ -434,7 +433,7 @@ public void sendAndReceiveDefaultDestination() { public void sendAndReceiveDefaultDestinationName() { this.messagingTemplate.setDefaultDestinationName("myQueue"); Message request = createTextMessage(); - javax.jms.Message replyJmsMessage = createJmsTextMessage(); + jakarta.jms.Message replyJmsMessage = createJmsTextMessage(); given(this.jmsTemplate.sendAndReceive(eq("myQueue"), any())).willReturn(replyJmsMessage); Message actual = this.messagingTemplate.sendAndReceive(request); @@ -453,7 +452,7 @@ public void sendAndReceiveNoDefaultSet() { @Test public void convertSendAndReceivePayload() throws JMSException { Destination destination = new Destination() {}; - javax.jms.Message replyJmsMessage = createJmsTextMessage("My reply"); + jakarta.jms.Message replyJmsMessage = createJmsTextMessage("My reply"); given(this.jmsTemplate.sendAndReceive(eq(destination), any())).willReturn(replyJmsMessage); String reply = this.messagingTemplate.convertSendAndReceive(destination, "my Payload", String.class); @@ -463,7 +462,7 @@ public void convertSendAndReceivePayload() throws JMSException { @Test public void convertSendAndReceivePayloadName() throws JMSException { - javax.jms.Message replyJmsMessage = createJmsTextMessage("My reply"); + jakarta.jms.Message replyJmsMessage = createJmsTextMessage("My reply"); given(this.jmsTemplate.sendAndReceive(eq("myQueue"), any())).willReturn(replyJmsMessage); String reply = this.messagingTemplate.convertSendAndReceive("myQueue", "my Payload", String.class); @@ -475,7 +474,7 @@ public void convertSendAndReceivePayloadName() throws JMSException { public void convertSendAndReceiveDefaultDestination() throws JMSException { Destination destination = new Destination() {}; this.messagingTemplate.setDefaultDestination(destination); - javax.jms.Message replyJmsMessage = createJmsTextMessage("My reply"); + jakarta.jms.Message replyJmsMessage = createJmsTextMessage("My reply"); given(this.jmsTemplate.sendAndReceive(eq(destination), any())).willReturn(replyJmsMessage); String reply = this.messagingTemplate.convertSendAndReceive("my Payload", String.class); @@ -486,7 +485,7 @@ public void convertSendAndReceiveDefaultDestination() throws JMSException { @Test public void convertSendAndReceiveDefaultDestinationName() throws JMSException { this.messagingTemplate.setDefaultDestinationName("myQueue"); - javax.jms.Message replyJmsMessage = createJmsTextMessage("My reply"); + jakarta.jms.Message replyJmsMessage = createJmsTextMessage("My reply"); given(this.jmsTemplate.sendAndReceive(eq("myQueue"), any())).willReturn(replyJmsMessage); String reply = this.messagingTemplate.convertSendAndReceive("my Payload", String.class); @@ -515,7 +514,7 @@ public void convertMessageConversionExceptionOnSend() throws JMSException { @Test public void convertMessageConversionExceptionOnReceive() throws JMSException { - javax.jms.Message message = createJmsTextMessage(); + jakarta.jms.Message message = createJmsTextMessage(); MessageConverter messageConverter = mock(MessageConverter.class); willThrow(org.springframework.jms.support.converter.MessageConversionException.class) .given(messageConverter).fromMessage(message); @@ -611,7 +610,7 @@ private Message createTextMessage() { return createTextMessage("Hello"); } - private javax.jms.Message createJmsTextMessage(String payload) { + private jakarta.jms.Message createJmsTextMessage(String payload) { try { StubTextMessage jmsMessage = new StubTextMessage(payload); jmsMessage.setStringProperty("foo", "bar"); @@ -622,7 +621,7 @@ private javax.jms.Message createJmsTextMessage(String payload) { } } - private javax.jms.Message createJmsTextMessage() { + private jakarta.jms.Message createJmsTextMessage() { return createJmsTextMessage("Hello"); } @@ -650,7 +649,7 @@ protected TextMessage createTextMessage(MessageCreator creator) throws JMSExcept given(mock.createTextMessage(any())).willAnswer( (Answer) invocation -> new StubTextMessage((String) invocation.getArguments()[0])); - javax.jms.Message message = creator.createMessage(mock); + jakarta.jms.Message message = creator.createMessage(mock); verify(mock).createTextMessage(any()); return (TextMessage) message; } 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 0690e7d349d8..9f82be855f91 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 @@ -20,20 +20,20 @@ import java.io.StringWriter; import java.util.List; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.DeliveryMode; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TemporaryQueue; -import javax.jms.TextMessage; import javax.naming.Context; +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.DeliveryMode; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageConsumer; +import jakarta.jms.MessageProducer; +import jakarta.jms.Queue; +import jakarta.jms.Session; +import jakarta.jms.TemporaryQueue; +import jakarta.jms.TextMessage; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -721,67 +721,67 @@ else if (explicitDestination) { @Test void testIllegalStateException() throws Exception { - doTestJmsException(new javax.jms.IllegalStateException(""), org.springframework.jms.IllegalStateException.class); + doTestJmsException(new jakarta.jms.IllegalStateException(""), org.springframework.jms.IllegalStateException.class); } @Test void testInvalidClientIDException() throws Exception { - doTestJmsException(new javax.jms.InvalidClientIDException(""), InvalidClientIDException.class); + doTestJmsException(new jakarta.jms.InvalidClientIDException(""), InvalidClientIDException.class); } @Test void testInvalidDestinationException() throws Exception { - doTestJmsException(new javax.jms.InvalidDestinationException(""), InvalidDestinationException.class); + doTestJmsException(new jakarta.jms.InvalidDestinationException(""), InvalidDestinationException.class); } @Test void testInvalidSelectorException() throws Exception { - doTestJmsException(new javax.jms.InvalidSelectorException(""), InvalidSelectorException.class); + doTestJmsException(new jakarta.jms.InvalidSelectorException(""), InvalidSelectorException.class); } @Test void testJmsSecurityException() throws Exception { - doTestJmsException(new javax.jms.JMSSecurityException(""), JmsSecurityException.class); + doTestJmsException(new jakarta.jms.JMSSecurityException(""), JmsSecurityException.class); } @Test void testMessageEOFException() throws Exception { - doTestJmsException(new javax.jms.MessageEOFException(""), MessageEOFException.class); + doTestJmsException(new jakarta.jms.MessageEOFException(""), MessageEOFException.class); } @Test void testMessageFormatException() throws Exception { - doTestJmsException(new javax.jms.MessageFormatException(""), MessageFormatException.class); + doTestJmsException(new jakarta.jms.MessageFormatException(""), MessageFormatException.class); } @Test void testMessageNotReadableException() throws Exception { - doTestJmsException(new javax.jms.MessageNotReadableException(""), MessageNotReadableException.class); + doTestJmsException(new jakarta.jms.MessageNotReadableException(""), MessageNotReadableException.class); } @Test void testMessageNotWriteableException() throws Exception { - doTestJmsException(new javax.jms.MessageNotWriteableException(""), MessageNotWriteableException.class); + doTestJmsException(new jakarta.jms.MessageNotWriteableException(""), MessageNotWriteableException.class); } @Test void testResourceAllocationException() throws Exception { - doTestJmsException(new javax.jms.ResourceAllocationException(""), ResourceAllocationException.class); + doTestJmsException(new jakarta.jms.ResourceAllocationException(""), ResourceAllocationException.class); } @Test void testTransactionInProgressException() throws Exception { - doTestJmsException(new javax.jms.TransactionInProgressException(""), TransactionInProgressException.class); + doTestJmsException(new jakarta.jms.TransactionInProgressException(""), TransactionInProgressException.class); } @Test void testTransactionRolledBackException() throws Exception { - doTestJmsException(new javax.jms.TransactionRolledBackException(""), TransactionRolledBackException.class); + doTestJmsException(new jakarta.jms.TransactionRolledBackException(""), TransactionRolledBackException.class); } @Test void testUncategorizedJmsException() throws Exception { - doTestJmsException(new javax.jms.JMSException(""), UncategorizedJmsException.class); + doTestJmsException(new jakarta.jms.JMSException(""), UncategorizedJmsException.class); } protected void doTestJmsException(JMSException original, Class thrownExceptionClass) throws Exception { diff --git a/spring-jms/src/test/java/org/springframework/jms/core/JmsTemplateTransactedTests.java b/spring-jms/src/test/java/org/springframework/jms/core/JmsTemplateTransactedTests.java index db51d87d1322..e23fe83228f8 100644 --- a/spring-jms/src/test/java/org/springframework/jms/core/JmsTemplateTransactedTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/core/JmsTemplateTransactedTests.java @@ -16,8 +16,7 @@ package org.springframework.jms.core; -import javax.jms.Session; - +import jakarta.jms.Session; import org.junit.jupiter.api.BeforeEach; import static org.mockito.BDDMockito.given; diff --git a/spring-jms/src/test/java/org/springframework/jms/core/support/JmsGatewaySupportTests.java b/spring-jms/src/test/java/org/springframework/jms/core/support/JmsGatewaySupportTests.java index b4b7d3ab4452..ead313c5396d 100644 --- a/spring-jms/src/test/java/org/springframework/jms/core/support/JmsGatewaySupportTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/core/support/JmsGatewaySupportTests.java @@ -18,8 +18,7 @@ import java.util.ArrayList; import java.util.List; -import javax.jms.ConnectionFactory; - +import jakarta.jms.ConnectionFactory; import org.junit.jupiter.api.Test; import org.springframework.jms.core.JmsTemplate; diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/DefaultMessageListenerContainerTests.java b/spring-jms/src/test/java/org/springframework/jms/listener/DefaultMessageListenerContainerTests.java index 4a83e858a337..66d638143f0f 100644 --- a/spring-jms/src/test/java/org/springframework/jms/listener/DefaultMessageListenerContainerTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/listener/DefaultMessageListenerContainerTests.java @@ -19,11 +19,10 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.Destination; -import javax.jms.JMSException; - +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; import org.junit.jupiter.api.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/MessageListenerContainerIntegrationTests.java b/spring-jms/src/test/java/org/springframework/jms/listener/MessageListenerContainerIntegrationTests.java deleted file mode 100644 index 306c88394f43..000000000000 --- a/spring-jms/src/test/java/org/springframework/jms/listener/MessageListenerContainerIntegrationTests.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jms.listener; - -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import javax.jms.JMSException; -import javax.jms.Session; -import javax.jms.TextMessage; - -import org.apache.activemq.ActiveMQConnectionFactory; -import org.junit.jupiter.api.Test; - -import org.springframework.jms.core.JmsTemplate; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Juergen Hoeller - * @since 5.3.5 - */ -public class MessageListenerContainerIntegrationTests { - - @Test - public void simpleMessageListenerContainer() throws InterruptedException { - SimpleMessageListenerContainer mlc = new SimpleMessageListenerContainer(); - - testMessageListenerContainer(mlc); - } - - @Test - public void defaultMessageListenerContainer() throws InterruptedException { - DefaultMessageListenerContainer mlc = new DefaultMessageListenerContainer(); - - testMessageListenerContainer(mlc); - } - - @Test - public void defaultMessageListenerContainerWithMaxMessagesPerTask() throws InterruptedException { - DefaultMessageListenerContainer mlc = new DefaultMessageListenerContainer(); - mlc.setConcurrentConsumers(1); - mlc.setMaxConcurrentConsumers(2); - mlc.setMaxMessagesPerTask(1); - - testMessageListenerContainer(mlc); - } - - @Test - public void defaultMessageListenerContainerWithIdleReceivesPerTaskLimit() throws InterruptedException { - DefaultMessageListenerContainer mlc = new DefaultMessageListenerContainer(); - mlc.setConcurrentConsumers(1); - mlc.setMaxConcurrentConsumers(2); - mlc.setIdleReceivesPerTaskLimit(1); - - testMessageListenerContainer(mlc); - } - - private void testMessageListenerContainer(AbstractMessageListenerContainer mlc) throws InterruptedException { - ActiveMQConnectionFactory aqcf = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false"); - TestMessageListener tml = new TestMessageListener(); - - mlc.setConnectionFactory(aqcf); - mlc.setMessageListener(tml); - mlc.setDestinationName("test"); - mlc.afterPropertiesSet(); - mlc.start(); - - JmsTemplate jt = new JmsTemplate(aqcf); - jt.setDefaultDestinationName("test"); - - Set messages = new HashSet<>(); - messages.add("text1"); - messages.add("text2"); - for (String message : messages) { - jt.convertAndSend(message); - } - assertThat(tml.result()).isEqualTo(messages); - - mlc.destroy(); - } - - - private static class TestMessageListener implements SessionAwareMessageListener { - - private final CountDownLatch latch = new CountDownLatch(2); - - private final Set messages = new CopyOnWriteArraySet<>(); - - @Override - public void onMessage(TextMessage message, Session session) throws JMSException { - this.messages.add(message.getText()); - this.latch.countDown(); - } - - public Set result() throws InterruptedException { - assertThat(this.latch.await(5, TimeUnit.SECONDS)).isTrue(); - return this.messages; - } - } - -} diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/SimpleMessageListenerContainerTests.java b/spring-jms/src/test/java/org/springframework/jms/listener/SimpleMessageListenerContainerTests.java index 76bd754e2cc5..7b001de2ab2a 100644 --- a/spring-jms/src/test/java/org/springframework/jms/listener/SimpleMessageListenerContainerTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/listener/SimpleMessageListenerContainerTests.java @@ -19,15 +19,14 @@ import java.util.HashSet; import java.util.Set; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.Session; - +import jakarta.jms.Connection; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.ExceptionListener; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageConsumer; +import jakarta.jms.MessageListener; +import jakarta.jms.Session; import org.junit.jupiter.api.Test; import org.springframework.context.support.GenericApplicationContext; diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/JmsResponseTests.java b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/JmsResponseTests.java index b373b061a9b3..c32fc0dd14ee 100644 --- a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/JmsResponseTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/JmsResponseTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,9 @@ package org.springframework.jms.listener.adapter; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Session; - +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Session; import org.junit.jupiter.api.Test; import org.springframework.jms.support.destination.DestinationResolver; @@ -54,7 +53,7 @@ public void resolveDestinationForQueue() throws JMSException { } @Test - public void createWithNulResponse() { + public void createWithNullResponse() { assertThatIllegalArgumentException().isThrownBy(() -> JmsResponse.forQueue(null, "myQueue")); } diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessageDelegate.java b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessageDelegate.java index 7138f269868b..3c8f4de9cec5 100644 --- a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessageDelegate.java +++ b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessageDelegate.java @@ -16,10 +16,10 @@ package org.springframework.jms.listener.adapter; -import javax.jms.BytesMessage; -import javax.jms.MapMessage; -import javax.jms.ObjectMessage; -import javax.jms.TextMessage; +import jakarta.jms.BytesMessage; +import jakarta.jms.MapMessage; +import jakarta.jms.ObjectMessage; +import jakarta.jms.TextMessage; /** * See the MessageListenerAdapterTests class for usage. diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessageListenerAdapterTests.java b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessageListenerAdapterTests.java index ceeab1c3b36a..751ca9c27a26 100644 --- a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessageListenerAdapterTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessageListenerAdapterTests.java @@ -19,18 +19,17 @@ import java.io.ByteArrayInputStream; import java.io.Serializable; -import javax.jms.BytesMessage; -import javax.jms.InvalidDestinationException; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageProducer; -import javax.jms.ObjectMessage; -import javax.jms.Queue; -import javax.jms.QueueSender; -import javax.jms.QueueSession; -import javax.jms.Session; -import javax.jms.TextMessage; - +import jakarta.jms.BytesMessage; +import jakarta.jms.InvalidDestinationException; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageProducer; +import jakarta.jms.ObjectMessage; +import jakarta.jms.Queue; +import jakarta.jms.QueueSender; +import jakarta.jms.QueueSession; +import jakarta.jms.Session; +import jakarta.jms.TextMessage; import org.junit.jupiter.api.Test; import org.mockito.stubbing.Answer; diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapterTests.java b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapterTests.java index 4a984a256e37..03f44a70f30e 100644 --- a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapterTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapterTests.java @@ -20,16 +20,15 @@ import java.util.ArrayList; import java.util.List; -import javax.jms.DeliveryMode; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TextMessage; -import javax.jms.Topic; - import com.fasterxml.jackson.annotation.JsonView; +import jakarta.jms.DeliveryMode; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.MessageProducer; +import jakarta.jms.Queue; +import jakarta.jms.Session; +import jakarta.jms.TextMessage; +import jakarta.jms.Topic; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -85,7 +84,7 @@ public void buildMessageWithStandardMessage() throws JMSException { Session session = mock(Session.class); given(session.createTextMessage("Response")).willReturn(new StubTextMessage("Response")); MessagingMessageListenerAdapter listener = getSimpleInstance("echo", Message.class); - javax.jms.Message replyMessage = listener.buildMessage(session, result); + jakarta.jms.Message replyMessage = listener.buildMessage(session, result); verify(session).createTextMessage("Response"); assertThat(replyMessage).as("reply should never be null").isNotNull(); @@ -97,7 +96,7 @@ public void buildMessageWithStandardMessage() throws JMSException { @Test public void exceptionInListener() { - javax.jms.Message message = new StubTextMessage("foo"); + jakarta.jms.Message message = new StubTextMessage("foo"); Session session = mock(Session.class); MessagingMessageListenerAdapter listener = getSimpleInstance("fail", String.class); assertThatExceptionOfType(ListenerExecutionFailedException.class) @@ -109,7 +108,7 @@ public void exceptionInListener() { @Test public void exceptionInInvocation() { - javax.jms.Message message = new StubTextMessage("foo"); + jakarta.jms.Message message = new StubTextMessage("foo"); Session session = mock(Session.class); MessagingMessageListenerAdapter listener = getSimpleInstance("wrongParam", Integer.class); @@ -120,7 +119,7 @@ public void exceptionInInvocation() { @Test public void payloadConversionLazilyInvoked() throws JMSException { - javax.jms.Message jmsMessage = mock(javax.jms.Message.class); + jakarta.jms.Message jmsMessage = mock(jakarta.jms.Message.class); MessageConverter messageConverter = mock(MessageConverter.class); given(messageConverter.fromMessage(jmsMessage)).willReturn("FooBar"); MessagingMessageListenerAdapter listener = getSimpleInstance("simple", Message.class); @@ -133,7 +132,7 @@ public void payloadConversionLazilyInvoked() throws JMSException { @Test public void headerConversionLazilyInvoked() throws JMSException { - javax.jms.Message jmsMessage = mock(javax.jms.Message.class); + jakarta.jms.Message jmsMessage = mock(jakarta.jms.Message.class); given(jmsMessage.getPropertyNames()).willThrow(new IllegalArgumentException("Header failure")); MessagingMessageListenerAdapter listener = getSimpleInstance("simple", Message.class); Message message = listener.toMessagingMessage(jmsMessage); @@ -146,7 +145,7 @@ public void headerConversionLazilyInvoked() throws JMSException { @Test public void incomingMessageUsesMessageConverter() throws JMSException { - javax.jms.Message jmsMessage = mock(javax.jms.Message.class); + jakarta.jms.Message jmsMessage = mock(jakarta.jms.Message.class); Session session = mock(Session.class); MessageConverter messageConverter = mock(MessageConverter.class); given(messageConverter.fromMessage(jmsMessage)).willReturn("FooBar"); @@ -167,7 +166,7 @@ public void replyUsesMessageConverterForPayload() throws JMSException { Message result = MessageBuilder.withPayload("Response").build(); MessagingMessageListenerAdapter listener = getSimpleInstance("echo", Message.class); listener.setMessageConverter(messageConverter); - javax.jms.Message replyMessage = listener.buildMessage(session, result); + jakarta.jms.Message replyMessage = listener.buildMessage(session, result); verify(messageConverter, times(1)).toMessage("Response", session); assertThat(replyMessage).as("reply should never be null").isNotNull(); @@ -186,7 +185,7 @@ public void replyPayloadToQueue() throws JMSException { given(session.createProducer(replyDestination)).willReturn(messageProducer); MessagingMessageListenerAdapter listener = getPayloadInstance("Response", "replyPayloadToQueue", Message.class); - listener.onMessage(mock(javax.jms.Message.class), session); + listener.onMessage(mock(jakarta.jms.Message.class), session); verify(session).createQueue("queueOut"); verify(session).createTextMessage("Response"); @@ -209,11 +208,11 @@ public void replyWithCustomTimeToLive() throws JMSException { QosSettings settings = new QosSettings(); settings.setTimeToLive(6000); listener.setResponseQosSettings(settings); - listener.onMessage(mock(javax.jms.Message.class), session); + listener.onMessage(mock(jakarta.jms.Message.class), session); verify(session).createQueue("queueOut"); verify(session).createTextMessage("Response"); - verify(messageProducer).send(responseMessage, javax.jms.Message.DEFAULT_DELIVERY_MODE, - javax.jms.Message.DEFAULT_PRIORITY, 6000); + verify(messageProducer).send(responseMessage, jakarta.jms.Message.DEFAULT_DELIVERY_MODE, + jakarta.jms.Message.DEFAULT_PRIORITY, 6000); verify(messageProducer).close(); } @@ -231,7 +230,7 @@ public void replyWithFullQoS() throws JMSException { MessagingMessageListenerAdapter listener = getPayloadInstance("Response", "replyPayloadToQueue", Message.class); QosSettings settings = new QosSettings(DeliveryMode.NON_PERSISTENT, 6, 6000); listener.setResponseQosSettings(settings); - listener.onMessage(mock(javax.jms.Message.class), session); + listener.onMessage(mock(jakarta.jms.Message.class), session); verify(session).createQueue("queueOut"); verify(session).createTextMessage("Response"); verify(messageProducer).send(responseMessage, DeliveryMode.NON_PERSISTENT, 6, 6000); @@ -250,7 +249,7 @@ public void replyPayloadToTopic() throws JMSException { given(session.createProducer(replyDestination)).willReturn(messageProducer); MessagingMessageListenerAdapter listener = getPayloadInstance("Response", "replyPayloadToTopic", Message.class); - listener.onMessage(mock(javax.jms.Message.class), session); + listener.onMessage(mock(jakarta.jms.Message.class), session); verify(session).createTopic("topicOut"); verify(session).createTextMessage("Response"); @@ -267,7 +266,7 @@ public void replyPayloadToDestination() throws JMSException { given(session.createProducer(sharedReplyDestination)).willReturn(messageProducer); MessagingMessageListenerAdapter listener = getPayloadInstance("Response", "replyPayloadToDestination", Message.class); - listener.onMessage(mock(javax.jms.Message.class), session); + listener.onMessage(mock(jakarta.jms.Message.class), session); verify(session, times(0)).createQueue(anyString()); verify(session).createTextMessage("Response"); @@ -288,7 +287,7 @@ public void replyPayloadNoDestination() throws JMSException { MessagingMessageListenerAdapter listener = getPayloadInstance("Response", "replyPayloadNoDestination", Message.class); listener.setDefaultResponseDestination(replyDestination); - listener.onMessage(mock(javax.jms.Message.class), session); + listener.onMessage(mock(jakarta.jms.Message.class), session); verify(session, times(0)).createQueue(anyString()); verify(session).createTextMessage("Response"); @@ -331,7 +330,7 @@ public TextMessage testReplyWithJackson(String methodName, String replyContent) messageConverter.setTargetType(MessageType.TEXT); listener.setMessageConverter(messageConverter); listener.setDefaultResponseDestination(replyDestination); - listener.onMessage(mock(javax.jms.Message.class), session); + listener.onMessage(mock(jakarta.jms.Message.class), session); verify(session, times(0)).createQueue(anyString()); verify(session).createTextMessage(replyContent); @@ -358,7 +357,7 @@ protected MessagingMessageListenerAdapter getPayloadInstance(final Object payloa Method method = ReflectionUtils.findMethod(SampleBean.class, methodName, parameterTypes); MessagingMessageListenerAdapter adapter = new MessagingMessageListenerAdapter() { @Override - protected Object extractMessage(javax.jms.Message message) { + protected Object extractMessage(jakarta.jms.Message message) { return payload; } }; diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/ResponsiveJmsTextMessageReturningMessageDelegate.java b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/ResponsiveJmsTextMessageReturningMessageDelegate.java index 1ad045348404..0fcecaed3d95 100644 --- a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/ResponsiveJmsTextMessageReturningMessageDelegate.java +++ b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/ResponsiveJmsTextMessageReturningMessageDelegate.java @@ -16,7 +16,7 @@ package org.springframework.jms.listener.adapter; -import javax.jms.TextMessage; +import jakarta.jms.TextMessage; /** * See the MessageListenerAdapterTests class for usage. diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/ResponsiveMessageDelegate.java b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/ResponsiveMessageDelegate.java index c162dc098147..fe4b6970c93f 100644 --- a/spring-jms/src/test/java/org/springframework/jms/listener/adapter/ResponsiveMessageDelegate.java +++ b/spring-jms/src/test/java/org/springframework/jms/listener/adapter/ResponsiveMessageDelegate.java @@ -19,10 +19,10 @@ import java.io.Serializable; import java.util.Map; -import javax.jms.BytesMessage; -import javax.jms.MapMessage; -import javax.jms.ObjectMessage; -import javax.jms.TextMessage; +import jakarta.jms.BytesMessage; +import jakarta.jms.MapMessage; +import jakarta.jms.ObjectMessage; +import jakarta.jms.TextMessage; /** * See the MessageListenerAdapterTests class for usage. diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/DefaultJmsActivationSpecFactoryTests.java b/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/DefaultJmsActivationSpecFactoryTests.java index 32e9400b7c11..0540c97ea30d 100644 --- a/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/DefaultJmsActivationSpecFactoryTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/DefaultJmsActivationSpecFactoryTests.java @@ -16,9 +16,8 @@ package org.springframework.jms.listener.endpoint; -import javax.jms.Destination; -import javax.jms.Session; - +import jakarta.jms.Destination; +import jakarta.jms.Session; import org.junit.jupiter.api.Test; import org.springframework.jca.StubResourceAdapter; diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/StubJmsActivationSpec.java b/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/StubJmsActivationSpec.java index c9d16c4e04bb..b648e7f8daa9 100644 --- a/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/StubJmsActivationSpec.java +++ b/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/StubJmsActivationSpec.java @@ -16,7 +16,7 @@ package org.springframework.jms.listener.endpoint; -import javax.jms.Destination; +import jakarta.jms.Destination; import org.springframework.jca.StubActivationSpec; diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/StubJmsActivationSpecFactory.java b/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/StubJmsActivationSpecFactory.java index 17e4aafd554e..735070cc5db4 100644 --- a/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/StubJmsActivationSpecFactory.java +++ b/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/StubJmsActivationSpecFactory.java @@ -16,8 +16,8 @@ package org.springframework.jms.listener.endpoint; -import javax.resource.spi.ActivationSpec; -import javax.resource.spi.ResourceAdapter; +import jakarta.resource.spi.ActivationSpec; +import jakarta.resource.spi.ResourceAdapter; import org.springframework.jca.StubActivationSpec; diff --git a/spring-jms/src/test/java/org/springframework/jms/support/JmsAccessorTests.java b/spring-jms/src/test/java/org/springframework/jms/support/JmsAccessorTests.java index bb1710043e58..1e2f4b667637 100644 --- a/spring-jms/src/test/java/org/springframework/jms/support/JmsAccessorTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/support/JmsAccessorTests.java @@ -16,8 +16,7 @@ package org.springframework.jms.support; -import javax.jms.Session; - +import jakarta.jms.Session; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-jms/src/test/java/org/springframework/jms/support/JmsMessageHeaderAccessorTests.java b/spring-jms/src/test/java/org/springframework/jms/support/JmsMessageHeaderAccessorTests.java index 2255f34ea5d7..939cb6aa29b8 100644 --- a/spring-jms/src/test/java/org/springframework/jms/support/JmsMessageHeaderAccessorTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/support/JmsMessageHeaderAccessorTests.java @@ -18,9 +18,8 @@ import java.util.Map; -import javax.jms.Destination; -import javax.jms.JMSException; - +import jakarta.jms.Destination; +import jakarta.jms.JMSException; import org.junit.jupiter.api.Test; import org.springframework.jms.StubTextMessage; diff --git a/spring-jms/src/test/java/org/springframework/jms/support/SimpleJmsHeaderMapperTests.java b/spring-jms/src/test/java/org/springframework/jms/support/SimpleJmsHeaderMapperTests.java index 8839696b4d38..331fdaa0a568 100644 --- a/spring-jms/src/test/java/org/springframework/jms/support/SimpleJmsHeaderMapperTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/support/SimpleJmsHeaderMapperTests.java @@ -19,10 +19,9 @@ import java.util.Date; import java.util.Map; -import javax.jms.DeliveryMode; -import javax.jms.Destination; -import javax.jms.JMSException; - +import jakarta.jms.DeliveryMode; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; import org.junit.jupiter.api.Test; import org.springframework.jms.StubTextMessage; @@ -51,7 +50,7 @@ public void jmsReplyToMappedFromHeader() throws JMSException { Message message = initBuilder() .setHeader(JmsHeaders.REPLY_TO, replyTo).build(); - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); mapper.fromHeaders(message.getHeaders(), jmsMessage); assertThat(jmsMessage.getJMSReplyTo()).isNotNull(); assertThat(jmsMessage.getJMSReplyTo()).isSameAs(replyTo); @@ -61,7 +60,7 @@ public void jmsReplyToMappedFromHeader() throws JMSException { public void JmsReplyToIgnoredIfIncorrectType() throws JMSException { Message message = initBuilder() .setHeader(JmsHeaders.REPLY_TO, "not-a-destination").build(); - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); mapper.fromHeaders(message.getHeaders(), jmsMessage); assertThat(jmsMessage.getJMSReplyTo()).isNull(); } @@ -71,7 +70,7 @@ public void jmsCorrelationIdMappedFromHeader() throws JMSException { String jmsCorrelationId = "ABC-123"; Message message = initBuilder() .setHeader(JmsHeaders.CORRELATION_ID, jmsCorrelationId).build(); - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); mapper.fromHeaders(message.getHeaders(), jmsMessage); assertThat(jmsMessage.getJMSCorrelationID()).isNotNull(); assertThat(jmsMessage.getJMSCorrelationID()).isEqualTo(jmsCorrelationId); @@ -81,7 +80,7 @@ public void jmsCorrelationIdMappedFromHeader() throws JMSException { public void jmsCorrelationIdNumberConvertsToString() throws JMSException { Message message = initBuilder() .setHeader(JmsHeaders.CORRELATION_ID, 123).build(); - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); mapper.fromHeaders(message.getHeaders(), jmsMessage); assertThat(jmsMessage.getJMSCorrelationID()).isEqualTo("123"); } @@ -90,7 +89,7 @@ public void jmsCorrelationIdNumberConvertsToString() throws JMSException { public void jmsCorrelationIdIgnoredIfIncorrectType() throws JMSException { Message message = initBuilder() .setHeader(JmsHeaders.CORRELATION_ID, new Date()).build(); - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); mapper.fromHeaders(message.getHeaders(), jmsMessage); assertThat(jmsMessage.getJMSCorrelationID()).isNull(); } @@ -100,7 +99,7 @@ public void jmsTypeMappedFromHeader() throws JMSException { String jmsType = "testing"; Message message = initBuilder() .setHeader(JmsHeaders.TYPE, jmsType).build(); - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); mapper.fromHeaders(message.getHeaders(), jmsMessage); assertThat(jmsMessage.getJMSType()).isNotNull(); assertThat(jmsMessage.getJMSType()).isEqualTo(jmsType); @@ -110,7 +109,7 @@ public void jmsTypeMappedFromHeader() throws JMSException { public void jmsTypeIgnoredIfIncorrectType() throws JMSException { Message message = initBuilder() .setHeader(JmsHeaders.TYPE, 123).build(); - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); mapper.fromHeaders(message.getHeaders(), jmsMessage); assertThat(jmsMessage.getJMSType()).isNull(); } @@ -126,13 +125,13 @@ public void jmsReadOnlyPropertiesNotMapped() throws JMSException { .setHeader(JmsHeaders.REDELIVERED, true) .setHeader(JmsHeaders.TIMESTAMP, System.currentTimeMillis()) .build(); - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); mapper.fromHeaders(message.getHeaders(), jmsMessage); assertThat(jmsMessage.getJMSDestination()).isNull(); assertThat(jmsMessage.getJMSDeliveryMode()).isEqualTo(DeliveryMode.PERSISTENT); assertThat(jmsMessage.getJMSExpiration()).isEqualTo(0); assertThat(jmsMessage.getJMSMessageID()).isNull(); - assertThat(jmsMessage.getJMSPriority()).isEqualTo(javax.jms.Message.DEFAULT_PRIORITY); + assertThat(jmsMessage.getJMSPriority()).isEqualTo(jakarta.jms.Message.DEFAULT_PRIORITY); assertThat(jmsMessage.getJMSRedelivered()).isFalse(); assertThat(jmsMessage.getJMSTimestamp()).isEqualTo(0); } @@ -142,7 +141,7 @@ public void contentTypePropertyMappedFromHeader() throws JMSException { Message message = initBuilder() .setHeader(MessageHeaders.CONTENT_TYPE, "foo") .build(); - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); mapper.fromHeaders(message.getHeaders(), jmsMessage); Object value = jmsMessage.getObjectProperty(JmsHeaderMapper.CONTENT_TYPE_PROPERTY); assertThat(value).isNotNull(); @@ -154,7 +153,7 @@ public void userDefinedPropertyMappedFromHeader() throws JMSException { Message message = initBuilder() .setHeader("foo", 123) .build(); - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); mapper.fromHeaders(message.getHeaders(), jmsMessage); Object value = jmsMessage.getObjectProperty("foo"); assertThat(value).isNotNull(); @@ -168,7 +167,7 @@ public void userDefinedPropertyMappedFromHeaderWithCustomPrefix() throws JMSExce .setHeader("foo", 123) .build(); mapper.setOutboundPrefix("custom_"); - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); mapper.fromHeaders(message.getHeaders(), jmsMessage); Object value = jmsMessage.getObjectProperty("custom_foo"); assertThat(value).isNotNull(); @@ -182,7 +181,7 @@ public void userDefinedPropertyWithUnsupportedType() throws JMSException { Message message = initBuilder() .setHeader("destination", destination) .build(); - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); mapper.fromHeaders(message.getHeaders(), jmsMessage); Object value = jmsMessage.getObjectProperty("destination"); assertThat(value).isNull(); @@ -190,7 +189,7 @@ public void userDefinedPropertyWithUnsupportedType() throws JMSException { @Test public void attemptToReadDisallowedCorrelationIdPropertyIsNotFatal() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public String getJMSCorrelationID() throws JMSException { throw new JMSException("illegal property"); @@ -201,7 +200,7 @@ public String getJMSCorrelationID() throws JMSException { @Test public void attemptToReadDisallowedDestinationPropertyIsNotFatal() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public Destination getJMSDestination() throws JMSException { throw new JMSException("illegal property"); @@ -212,7 +211,7 @@ public Destination getJMSDestination() throws JMSException { @Test public void attemptToReadDisallowedDeliveryModePropertyIsNotFatal() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public int getJMSDeliveryMode() throws JMSException { throw new JMSException("illegal property"); @@ -223,7 +222,7 @@ public int getJMSDeliveryMode() throws JMSException { @Test public void attemptToReadDisallowedExpirationPropertyIsNotFatal() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public long getJMSExpiration() throws JMSException { throw new JMSException("illegal property"); @@ -234,7 +233,7 @@ public long getJMSExpiration() throws JMSException { @Test public void attemptToReadDisallowedMessageIdPropertyIsNotFatal() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public String getJMSMessageID() throws JMSException { throw new JMSException("illegal property"); @@ -245,7 +244,7 @@ public String getJMSMessageID() throws JMSException { @Test public void attemptToReadDisallowedPriorityPropertyIsNotFatal() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public int getJMSPriority() throws JMSException { throw new JMSException("illegal property"); @@ -256,7 +255,7 @@ public int getJMSPriority() throws JMSException { @Test public void attemptToReadDisallowedReplyToPropertyIsNotFatal() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public Destination getJMSReplyTo() throws JMSException { throw new JMSException("illegal property"); @@ -267,7 +266,7 @@ public Destination getJMSReplyTo() throws JMSException { @Test public void attemptToReadDisallowedRedeliveredPropertyIsNotFatal() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public boolean getJMSRedelivered() throws JMSException { throw new JMSException("illegal property"); @@ -278,7 +277,7 @@ public boolean getJMSRedelivered() throws JMSException { @Test public void attemptToReadDisallowedTypePropertyIsNotFatal() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public String getJMSType() throws JMSException { throw new JMSException("illegal property"); @@ -289,7 +288,7 @@ public String getJMSType() throws JMSException { @Test public void attemptToReadDisallowedTimestampPropertyIsNotFatal() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public long getJMSTimestamp() throws JMSException { throw new JMSException("illegal property"); @@ -300,7 +299,7 @@ public long getJMSTimestamp() throws JMSException { @Test public void attemptToReadDisallowedUserPropertyIsNotFatal() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public Object getObjectProperty(String name) throws JMSException { if (name.equals("fail")) { @@ -321,7 +320,7 @@ public Object getObjectProperty(String name) throws JMSException { @Test public void jmsCorrelationIdMappedToHeader() throws JMSException { String correlationId = "ABC-123"; - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); jmsMessage.setJMSCorrelationID(correlationId); assertInboundHeader(jmsMessage, JmsHeaders.CORRELATION_ID, correlationId); } @@ -329,7 +328,7 @@ public void jmsCorrelationIdMappedToHeader() throws JMSException { @Test public void destinationMappedToHeader() throws JMSException { Destination destination = new Destination() {}; - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); jmsMessage.setJMSDestination(destination); assertInboundHeader(jmsMessage, JmsHeaders.DESTINATION, destination); } @@ -337,7 +336,7 @@ public void destinationMappedToHeader() throws JMSException { @Test public void jmsDeliveryModeMappedToHeader() throws JMSException { int deliveryMode = 1; - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); jmsMessage.setJMSDeliveryMode(deliveryMode); assertInboundHeader(jmsMessage, JmsHeaders.DELIVERY_MODE, deliveryMode); } @@ -345,7 +344,7 @@ public void jmsDeliveryModeMappedToHeader() throws JMSException { @Test public void jmsExpirationMappedToHeader() throws JMSException { long expiration = 1000L; - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); jmsMessage.setJMSExpiration(expiration); assertInboundHeader(jmsMessage, JmsHeaders.EXPIRATION, expiration); } @@ -353,7 +352,7 @@ public void jmsExpirationMappedToHeader() throws JMSException { @Test public void jmsMessageIdMappedToHeader() throws JMSException { String messageId = "ID:ABC-123"; - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); jmsMessage.setJMSMessageID(messageId); assertInboundHeader(jmsMessage, JmsHeaders.MESSAGE_ID, messageId); } @@ -361,7 +360,7 @@ public void jmsMessageIdMappedToHeader() throws JMSException { @Test public void jmsPriorityMappedToHeader() throws JMSException { int priority = 8; - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); jmsMessage.setJMSPriority(priority); assertInboundHeader(jmsMessage, JmsHeaders.PRIORITY, priority); } @@ -369,7 +368,7 @@ public void jmsPriorityMappedToHeader() throws JMSException { @Test public void jmsReplyToMappedToHeader() throws JMSException { Destination replyTo = new Destination() {}; - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); jmsMessage.setJMSReplyTo(replyTo); assertInboundHeader(jmsMessage, JmsHeaders.REPLY_TO, replyTo); } @@ -377,7 +376,7 @@ public void jmsReplyToMappedToHeader() throws JMSException { @Test public void jmsTypeMappedToHeader() throws JMSException { String type = "testing"; - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); jmsMessage.setJMSType(type); assertInboundHeader(jmsMessage, JmsHeaders.TYPE, type); } @@ -385,28 +384,28 @@ public void jmsTypeMappedToHeader() throws JMSException { @Test public void jmsTimestampMappedToHeader() throws JMSException { long timestamp = 123L; - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); jmsMessage.setJMSTimestamp(timestamp); assertInboundHeader(jmsMessage, JmsHeaders.TIMESTAMP, timestamp); } @Test public void contentTypePropertyMappedToHeader() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); jmsMessage.setStringProperty("content_type", "foo"); assertInboundHeader(jmsMessage, MessageHeaders.CONTENT_TYPE, "foo"); } @Test public void userDefinedPropertyMappedToHeader() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); jmsMessage.setIntProperty("foo", 123); assertInboundHeader(jmsMessage, "foo", 123); } @Test public void userDefinedPropertyMappedToHeaderWithCustomPrefix() throws JMSException { - javax.jms.Message jmsMessage = new StubTextMessage(); + jakarta.jms.Message jmsMessage = new StubTextMessage(); jmsMessage.setIntProperty("foo", 123); mapper.setInboundPrefix("custom_"); assertInboundHeader(jmsMessage, "custom_foo", 123); @@ -419,7 +418,7 @@ public void propertyMappingExceptionIsNotFatal() throws JMSException { .setHeader("bad", 456) .setHeader("bar", 789) .build(); - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public void setObjectProperty(String name, Object value) throws JMSException { if (name.equals("bad")) { @@ -444,7 +443,7 @@ public void illegalArgumentExceptionIsNotFatal() throws JMSException { .setHeader("bad", 456) .setHeader("bar", 789) .build(); - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public void setObjectProperty(String name, Object value) throws JMSException { if (name.equals("bad")) { @@ -468,7 +467,7 @@ public void attemptToWriteDisallowedReplyToPropertyIsNotFatal() throws JMSExcept .setHeader(JmsHeaders.REPLY_TO, new Destination() {}) .setHeader("foo", "bar") .build(); - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public void setJMSReplyTo(Destination replyTo) throws JMSException { throw new JMSException("illegal property"); @@ -486,7 +485,7 @@ public void attemptToWriteDisallowedTypePropertyIsNotFatal() throws JMSException .setHeader(JmsHeaders.TYPE, "someType") .setHeader("foo", "bar") .build(); - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public void setJMSType(String type) throws JMSException { throw new JMSException("illegal property"); @@ -504,7 +503,7 @@ public void attemptToWriteDisallowedCorrelationIdStringPropertyIsNotFatal() thro .setHeader(JmsHeaders.CORRELATION_ID, "abc") .setHeader("foo", "bar") .build(); - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public void setJMSCorrelationID(String correlationId) throws JMSException { throw new JMSException("illegal property"); @@ -522,7 +521,7 @@ public void attemptToWriteDisallowedCorrelationIdNumberPropertyIsNotFatal() thro .setHeader(JmsHeaders.CORRELATION_ID, 123) .setHeader("foo", "bar") .build(); - javax.jms.Message jmsMessage = new StubTextMessage() { + jakarta.jms.Message jmsMessage = new StubTextMessage() { @Override public void setJMSCorrelationID(String correlationId) throws JMSException { throw new JMSException("illegal property"); @@ -535,7 +534,7 @@ public void setJMSCorrelationID(String correlationId) throws JMSException { } - private void assertInboundHeader(javax.jms.Message jmsMessage, String headerId, Object value) { + private void assertInboundHeader(jakarta.jms.Message jmsMessage, String headerId, Object value) { Map headers = mapper.toHeaders(jmsMessage); Object headerValue = headers.get(headerId); if (value == null) { @@ -548,7 +547,7 @@ private void assertInboundHeader(javax.jms.Message jmsMessage, String headerId, } } - private void assertAttemptReadDisallowedPropertyIsNotFatal(javax.jms.Message jmsMessage, String headerId) + private void assertAttemptReadDisallowedPropertyIsNotFatal(jakarta.jms.Message jmsMessage, String headerId) throws JMSException { jmsMessage.setStringProperty("foo", "bar"); Map headers = mapper.toHeaders(jmsMessage); diff --git a/spring-jms/src/test/java/org/springframework/jms/support/SimpleMessageConverterTests.java b/spring-jms/src/test/java/org/springframework/jms/support/SimpleMessageConverterTests.java index 41aed17f47aa..bcbb41a64a3f 100644 --- a/spring-jms/src/test/java/org/springframework/jms/support/SimpleMessageConverterTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/support/SimpleMessageConverterTests.java @@ -21,14 +21,13 @@ import java.util.HashMap; import java.util.Map; -import javax.jms.BytesMessage; -import javax.jms.JMSException; -import javax.jms.MapMessage; -import javax.jms.Message; -import javax.jms.ObjectMessage; -import javax.jms.Session; -import javax.jms.TextMessage; - +import jakarta.jms.BytesMessage; +import jakarta.jms.JMSException; +import jakarta.jms.MapMessage; +import jakarta.jms.Message; +import jakarta.jms.ObjectMessage; +import jakarta.jms.Session; +import jakarta.jms.TextMessage; import org.junit.jupiter.api.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; diff --git a/spring-jms/src/test/java/org/springframework/jms/support/converter/MappingJackson2MessageConverterTests.java b/spring-jms/src/test/java/org/springframework/jms/support/converter/MappingJackson2MessageConverterTests.java index 4f428c270939..42eb86a6871f 100644 --- a/spring-jms/src/test/java/org/springframework/jms/support/converter/MappingJackson2MessageConverterTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/support/converter/MappingJackson2MessageConverterTests.java @@ -23,12 +23,11 @@ import java.util.HashMap; import java.util.Map; -import javax.jms.BytesMessage; -import javax.jms.JMSException; -import javax.jms.Session; -import javax.jms.TextMessage; - import com.fasterxml.jackson.annotation.JsonView; +import jakarta.jms.BytesMessage; +import jakarta.jms.JMSException; +import jakarta.jms.Session; +import jakarta.jms.TextMessage; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.stubbing.Answer; diff --git a/spring-jms/src/test/java/org/springframework/jms/support/converter/MarshallingMessageConverterTests.java b/spring-jms/src/test/java/org/springframework/jms/support/converter/MarshallingMessageConverterTests.java index b0c23cd0bff6..a0c37d174505 100644 --- a/spring-jms/src/test/java/org/springframework/jms/support/converter/MarshallingMessageConverterTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/support/converter/MarshallingMessageConverterTests.java @@ -16,12 +16,12 @@ package org.springframework.jms.support.converter; -import javax.jms.BytesMessage; -import javax.jms.Session; -import javax.jms.TextMessage; import javax.xml.transform.Result; import javax.xml.transform.Source; +import jakarta.jms.BytesMessage; +import jakarta.jms.Session; +import jakarta.jms.TextMessage; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-jms/src/test/java/org/springframework/jms/support/converter/MessagingMessageConverterTests.java b/spring-jms/src/test/java/org/springframework/jms/support/converter/MessagingMessageConverterTests.java index d1c28956e5e3..e5e5a26bb470 100644 --- a/spring-jms/src/test/java/org/springframework/jms/support/converter/MessagingMessageConverterTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/support/converter/MessagingMessageConverterTests.java @@ -18,11 +18,10 @@ import java.io.Serializable; -import javax.jms.JMSException; -import javax.jms.ObjectMessage; -import javax.jms.Session; -import javax.jms.TextMessage; - +import jakarta.jms.JMSException; +import jakarta.jms.ObjectMessage; +import jakarta.jms.Session; +import jakarta.jms.TextMessage; import org.junit.jupiter.api.Test; import org.springframework.jms.StubTextMessage; @@ -75,7 +74,7 @@ static class TestMessageConverter extends SimpleMessageConverter { private boolean called; @Override - public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException { + public Object fromMessage(jakarta.jms.Message message) throws JMSException, MessageConversionException { if (this.called) { throw new java.lang.IllegalStateException("Converter called twice"); } diff --git a/spring-jms/src/test/java/org/springframework/jms/support/destination/DynamicDestinationResolverTests.java b/spring-jms/src/test/java/org/springframework/jms/support/destination/DynamicDestinationResolverTests.java index 0a11c2e186b9..841cb96bd523 100644 --- a/spring-jms/src/test/java/org/springframework/jms/support/destination/DynamicDestinationResolverTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/support/destination/DynamicDestinationResolverTests.java @@ -16,14 +16,13 @@ package org.springframework.jms.support.destination; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Queue; -import javax.jms.QueueSession; -import javax.jms.Session; -import javax.jms.Topic; -import javax.jms.TopicSession; - +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Queue; +import jakarta.jms.QueueSession; +import jakarta.jms.Session; +import jakarta.jms.Topic; +import jakarta.jms.TopicSession; import org.junit.jupiter.api.Test; import org.springframework.jms.StubQueue; diff --git a/spring-jms/src/test/java/org/springframework/jms/support/destination/JmsDestinationAccessorTests.java b/spring-jms/src/test/java/org/springframework/jms/support/destination/JmsDestinationAccessorTests.java index 24e1777ca42f..3e02eabc4ee3 100644 --- a/spring-jms/src/test/java/org/springframework/jms/support/destination/JmsDestinationAccessorTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/support/destination/JmsDestinationAccessorTests.java @@ -16,8 +16,7 @@ package org.springframework.jms.support.destination; -import javax.jms.ConnectionFactory; - +import jakarta.jms.ConnectionFactory; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-jms/src/test/java/org/springframework/jms/support/destination/JndiDestinationResolverTests.java b/spring-jms/src/test/java/org/springframework/jms/support/destination/JndiDestinationResolverTests.java index 29003335868a..895373eab595 100644 --- a/spring-jms/src/test/java/org/springframework/jms/support/destination/JndiDestinationResolverTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/support/destination/JndiDestinationResolverTests.java @@ -16,10 +16,10 @@ package org.springframework.jms.support.destination; -import javax.jms.Destination; -import javax.jms.Session; import javax.naming.NamingException; +import jakarta.jms.Destination; +import jakarta.jms.Session; import org.junit.jupiter.api.Test; import org.springframework.jms.StubTopic; diff --git a/spring-messaging/spring-messaging.gradle b/spring-messaging/spring-messaging.gradle index c0c7270ebde2..61554bc71839 100644 --- a/spring-messaging/spring-messaging.gradle +++ b/spring-messaging/spring-messaging.gradle @@ -13,15 +13,15 @@ dependencies { optional("io.rsocket:rsocket-transport-netty") optional("com.fasterxml.jackson.core:jackson-databind") optional("com.google.code.gson:gson") - optional("javax.json.bind:javax.json.bind-api") - optional("javax.xml.bind:jaxb-api") + optional("jakarta.json.bind:jakarta.json.bind-api") + optional("jakarta.xml.bind:jakarta.xml.bind-api") optional("com.google.protobuf:protobuf-java-util") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") optional("org.jetbrains.kotlinx:kotlinx-serialization-json") testImplementation(testFixtures(project(":spring-core"))) - testImplementation("javax.inject:javax.inject-tck") - testImplementation("javax.servlet:javax.servlet-api") - testImplementation("javax.validation:validation-api") + testImplementation("jakarta.inject:jakarta.inject-tck") + testImplementation("jakarta.servlet:jakarta.servlet-api") + testImplementation("jakarta.validation:jakarta.validation-api") testImplementation("com.thoughtworks.xstream:xstream") testImplementation("org.apache.activemq:activemq-broker") testImplementation("org.apache.activemq:activemq-kahadb-store") @@ -32,10 +32,10 @@ dependencies { testImplementation("org.jetbrains.kotlin:kotlin-stdlib") testImplementation("org.xmlunit:xmlunit-assertj") testImplementation("org.xmlunit:xmlunit-matchers") - testRuntimeOnly("com.sun.activation:javax.activation") + testRuntimeOnly("com.sun.activation:jakarta.activation") testRuntimeOnly("com.sun.xml.bind:jaxb-core") testRuntimeOnly("com.sun.xml.bind:jaxb-impl") - testRuntimeOnly("javax.json:javax.json-api") - testRuntimeOnly("org.apache.johnzon:johnzon-jsonb") + testRuntimeOnly("jakarta.json:jakarta.json-api") + testRuntimeOnly("org.eclipse:yasson") testRuntimeOnly(project(":spring-context")) } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/JsonbMessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/JsonbMessageConverter.java index e327edbc2fcb..53ea6058798b 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/JsonbMessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/JsonbMessageConverter.java @@ -21,9 +21,9 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import javax.json.bind.Jsonb; -import javax.json.bind.JsonbBuilder; -import javax.json.bind.JsonbConfig; +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; +import jakarta.json.bind.JsonbConfig; import org.springframework.util.Assert; @@ -33,8 +33,8 @@ * * @author Juergen Hoeller * @since 5.3 - * @see javax.json.bind.Jsonb - * @see javax.json.bind.JsonbBuilder + * @see jakarta.json.bind.Jsonb + * @see jakarta.json.bind.JsonbBuilder * @see #setJsonb */ public class JsonbMessageConverter extends AbstractJsonMessageConverter { diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolver.java index c36a99ba97a4..07b0d28a4dfc 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolver.java @@ -63,7 +63,7 @@ * {@link DataBuffer DataBuffer}. * *

    Validation is applied if the method argument is annotated with - * {@code @javax.validation.Valid} or + * {@code @jakarta.validation.Valid} or * {@link org.springframework.validation.annotation.Validated}. Validation * failure results in an {@link MethodArgumentNotValidException}. * @@ -143,7 +143,7 @@ public boolean supportsParameter(MethodParameter parameter) { * {@link Decoder}. * *

    Validation is applied if the method argument is annotated with - * {@code @javax.validation.Valid} or + * {@code @jakarta.validation.Valid} or * {@link org.springframework.validation.annotation.Validated}. Validation * failure results in an {@link MethodArgumentNotValidException}. * diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java index 2ced8c86cd45..92e5d5ecc9f5 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java @@ -190,7 +190,7 @@ protected Class resolveTargetClass(MethodParameter parameter, Message mess /** * Validate the payload if applicable. - *

    The default implementation checks for {@code @javax.validation.Valid}, + *

    The default implementation checks for {@code @jakarta.validation.Valid}, * Spring's {@link Validated}, * and custom annotations whose name starts with "Valid". * @param message the currently processed message diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java index fb4150ad7b0e..c44ff260103a 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java @@ -112,7 +112,7 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader); gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader); - jsonbPresent = ClassUtils.isPresent("javax.json.bind.Jsonb", classLoader); + jsonbPresent = ClassUtils.isPresent("jakarta.json.bind.Jsonb", classLoader); kotlinSerializationJsonPresent = ClassUtils.isPresent("kotlinx.serialization.json.Json", classLoader); } @@ -553,7 +553,7 @@ protected Validator simpValidator() { if (this.applicationContext != null && this.applicationContext.containsBean(MVC_VALIDATOR_NAME)) { validator = this.applicationContext.getBean(MVC_VALIDATOR_NAME, Validator.class); } - else if (ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) { + else if (ClassUtils.isPresent("jakarta.validation.Validator", getClass().getClassLoader())) { Class clazz; try { String className = "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean"; diff --git a/spring-messaging/src/test/java/org/springframework/messaging/converter/JsonbMessageConverterTests.java b/spring-messaging/src/test/java/org/springframework/messaging/converter/JsonbMessageConverterTests.java index 63380ea4ebcf..b5026deffdc1 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/converter/JsonbMessageConverterTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/converter/JsonbMessageConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.messaging.converter; import java.lang.reflect.Method; +import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashMap; @@ -74,8 +75,8 @@ public void fromMessageUntyped() { HashMap actual = (HashMap) converter.fromMessage(message, HashMap.class); assertThat(actual.get("string")).isEqualTo("Foo"); - assertThat(actual.get("number")).isEqualTo(42); - assertThat((Double) actual.get("fraction")).isCloseTo(42D, within(0D)); + assertThat(actual.get("number")).isEqualTo(new BigDecimal(42)); + assertThat((BigDecimal) actual.get("fraction")).isCloseTo(new BigDecimal(42), within(new BigDecimal(0))); assertThat(actual.get("array")).isEqualTo(Arrays.asList("Foo", "Bar")); assertThat(actual.get("bool")).isEqualTo(Boolean.TRUE); } @@ -165,7 +166,7 @@ public void toMessageUtf16() { String payload = "H\u00e9llo W\u00f6rld"; Message message = converter.toMessage(payload, headers); - assertThat(new String((byte[]) message.getPayload(), StandardCharsets.UTF_16BE)).isEqualTo(payload); + assertThat(new String((byte[]) message.getPayload(), StandardCharsets.UTF_16BE)).isEqualTo("\"" + payload + "\""); assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE)).isEqualTo(contentType); } @@ -181,7 +182,7 @@ public void toMessageUtf16String() { String payload = "H\u00e9llo W\u00f6rld"; Message message = converter.toMessage(payload, headers); - assertThat(message.getPayload()).isEqualTo(payload); + assertThat(message.getPayload()).isEqualTo("\"" + payload + "\""); assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE)).isEqualTo(contentType); } diff --git a/spring-messaging/src/test/java/org/springframework/messaging/converter/MarshallingMessageConverterTests.java b/spring-messaging/src/test/java/org/springframework/messaging/converter/MarshallingMessageConverterTests.java index a676edb99b10..19aad50fdd98 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/converter/MarshallingMessageConverterTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/converter/MarshallingMessageConverterTests.java @@ -19,8 +19,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; -import javax.xml.bind.annotation.XmlRootElement; - +import jakarta.xml.bind.annotation.XmlRootElement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.xmlunit.diff.DifferenceEvaluator; diff --git a/spring-orm/spring-orm.gradle b/spring-orm/spring-orm.gradle index 7870f5d77d72..d7d2bebf52bb 100644 --- a/spring-orm/spring-orm.gradle +++ b/spring-orm/spring-orm.gradle @@ -9,13 +9,13 @@ dependencies { optional(project(":spring-context")) optional(project(":spring-web")) optional("org.eclipse.persistence:org.eclipse.persistence.jpa") - optional("org.hibernate:hibernate-core") - optional("javax.servlet:javax.servlet-api") + optional("org.hibernate:hibernate-core-jakarta") + optional("jakarta.servlet:jakarta.servlet-api") testImplementation(testFixtures(project(":spring-beans"))) testImplementation(testFixtures(project(":spring-context"))) testImplementation(testFixtures(project(":spring-core"))) testImplementation(testFixtures(project(":spring-web"))) testImplementation("org.aspectj:aspectjweaver") testImplementation("org.hsqldb:hsqldb") - testRuntimeOnly("javax.xml.bind:jaxb-api") + testRuntimeOnly("jakarta.xml.bind:jakarta.xml.bind-api") } diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/ConfigurableJtaPlatform.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/ConfigurableJtaPlatform.java index 839fe1777ca3..38265a6f1f9d 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/ConfigurableJtaPlatform.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/ConfigurableJtaPlatform.java @@ -16,14 +16,13 @@ package org.springframework.orm.hibernate5; -import javax.transaction.Status; -import javax.transaction.Synchronization; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; -import javax.transaction.TransactionSynchronizationRegistry; -import javax.transaction.UserTransaction; - +import jakarta.transaction.Status; +import jakarta.transaction.Synchronization; +import jakarta.transaction.SystemException; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; +import jakarta.transaction.TransactionSynchronizationRegistry; +import jakarta.transaction.UserTransaction; import org.hibernate.TransactionException; import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform; diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateExceptionTranslator.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateExceptionTranslator.java index bfd086eb626e..2f69163421f6 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateExceptionTranslator.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateExceptionTranslator.java @@ -16,8 +16,7 @@ package org.springframework.orm.hibernate5; -import javax.persistence.PersistenceException; - +import jakarta.persistence.PersistenceException; import org.hibernate.HibernateException; import org.hibernate.JDBCException; diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java index e624fca329af..dd2d7ff1fadb 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java @@ -25,8 +25,7 @@ import java.util.Iterator; import java.util.List; -import javax.persistence.PersistenceException; - +import jakarta.persistence.PersistenceException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.Criteria; diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java index 65990f3e8333..8d0001c57411 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java @@ -20,9 +20,9 @@ import java.sql.ResultSet; import java.util.function.Consumer; -import javax.persistence.PersistenceException; import javax.sql.DataSource; +import jakarta.persistence.PersistenceException; import org.hibernate.ConnectionReleaseMode; import org.hibernate.FlushMode; import org.hibernate.HibernateException; diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java index dc840bdfdc5c..eb8fc4acfebf 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java @@ -281,7 +281,7 @@ public void setPhysicalNamingStrategy(PhysicalNamingStrategy physicalNamingStrat /** * Set the Spring {@link org.springframework.transaction.jta.JtaTransactionManager} - * or the JTA {@link javax.transaction.TransactionManager} to be used with Hibernate, + * or the JTA {@link jakarta.transaction.TransactionManager} to be used with Hibernate, * if any. Implicitly sets up {@code JtaPlatform}. * @see LocalSessionFactoryBuilder#setJtaTransactionManager */ @@ -343,8 +343,8 @@ public Properties getHibernateProperties() { /** * Specify custom type filters for Spring-based scanning for entity classes. *

    Default is to search all specified packages for classes annotated with - * {@code @javax.persistence.Entity}, {@code @javax.persistence.Embeddable} - * or {@code @javax.persistence.MappedSuperclass}. + * {@code @jakarta.persistence.Entity}, {@code @jakarta.persistence.Embeddable} + * or {@code @jakarta.persistence.MappedSuperclass}. * @see #setPackagesToScan */ public void setEntityTypeFilters(TypeFilter... entityTypeFilters) { diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java index 9011db8fb55b..5fac7741cd22 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java @@ -28,14 +28,14 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import javax.persistence.AttributeConverter; -import javax.persistence.Converter; -import javax.persistence.Embeddable; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; import javax.sql.DataSource; -import javax.transaction.TransactionManager; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.persistence.MappedSuperclass; +import jakarta.transaction.TransactionManager; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.SessionFactory; @@ -269,8 +269,8 @@ public void setCurrentTenantIdentifierResolver(CurrentTenantIdentifierResolver c /** * Specify custom type filters for Spring-based scanning for entity classes. *

    Default is to search all specified packages for classes annotated with - * {@code @javax.persistence.Entity}, {@code @javax.persistence.Embeddable} - * or {@code @javax.persistence.MappedSuperclass}. + * {@code @jakarta.persistence.Entity}, {@code @jakarta.persistence.Embeddable} + * or {@code @jakarta.persistence.MappedSuperclass}. * @see #scanPackages */ public LocalSessionFactoryBuilder setEntityTypeFilters(TypeFilter... entityTypeFilters) { diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java index d3b61969aac0..32cf2bc90e72 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java @@ -19,9 +19,9 @@ import java.lang.reflect.Method; import java.util.Map; -import javax.persistence.PersistenceException; import javax.sql.DataSource; +import jakarta.persistence.PersistenceException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.HibernateException; diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java index 859abaf72841..a7a5e2f3d26a 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java @@ -16,10 +16,9 @@ package org.springframework.orm.hibernate5; -import javax.transaction.Status; -import javax.transaction.SystemException; -import javax.transaction.TransactionManager; - +import jakarta.transaction.Status; +import jakarta.transaction.SystemException; +import jakarta.transaction.TransactionManager; import org.apache.commons.logging.LogFactory; import org.hibernate.FlushMode; import org.hibernate.HibernateException; diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java index 3379e517c383..7c90bf31ba11 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java @@ -18,11 +18,10 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.hibernate.FlushMode; import org.hibernate.HibernateException; import org.hibernate.Session; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java index 4a787866287d..1a7328254610 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java @@ -34,15 +34,15 @@ import java.util.concurrent.Future; import java.util.function.Consumer; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.PersistenceException; -import javax.persistence.Query; -import javax.persistence.SynchronizationType; -import javax.persistence.spi.PersistenceProvider; -import javax.persistence.spi.PersistenceUnitInfo; import javax.sql.DataSource; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.PersistenceException; +import jakarta.persistence.Query; +import jakarta.persistence.SynchronizationType; +import jakarta.persistence.spi.PersistenceProvider; +import jakarta.persistence.spi.PersistenceUnitInfo; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -64,7 +64,7 @@ /** * Abstract {@link org.springframework.beans.factory.FactoryBean} that creates - * a local JPA {@link javax.persistence.EntityManagerFactory} instance within + * a local JPA {@link jakarta.persistence.EntityManagerFactory} instance within * a Spring application context. * *

    Encapsulates the common functionality between the different JPA bootstrap @@ -149,8 +149,8 @@ public abstract class AbstractEntityManagerFactoryBean implements * taken from the JpaVendorAdapter (if any) or retrieved through scanning * (as far as possible). * @see JpaVendorAdapter#getPersistenceProvider() - * @see javax.persistence.spi.PersistenceProvider - * @see javax.persistence.Persistence + * @see jakarta.persistence.spi.PersistenceProvider + * @see jakarta.persistence.Persistence */ public void setPersistenceProviderClass(Class persistenceProviderClass) { this.persistenceProvider = BeanUtils.instantiateClass(persistenceProviderClass); @@ -162,8 +162,8 @@ public void setPersistenceProviderClass(Class per * will be taken from the JpaVendorAdapter (if any) or determined * by the persistence unit deployment descriptor (as far as possible). * @see JpaVendorAdapter#getPersistenceProvider() - * @see javax.persistence.spi.PersistenceProvider - * @see javax.persistence.Persistence + * @see jakarta.persistence.spi.PersistenceProvider + * @see jakarta.persistence.Persistence */ public void setPersistenceProvider(@Nullable PersistenceProvider persistenceProvider) { this.persistenceProvider = persistenceProvider; @@ -180,7 +180,7 @@ public PersistenceProvider getPersistenceProvider() { *

    Default is none, indicating the default EntityManagerFactory * configuration. The persistence provider will throw an exception if * ambiguous EntityManager configurations are found. - * @see javax.persistence.Persistence#createEntityManagerFactory(String) + * @see jakarta.persistence.Persistence#createEntityManagerFactory(String) */ public void setPersistenceUnitName(@Nullable String persistenceUnitName) { this.persistenceUnitName = persistenceUnitName; @@ -197,8 +197,8 @@ public String getPersistenceUnitName() { * {@code Persistence.createEntityManagerFactory} (if any). *

    Can be populated with a String "value" (parsed via PropertiesEditor) or a * "props" element in XML bean definitions. - * @see javax.persistence.Persistence#createEntityManagerFactory(String, Map) - * @see javax.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory(PersistenceUnitInfo, Map) + * @see jakarta.persistence.Persistence#createEntityManagerFactory(String, Map) + * @see jakarta.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory(PersistenceUnitInfo, Map) */ public void setJpaProperties(Properties jpaProperties) { CollectionUtils.mergePropertiesIntoMap(jpaProperties, this.jpaPropertyMap); @@ -208,8 +208,8 @@ public void setJpaProperties(Properties jpaProperties) { * Specify JPA properties as a Map, to be passed into * {@code Persistence.createEntityManagerFactory} (if any). *

    Can be populated with a "map" or "props" element in XML bean definitions. - * @see javax.persistence.Persistence#createEntityManagerFactory(String, Map) - * @see javax.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory(PersistenceUnitInfo, Map) + * @see jakarta.persistence.Persistence#createEntityManagerFactory(String, Map) + * @see jakarta.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory(PersistenceUnitInfo, Map) */ public void setJpaPropertyMap(@Nullable Map jpaProperties) { if (jpaProperties != null) { @@ -231,7 +231,7 @@ public Map getJpaPropertyMap() { * Specify the (potentially vendor-specific) EntityManagerFactory interface * that this EntityManagerFactory proxy is supposed to implement. *

    The default will be taken from the specific JpaVendorAdapter, if any, - * or set to the standard {@code javax.persistence.EntityManagerFactory} + * or set to the standard {@code jakarta.persistence.EntityManagerFactory} * interface else. * @see JpaVendorAdapter#getEntityManagerFactoryInterface() */ @@ -243,7 +243,7 @@ public void setEntityManagerFactoryInterface(ClassThe default will be taken from the specific JpaVendorAdapter, if any, - * or set to the standard {@code javax.persistence.EntityManager} + * or set to the standard {@code jakarta.persistence.EntityManager} * interface else. * @see JpaVendorAdapter#getEntityManagerInterface() * @see EntityManagerFactoryInfo#getEntityManagerInterface() @@ -468,7 +468,7 @@ else if (emf != null) { if (entityManagerFactoryInterface != null) { throw new IllegalStateException("EntityManagerFactory interface [" + entityManagerFactoryInterface + "] seems to conflict with Spring's EntityManagerFactoryInfo mixin - consider resetting the "+ - "'entityManagerFactoryInterface' property to plain [javax.persistence.EntityManagerFactory]", ex); + "'entityManagerFactoryInterface' property to plain [jakarta.persistence.EntityManagerFactory]", ex); } else { throw new IllegalStateException("Conflicting EntityManagerFactory interfaces - " + diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/DefaultJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/DefaultJpaDialect.java index 7fe2d71eeffb..d78a2f79948b 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/DefaultJpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/DefaultJpaDialect.java @@ -19,8 +19,8 @@ import java.io.Serializable; import java.sql.SQLException; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceException; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceException; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.datasource.ConnectionHandle; @@ -53,7 +53,7 @@ public class DefaultJpaDialect implements JpaDialect, Serializable { * is no state to be kept for a standard JPA transaction. Hence, subclasses do not * have to care about the return value ({@code null}) of this implementation * and are free to return their own transaction data Object. - * @see javax.persistence.EntityTransaction#begin + * @see jakarta.persistence.EntityTransaction#begin * @see org.springframework.transaction.InvalidIsolationLevelException * @see #cleanupTransaction */ diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryAccessor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryAccessor.java index b7ca9b83cd06..5f73add85814 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryAccessor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryAccessor.java @@ -20,9 +20,8 @@ import java.util.Map; import java.util.Properties; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -59,8 +58,8 @@ public abstract class EntityManagerFactoryAccessor implements BeanFactoryAware { /** * Set the JPA EntityManagerFactory that should be used to create * EntityManagers. - * @see javax.persistence.EntityManagerFactory#createEntityManager() - * @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map) + * @see jakarta.persistence.EntityManagerFactory#createEntityManager() + * @see jakarta.persistence.EntityManagerFactory#createEntityManager(java.util.Map) */ public void setEntityManagerFactory(@Nullable EntityManagerFactory emf) { this.entityManagerFactory = emf; @@ -112,7 +111,7 @@ public String getPersistenceUnitName() { * {@code EntityManagerFactory.createEntityManager(Map)} (if any). *

    Can be populated with a String "value" (parsed via PropertiesEditor) * or a "props" element in XML bean definitions. - * @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map) + * @see jakarta.persistence.EntityManagerFactory#createEntityManager(java.util.Map) */ public void setJpaProperties(Properties jpaProperties) { CollectionUtils.mergePropertiesIntoMap(jpaProperties, this.jpaPropertyMap); @@ -122,7 +121,7 @@ public void setJpaProperties(Properties jpaProperties) { * Specify JPA properties as a Map, to be passed into * {@code EntityManagerFactory.createEntityManager(Map)} (if any). *

    Can be populated with a "map" or "props" element in XML bean definitions. - * @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map) + * @see jakarta.persistence.EntityManagerFactory#createEntityManager(java.util.Map) */ public void setJpaPropertyMap(@Nullable Map jpaProperties) { if (jpaProperties != null) { @@ -162,8 +161,8 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException { *

    Can be overridden in subclasses to create specific EntityManager variants. * @return a new EntityManager * @throws IllegalStateException if this accessor is not configured with an EntityManagerFactory - * @see javax.persistence.EntityManagerFactory#createEntityManager() - * @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map) + * @see jakarta.persistence.EntityManagerFactory#createEntityManager() + * @see jakarta.persistence.EntityManagerFactory#createEntityManager(java.util.Map) */ protected EntityManager createEntityManager() throws IllegalStateException { EntityManagerFactory emf = obtainEntityManagerFactory(); @@ -175,8 +174,8 @@ protected EntityManager createEntityManager() throws IllegalStateException { * Obtain the transactional EntityManager for this accessor's EntityManagerFactory, if any. * @return the transactional EntityManager, or {@code null} if none * @throws IllegalStateException if this accessor is not configured with an EntityManagerFactory - * @see EntityManagerFactoryUtils#getTransactionalEntityManager(javax.persistence.EntityManagerFactory) - * @see EntityManagerFactoryUtils#getTransactionalEntityManager(javax.persistence.EntityManagerFactory, java.util.Map) + * @see EntityManagerFactoryUtils#getTransactionalEntityManager(jakarta.persistence.EntityManagerFactory) + * @see EntityManagerFactoryUtils#getTransactionalEntityManager(jakarta.persistence.EntityManagerFactory, java.util.Map) */ @Nullable protected EntityManager getTransactionalEntityManager() throws IllegalStateException{ diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryInfo.java b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryInfo.java index 2b4d72159b4d..cdb9dda3ce55 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryInfo.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryInfo.java @@ -18,12 +18,13 @@ import java.util.Map; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.spi.PersistenceProvider; -import javax.persistence.spi.PersistenceUnitInfo; import javax.sql.DataSource; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.spi.PersistenceProvider; +import jakarta.persistence.spi.PersistenceUnitInfo; + import org.springframework.lang.Nullable; /** @@ -65,7 +66,7 @@ public interface EntityManagerFactoryInfo { * {@code getPersistenceUnitName()} must be equal to the value returned by * {@code PersistenceUnitInfo.getPersistenceUnitName()}. * @see #getPersistenceUnitInfo() - * @see javax.persistence.spi.PersistenceUnitInfo#getPersistenceUnitName() + * @see jakarta.persistence.spi.PersistenceUnitInfo#getPersistenceUnitName() */ @Nullable String getPersistenceUnitName(); @@ -83,7 +84,7 @@ public interface EntityManagerFactoryInfo { * that this factory's EntityManagers will implement. *

    A {@code null} return value suggests that autodetection is supposed * to happen: either based on a target {@code EntityManager} instance - * or simply defaulting to {@code javax.persistence.EntityManager}. + * or simply defaulting to {@code jakarta.persistence.EntityManager}. */ @Nullable Class getEntityManagerInterface(); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java index e8fb5e15fb8c..2bf679271249 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java @@ -18,21 +18,20 @@ import java.util.Map; -import javax.persistence.EntityExistsException; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityNotFoundException; -import javax.persistence.LockTimeoutException; -import javax.persistence.NoResultException; -import javax.persistence.NonUniqueResultException; -import javax.persistence.OptimisticLockException; -import javax.persistence.PersistenceException; -import javax.persistence.PessimisticLockException; -import javax.persistence.Query; -import javax.persistence.QueryTimeoutException; -import javax.persistence.SynchronizationType; -import javax.persistence.TransactionRequiredException; - +import jakarta.persistence.EntityExistsException; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityNotFoundException; +import jakarta.persistence.LockTimeoutException; +import jakarta.persistence.NoResultException; +import jakarta.persistence.NonUniqueResultException; +import jakarta.persistence.OptimisticLockException; +import jakarta.persistence.PersistenceException; +import jakarta.persistence.PessimisticLockException; +import jakarta.persistence.Query; +import jakarta.persistence.QueryTimeoutException; +import jakarta.persistence.SynchronizationType; +import jakarta.persistence.TransactionRequiredException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -168,8 +167,8 @@ public static EntityManager getTransactionalEntityManager(EntityManagerFactory e * @param properties the properties to be passed into the {@code createEntityManager} * call (may be {@code null}) * @return the EntityManager, or {@code null} if none found - * @throws javax.persistence.PersistenceException if the EntityManager couldn't be created - * @see #getTransactionalEntityManager(javax.persistence.EntityManagerFactory) + * @throws jakarta.persistence.PersistenceException if the EntityManager couldn't be created + * @see #getTransactionalEntityManager(jakarta.persistence.EntityManagerFactory) * @see JpaTransactionManager */ @Nullable @@ -189,8 +188,8 @@ public static EntityManager doGetTransactionalEntityManager(EntityManagerFactory * @param synchronizedWithTransaction whether to automatically join ongoing * transactions (according to the JPA 2.1 SynchronizationType rules) * @return the EntityManager, or {@code null} if none found - * @throws javax.persistence.PersistenceException if the EntityManager couldn't be created - * @see #getTransactionalEntityManager(javax.persistence.EntityManagerFactory) + * @throws jakarta.persistence.PersistenceException if the EntityManager couldn't be created + * @see #getTransactionalEntityManager(jakarta.persistence.EntityManagerFactory) * @see JpaTransactionManager */ @Nullable @@ -334,7 +333,7 @@ private static void cleanupTransaction(@Nullable Object transactionData, EntityM /** * Apply the current transaction timeout, if any, to the given JPA Query object. - *

    This method sets the JPA 2.0 query hint "javax.persistence.query.timeout" accordingly. + *

    This method sets the JPA 2.0 query hint "jakarta.persistence.query.timeout" accordingly. * @param query the JPA Query object * @param emf the JPA EntityManagerFactory that the Query was created for */ @@ -343,7 +342,7 @@ public static void applyTransactionTimeout(Query query, EntityManagerFactory emf if (emHolder != null && emHolder.hasTimeout()) { int timeoutValue = (int) emHolder.getTimeToLiveInMillis(); try { - query.setHint("javax.persistence.query.timeout", timeoutValue); + query.setHint("jakarta.persistence.query.timeout", timeoutValue); } catch (IllegalArgumentException ex) { // oh well, at least we tried... @@ -418,7 +417,7 @@ public static DataAccessException convertJpaAccessExceptionIfPossible(RuntimeExc * Close the given JPA EntityManager, * catching and logging any cleanup exceptions thrown. * @param em the JPA EntityManager to close (may be {@code null}) - * @see javax.persistence.EntityManager#close() + * @see jakarta.persistence.EntityManager#close() */ public static void closeEntityManager(@Nullable EntityManager em) { if (em != null) { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerHolder.java b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerHolder.java index 512cac8fe9c2..cc72652674dd 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerHolder.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerHolder.java @@ -16,7 +16,7 @@ package org.springframework.orm.jpa; -import javax.persistence.EntityManager; +import jakarta.persistence.EntityManager; import org.springframework.lang.Nullable; import org.springframework.transaction.SavepointManager; @@ -26,7 +26,7 @@ /** * Resource holder wrapping a JPA {@link EntityManager}. * {@link JpaTransactionManager} binds instances of this class to the thread, - * for a given {@link javax.persistence.EntityManagerFactory}. + * for a given {@link jakarta.persistence.EntityManagerFactory}. * *

    Also serves as a base class for {@link org.springframework.orm.hibernate5.SessionHolder}, * as of 5.1. diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerProxy.java b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerProxy.java index 84e574d538f1..704b60d234cd 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerProxy.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerProxy.java @@ -16,14 +16,14 @@ package org.springframework.orm.jpa; -import javax.persistence.EntityManager; +import jakarta.persistence.EntityManager; /** - * Subinterface of {@link javax.persistence.EntityManager} to be implemented by + * Subinterface of {@link jakarta.persistence.EntityManager} to be implemented by * EntityManager proxies. Allows access to the underlying target EntityManager. * *

    This interface is mainly intended for framework usage. Application code - * should prefer the use of the {@link javax.persistence.EntityManager#getDelegate()} + * should prefer the use of the {@link jakarta.persistence.EntityManager#getDelegate()} * method to access native functionality of the underlying resource. * * @author Juergen Hoeller diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java b/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java index 8e9173a94bfd..29b7a008ca93 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java @@ -25,13 +25,12 @@ import java.util.Map; import java.util.Set; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.TransactionRequiredException; -import javax.persistence.spi.PersistenceUnitInfo; -import javax.persistence.spi.PersistenceUnitTransactionType; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityTransaction; +import jakarta.persistence.TransactionRequiredException; +import jakarta.persistence.spi.PersistenceUnitInfo; +import jakarta.persistence.spi.PersistenceUnitTransactionType; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -47,14 +46,14 @@ import org.springframework.util.ConcurrentReferenceHashMap; /** - * Delegate for creating a variety of {@link javax.persistence.EntityManager} + * Delegate for creating a variety of {@link jakarta.persistence.EntityManager} * proxies that follow the JPA spec's semantics for "extended" EntityManagers. * *

    Supports several different variants of "extended" EntityManagers: * in particular, an "application-managed extended EntityManager", as defined - * by {@link javax.persistence.EntityManagerFactory#createEntityManager()}, + * by {@link jakarta.persistence.EntityManagerFactory#createEntityManager()}, * as well as a "container-managed extended EntityManager", as defined by - * {@link javax.persistence.PersistenceContextType#EXTENDED}. + * {@link jakarta.persistence.PersistenceContextType#EXTENDED}. * *

    The original difference between "application-managed" and "container-managed" * was the need for explicit joining of an externally managed transaction through @@ -69,9 +68,9 @@ * @author Rod Johnson * @author Mark Paluch * @since 2.0 - * @see javax.persistence.EntityManagerFactory#createEntityManager() - * @see javax.persistence.PersistenceContextType#EXTENDED - * @see javax.persistence.EntityManager#joinTransaction() + * @see jakarta.persistence.EntityManagerFactory#createEntityManager() + * @see jakarta.persistence.PersistenceContextType#EXTENDED + * @see jakarta.persistence.EntityManager#joinTransaction() * @see SharedEntityManagerCreator */ public abstract class ExtendedEntityManagerCreator { @@ -131,7 +130,7 @@ public static EntityManager createContainerManagedEntityManager( * JpaDialect and PersistenceUnitInfo will be detected accordingly. * @return a container-managed EntityManager that will automatically participate * in any managed transaction - * @see javax.persistence.EntityManagerFactory#createEntityManager() + * @see jakarta.persistence.EntityManagerFactory#createEntityManager() */ public static EntityManager createContainerManagedEntityManager(EntityManagerFactory emf) { return createContainerManagedEntityManager(emf, null, true); @@ -146,7 +145,7 @@ public static EntityManager createContainerManagedEntityManager(EntityManagerFac * call (may be {@code null}) * @return a container-managed EntityManager that will automatically participate * in any managed transaction - * @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map) + * @see jakarta.persistence.EntityManagerFactory#createEntityManager(java.util.Map) */ public static EntityManager createContainerManagedEntityManager(EntityManagerFactory emf, @Nullable Map properties) { return createContainerManagedEntityManager(emf, properties, true); @@ -164,7 +163,7 @@ public static EntityManager createContainerManagedEntityManager(EntityManagerFac * @return a container-managed EntityManager that expects container-driven lifecycle * management but may opt out of automatic transaction synchronization * @since 4.0 - * @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map) + * @see jakarta.persistence.EntityManagerFactory#createEntityManager(java.util.Map) */ public static EntityManager createContainerManagedEntityManager( EntityManagerFactory emf, @Nullable Map properties, boolean synchronizedWithTransaction) { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaDialect.java index 9ef53884a49f..b2c172b453f2 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaDialect.java @@ -18,8 +18,8 @@ import java.sql.SQLException; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceException; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.jdbc.datasource.ConnectionHandle; @@ -73,11 +73,11 @@ public interface JpaDialect extends PersistenceExceptionTranslator { * @return an arbitrary object that holds transaction data, if any * (to be passed into {@link #cleanupTransaction}). May implement the * {@link org.springframework.transaction.SavepointManager} interface. - * @throws javax.persistence.PersistenceException if thrown by JPA methods + * @throws jakarta.persistence.PersistenceException if thrown by JPA methods * @throws java.sql.SQLException if thrown by JDBC methods * @throws org.springframework.transaction.TransactionException in case of invalid arguments * @see #cleanupTransaction - * @see javax.persistence.EntityTransaction#begin + * @see jakarta.persistence.EntityTransaction#begin * @see org.springframework.jdbc.datasource.DataSourceUtils#prepareConnectionForTransaction */ @Nullable @@ -100,7 +100,7 @@ Object beginTransaction(EntityManager entityManager, TransactionDefinition defin * @param name the name of the transaction (if any) * @return an arbitrary object that holds transaction data, if any * (to be passed into cleanupTransaction) - * @throws javax.persistence.PersistenceException if thrown by JPA methods + * @throws jakarta.persistence.PersistenceException if thrown by JPA methods * @see #cleanupTransaction */ @Nullable @@ -143,7 +143,7 @@ Object prepareTransaction(EntityManager entityManager, boolean readOnly, @Nullab * @param readOnly whether the Connection is only needed for read-only purposes * @return a handle for the Connection, to be passed into {@code releaseJdbcConnection}, * or {@code null} if no JDBC Connection can be retrieved - * @throws javax.persistence.PersistenceException if thrown by JPA methods + * @throws jakarta.persistence.PersistenceException if thrown by JPA methods * @throws java.sql.SQLException if thrown by JDBC methods * @see #releaseJdbcConnection * @see org.springframework.jdbc.datasource.ConnectionHandle#getConnection @@ -163,7 +163,7 @@ ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly * transaction completes or when the EntityManager is closed. * @param conHandle the JDBC Connection handle to release * @param entityManager the current JPA EntityManager - * @throws javax.persistence.PersistenceException if thrown by JPA methods + * @throws jakarta.persistence.PersistenceException if thrown by JPA methods * @throws java.sql.SQLException if thrown by JDBC methods * @see #getJdbcConnection */ diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaObjectRetrievalFailureException.java b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaObjectRetrievalFailureException.java index 26e51471682b..20bb6ba841be 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaObjectRetrievalFailureException.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaObjectRetrievalFailureException.java @@ -16,7 +16,7 @@ package org.springframework.orm.jpa; -import javax.persistence.EntityNotFoundException; +import jakarta.persistence.EntityNotFoundException; import org.springframework.orm.ObjectRetrievalFailureException; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaOptimisticLockingFailureException.java b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaOptimisticLockingFailureException.java index 89b6bfcce5cf..a6eb2d1c4462 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaOptimisticLockingFailureException.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaOptimisticLockingFailureException.java @@ -16,7 +16,7 @@ package org.springframework.orm.jpa; -import javax.persistence.OptimisticLockException; +import jakarta.persistence.OptimisticLockException; import org.springframework.orm.ObjectOptimisticLockingFailureException; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaTransactionManager.java b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaTransactionManager.java index 2746339bc626..79e48b7d0f32 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaTransactionManager.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaTransactionManager.java @@ -21,13 +21,14 @@ import java.util.Properties; import java.util.function.Consumer; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.PersistenceException; -import javax.persistence.RollbackException; import javax.sql.DataSource; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityTransaction; +import jakarta.persistence.PersistenceException; +import jakarta.persistence.RollbackException; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -58,7 +59,7 @@ /** * {@link org.springframework.transaction.PlatformTransactionManager} implementation - * for a single JPA {@link javax.persistence.EntityManagerFactory}. Binds a JPA + * for a single JPA {@link jakarta.persistence.EntityManagerFactory}. Binds a JPA * EntityManager from the specified factory to the thread, potentially allowing for * one thread-bound EntityManager per factory. {@link SharedEntityManagerCreator} and * {@code @PersistenceContext} are aware of thread-bound entity managers and participate @@ -209,7 +210,7 @@ public String getPersistenceUnitName() { * {@code EntityManagerFactory.createEntityManager(Map)} (if any). *

    Can be populated with a String "value" (parsed via PropertiesEditor) * or a "props" element in XML bean definitions. - * @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map) + * @see jakarta.persistence.EntityManagerFactory#createEntityManager(java.util.Map) */ public void setJpaProperties(@Nullable Properties jpaProperties) { CollectionUtils.mergePropertiesIntoMap(jpaProperties, this.jpaPropertyMap); @@ -219,7 +220,7 @@ public void setJpaProperties(@Nullable Properties jpaProperties) { * Specify JPA properties as a Map, to be passed into * {@code EntityManagerFactory.createEntityManager(Map)} (if any). *

    Can be populated with a "map" or "props" element in XML bean definitions. - * @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map) + * @see jakarta.persistence.EntityManagerFactory#createEntityManager(java.util.Map) */ public void setJpaPropertyMap(@Nullable Map jpaProperties) { if (jpaProperties != null) { @@ -475,7 +476,7 @@ protected void doBegin(Object transaction, TransactionDefinition definition) { * {@link EntityManagerFactoryInfo#createNativeEntityManager} * if possible which in turns applies * {@link JpaVendorAdapter#postProcessEntityManager(EntityManager)}. - * @see javax.persistence.EntityManagerFactory#createEntityManager() + * @see jakarta.persistence.EntityManagerFactory#createEntityManager() */ protected EntityManager createEntityManagerForTransaction() { EntityManagerFactory emf = obtainEntityManagerFactory(); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaVendorAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaVendorAdapter.java index 4d283283a3e7..7ea555d6d77d 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaVendorAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaVendorAdapter.java @@ -19,10 +19,10 @@ import java.util.Collections; import java.util.Map; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.spi.PersistenceProvider; -import javax.persistence.spi.PersistenceUnitInfo; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.spi.PersistenceProvider; +import jakarta.persistence.spi.PersistenceUnitInfo; import org.springframework.lang.Nullable; @@ -64,10 +64,10 @@ default String getPersistenceProviderRootPackage() { * non-unit-dependent properties. Effectively, this PersistenceUnitInfo-based * variant only needs to be implemented if there is an actual need to react * to unit-specific characteristics such as the transaction type. - *

    NOTE: This variant will only be invoked in case of Java EE style + *

    NOTE: This variant will only be invoked in case of Jakarta EE style * container bootstrapping where a {@link PersistenceUnitInfo} is present * (i.e. {@link LocalContainerEntityManagerFactoryBean}. In case of simple - * Java SE style bootstrapping via {@link javax.persistence.Persistence} + * Java SE style bootstrapping via {@link jakarta.persistence.Persistence} * (i.e. {@link LocalEntityManagerFactoryBean}), the parameter-less * {@link #getJpaPropertyMap()} variant will be called directly. * @param pui the PersistenceUnitInfo for the current persistence unit @@ -75,7 +75,7 @@ default String getPersistenceProviderRootPackage() { * facilities, or an empty Map if there are no properties to expose * @since 4.3.13 * @see PersistenceUnitInfo#getTransactionType() - * @see javax.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory(PersistenceUnitInfo, Map) + * @see jakarta.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory(PersistenceUnitInfo, Map) */ default Map getJpaPropertyMap(PersistenceUnitInfo pui) { return getJpaPropertyMap(); @@ -89,7 +89,7 @@ default String getPersistenceProviderRootPackage() { * JPA property values specified here. * @return a Map of JPA properties, as accepted by the standard JPA bootstrap * facilities, or an empty Map if there are no properties to expose - * @see javax.persistence.Persistence#createEntityManagerFactory(String, Map) + * @see jakarta.persistence.Persistence#createEntityManagerFactory(String, Map) */ default Map getJpaPropertyMap() { return Collections.emptyMap(); @@ -109,7 +109,7 @@ default JpaDialect getJpaDialect() { * that the EntityManagerFactory proxy is supposed to implement. *

    If the provider does not offer any EntityManagerFactory extensions, * the adapter should simply return the standard - * {@link javax.persistence.EntityManagerFactory} class here. + * {@link jakarta.persistence.EntityManagerFactory} class here. * @since 2.5.2 */ default Class getEntityManagerFactoryInterface() { @@ -121,7 +121,7 @@ default Class getEntityManagerFactoryInterface() * that this provider's EntityManagers will implement. *

    If the provider does not offer any EntityManager extensions, * the adapter should simply return the standard - * {@link javax.persistence.EntityManager} class here. + * {@link jakarta.persistence.EntityManager} class here. */ default Class getEntityManagerInterface() { return EntityManager.class; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java index 6fc17b5c5fdc..3ec01ff8d847 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java @@ -16,14 +16,15 @@ package org.springframework.orm.jpa; -import javax.persistence.EntityManagerFactory; -import javax.persistence.PersistenceException; -import javax.persistence.SharedCacheMode; -import javax.persistence.ValidationMode; -import javax.persistence.spi.PersistenceProvider; -import javax.persistence.spi.PersistenceUnitInfo; import javax.sql.DataSource; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.PersistenceException; +import jakarta.persistence.SharedCacheMode; +import jakarta.persistence.ValidationMode; +import jakarta.persistence.spi.PersistenceProvider; +import jakarta.persistence.spi.PersistenceUnitInfo; + import org.springframework.beans.BeanUtils; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.weaving.LoadTimeWeaverAware; @@ -40,7 +41,7 @@ /** * {@link org.springframework.beans.factory.FactoryBean} that creates a JPA - * {@link javax.persistence.EntityManagerFactory} according to JPA's standard + * {@link jakarta.persistence.EntityManagerFactory} according to JPA's standard * container bootstrap contract. This is the most powerful way to set * up a shared JPA EntityManagerFactory in a Spring application context; * the EntityManagerFactory can then be passed to JPA-based DAOs via @@ -58,10 +59,10 @@ * instead of being tied to a special VM agent specified on JVM startup. * *

    Internally, this FactoryBean parses the {@code persistence.xml} file - * itself and creates a corresponding {@link javax.persistence.spi.PersistenceUnitInfo} + * itself and creates a corresponding {@link jakarta.persistence.spi.PersistenceUnitInfo} * object (with further configuration merged in, such as JDBC DataSources and the * Spring LoadTimeWeaver), to be passed to the chosen JPA - * {@link javax.persistence.spi.PersistenceProvider}. This corresponds to a + * {@link jakarta.persistence.spi.PersistenceProvider}. This corresponds to a * local JPA container with full support for the standard JPA container contract. * *

    The exposed EntityManagerFactory object will implement all the interfaces of @@ -84,7 +85,7 @@ * @see EntityManagerFactoryInfo * @see LocalEntityManagerFactoryBean * @see org.springframework.orm.jpa.support.SharedEntityManagerBean - * @see javax.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory + * @see jakarta.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory */ @SuppressWarnings("serial") public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean @@ -220,7 +221,7 @@ public void setMappingResources(String... mappingResources) { * overriding a value in {@code persistence.xml} if set. *

    NOTE: Only applied if no external PersistenceUnitManager specified. * @since 4.0 - * @see javax.persistence.spi.PersistenceUnitInfo#getSharedCacheMode() + * @see jakarta.persistence.spi.PersistenceUnitInfo#getSharedCacheMode() * @see #setPersistenceUnitManager */ public void setSharedCacheMode(SharedCacheMode sharedCacheMode) { @@ -232,7 +233,7 @@ public void setSharedCacheMode(SharedCacheMode sharedCacheMode) { * overriding a value in {@code persistence.xml} if set. *

    NOTE: Only applied if no external PersistenceUnitManager specified. * @since 4.0 - * @see javax.persistence.spi.PersistenceUnitInfo#getValidationMode() + * @see jakarta.persistence.spi.PersistenceUnitInfo#getValidationMode() * @see #setPersistenceUnitManager */ public void setValidationMode(ValidationMode validationMode) { @@ -250,7 +251,7 @@ public void setValidationMode(ValidationMode validationMode) { * Note that this variant typically works for JTA transaction management as well; * if it does not, consider using the explicit {@link #setJtaDataSource} instead. *

    NOTE: Only applied if no external PersistenceUnitManager specified. - * @see javax.persistence.spi.PersistenceUnitInfo#getNonJtaDataSource() + * @see jakarta.persistence.spi.PersistenceUnitInfo#getNonJtaDataSource() * @see #setPersistenceUnitManager */ public void setDataSource(DataSource dataSource) { @@ -267,7 +268,7 @@ public void setDataSource(DataSource dataSource) { * on the PersistenceUnitInfo passed to the PersistenceProvider, as well as * overriding data source configuration in {@code persistence.xml} (if any). *

    NOTE: Only applied if no external PersistenceUnitManager specified. - * @see javax.persistence.spi.PersistenceUnitInfo#getJtaDataSource() + * @see jakarta.persistence.spi.PersistenceUnitInfo#getJtaDataSource() * @see #setPersistenceUnitManager */ public void setJtaDataSource(DataSource jtaDataSource) { @@ -394,7 +395,7 @@ protected PersistenceUnitInfo determinePersistenceUnitInfo(PersistenceUnitManage *

    The default implementation is empty. * @param emf the newly created EntityManagerFactory we are working with * @param pui the PersistenceUnitInfo used to configure the EntityManagerFactory - * @see javax.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory + * @see jakarta.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory */ protected void postProcessEntityManagerFactory(EntityManagerFactory emf, PersistenceUnitInfo pui) { } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java index dcc9961f55c0..10e528cee583 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java @@ -16,14 +16,14 @@ package org.springframework.orm.jpa; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import javax.persistence.PersistenceException; -import javax.persistence.spi.PersistenceProvider; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; +import jakarta.persistence.PersistenceException; +import jakarta.persistence.spi.PersistenceProvider; /** * {@link org.springframework.beans.factory.FactoryBean} that creates a JPA - * {@link javax.persistence.EntityManagerFactory} according to JPA's standard + * {@link jakarta.persistence.EntityManagerFactory} according to JPA's standard * standalone bootstrap contract. This is the simplest way to set up a * shared JPA EntityManagerFactory in a Spring application context; the * EntityManagerFactory can then be passed to JPA-based DAOs via @@ -41,7 +41,7 @@ *

    This EntityManagerFactory bootstrap is appropriate for standalone applications * which solely use JPA for data access. If you want to set up your persistence * provider for an external DataSource and/or for global transactions which span - * multiple resources, you will need to either deploy it into a full Java EE + * multiple resources, you will need to either deploy it into a full Jakarta EE * application server and access the deployed EntityManagerFactory via JNDI, * or use Spring's {@link LocalContainerEntityManagerFactoryBean} with appropriate * configuration for local setup according to JPA's container contract. @@ -65,15 +65,15 @@ * @see LocalContainerEntityManagerFactoryBean * @see org.springframework.jndi.JndiObjectFactoryBean * @see org.springframework.orm.jpa.support.SharedEntityManagerBean - * @see javax.persistence.Persistence#createEntityManagerFactory - * @see javax.persistence.spi.PersistenceProvider#createEntityManagerFactory + * @see jakarta.persistence.Persistence#createEntityManagerFactory + * @see jakarta.persistence.spi.PersistenceProvider#createEntityManagerFactory */ @SuppressWarnings("serial") public class LocalEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean { /** * Initialize the EntityManagerFactory for the given configuration. - * @throws javax.persistence.PersistenceException in case of JPA initialization errors + * @throws jakarta.persistence.PersistenceException in case of JPA initialization errors */ @Override protected EntityManagerFactory createNativeEntityManagerFactory() throws PersistenceException { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java index 5b109cf89864..26add517b036 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java @@ -28,13 +28,12 @@ import java.util.Map; import java.util.Set; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.ParameterMode; -import javax.persistence.Query; -import javax.persistence.StoredProcedureQuery; -import javax.persistence.TransactionRequiredException; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.ParameterMode; +import jakarta.persistence.Query; +import jakarta.persistence.StoredProcedureQuery; +import jakarta.persistence.TransactionRequiredException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -45,8 +44,8 @@ import org.springframework.util.ConcurrentReferenceHashMap; /** - * Delegate for creating a shareable JPA {@link javax.persistence.EntityManager} - * reference for a given {@link javax.persistence.EntityManagerFactory}. + * Delegate for creating a shareable JPA {@link jakarta.persistence.EntityManager} + * reference for a given {@link jakarta.persistence.EntityManagerFactory}. * *

    A shared EntityManager will behave just like an EntityManager fetched from * an application server's JNDI environment, as defined by the JPA specification. @@ -54,17 +53,17 @@ * otherwise it will fall back to a newly created EntityManager per operation. * *

    For a behavioral definition of such a shared transactional EntityManager, - * see {@link javax.persistence.PersistenceContextType#TRANSACTION} and its + * see {@link jakarta.persistence.PersistenceContextType#TRANSACTION} and its * discussion in the JPA spec document. This is also the default being used - * for the annotation-based {@link javax.persistence.PersistenceContext#type()}. + * for the annotation-based {@link jakarta.persistence.PersistenceContext#type()}. * * @author Juergen Hoeller * @author Rod Johnson * @author Oliver Gierke * @author Mark Paluch * @since 2.0 - * @see javax.persistence.PersistenceContext - * @see javax.persistence.PersistenceContextType#TRANSACTION + * @see jakarta.persistence.PersistenceContext + * @see jakarta.persistence.PersistenceContextType#TRANSACTION * @see org.springframework.orm.jpa.JpaTransactionManager * @see ExtendedEntityManagerCreator */ diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/ClassFileTransformerAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/ClassFileTransformerAdapter.java index 162e886c2db2..0654e12c3d9e 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/ClassFileTransformerAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/ClassFileTransformerAdapter.java @@ -19,8 +19,7 @@ import java.lang.instrument.ClassFileTransformer; import java.security.ProtectionDomain; -import javax.persistence.spi.ClassTransformer; - +import jakarta.persistence.spi.ClassTransformer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -35,7 +34,7 @@ * @author Rod Johnson * @author Juergen Hoeller * @since 2.0 - * @see javax.persistence.spi.PersistenceUnitInfo#addTransformer(javax.persistence.spi.ClassTransformer) + * @see jakarta.persistence.spi.PersistenceUnitInfo#addTransformer(jakarta.persistence.spi.ClassTransformer) */ class ClassFileTransformerAdapter implements ClassFileTransformer { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java index 8e2fd410d54b..c16527b6153d 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java @@ -26,16 +26,16 @@ import java.util.Map; import java.util.Set; -import javax.persistence.Converter; -import javax.persistence.Embeddable; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; -import javax.persistence.PersistenceException; -import javax.persistence.SharedCacheMode; -import javax.persistence.ValidationMode; -import javax.persistence.spi.PersistenceUnitInfo; import javax.sql.DataSource; +import jakarta.persistence.Converter; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.persistence.MappedSuperclass; +import jakarta.persistence.PersistenceException; +import jakarta.persistence.SharedCacheMode; +import jakarta.persistence.ValidationMode; +import jakarta.persistence.spi.PersistenceUnitInfo; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -274,7 +274,7 @@ public void setMappingResources(String... mappingResources) { * Specify the JPA 2.0 shared cache mode for all of this manager's persistence * units, overriding any value in {@code persistence.xml} if set. * @since 4.0 - * @see javax.persistence.spi.PersistenceUnitInfo#getSharedCacheMode() + * @see jakarta.persistence.spi.PersistenceUnitInfo#getSharedCacheMode() */ public void setSharedCacheMode(SharedCacheMode sharedCacheMode) { this.sharedCacheMode = sharedCacheMode; @@ -284,7 +284,7 @@ public void setSharedCacheMode(SharedCacheMode sharedCacheMode) { * Specify the JPA 2.0 validation mode for all of this manager's persistence * units, overriding any value in {@code persistence.xml} if set. * @since 4.0 - * @see javax.persistence.spi.PersistenceUnitInfo#getValidationMode() + * @see jakarta.persistence.spi.PersistenceUnitInfo#getValidationMode() */ public void setValidationMode(ValidationMode validationMode) { this.validationMode = validationMode; @@ -341,7 +341,7 @@ public DataSourceLookup getDataSourceLookup() { *

    In JPA speak, a DataSource passed in here will be uses as "nonJtaDataSource" * on the PersistenceUnitInfo passed to the PersistenceProvider, provided that * none has been registered before. - * @see javax.persistence.spi.PersistenceUnitInfo#getNonJtaDataSource() + * @see jakarta.persistence.spi.PersistenceUnitInfo#getNonJtaDataSource() */ public void setDefaultDataSource(@Nullable DataSource defaultDataSource) { this.defaultDataSource = defaultDataSource; @@ -363,7 +363,7 @@ public DataSource getDefaultDataSource() { *

    In JPA speak, a DataSource passed in here will be uses as "jtaDataSource" * on the PersistenceUnitInfo passed to the PersistenceProvider, provided that * none has been registered before. - * @see javax.persistence.spi.PersistenceUnitInfo#getJtaDataSource() + * @see jakarta.persistence.spi.PersistenceUnitInfo#getJtaDataSource() */ public void setDefaultJtaDataSource(@Nullable DataSource defaultJtaDataSource) { this.defaultJtaDataSource = defaultJtaDataSource; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/MutablePersistenceUnitInfo.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/MutablePersistenceUnitInfo.java index b006f76bfaff..7bd5304b0062 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/MutablePersistenceUnitInfo.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/MutablePersistenceUnitInfo.java @@ -21,19 +21,20 @@ import java.util.List; import java.util.Properties; -import javax.persistence.SharedCacheMode; -import javax.persistence.ValidationMode; -import javax.persistence.spi.ClassTransformer; -import javax.persistence.spi.PersistenceUnitTransactionType; import javax.sql.DataSource; +import jakarta.persistence.SharedCacheMode; +import jakarta.persistence.ValidationMode; +import jakarta.persistence.spi.ClassTransformer; +import jakarta.persistence.spi.PersistenceUnitTransactionType; + import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; /** * Spring's base implementation of the JPA - * {@link javax.persistence.spi.PersistenceUnitInfo} interface, + * {@link jakarta.persistence.spi.PersistenceUnitInfo} interface, * used to bootstrap an {@code EntityManagerFactory} in a container. * *

    This implementation is largely a JavaBean, offering mutators @@ -171,7 +172,7 @@ public URL getPersistenceUnitRootUrl() { /** * Add a managed class name to the persistence provider's metadata. - * @see javax.persistence.spi.PersistenceUnitInfo#getManagedClassNames() + * @see jakarta.persistence.spi.PersistenceUnitInfo#getManagedClassNames() * @see #addManagedPackage */ public void addManagedClassName(String managedClassName) { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitManager.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitManager.java index e9bb1429a7fd..bf69b58929e5 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitManager.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitManager.java @@ -16,14 +16,14 @@ package org.springframework.orm.jpa.persistenceunit; -import javax.persistence.spi.PersistenceUnitInfo; +import jakarta.persistence.spi.PersistenceUnitInfo; /** * Interface that defines an abstraction for finding and managing * JPA PersistenceUnitInfos. Used by * {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean} - * in order to obtain a {@link javax.persistence.spi.PersistenceUnitInfo} - * for building a concrete {@link javax.persistence.EntityManagerFactory}. + * in order to obtain a {@link jakarta.persistence.spi.PersistenceUnitInfo} + * for building a concrete {@link jakarta.persistence.EntityManagerFactory}. * *

    Obtaining a PersistenceUnitInfo instance is an exclusive process. * A PersistenceUnitInfo instance is not available for further calls diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitReader.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitReader.java index 092285cd25fd..1b2cd4b53e22 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitReader.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitReader.java @@ -22,13 +22,13 @@ import java.util.ArrayList; import java.util.List; -import javax.persistence.SharedCacheMode; -import javax.persistence.ValidationMode; -import javax.persistence.spi.PersistenceUnitTransactionType; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import jakarta.persistence.SharedCacheMode; +import jakarta.persistence.ValidationMode; +import jakarta.persistence.spi.PersistenceUnitTransactionType; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SmartPersistenceUnitInfo.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SmartPersistenceUnitInfo.java index 1ed577af6e4d..3ad341cc9c1c 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SmartPersistenceUnitInfo.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SmartPersistenceUnitInfo.java @@ -18,7 +18,7 @@ import java.util.List; -import javax.persistence.spi.PersistenceUnitInfo; +import jakarta.persistence.spi.PersistenceUnitInfo; /** * Extension of the standard JPA PersistenceUnitInfo interface, for advanced collaboration @@ -42,7 +42,7 @@ public interface SmartPersistenceUnitInfo extends PersistenceUnitInfo { /** * Set the persistence provider's own package name, for exclusion from class transformation. - * @see #addTransformer(javax.persistence.spi.ClassTransformer) + * @see #addTransformer(jakarta.persistence.spi.ClassTransformer) * @see #getNewTempClassLoader() */ void setPersistenceProviderPackageName(String persistenceProviderPackageName); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java index 0cf289f3ee14..da5e46fdbd83 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java @@ -16,7 +16,7 @@ package org.springframework.orm.jpa.persistenceunit; -import javax.persistence.spi.ClassTransformer; +import jakarta.persistence.spi.ClassTransformer; import org.springframework.core.DecoratingClassLoader; import org.springframework.instrument.classloading.LoadTimeWeaver; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/AsyncRequestInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/AsyncRequestInterceptor.java index 7f31393e1324..46efcd21cb75 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/AsyncRequestInterceptor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/AsyncRequestInterceptor.java @@ -18,8 +18,7 @@ import java.util.concurrent.Callable; -import javax.persistence.EntityManagerFactory; - +import jakarta.persistence.EntityManagerFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewFilter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewFilter.java index a36c0d64c8f7..4b1854005440 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewFilter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewFilter.java @@ -18,13 +18,13 @@ import java.io.IOException; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.PersistenceException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.PersistenceException; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.lang.Nullable; @@ -242,7 +242,7 @@ else if (!StringUtils.hasLength(puName) && wac.containsBean(DEFAULT_ENTITY_MANAG * Create a JPA EntityManager to be bound to a request. *

    Can be overridden in subclasses. * @param emf the EntityManagerFactory to use - * @see javax.persistence.EntityManagerFactory#createEntityManager() + * @see jakarta.persistence.EntityManagerFactory#createEntityManager() */ protected EntityManager createEntityManager(EntityManagerFactory emf) { return emf.createEntityManager(); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewInterceptor.java index 5382e9bdfab7..e6cc8f14fe55 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewInterceptor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewInterceptor.java @@ -16,9 +16,9 @@ package org.springframework.orm.jpa.support; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.PersistenceException; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.PersistenceException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java index d9ff7afc1414..20747130ac71 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java @@ -29,13 +29,13 @@ import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.PersistenceContext; -import javax.persistence.PersistenceContextType; -import javax.persistence.PersistenceProperty; -import javax.persistence.PersistenceUnit; -import javax.persistence.SynchronizationType; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.PersistenceContextType; +import jakarta.persistence.PersistenceProperty; +import jakarta.persistence.PersistenceUnit; +import jakarta.persistence.SynchronizationType; import org.springframework.beans.BeanUtils; import org.springframework.beans.PropertyValues; @@ -71,10 +71,10 @@ import org.springframework.util.StringUtils; /** - * BeanPostProcessor that processes {@link javax.persistence.PersistenceUnit} - * and {@link javax.persistence.PersistenceContext} annotations, for injection of - * the corresponding JPA resources {@link javax.persistence.EntityManagerFactory} - * and {@link javax.persistence.EntityManager}. Any such annotated fields or methods + * BeanPostProcessor that processes {@link jakarta.persistence.PersistenceUnit} + * and {@link jakarta.persistence.PersistenceContext} annotations, for injection of + * the corresponding JPA resources {@link jakarta.persistence.EntityManagerFactory} + * and {@link jakarta.persistence.EntityManager}. Any such annotated fields or methods * in any Spring-managed object will automatically be injected. * *

    This post-processor will inject sub-interfaces of {@code EntityManagerFactory} @@ -88,7 +88,7 @@ * with the "unitName" attribute, or no attribute at all (for the default unit). * If those annotations are present with the "name" attribute at the class level, * they will simply be ignored, since those only serve as deployment hint - * (as per the Java EE specification). + * (as per the Jakarta EE specification). * *

    This post-processor can either obtain EntityManagerFactory beans defined * in the Spring application context (the default), or obtain EntityManagerFactory @@ -106,9 +106,9 @@ * * In the JNDI case, specify the corresponding JNDI names in this post-processor's * {@link #setPersistenceUnits "persistenceUnits" map}, typically with matching - * {@code persistence-unit-ref} entries in the Java EE deployment descriptor. + * {@code persistence-unit-ref} entries in the Jakarta EE deployment descriptor. * By default, those names are considered as resource references (according to the - * Java EE resource-ref convention), located underneath the "java:comp/env/" namespace. + * Jakarta EE resource-ref convention), located underneath the "java:comp/env/" namespace. * For example: * *

    @@ -123,18 +123,18 @@
      *
      * In this case, the specified persistence units will always be resolved in JNDI
      * rather than as Spring-defined beans. The entire persistence unit deployment,
    - * including the weaving of persistent classes, is then up to the Java EE server.
    + * including the weaving of persistent classes, is then up to the Jakarta EE server.
      * Persistence contexts (i.e. EntityManager references) will be built based on
      * those server-provided EntityManagerFactory references, using Spring's own
      * transaction synchronization facilities for transactional EntityManager handling
      * (typically with Spring's {@code @Transactional} annotation for demarcation
      * and {@link org.springframework.transaction.jta.JtaTransactionManager} as backend).
      *
    - * 

    If you prefer the Java EE server's own EntityManager handling, specify entries + *

    If you prefer the Jakarta EE server's own EntityManager handling, specify entries * in this post-processor's {@link #setPersistenceContexts "persistenceContexts" map} * (or {@link #setExtendedPersistenceContexts "extendedPersistenceContexts" map}, * typically with matching {@code persistence-context-ref} entries in the - * Java EE deployment descriptor. For example: + * Jakarta EE deployment descriptor. For example: * *

      * <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor">
    @@ -165,8 +165,8 @@
      * @author Rod Johnson
      * @author Juergen Hoeller
      * @since 2.0
    - * @see javax.persistence.PersistenceUnit
    - * @see javax.persistence.PersistenceContext
    + * @see jakarta.persistence.PersistenceUnit
    + * @see jakarta.persistence.PersistenceContext
      */
     @SuppressWarnings("serial")
     public class PersistenceAnnotationBeanPostProcessor
    @@ -216,7 +216,7 @@ public void setJndiEnvironment(Properties jndiEnvironment) {
     	}
     
     	/**
    -	 * Set whether the lookup occurs in a Java EE container, i.e. if the prefix
    +	 * Set whether the lookup occurs in a Jakarta EE container, i.e. if the prefix
     	 * "java:comp/env/" needs to be added if the JNDI name doesn't already
     	 * contain it. PersistenceAnnotationBeanPostProcessor's default is "true".
     	 * @see org.springframework.jndi.JndiLocatorSupport#setResourceRef
    @@ -230,12 +230,12 @@ public void setResourceRef(boolean resourceRef) {
     	 * as a Map from persistence unit name to persistence unit JNDI name
     	 * (which needs to resolve to an EntityManagerFactory instance).
     	 * 

    JNDI names specified here should refer to {@code persistence-unit-ref} - * entries in the Java EE deployment descriptor, matching the target persistence unit. + * entries in the Jakarta EE deployment descriptor, matching the target persistence unit. *

    In case of no unit name specified in the annotation, the specified value * for the {@link #setDefaultPersistenceUnitName default persistence unit} * will be taken (by default, the value mapped to the empty String), * or simply the single persistence unit if there is only one. - *

    This is mainly intended for use in a Java EE environment, with all lookup + *

    This is mainly intended for use in a Jakarta EE environment, with all lookup * driven by the standard JPA annotations, and all EntityManagerFactory * references obtained from JNDI. No separate EntityManagerFactory bean * definitions are necessary in such a scenario. @@ -244,7 +244,7 @@ public void setResourceRef(boolean resourceRef) { * EntityManagers built on top of the EntityManagerFactory defined here. * Note that those will be Spring-managed EntityManagers, which implement * transaction synchronization based on Spring's facilities. - * If you prefer the Java EE server's own EntityManager handling, + * If you prefer the Jakarta EE server's own EntityManager handling, * specify corresponding "persistenceContexts"/"extendedPersistenceContexts". */ public void setPersistenceUnits(Map persistenceUnits) { @@ -256,17 +256,17 @@ public void setPersistenceUnits(Map persistenceUnits) { * as a Map from persistence unit name to persistence context JNDI name * (which needs to resolve to an EntityManager instance). *

    JNDI names specified here should refer to {@code persistence-context-ref} - * entries in the Java EE deployment descriptors, matching the target persistence unit + * entries in the Jakarta EE deployment descriptors, matching the target persistence unit * and being set up with persistence context type {@code Transaction}. *

    In case of no unit name specified in the annotation, the specified value * for the {@link #setDefaultPersistenceUnitName default persistence unit} * will be taken (by default, the value mapped to the empty String), * or simply the single persistence unit if there is only one. - *

    This is mainly intended for use in a Java EE environment, with all + *

    This is mainly intended for use in a Jakarta EE environment, with all * lookup driven by the standard JPA annotations, and all EntityManager * references obtained from JNDI. No separate EntityManagerFactory bean * definitions are necessary in such a scenario, and all EntityManager - * handling is done by the Java EE server itself. + * handling is done by the Jakarta EE server itself. */ public void setPersistenceContexts(Map persistenceContexts) { this.persistenceContexts = persistenceContexts; @@ -277,17 +277,17 @@ public void setPersistenceContexts(Map persistenceContexts) { * as a Map from persistence unit name to persistence context JNDI name * (which needs to resolve to an EntityManager instance). *

    JNDI names specified here should refer to {@code persistence-context-ref} - * entries in the Java EE deployment descriptors, matching the target persistence unit + * entries in the Jakarta EE deployment descriptors, matching the target persistence unit * and being set up with persistence context type {@code Extended}. *

    In case of no unit name specified in the annotation, the specified value * for the {@link #setDefaultPersistenceUnitName default persistence unit} * will be taken (by default, the value mapped to the empty String), * or simply the single persistence unit if there is only one. - *

    This is mainly intended for use in a Java EE environment, with all + *

    This is mainly intended for use in a Jakarta EE environment, with all * lookup driven by the standard JPA annotations, and all EntityManager * references obtained from JNDI. No separate EntityManagerFactory bean * definitions are necessary in such a scenario, and all EntityManager - * handling is done by the Java EE server itself. + * handling is done by the Jakarta EE server itself. */ public void setExtendedPersistenceContexts(Map extendedPersistenceContexts) { this.extendedPersistenceContexts = extendedPersistenceContexts; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/SharedEntityManagerBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/SharedEntityManagerBean.java index 60c37803cdaa..a3f465dc68d9 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/SharedEntityManagerBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/SharedEntityManagerBean.java @@ -16,8 +16,8 @@ package org.springframework.orm.jpa.support; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; @@ -28,10 +28,10 @@ import org.springframework.util.Assert; /** - * {@link FactoryBean} that exposes a shared JPA {@link javax.persistence.EntityManager} + * {@link FactoryBean} that exposes a shared JPA {@link jakarta.persistence.EntityManager} * reference for a given EntityManagerFactory. Typically used for an EntityManagerFactory * created by {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean}, - * as direct alternative to a JNDI lookup for a Java EE server's EntityManager reference. + * as direct alternative to a JNDI lookup for a Jakarta EE server's EntityManager reference. * *

    The shared EntityManager will behave just like an EntityManager fetched from an * application server's JNDI environment, as defined by the JPA specification. @@ -65,9 +65,9 @@ public class SharedEntityManagerBean extends EntityManagerFactoryAccessor * Specify the EntityManager interface to expose. *

    Default is the EntityManager interface as defined by the * EntityManagerFactoryInfo, if available. Else, the standard - * {@code javax.persistence.EntityManager} interface will be used. + * {@code jakarta.persistence.EntityManager} interface will be used. * @see org.springframework.orm.jpa.EntityManagerFactoryInfo#getEntityManagerInterface() - * @see javax.persistence.EntityManager + * @see jakarta.persistence.EntityManager */ public void setEntityManagerInterface(Class entityManagerInterface) { Assert.notNull(entityManagerInterface, "'entityManagerInterface' must not be null"); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/AbstractJpaVendorAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/AbstractJpaVendorAdapter.java index 37203ab9c4bb..8e6d0101f564 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/AbstractJpaVendorAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/AbstractJpaVendorAdapter.java @@ -19,9 +19,9 @@ import java.util.Collections; import java.util.Map; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.spi.PersistenceUnitInfo; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.spi.PersistenceUnitInfo; import org.springframework.lang.Nullable; import org.springframework.orm.jpa.JpaDialect; @@ -89,7 +89,7 @@ protected String getDatabasePlatform() { * persistence provider. For any more advanced needs, specify the appropriate * vendor-specific settings as "jpaProperties". *

    NOTE: Do not set this flag to 'true' while also setting JPA 2.1's - * {@code javax.persistence.schema-generation.database.action} property. + * {@code jakarta.persistence.schema-generation.database.action} property. * These two schema generation mechanisms - standard JPA versus provider-native - * are mutually exclusive, e.g. with Hibernate 5. * @see org.springframework.orm.jpa.AbstractEntityManagerFactoryBean#setJpaProperties diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaDialect.java index 30db932f1677..7fefab90c241 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaDialect.java @@ -19,9 +19,8 @@ import java.sql.Connection; import java.sql.SQLException; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceException; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceException; import org.eclipse.persistence.sessions.UnitOfWork; import org.springframework.jdbc.datasource.ConnectionHandle; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java index f3bc463226b0..b64258d9dbf0 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java @@ -20,9 +20,8 @@ import java.util.Map; import java.util.logging.Level; -import javax.persistence.EntityManager; -import javax.persistence.spi.PersistenceProvider; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.spi.PersistenceProvider; import org.eclipse.persistence.config.PersistenceUnitProperties; import org.eclipse.persistence.config.TargetDatabase; import org.eclipse.persistence.jpa.JpaEntityManager; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java index a6d82beb63c1..327f887f08ff 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java @@ -19,9 +19,8 @@ import java.sql.Connection; import java.sql.SQLException; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceException; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceException; import org.hibernate.ConnectionReleaseMode; import org.hibernate.FlushMode; import org.hibernate.HibernateException; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaSessionFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaSessionFactoryBean.java index 090bd23b5135..b02e90d04f86 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaSessionFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaSessionFactoryBean.java @@ -18,8 +18,7 @@ import java.lang.reflect.Method; -import javax.persistence.EntityManagerFactory; - +import jakarta.persistence.EntityManagerFactory; import org.hibernate.SessionFactory; import org.springframework.beans.factory.FactoryBean; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java index ef3324db3523..5807200a9c2a 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java @@ -19,12 +19,11 @@ import java.util.HashMap; import java.util.Map; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.spi.PersistenceProvider; -import javax.persistence.spi.PersistenceUnitInfo; -import javax.persistence.spi.PersistenceUnitTransactionType; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.spi.PersistenceProvider; +import jakarta.persistence.spi.PersistenceUnitInfo; +import jakarta.persistence.spi.PersistenceUnitTransactionType; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AvailableSettings; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateJpaPersistenceProvider.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateJpaPersistenceProvider.java index 32c6b4ed5247..f0e98f85456a 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateJpaPersistenceProvider.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/SpringHibernateJpaPersistenceProvider.java @@ -20,9 +20,8 @@ import java.util.List; import java.util.Map; -import javax.persistence.EntityManagerFactory; -import javax.persistence.spi.PersistenceUnitInfo; - +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.spi.PersistenceUnitInfo; import org.hibernate.cfg.Configuration; import org.hibernate.jpa.HibernatePersistenceProvider; import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/AbstractContainerEntityManagerFactoryIntegrationTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/AbstractContainerEntityManagerFactoryIntegrationTests.java index 8885d6eb7e02..30218d1dd861 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/AbstractContainerEntityManagerFactoryIntegrationTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/AbstractContainerEntityManagerFactoryIntegrationTests.java @@ -19,11 +19,10 @@ import java.lang.reflect.Proxy; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.FlushModeType; -import javax.persistence.NoResultException; -import javax.persistence.Query; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.FlushModeType; +import jakarta.persistence.NoResultException; +import jakarta.persistence.Query; import org.junit.jupiter.api.Test; import org.springframework.core.testfixture.io.SerializationTestUtils; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBeanTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBeanTests.java index 3220e271bf2f..084391597c1b 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBeanTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBeanTests.java @@ -16,10 +16,9 @@ package org.springframework.orm.jpa; -import javax.persistence.EntityManagerFactory; -import javax.persistence.PersistenceException; -import javax.persistence.spi.PersistenceUnitInfo; - +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.PersistenceException; +import jakarta.persistence.spi.PersistenceUnitInfo; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryIntegrationTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryIntegrationTests.java index 56a6d288a5eb..5a314c2fa376 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryIntegrationTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryIntegrationTests.java @@ -16,11 +16,11 @@ package org.springframework.orm.jpa; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Query; import javax.sql.DataSource; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Query; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/ApplicationManagedEntityManagerIntegrationTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/ApplicationManagedEntityManagerIntegrationTests.java index 69986ebf539a..765d62bfcfbe 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/ApplicationManagedEntityManagerIntegrationTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/ApplicationManagedEntityManagerIntegrationTests.java @@ -19,10 +19,9 @@ import java.lang.reflect.Proxy; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.Query; -import javax.persistence.TransactionRequiredException; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.Query; +import jakarta.persistence.TransactionRequiredException; import org.junit.jupiter.api.Test; import org.springframework.orm.jpa.domain.Person; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/ContainerManagedEntityManagerIntegrationTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/ContainerManagedEntityManagerIntegrationTests.java index f87101156d23..a61c10cd0a33 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/ContainerManagedEntityManagerIntegrationTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/ContainerManagedEntityManagerIntegrationTests.java @@ -19,11 +19,10 @@ import java.lang.reflect.Proxy; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceException; -import javax.persistence.Query; -import javax.persistence.TransactionRequiredException; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceException; +import jakarta.persistence.Query; +import jakarta.persistence.TransactionRequiredException; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/DefaultJpaDialectTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/DefaultJpaDialectTests.java index fedb323fba7a..12c75166f6f6 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/DefaultJpaDialectTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/DefaultJpaDialectTests.java @@ -16,10 +16,9 @@ package org.springframework.orm.jpa; -import javax.persistence.EntityManager; -import javax.persistence.EntityTransaction; -import javax.persistence.OptimisticLockException; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityTransaction; +import jakarta.persistence.OptimisticLockException; import org.junit.jupiter.api.Test; import org.springframework.transaction.TransactionDefinition; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/EntityManagerFactoryUtilsTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/EntityManagerFactoryUtilsTests.java index 4525931ed531..b651f8eb6772 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/EntityManagerFactoryUtilsTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/EntityManagerFactoryUtilsTests.java @@ -16,16 +16,15 @@ package org.springframework.orm.jpa; -import javax.persistence.EntityExistsException; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityNotFoundException; -import javax.persistence.NoResultException; -import javax.persistence.NonUniqueResultException; -import javax.persistence.OptimisticLockException; -import javax.persistence.PersistenceException; -import javax.persistence.TransactionRequiredException; - +import jakarta.persistence.EntityExistsException; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityNotFoundException; +import jakarta.persistence.NoResultException; +import jakarta.persistence.NonUniqueResultException; +import jakarta.persistence.OptimisticLockException; +import jakarta.persistence.PersistenceException; +import jakarta.persistence.TransactionRequiredException; import org.junit.jupiter.api.Test; import org.springframework.dao.DataAccessException; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/JpaTransactionManagerTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/JpaTransactionManagerTests.java index 3a53b2cb9a1d..881bccca79b6 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/JpaTransactionManagerTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/JpaTransactionManagerTests.java @@ -19,11 +19,10 @@ import java.util.ArrayList; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.RollbackException; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityTransaction; +import jakarta.persistence.RollbackException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBeanTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBeanTests.java index a2495d2267cc..d3741988e257 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBeanTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBeanTests.java @@ -19,16 +19,15 @@ import java.util.Map; import java.util.Properties; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.OptimisticLockException; -import javax.persistence.PersistenceException; -import javax.persistence.spi.PersistenceProvider; -import javax.persistence.spi.PersistenceUnitInfo; -import javax.persistence.spi.PersistenceUnitTransactionType; -import javax.persistence.spi.ProviderUtil; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityTransaction; +import jakarta.persistence.OptimisticLockException; +import jakarta.persistence.PersistenceException; +import jakarta.persistence.spi.PersistenceProvider; +import jakarta.persistence.spi.PersistenceUnitInfo; +import jakarta.persistence.spi.PersistenceUnitTransactionType; +import jakarta.persistence.spi.ProviderUtil; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.support.DefaultListableBeanFactory; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBeanTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBeanTests.java index 4d6b8095b955..b3d16aaf0093 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBeanTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBeanTests.java @@ -19,11 +19,10 @@ import java.util.Map; import java.util.Properties; -import javax.persistence.EntityManagerFactory; -import javax.persistence.spi.PersistenceProvider; -import javax.persistence.spi.PersistenceUnitInfo; -import javax.persistence.spi.ProviderUtil; - +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.spi.PersistenceProvider; +import jakarta.persistence.spi.PersistenceUnitInfo; +import jakarta.persistence.spi.ProviderUtil; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/SharedEntityManagerCreatorTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/SharedEntityManagerCreatorTests.java index 86df24330b85..f2768122b78b 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/SharedEntityManagerCreatorTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/SharedEntityManagerCreatorTests.java @@ -16,13 +16,12 @@ package org.springframework.orm.jpa; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.ParameterMode; -import javax.persistence.Query; -import javax.persistence.StoredProcedureQuery; -import javax.persistence.TransactionRequiredException; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.ParameterMode; +import jakarta.persistence.Query; +import jakarta.persistence.StoredProcedureQuery; +import jakarta.persistence.TransactionRequiredException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/domain/DriversLicense.java b/spring-orm/src/test/java/org/springframework/orm/jpa/domain/DriversLicense.java index 4bb0082dde48..0a088e3efe74 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/domain/DriversLicense.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/domain/DriversLicense.java @@ -16,9 +16,9 @@ package org.springframework.orm.jpa.domain; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name="DRIVERS_LICENSE") diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/domain/Person.java b/spring-orm/src/test/java/org/springframework/orm/jpa/domain/Person.java index 1586a2c25017..b8c0e564b147 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/domain/Person.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/domain/Person.java @@ -16,16 +16,16 @@ package org.springframework.orm.jpa.domain; -import javax.persistence.Basic; -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.EntityListeners; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToOne; +import jakarta.persistence.Basic; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; import org.springframework.beans.testfixture.beans.TestBean; import org.springframework.context.ApplicationContext; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/domain/PersonListener.java b/spring-orm/src/test/java/org/springframework/orm/jpa/domain/PersonListener.java index 072e2f9795bd..90a6e94e00d1 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/domain/PersonListener.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/domain/PersonListener.java @@ -16,7 +16,7 @@ package org.springframework.orm.jpa.domain; -import javax.persistence.PostLoad; +import jakarta.persistence.PostLoad; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java index 03206c523cee..c8c9e5e2854f 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateEntityManagerFactoryIntegrationTests.java @@ -16,8 +16,7 @@ package org.springframework.orm.jpa.hibernate; -import javax.persistence.EntityManager; - +import jakarta.persistence.EntityManager; import org.hibernate.FlushMode; import org.hibernate.Session; import org.hibernate.SessionFactory; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateMultiEntityManagerFactoryIntegrationTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateMultiEntityManagerFactoryIntegrationTests.java index 5653474b60d1..2a959616964c 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateMultiEntityManagerFactoryIntegrationTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateMultiEntityManagerFactoryIntegrationTests.java @@ -16,9 +16,8 @@ package org.springframework.orm.jpa.hibernate; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTests.java index 5eb4055b4170..5e5d848e1afc 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTests.java @@ -16,8 +16,7 @@ package org.springframework.orm.jpa.hibernate; -import javax.persistence.AttributeConverter; - +import jakarta.persistence.AttributeConverter; import org.hibernate.SessionFactory; import org.hibernate.resource.beans.container.spi.BeanContainer; import org.hibernate.resource.beans.container.spi.ContainedBean; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceXmlParsingTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceXmlParsingTests.java index d7a78f9e87b8..253c3a2f2478 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceXmlParsingTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceXmlParsingTests.java @@ -21,10 +21,10 @@ import java.util.Map; import java.util.Properties; -import javax.persistence.spi.PersistenceUnitInfo; -import javax.persistence.spi.PersistenceUnitTransactionType; import javax.sql.DataSource; +import jakarta.persistence.spi.PersistenceUnitInfo; +import jakarta.persistence.spi.PersistenceUnitTransactionType; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewTests.java index 70360c26dea6..1851fdfb622f 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewTests.java @@ -21,12 +21,11 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; -import javax.servlet.FilterChain; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.servlet.AsyncEvent; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.FilterChain; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceContextTransactionTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceContextTransactionTests.java index 9d5fc76147ac..82e22136e0be 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceContextTransactionTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceContextTransactionTests.java @@ -16,13 +16,12 @@ package org.springframework.orm.jpa.support; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.PersistenceContext; -import javax.persistence.PersistenceContextType; -import javax.persistence.SynchronizationType; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityTransaction; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.PersistenceContextType; +import jakarta.persistence.SynchronizationType; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceInjectionTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceInjectionTests.java index 919f2fb1259c..c38924840ab6 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceInjectionTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceInjectionTests.java @@ -24,13 +24,12 @@ import java.util.Map; import java.util.Properties; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.PersistenceContext; -import javax.persistence.PersistenceContextType; -import javax.persistence.PersistenceProperty; -import javax.persistence.PersistenceUnit; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.PersistenceContextType; +import jakarta.persistence.PersistenceProperty; +import jakarta.persistence.PersistenceUnit; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.FactoryBean; diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/support/SharedEntityManagerFactoryTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/support/SharedEntityManagerFactoryTests.java index 4e344c183000..93f53e1e5110 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/support/SharedEntityManagerFactoryTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/support/SharedEntityManagerFactoryTests.java @@ -16,9 +16,8 @@ package org.springframework.orm.jpa.support; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; - +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; import org.junit.jupiter.api.Test; import org.springframework.orm.jpa.EntityManagerHolder; diff --git a/spring-orm/src/test/resources/org/springframework/orm/jpa/domain/spring.components b/spring-orm/src/test/resources/org/springframework/orm/jpa/domain/spring.components index 4b6de536dfa4..f42629baebf7 100644 --- a/spring-orm/src/test/resources/org/springframework/orm/jpa/domain/spring.components +++ b/spring-orm/src/test/resources/org/springframework/orm/jpa/domain/spring.components @@ -1,2 +1,2 @@ -org.springframework.orm.jpa.domain.Person=javax.persistence.Entity -org.springframework.orm.jpa.domain.DriversLicense=javax.persistence.Entity \ No newline at end of file +org.springframework.orm.jpa.domain.Person=jakarta.persistence.Entity +org.springframework.orm.jpa.domain.DriversLicense=jakarta.persistence.Entity \ No newline at end of file diff --git a/spring-orm/src/test/resources/org/springframework/orm/jpa/hibernate/hibernate-manager-native.xml b/spring-orm/src/test/resources/org/springframework/orm/jpa/hibernate/hibernate-manager-native.xml index 95572a9f7599..90c0d836c1d1 100644 --- a/spring-orm/src/test/resources/org/springframework/orm/jpa/hibernate/hibernate-manager-native.xml +++ b/spring-orm/src/test/resources/org/springframework/orm/jpa/hibernate/hibernate-manager-native.xml @@ -28,6 +28,6 @@ - + diff --git a/spring-oxm/spring-oxm.gradle b/spring-oxm/spring-oxm.gradle index f47726a8bd5b..bce9c1517691 100644 --- a/spring-oxm/spring-oxm.gradle +++ b/spring-oxm/spring-oxm.gradle @@ -4,17 +4,8 @@ plugins { description = "Spring Object/XML Marshalling" -configurations { - jibx -} - -dependencies { - jibx "org.jibx:jibx-bind:1.3.3" - jibx "org.apache.bcel:bcel:6.0" -} - xjc { - xjcVersion = '2.2' + xjcVersion = '3.0' } sourceSets { @@ -26,10 +17,9 @@ sourceSets { dependencies { api(project(":spring-beans")) api(project(":spring-core")) - optional("javax.xml.bind:jaxb-api") - optional("javax.activation:javax.activation-api") + optional("jakarta.xml.bind:jakarta.xml.bind-api") + optional("jakarta.activation:jakarta.activation-api") optional("com.thoughtworks.xstream:xstream") - optional("org.jibx:jibx-run") testImplementation(project(":spring-context")) testImplementation(testFixtures(project(":spring-core"))) testImplementation("org.ogce:xpp3") @@ -42,25 +32,3 @@ dependencies { testRuntimeOnly("com.sun.xml.bind:jaxb-core") testRuntimeOnly("com.sun.xml.bind:jaxb-impl") } - -// JiBX compiler is currently not compatible with JDK 9+. -// If testToolchain has been set, we assume the custom JDK version is 9+. -if ((JavaVersion.current() == JavaVersion.VERSION_1_8) && !project.hasProperty("testToolchain")) { - compileTestJava { - def bindingXml = "${projectDir}/src/test/resources/org/springframework/oxm/jibx/binding.xml" - - doLast() { - project.ant { - taskdef(name: "jibx", - classname: "org.jibx.binding.ant.CompileTask", - classpath: configurations.jibx.asPath) - - jibx(verbose: false, load: true, binding: bindingXml) { - classpathset(dir: sourceSets.test.java.classesDirectory.get().getAsFile()) { - include(name: "**/jibx/**/*") - } - } - } - } - } -} diff --git a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/ClassPathJaxb2TypeScanner.java b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/ClassPathJaxb2TypeScanner.java index 520d2a627d75..b989541fd35a 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/ClassPathJaxb2TypeScanner.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/ClassPathJaxb2TypeScanner.java @@ -20,11 +20,11 @@ import java.util.ArrayList; import java.util.List; -import javax.xml.bind.annotation.XmlEnum; -import javax.xml.bind.annotation.XmlRegistry; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSeeAlso; -import javax.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlEnum; +import jakarta.xml.bind.annotation.XmlRegistry; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlSeeAlso; +import jakarta.xml.bind.annotation.XmlType; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; diff --git a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java index 176ccc83f8ba..7267f311cc08 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,22 +38,7 @@ import java.util.Map; import java.util.UUID; -import javax.activation.DataHandler; -import javax.activation.DataSource; import javax.xml.XMLConstants; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.JAXBException; -import javax.xml.bind.MarshalException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.UnmarshalException; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.ValidationEventHandler; -import javax.xml.bind.ValidationException; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.adapters.XmlAdapter; -import javax.xml.bind.attachment.AttachmentMarshaller; -import javax.xml.bind.attachment.AttachmentUnmarshaller; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; @@ -70,6 +55,21 @@ import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; +import jakarta.activation.DataHandler; +import jakarta.activation.DataSource; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.MarshalException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.UnmarshalException; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.ValidationEventHandler; +import jakarta.xml.bind.ValidationException; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.adapters.XmlAdapter; +import jakarta.xml.bind.attachment.AttachmentMarshaller; +import jakarta.xml.bind.attachment.AttachmentUnmarshaller; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.ls.LSResourceResolver; @@ -275,11 +275,11 @@ public void setJaxbContextProperties(Map jaxbContextProperties) { *

    These properties will be set on the underlying JAXB {@code Marshaller}, * and allow for features such as indentation. * @param properties the properties - * @see javax.xml.bind.Marshaller#setProperty(String, Object) - * @see javax.xml.bind.Marshaller#JAXB_ENCODING - * @see javax.xml.bind.Marshaller#JAXB_FORMATTED_OUTPUT - * @see javax.xml.bind.Marshaller#JAXB_NO_NAMESPACE_SCHEMA_LOCATION - * @see javax.xml.bind.Marshaller#JAXB_SCHEMA_LOCATION + * @see jakarta.xml.bind.Marshaller#setProperty(String, Object) + * @see jakarta.xml.bind.Marshaller#JAXB_ENCODING + * @see jakarta.xml.bind.Marshaller#JAXB_FORMATTED_OUTPUT + * @see jakarta.xml.bind.Marshaller#JAXB_NO_NAMESPACE_SCHEMA_LOCATION + * @see jakarta.xml.bind.Marshaller#JAXB_SCHEMA_LOCATION */ public void setMarshallerProperties(Map properties) { this.marshallerProperties = properties; @@ -289,7 +289,7 @@ public void setMarshallerProperties(Map properties) { * Set the JAXB {@code Unmarshaller} properties. *

    These properties will be set on the underlying JAXB {@code Unmarshaller}. * @param properties the properties - * @see javax.xml.bind.Unmarshaller#setProperty(String, Object) + * @see jakarta.xml.bind.Unmarshaller#setProperty(String, Object) */ public void setUnmarshallerProperties(Map properties) { this.unmarshallerProperties = properties; @@ -409,7 +409,7 @@ public void setCheckForXmlRootElement(boolean checkForXmlRootElement) { /** * Specify a JAXB mapped class for partial unmarshalling. - * @see javax.xml.bind.Unmarshaller#unmarshal(javax.xml.transform.Source, Class) + * @see jakarta.xml.bind.Unmarshaller#unmarshal(javax.xml.transform.Source, Class) */ public void setMappedClass(Class mappedClass) { this.mappedClass = mappedClass; @@ -574,7 +574,7 @@ private JAXBContext createJaxbContextFromPackages(String... packagesToScan) thro } } - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") private Schema loadSchema(Resource[] resources, String schemaLanguage) throws IOException, SAXException { if (logger.isDebugEnabled()) { logger.debug("Setting validation schema to " + @@ -857,7 +857,7 @@ protected Object unmarshalStaxSource(Unmarshaller jaxbUnmarshaller, Source staxS } } - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") private Source processSource(Source source) { if (StaxUtils.isStaxSource(source) || source instanceof DOMSource) { return source; diff --git a/spring-oxm/src/main/java/org/springframework/oxm/mime/MimeContainer.java b/spring-oxm/src/main/java/org/springframework/oxm/mime/MimeContainer.java index 035457239516..11f24456d0a7 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/mime/MimeContainer.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/mime/MimeContainer.java @@ -16,7 +16,7 @@ package org.springframework.oxm.mime; -import javax.activation.DataHandler; +import jakarta.activation.DataHandler; import org.springframework.lang.Nullable; diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Airplane.java b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Airplane.java index e9436034e818..503fb73315b3 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Airplane.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Airplane.java @@ -16,7 +16,7 @@ package org.springframework.oxm.jaxb; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Airplane { diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/BinaryObject.java b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/BinaryObject.java index 4457329e31ba..b76441b806a4 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/BinaryObject.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/BinaryObject.java @@ -16,10 +16,10 @@ package org.springframework.oxm.jaxb; -import javax.activation.DataHandler; -import javax.xml.bind.annotation.XmlAttachmentRef; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.activation.DataHandler; +import jakarta.xml.bind.annotation.XmlAttachmentRef; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; @XmlRootElement(namespace = "http://springframework.org/spring-ws") public class BinaryObject { diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2MarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2MarshallerTests.java index a0e88fef2689..07453a56864d 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2MarshallerTests.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2MarshallerTests.java @@ -23,11 +23,6 @@ import java.lang.reflect.Type; import java.util.Collections; -import javax.activation.DataHandler; -import javax.activation.FileDataSource; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; import javax.xml.namespace.QName; import javax.xml.transform.Result; import javax.xml.transform.sax.SAXResult; @@ -35,6 +30,11 @@ import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import jakarta.activation.DataHandler; +import jakarta.activation.FileDataSource; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; @@ -141,7 +141,7 @@ void properties() throws Exception { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); marshaller.setContextPath(CONTEXT_PATH); marshaller.setMarshallerProperties( - Collections.singletonMap(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE)); + Collections.singletonMap(jakarta.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE)); marshaller.afterPropertiesSet(); } @@ -307,10 +307,10 @@ void marshalAWrappedObjectHoldingAnXmlElementDeclElement() throws Exception { @Test // SPR-10806 void unmarshalStreamSourceWithXmlOptions() throws Exception { - final javax.xml.bind.Unmarshaller unmarshaller = mock(javax.xml.bind.Unmarshaller.class); + final jakarta.xml.bind.Unmarshaller unmarshaller = mock(jakarta.xml.bind.Unmarshaller.class); Jaxb2Marshaller marshaller = new Jaxb2Marshaller() { @Override - public javax.xml.bind.Unmarshaller createUnmarshaller() { + public jakarta.xml.bind.Unmarshaller createUnmarshaller() { return unmarshaller; } }; @@ -341,10 +341,10 @@ public javax.xml.bind.Unmarshaller createUnmarshaller() { @Test // SPR-10806 void unmarshalSaxSourceWithXmlOptions() throws Exception { - final javax.xml.bind.Unmarshaller unmarshaller = mock(javax.xml.bind.Unmarshaller.class); + final jakarta.xml.bind.Unmarshaller unmarshaller = mock(jakarta.xml.bind.Unmarshaller.class); Jaxb2Marshaller marshaller = new Jaxb2Marshaller() { @Override - public javax.xml.bind.Unmarshaller createUnmarshaller() { + public jakarta.xml.bind.Unmarshaller createUnmarshaller() { return unmarshaller; } }; diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2UnmarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2UnmarshallerTests.java index 4a4b9c9998ce..0b9ac09b56f7 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2UnmarshallerTests.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2UnmarshallerTests.java @@ -20,14 +20,14 @@ import java.io.IOException; import java.io.StringReader; -import javax.activation.DataHandler; -import javax.activation.FileDataSource; -import javax.xml.bind.JAXBElement; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; +import jakarta.activation.DataHandler; +import jakarta.activation.FileDataSource; +import jakarta.xml.bind.JAXBElement; import org.junit.jupiter.api.Test; import org.springframework.core.io.ClassPathResource; diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Primitives.java b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Primitives.java index 2f61fc4b669b..d02de24e8081 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Primitives.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Primitives.java @@ -16,9 +16,10 @@ package org.springframework.oxm.jaxb; -import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; +import jakarta.xml.bind.JAXBElement; + /** * Used by {@link org.springframework.oxm.jaxb.Jaxb2MarshallerTests}. * diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/StandardClasses.java b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/StandardClasses.java index c5e3c2ae7ed3..14adba20759c 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/StandardClasses.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/StandardClasses.java @@ -26,17 +26,18 @@ import java.util.GregorianCalendar; import java.util.UUID; -import javax.activation.DataHandler; -import javax.activation.DataSource; -import javax.activation.URLDataSource; import javax.imageio.ImageIO; -import javax.xml.bind.JAXBElement; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import jakarta.activation.DataHandler; +import jakarta.activation.DataSource; +import jakarta.activation.URLDataSource; +import jakarta.xml.bind.JAXBElement; + /** * Used by {@link org.springframework.oxm.jaxb.Jaxb2MarshallerTests}. * @@ -58,7 +59,7 @@ public StandardClasses() throws DatatypeConfigurationException { javax.xml.datatype.Duration java.lang.Object java.awt.Image - javax.activation.DataHandler + jakarta.activation.DataHandler javax.xml.transform.Source java.util.UUID */ diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/XmlRegObjectFactory.java b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/XmlRegObjectFactory.java index 458385eda86e..547367c856d8 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/XmlRegObjectFactory.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/XmlRegObjectFactory.java @@ -16,11 +16,12 @@ package org.springframework.oxm.jaxb; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlRegistry; import javax.xml.namespace.QName; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.annotation.XmlElementDecl; +import jakarta.xml.bind.annotation.XmlRegistry; + @XmlRegistry public class XmlRegObjectFactory { diff --git a/spring-test/spring-test.gradle b/spring-test/spring-test.gradle index 365ce7d316f9..8d0e2076243c 100644 --- a/spring-test/spring-test.gradle +++ b/spring-test/spring-test.gradle @@ -14,21 +14,21 @@ dependencies { optional(project(":spring-webflux")) optional(project(":spring-webmvc")) optional(project(":spring-websocket")) - optional("javax.activation:javax.activation-api") - optional("javax.el:javax.el-api") - optional("javax.inject:javax.inject") - optional("javax.servlet:javax.servlet-api") - optional("javax.servlet.jsp:javax.servlet.jsp-api") - optional("javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api") - optional("javax.xml.bind:jaxb-api") - optional("javax.websocket:javax.websocket-api") + optional("jakarta.activation:jakarta.activation-api") + optional("jakarta.el:jakarta.el-api") + optional("jakarta.inject:jakarta.inject-api") + optional("jakarta.servlet:jakarta.servlet-api") + optional("jakarta.servlet.jsp:jakarta.servlet.jsp-api") + optional("jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api") + optional("jakarta.xml.bind:jakarta.xml.bind-api") + optional("jakarta.websocket:jakarta.websocket-api") optional("junit:junit") + optional("org.apache.tomcat.embed:tomcat-embed-core") optional("org.junit.jupiter:junit-jupiter-api") optional("org.testng:testng") optional("org.aspectj:aspectjweaver") optional("org.codehaus.groovy:groovy") optional("org.hamcrest:hamcrest") - optional("org.apache.taglibs:taglibs-standard-jstlel") optional("net.sourceforge.htmlunit:htmlunit") optional("org.seleniumhq.selenium:htmlunit-driver") { exclude group: "net.bytebuddy", module: "byte-buddy" @@ -39,7 +39,6 @@ dependencies { optional("org.xmlunit:xmlunit-matchers") optional("org.skyscreamer:jsonassert") optional("com.jayway.jsonpath:json-path") - optional("commons-fileupload:commons-fileupload") optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") optional("io.projectreactor:reactor-test") @@ -52,14 +51,14 @@ dependencies { testImplementation(testFixtures(project(":spring-core"))) testImplementation(testFixtures(project(":spring-tx"))) testImplementation(testFixtures(project(":spring-web"))) - testImplementation("javax.annotation:javax.annotation-api") + testImplementation("jakarta.annotation:jakarta.annotation-api") testImplementation("javax.cache:cache-api") - testImplementation("javax.ejb:javax.ejb-api") - testImplementation("javax.interceptor:javax.interceptor-api") - testImplementation("javax.mail:javax.mail-api") - testImplementation("org.hibernate:hibernate-core") + testImplementation("jakarta.ejb:jakarta.ejb-api") + testImplementation("jakarta.interceptor:jakarta.interceptor-api") + testImplementation("jakarta.mail:jakarta.mail-api") + testImplementation("org.hibernate:hibernate-core-jakarta") testImplementation("org.hibernate:hibernate-validator") - testImplementation("javax.validation:validation-api") + testImplementation("jakarta.validation:jakarta.validation-api") testImplementation("org.junit.platform:junit-platform-runner") { exclude group: "junit", module: "junit" } @@ -67,9 +66,6 @@ dependencies { testImplementation("com.fasterxml.jackson.core:jackson-databind") testImplementation("com.thoughtworks.xstream:xstream") testImplementation("com.rometools:rome") - testImplementation("org.apache.tiles:tiles-api") - testImplementation("org.apache.tiles:tiles-core") - testImplementation("org.apache.tiles:tiles-servlet") testImplementation("org.hsqldb:hsqldb") testImplementation("org.apache.httpcomponents:httpclient") testImplementation("io.projectreactor.netty:reactor-netty-http") @@ -77,7 +73,7 @@ dependencies { testRuntimeOnly("org.junit.vintage:junit-vintage-engine") { exclude group: "junit", module: "junit" } - testRuntimeOnly("org.glassfish:javax.el") + testRuntimeOnly("org.glassfish:jakarta.el") testRuntimeOnly("com.sun.xml.bind:jaxb-core") testRuntimeOnly("com.sun.xml.bind:jaxb-impl") } diff --git a/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContextBuilder.java b/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContextBuilder.java index 2d6110b6926f..802dcaf32c43 100644 --- a/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContextBuilder.java +++ b/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContextBuilder.java @@ -39,7 +39,7 @@ * configure JNDI appropriately, so that {@code new InitialContext()} * will expose the required objects. Also usable for standalone applications, * e.g. for binding a JDBC DataSource to a well-known JNDI location, to be - * able to use traditional Java EE data access code outside of a Java EE + * able to use traditional Jakarta EE data access code outside of a Jakarta EE * container. * *

    There are various choices for DataSource implementations: diff --git a/spring-test/src/main/java/org/springframework/mock/jndi/package-info.java b/spring-test/src/main/java/org/springframework/mock/jndi/package-info.java index fc31fe57512a..b2ec4eaacaa7 100644 --- a/spring-test/src/main/java/org/springframework/mock/jndi/package-info.java +++ b/spring-test/src/main/java/org/springframework/mock/jndi/package-info.java @@ -7,7 +7,7 @@ * *

    Useful for setting up a simple JNDI environment for test suites * or stand-alone applications. If, for example, JDBC DataSources get bound to the - * same JNDI names as within a Java EE container, both application code and + * same JNDI names as within a Jakarta EE container, both application code and * configuration can be reused without changes. */ @NonNullApi diff --git a/spring-test/src/main/java/org/springframework/mock/web/DelegatingServletInputStream.java b/spring-test/src/main/java/org/springframework/mock/web/DelegatingServletInputStream.java index 4b69e1649156..1be569c22173 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/DelegatingServletInputStream.java +++ b/spring-test/src/main/java/org/springframework/mock/web/DelegatingServletInputStream.java @@ -19,13 +19,13 @@ import java.io.IOException; import java.io.InputStream; -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; import org.springframework.util.Assert; /** - * Delegating implementation of {@link javax.servlet.ServletInputStream}. + * Delegating implementation of {@link jakarta.servlet.ServletInputStream}. * *

    Used by {@link MockHttpServletRequest}; typically not directly * used for testing application controllers. diff --git a/spring-test/src/main/java/org/springframework/mock/web/DelegatingServletOutputStream.java b/spring-test/src/main/java/org/springframework/mock/web/DelegatingServletOutputStream.java index 9fa54fed4822..41ff6b15b7d2 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/DelegatingServletOutputStream.java +++ b/spring-test/src/main/java/org/springframework/mock/web/DelegatingServletOutputStream.java @@ -19,13 +19,13 @@ import java.io.IOException; import java.io.OutputStream; -import javax.servlet.ServletOutputStream; -import javax.servlet.WriteListener; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.WriteListener; import org.springframework.util.Assert; /** - * Delegating implementation of {@link javax.servlet.ServletOutputStream}. + * Delegating implementation of {@link jakarta.servlet.ServletOutputStream}. * *

    Used by {@link MockHttpServletResponse}; typically not directly * used for testing application controllers. diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockAsyncContext.java b/spring-test/src/main/java/org/springframework/mock/web/MockAsyncContext.java index f3c6fcc1ad65..982d4e3b261e 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockAsyncContext.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockAsyncContext.java @@ -20,15 +20,15 @@ import java.util.ArrayList; import java.util.List; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.AsyncContext; +import jakarta.servlet.AsyncEvent; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.BeanUtils; import org.springframework.lang.Nullable; diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockBodyContent.java b/spring-test/src/main/java/org/springframework/mock/web/MockBodyContent.java index a8c31873b041..85ee83f89feb 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockBodyContent.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockBodyContent.java @@ -21,14 +21,14 @@ import java.io.StringReader; import java.io.Writer; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.tagext.BodyContent; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.jsp.JspWriter; +import jakarta.servlet.jsp.tagext.BodyContent; import org.springframework.lang.Nullable; /** - * Mock implementation of the {@link javax.servlet.jsp.tagext.BodyContent} class. + * Mock implementation of the {@link jakarta.servlet.jsp.tagext.BodyContent} class. * Only necessary for testing applications when testing custom JSP tags. * * @author Juergen Hoeller diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockCookie.java b/spring-test/src/main/java/org/springframework/mock/web/MockCookie.java index 372898cd5a36..a00d67e335d3 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockCookie.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockCookie.java @@ -20,7 +20,7 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; -import javax.servlet.http.Cookie; +import jakarta.servlet.http.Cookie; import org.springframework.core.style.ToStringCreator; import org.springframework.lang.Nullable; diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockExpressionEvaluator.java b/spring-test/src/main/java/org/springframework/mock/web/MockExpressionEvaluator.java deleted file mode 100644 index bfd549ac5dc5..000000000000 --- a/spring-test/src/main/java/org/springframework/mock/web/MockExpressionEvaluator.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; - -import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager; - -/** - * Mock implementation of the JSP 2.0 {@link javax.servlet.jsp.el.ExpressionEvaluator} - * interface, delegating to the Apache JSTL {@link ExpressionEvaluatorManager}. - * Only necessary for testing applications when testing custom JSP tags. - * - *

    Note that the Apache JSTL implementation (jstl.jar, standard.jar) has to be - * available on the classpath to use this expression evaluator. - * - * @author Juergen Hoeller - * @since 1.1.5 - * @see org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager - */ -@SuppressWarnings("deprecation") -public class MockExpressionEvaluator extends javax.servlet.jsp.el.ExpressionEvaluator { - - private final PageContext pageContext; - - - /** - * Create a new MockExpressionEvaluator for the given PageContext. - * @param pageContext the JSP PageContext to run in - */ - public MockExpressionEvaluator(PageContext pageContext) { - this.pageContext = pageContext; - } - - - @Override - @SuppressWarnings("rawtypes") - public javax.servlet.jsp.el.Expression parseExpression(final String expression, final Class expectedType, - final javax.servlet.jsp.el.FunctionMapper functionMapper) throws javax.servlet.jsp.el.ELException { - - return new javax.servlet.jsp.el.Expression() { - @Override - public Object evaluate(javax.servlet.jsp.el.VariableResolver variableResolver) throws javax.servlet.jsp.el.ELException { - return doEvaluate(expression, expectedType, functionMapper); - } - }; - } - - @Override - @SuppressWarnings("rawtypes") - public Object evaluate(String expression, Class expectedType, javax.servlet.jsp.el.VariableResolver variableResolver, - javax.servlet.jsp.el.FunctionMapper functionMapper) throws javax.servlet.jsp.el.ELException { - - return doEvaluate(expression, expectedType, functionMapper); - } - - @SuppressWarnings("rawtypes") - protected Object doEvaluate(String expression, Class expectedType, javax.servlet.jsp.el.FunctionMapper functionMapper) - throws javax.servlet.jsp.el.ELException { - - try { - return ExpressionEvaluatorManager.evaluate("JSP EL expression", expression, expectedType, this.pageContext); - } - catch (JspException ex) { - throw new javax.servlet.jsp.el.ELException("Parsing of JSP EL expression \"" + expression + "\" failed", ex); - } - } - -} diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockFilterChain.java b/spring-test/src/main/java/org/springframework/mock/web/MockFilterChain.java index 0f60d941476a..39b874b1664d 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockFilterChain.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockFilterChain.java @@ -22,20 +22,20 @@ import java.util.Iterator; import java.util.List; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** - * Mock implementation of the {@link javax.servlet.FilterChain} interface. + * Mock implementation of the {@link jakarta.servlet.FilterChain} interface. * *

    A {@link MockFilterChain} can be configured with one or more filters and a * Servlet to invoke. The first time the chain is called, it invokes all filters diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockFilterConfig.java b/spring-test/src/main/java/org/springframework/mock/web/MockFilterConfig.java index 172dd6468738..4755b5168353 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockFilterConfig.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockFilterConfig.java @@ -21,17 +21,17 @@ import java.util.LinkedHashMap; import java.util.Map; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Mock implementation of the {@link javax.servlet.FilterConfig} interface. + * Mock implementation of the {@link jakarta.servlet.FilterConfig} interface. * *

    Used for testing the web framework; also useful for testing - * custom {@link javax.servlet.Filter} implementations. + * custom {@link jakarta.servlet.Filter} implementations. * * @author Juergen Hoeller * @since 1.0.2 diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletMapping.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletMapping.java index 62664d5dac32..17615a3bdcf9 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletMapping.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletMapping.java @@ -16,8 +16,8 @@ package org.springframework.mock.web; -import javax.servlet.http.HttpServletMapping; -import javax.servlet.http.MappingMatch; +import jakarta.servlet.http.HttpServletMapping; +import jakarta.servlet.http.MappingMatch; import org.springframework.lang.Nullable; diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java index e12c278baca2..1a3e7102e9e1 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java @@ -43,20 +43,20 @@ import java.util.TimeZone; import java.util.stream.Collectors; -import javax.servlet.AsyncContext; -import javax.servlet.DispatcherType; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpUpgradeHandler; -import javax.servlet.http.Part; +import jakarta.servlet.AsyncContext; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.HttpUpgradeHandler; +import jakarta.servlet.http.Part; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -71,7 +71,7 @@ import org.springframework.util.StringUtils; /** - * Mock implementation of the {@link javax.servlet.http.HttpServletRequest} interface. + * Mock implementation of the {@link jakarta.servlet.http.HttpServletRequest} interface. * *

    The default, preferred {@link Locale} for the server mocked by this request * is {@link Locale#ENGLISH}. This value can be changed via {@link #addPreferredLocale} @@ -820,7 +820,7 @@ private void updateAcceptLanguageHeader() { *

    In contrast to the Servlet specification, this mock implementation * does not take into consideration any locales * specified via the {@code Accept-Language} header. - * @see javax.servlet.ServletRequest#getLocale() + * @see jakarta.servlet.ServletRequest#getLocale() * @see #addPreferredLocale(Locale) * @see #setPreferredLocales(List) */ @@ -838,7 +838,7 @@ public Locale getLocale() { *

    In contrast to the Servlet specification, this mock implementation * does not take into consideration any locales * specified via the {@code Accept-Language} header. - * @see javax.servlet.ServletRequest#getLocales() + * @see jakarta.servlet.ServletRequest#getLocales() * @see #addPreferredLocale(Locale) * @see #setPreferredLocales(List) */ @@ -861,7 +861,7 @@ public void setSecure(boolean secure) { /** * Return {@code true} if the {@link #setSecure secure} flag has been set * to {@code true} or if the {@link #getScheme scheme} is {@code https}. - * @see javax.servlet.ServletRequest#isSecure() + * @see jakarta.servlet.ServletRequest#isSecure() */ @Override public boolean isSecure() { diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java index a1b3eca3b08d..df02fa4deba8 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java @@ -38,9 +38,9 @@ import java.util.Map; import java.util.TimeZone; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -51,7 +51,7 @@ import org.springframework.web.util.WebUtils; /** - * Mock implementation of the {@link javax.servlet.http.HttpServletResponse} interface. + * Mock implementation of the {@link jakarta.servlet.http.HttpServletResponse} interface. * *

    As of Spring Framework 5.0, this set of mocks is designed on a Servlet 4.0 baseline. * @@ -383,7 +383,7 @@ public void reset() { @Override public void setLocale(@Nullable Locale locale) { - // Although the Javadoc for javax.servlet.ServletResponse.setLocale(Locale) does not + // Although the Javadoc for jakarta.servlet.ServletResponse.setLocale(Locale) does not // state how a null value for the supplied Locale should be handled, both Tomcat and // Jetty simply ignore a null value. So we do the same here. if (locale == null) { diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpSession.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpSession.java index fb8e8bdddd49..244880d8d798 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpSession.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpSession.java @@ -25,17 +25,17 @@ import java.util.LinkedHashSet; import java.util.Map; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSessionBindingEvent; +import jakarta.servlet.http.HttpSessionBindingListener; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** - * Mock implementation of the {@link javax.servlet.http.HttpSession} interface. + * Mock implementation of the {@link jakarta.servlet.http.HttpSession} interface. * *

    As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline. * @@ -149,7 +149,7 @@ public int getMaxInactiveInterval() { } @Override - public javax.servlet.http.HttpSessionContext getSessionContext() { + public jakarta.servlet.http.HttpSessionContext getSessionContext() { throw new UnsupportedOperationException("getSessionContext"); } diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockJspWriter.java b/spring-test/src/main/java/org/springframework/mock/web/MockJspWriter.java index 5eabb13e27a7..b99202c1e530 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockJspWriter.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockJspWriter.java @@ -20,13 +20,13 @@ import java.io.PrintWriter; import java.io.Writer; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.JspWriter; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.jsp.JspWriter; import org.springframework.lang.Nullable; /** - * Mock implementation of the {@link javax.servlet.jsp.JspWriter} class. + * Mock implementation of the {@link jakarta.servlet.jsp.JspWriter} class. * Only necessary for testing applications when testing custom JSP tags. * * @author Juergen Hoeller diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java b/spring-test/src/main/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java index 15153dcea3e4..af199e423362 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java @@ -24,9 +24,9 @@ import java.util.List; import java.util.Map; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.Part; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Part; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockPageContext.java b/spring-test/src/main/java/org/springframework/mock/web/MockPageContext.java index 565da0386e1b..9911449917c9 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockPageContext.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockPageContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,24 +24,24 @@ import java.util.LinkedHashSet; import java.util.Map; -import javax.el.ELContext; -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.PageContext; +import jakarta.el.ELContext; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.jsp.JspWriter; +import jakarta.servlet.jsp.PageContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Mock implementation of the {@link javax.servlet.jsp.PageContext} interface. + * Mock implementation of the {@link jakarta.servlet.jsp.PageContext} interface. * Only necessary for testing applications when testing custom JSP tags. * *

    Note: Expects initialization via the constructor rather than via the @@ -293,8 +293,9 @@ public JspWriter getOut() { @Override @Deprecated - public javax.servlet.jsp.el.ExpressionEvaluator getExpressionEvaluator() { - return new MockExpressionEvaluator(this); + @Nullable + public jakarta.servlet.jsp.el.ExpressionEvaluator getExpressionEvaluator() { + return null; } @Override @@ -306,7 +307,7 @@ public ELContext getELContext() { @Override @Deprecated @Nullable - public javax.servlet.jsp.el.VariableResolver getVariableResolver() { + public jakarta.servlet.jsp.el.VariableResolver getVariableResolver() { return null; } diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockPart.java b/spring-test/src/main/java/org/springframework/mock/web/MockPart.java index d68dd3b3095c..f706aabbda74 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockPart.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockPart.java @@ -22,7 +22,7 @@ import java.util.Collection; import java.util.Collections; -import javax.servlet.http.Part; +import jakarta.servlet.http.Part; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -30,7 +30,7 @@ import org.springframework.util.Assert; /** - * Mock implementation of {@code javax.servlet.http.Part}. + * Mock implementation of {@code jakarta.servlet.http.Part}. * * @author Rossen Stoyanchev * @author Juergen Hoeller diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockRequestDispatcher.java b/spring-test/src/main/java/org/springframework/mock/web/MockRequestDispatcher.java index eb8d976539d8..9a34e6b45cce 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockRequestDispatcher.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockRequestDispatcher.java @@ -16,18 +16,17 @@ package org.springframework.mock.web; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.util.Assert; /** - * Mock implementation of the {@link javax.servlet.RequestDispatcher} interface. + * Mock implementation of the {@link jakarta.servlet.RequestDispatcher} interface. * * @author Rod Johnson * @author Juergen Hoeller diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockServletConfig.java b/spring-test/src/main/java/org/springframework/mock/web/MockServletConfig.java index 1f2208a10bcb..08b7d4826a31 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockServletConfig.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockServletConfig.java @@ -21,14 +21,14 @@ import java.util.LinkedHashMap; import java.util.Map; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Mock implementation of the {@link javax.servlet.ServletConfig} interface. + * Mock implementation of the {@link jakarta.servlet.ServletConfig} interface. * * @author Rod Johnson * @author Juergen Hoeller diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java b/spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java index 232faade3c34..736d44168ef1 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java @@ -31,17 +31,16 @@ import java.util.Map; import java.util.Set; -import javax.servlet.Filter; -import javax.servlet.FilterRegistration; -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; -import javax.servlet.SessionCookieConfig; -import javax.servlet.SessionTrackingMode; -import javax.servlet.descriptor.JspConfigDescriptor; - +import jakarta.servlet.Filter; +import jakarta.servlet.FilterRegistration; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRegistration; +import jakarta.servlet.SessionCookieConfig; +import jakarta.servlet.SessionTrackingMode; +import jakarta.servlet.descriptor.JspConfigDescriptor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -59,7 +58,7 @@ import org.springframework.web.util.WebUtils; /** - * Mock implementation of the {@link javax.servlet.ServletContext} interface. + * Mock implementation of the {@link jakarta.servlet.ServletContext} interface. * *

    As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline. * @@ -663,7 +662,7 @@ public T createServlet(Class c) throws ServletException { /** * This method always returns {@code null}. - * @see javax.servlet.ServletContext#getServletRegistration(java.lang.String) + * @see jakarta.servlet.ServletContext#getServletRegistration(java.lang.String) */ @Override @Nullable @@ -673,7 +672,7 @@ public ServletRegistration getServletRegistration(String servletName) { /** * This method always returns an {@linkplain Collections#emptyMap empty map}. - * @see javax.servlet.ServletContext#getServletRegistrations() + * @see jakarta.servlet.ServletContext#getServletRegistrations() */ @Override public Map getServletRegistrations() { @@ -702,7 +701,7 @@ public T createFilter(Class c) throws ServletException { /** * This method always returns {@code null}. - * @see javax.servlet.ServletContext#getFilterRegistration(java.lang.String) + * @see jakarta.servlet.ServletContext#getFilterRegistration(java.lang.String) */ @Override @Nullable @@ -712,7 +711,7 @@ public FilterRegistration getFilterRegistration(String filterName) { /** * This method always returns an {@linkplain Collections#emptyMap empty map}. - * @see javax.servlet.ServletContext#getFilterRegistrations() + * @see jakarta.servlet.ServletContext#getFilterRegistrations() */ @Override public Map getFilterRegistrations() { diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockSessionCookieConfig.java b/spring-test/src/main/java/org/springframework/mock/web/MockSessionCookieConfig.java index 8ea88f1a8bc5..3a98a87a6027 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockSessionCookieConfig.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockSessionCookieConfig.java @@ -16,16 +16,16 @@ package org.springframework.mock.web; -import javax.servlet.SessionCookieConfig; +import jakarta.servlet.SessionCookieConfig; import org.springframework.lang.Nullable; /** - * Mock implementation of the {@link javax.servlet.SessionCookieConfig} interface. + * Mock implementation of the {@link jakarta.servlet.SessionCookieConfig} interface. * * @author Juergen Hoeller * @since 4.0 - * @see javax.servlet.ServletContext#getSessionCookieConfig() + * @see jakarta.servlet.ServletContext#getSessionCookieConfig() */ public class MockSessionCookieConfig implements SessionCookieConfig { diff --git a/spring-test/src/main/java/org/springframework/mock/web/PassThroughFilterChain.java b/spring-test/src/main/java/org/springframework/mock/web/PassThroughFilterChain.java index dfc5f7b303ab..03fbfac1051c 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/PassThroughFilterChain.java +++ b/spring-test/src/main/java/org/springframework/mock/web/PassThroughFilterChain.java @@ -18,26 +18,26 @@ import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Implementation of the {@link javax.servlet.FilterConfig} interface which + * Implementation of the {@link jakarta.servlet.FilterConfig} interface which * simply passes the call through to a given Filter/FilterChain combination * (indicating the next Filter in the chain along with the FilterChain that it is * supposed to work on) or to a given Servlet (indicating the end of the chain). * * @author Juergen Hoeller * @since 2.0.3 - * @see javax.servlet.Filter - * @see javax.servlet.Servlet + * @see jakarta.servlet.Filter + * @see jakarta.servlet.Servlet * @see MockFilterChain */ public class PassThroughFilterChain implements FilterChain { diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java index 9eaabcb4f035..8b65d08e2b61 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java +++ b/spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java @@ -57,7 +57,7 @@ * {@link org.springframework.stereotype.Component @Component}, * {@link org.springframework.stereotype.Service @Service}, * {@link org.springframework.stereotype.Repository @Repository}, etc.) - *

  • A JSR-330 compliant class that is annotated with {@code javax.inject} annotations
  • + *
  • A JSR-330 compliant class that is annotated with {@code jakarta.inject} annotations
  • *
  • Any class that contains {@link org.springframework.context.annotation.Bean @Bean}-methods
  • *
  • Any other class that is intended to be registered as a Spring component (i.e., a Spring bean * in the {@code ApplicationContext}), potentially taking advantage of automatic autowiring of a diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/ContextLoader.java index 232846264a1d..8856f6d89c87 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/ContextLoader.java @@ -72,8 +72,8 @@ public interface ContextLoader { * contexts} loaded by this ContextLoader. Beans will therefore automatically * be candidates for annotation-based dependency injection using * {@link org.springframework.beans.factory.annotation.Autowired @Autowired}, - * {@link javax.annotation.Resource @Resource}, and - * {@link javax.inject.Inject @Inject}. + * {@link jakarta.annotation.Resource @Resource}, and + * {@link jakarta.inject.Inject @Inject}. *

    Any ApplicationContext loaded by a ContextLoader must * register a JVM shutdown hook for itself. Unless the context gets closed * early, all context instances will be automatically closed on JVM diff --git a/spring-test/src/main/java/org/springframework/test/context/SmartContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/SmartContextLoader.java index dfdd198c45fc..f59be7fc4f99 100644 --- a/spring-test/src/main/java/org/springframework/test/context/SmartContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/SmartContextLoader.java @@ -101,8 +101,8 @@ public interface SmartContextLoader extends ContextLoader { * {@code SmartContextLoader}. Beans will therefore automatically be * candidates for annotation-based dependency injection using * {@link org.springframework.beans.factory.annotation.Autowired @Autowired}, - * {@link javax.annotation.Resource @Resource}, and - * {@link javax.inject.Inject @Inject}. In addition, concrete implementations + * {@link jakarta.annotation.Resource @Resource}, and + * {@link jakarta.inject.Inject @Inject}. In addition, concrete implementations * should set the active bean definition profiles in the context's * {@link org.springframework.core.env.Environment Environment}. *

    Any {@code ApplicationContext} loaded by a diff --git a/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java index c363dd2d671c..e42545a46994 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java @@ -16,8 +16,7 @@ package org.springframework.test.context.web; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java index b981840f9ba5..3051524eb899 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java @@ -16,8 +16,7 @@ package org.springframework.test.context.web; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainer.java b/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainer.java index b375615283f7..cc86220b62d5 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainer.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainer.java @@ -21,16 +21,16 @@ import java.util.Collections; import java.util.Set; -import javax.websocket.ClientEndpointConfig; -import javax.websocket.DeploymentException; -import javax.websocket.Endpoint; -import javax.websocket.Extension; -import javax.websocket.Session; -import javax.websocket.server.ServerContainer; -import javax.websocket.server.ServerEndpointConfig; +import jakarta.websocket.ClientEndpointConfig; +import jakarta.websocket.DeploymentException; +import jakarta.websocket.Endpoint; +import jakarta.websocket.Extension; +import jakarta.websocket.Session; +import jakarta.websocket.server.ServerContainer; +import jakarta.websocket.server.ServerEndpointConfig; /** - * Mock implementation of the {@link javax.websocket.server.ServerContainer} interface. + * Mock implementation of the {@link jakarta.websocket.server.ServerContainer} interface. * * @author Sam Brannen * @since 4.3.1 diff --git a/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizer.java b/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizer.java index 1a8e129f80a9..c746941672bf 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizer.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizer.java @@ -16,7 +16,7 @@ package org.springframework.test.context.web.socket; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.lang.Nullable; @@ -27,7 +27,7 @@ /** * {@link ContextCustomizer} that instantiates a new {@link MockServerContainer} * and stores it in the {@code ServletContext} under the attribute named - * {@code "javax.websocket.server.ServerContainer"}. + * {@code "jakarta.websocket.server.ServerContainer"}. * * @author Sam Brannen * @since 4.3.1 @@ -40,7 +40,7 @@ public void customizeContext(ConfigurableApplicationContext context, MergedConte WebApplicationContext wac = (WebApplicationContext) context; ServletContext sc = wac.getServletContext(); if (sc != null) { - sc.setAttribute("javax.websocket.server.ServerContainer", new MockServerContainer()); + sc.setAttribute("jakarta.websocket.server.ServerContainer", new MockServerContainer()); } } } diff --git a/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizerFactory.java b/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizerFactory.java index e69b2bab0726..0cb74f154c0e 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizerFactory.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizerFactory.java @@ -42,7 +42,7 @@ class MockServerContainerContextCustomizerFactory implements ContextCustomizerFa private static final String MOCK_SERVER_CONTAINER_CONTEXT_CUSTOMIZER_CLASS_NAME = "org.springframework.test.context.web.socket.MockServerContainerContextCustomizer"; - private static final boolean webSocketPresent = ClassUtils.isPresent("javax.websocket.server.ServerContainer", + private static final boolean webSocketPresent = ClassUtils.isPresent("jakarta.websocket.server.ServerContainer", MockServerContainerContextCustomizerFactory.class.getClassLoader()); diff --git a/spring-test/src/main/java/org/springframework/test/util/ReflectionTestUtils.java b/spring-test/src/main/java/org/springframework/test/util/ReflectionTestUtils.java index 2197d861b0b0..419374b95767 100644 --- a/spring-test/src/main/java/org/springframework/test/util/ReflectionTestUtils.java +++ b/spring-test/src/main/java/org/springframework/test/util/ReflectionTestUtils.java @@ -45,12 +45,12 @@ * {@code public} setter methods for properties in a domain entity.

  • *
  • Spring's support for annotations such as * {@link org.springframework.beans.factory.annotation.Autowired @Autowired}, - * {@link javax.inject.Inject @Inject}, and - * {@link javax.annotation.Resource @Resource} which provides dependency + * {@link jakarta.inject.Inject @Inject}, and + * {@link jakarta.annotation.Resource @Resource} which provides dependency * injection for {@code private} or {@code protected} fields, setter methods, * and configuration methods.
  • - *
  • Use of annotations such as {@link javax.annotation.PostConstruct @PostConstruct} - * and {@link javax.annotation.PreDestroy @PreDestroy} for lifecycle callback + *
  • Use of annotations such as {@link jakarta.annotation.PostConstruct @PostConstruct} + * and {@link jakarta.annotation.PreDestroy @PreDestroy} for lifecycle callback * methods.
  • * * diff --git a/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java b/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java index ec883b02a41c..0ce6350a5da6 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,32 +16,36 @@ package org.springframework.test.web.client.match; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.util.List; import java.util.Map; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; +import org.apache.tomcat.util.http.fileupload.FileItem; +import org.apache.tomcat.util.http.fileupload.FileUpload; +import org.apache.tomcat.util.http.fileupload.UploadContext; +import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory; import org.hamcrest.Matcher; import org.w3c.dom.Node; import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.converter.FormHttpMessageConverter; +import org.springframework.lang.Nullable; import org.springframework.mock.http.MockHttpInputMessage; import org.springframework.mock.http.client.MockClientHttpRequest; -import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.test.util.JsonExpectationsHelper; import org.springframework.test.util.XmlExpectationsHelper; import org.springframework.test.web.client.RequestMatcher; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StreamUtils; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; -import org.springframework.web.multipart.commons.CommonsMultipartResolver; import static org.hamcrest.MatcherAssert.assertThat; import static org.springframework.test.util.AssertionErrors.assertEquals; @@ -217,7 +221,7 @@ public RequestMatcher multipartDataContains(Map expectedMap) { @SuppressWarnings("ConstantConditions") private RequestMatcher multipartData(MultiValueMap expectedMap, boolean containsExactly) { return request -> { - MultiValueMap actualMap = MultipartHelper.parse(request); + MultiValueMap actualMap = MultipartHelper.parse((MockClientHttpRequest) request); if (containsExactly) { assertEquals("Multipart request content: " + actualMap, expectedMap.size(), actualMap.size()); } @@ -235,8 +239,8 @@ private RequestMatcher multipartData(MultiValueMap expectedMap, boole expected = StreamUtils.copyToByteArray(((Resource) expected).getInputStream()); } if (expected instanceof byte[]) { - assertTrue("Multipart is not a file", actual instanceof MultipartFile); - assertEquals("Multipart content", expected, ((MultipartFile) actual).getBytes()); + assertTrue("Multipart is not a file", actual instanceof byte[]); + assertEquals("Multipart content", expected, (byte[]) actual); } else if (expected instanceof String) { assertTrue("Multipart is not a String", actual instanceof String); @@ -356,28 +360,42 @@ public final void match(ClientHttpRequest request) throws IOException, Assertion private static class MultipartHelper { - public static MultiValueMap parse(ClientHttpRequest request) { - MultipartHttpServletRequest servletRequest = adaptToMultipartRequest(request); - MultiValueMap result = new LinkedMultiValueMap<>(); - for (Map.Entry> entry : servletRequest.getMultiFileMap().entrySet()) { - for (MultipartFile value : entry.getValue()) { - result.add(entry.getKey(), value); + public static MultiValueMap parse(MockClientHttpRequest request) { + try { + FileUpload fileUpload = new FileUpload(new DiskFileItemFactory()); + + List fileItems = fileUpload.parseRequest(new UploadContext() { + private final byte[] body = request.getBodyAsBytes(); + @Override + @Nullable + public String getCharacterEncoding() { + return request.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING); + } + @Override + @Nullable + public String getContentType() { + return request.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE); + } + @Override + public InputStream getInputStream() { + return new ByteArrayInputStream(this.body); + } + @Override + public long contentLength() { + return this.body.length; + } + }); + + MultiValueMap result = new LinkedMultiValueMap<>(); + for (FileItem fileItem : fileItems) { + result.add(fileItem.getFieldName(), + (fileItem.isFormField() ? fileItem.getString() : fileItem.get())); } + return result; } - for (Map.Entry entry : servletRequest.getParameterMap().entrySet()) { - for (String value : entry.getValue()) { - result.add(entry.getKey(), value); - } + catch (Exception ex) { + throw new IllegalStateException("Failed to parse multipart request", ex); } - return result; - } - - private static MultipartHttpServletRequest adaptToMultipartRequest(ClientHttpRequest request) { - MockClientHttpRequest source = (MockClientHttpRequest) request; - MockHttpServletRequest target = new MockHttpServletRequest(); - target.setContent(source.getBodyAsBytes()); - source.getHeaders().forEach((name, values) -> values.forEach(v -> target.addHeader(name, v))); - return new CommonsMultipartResolver().resolveMultipart(target); } } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvc.java b/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvc.java index 0c8a28c7fd69..16a968e9a852 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvc.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvc.java @@ -20,13 +20,13 @@ import java.util.ArrayList; import java.util.List; -import javax.servlet.AsyncContext; -import javax.servlet.DispatcherType; -import javax.servlet.Filter; -import javax.servlet.ServletContext; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.AsyncContext; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.Filter; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.springframework.beans.Mergeable; import org.springframework.lang.Nullable; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvcBuilderSupport.java b/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvcBuilderSupport.java index d635b00b1bab..7ea2eac36338 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvcBuilderSupport.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvcBuilderSupport.java @@ -19,8 +19,8 @@ import java.nio.charset.Charset; import java.util.List; -import javax.servlet.Filter; -import javax.servlet.ServletException; +import jakarta.servlet.Filter; +import jakarta.servlet.ServletException; import org.springframework.core.NestedRuntimeException; import org.springframework.lang.Nullable; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/RequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/RequestBuilder.java index db14261075d3..e6537d810d35 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/RequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/RequestBuilder.java @@ -16,7 +16,7 @@ package org.springframework.test.web.servlet; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.mock.web.MockHttpServletRequest; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/TestDispatcherServlet.java b/spring-test/src/main/java/org/springframework/test/web/servlet/TestDispatcherServlet.java index 8c9a4f9fb7ac..6d97dfce3485 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/TestDispatcherServlet.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/TestDispatcherServlet.java @@ -20,10 +20,10 @@ import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.mock.web.MockAsyncContext; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java index cf1b2d60fe8a..e9ccb32e6b30 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java @@ -15,7 +15,7 @@ */ package org.springframework.test.web.servlet.client; -import javax.servlet.Filter; +import jakarta.servlet.Filter; import org.springframework.http.client.reactive.ClientHttpConnector; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcHttpConnector.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcHttpConnector.java index 705e89432b7c..edfd28361e29 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcHttpConnector.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcHttpConnector.java @@ -23,8 +23,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; -import javax.servlet.http.Cookie; - +import jakarta.servlet.http.Cookie; import reactor.core.publisher.Mono; import org.springframework.core.ResolvableType; @@ -166,7 +165,7 @@ private MockHttpServletRequestBuilder initRequestBuilder( buffer.read(partBytes); DataBufferUtils.release(buffer); - // Adapt to javax.servlet.http.Part... + // Adapt to jakarta.servlet.http.Part... MockPart mockPart = (part instanceof FilePart ? new MockPart(part.name(), ((FilePart) part).filename(), partBytes) : new MockPart(part.name(), partBytes)); diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java index a59879f795d4..2738797ad09b 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java @@ -17,7 +17,7 @@ import java.util.function.Supplier; -import javax.servlet.Filter; +import jakarta.servlet.Filter; import org.springframework.format.support.FormattingConversionService; import org.springframework.http.client.reactive.ClientHttpConnector; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java index 7d76e63e7511..16df1e7e4894 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java @@ -33,17 +33,16 @@ import java.util.Set; import java.util.StringTokenizer; -import javax.servlet.ServletContext; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - import com.gargoylesoftware.htmlunit.CookieManager; import com.gargoylesoftware.htmlunit.FormEncodingType; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.WebRequest; import com.gargoylesoftware.htmlunit.util.KeyDataPair; import com.gargoylesoftware.htmlunit.util.NameValuePair; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; import org.springframework.beans.Mergeable; import org.springframework.http.MediaType; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java index cbe396dc861b..e7d3eb3e3129 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java @@ -85,7 +85,7 @@ public MockMvcWebConnection(MockMvc mockMvc, WebClient webClient) { * Create a new instance with the specified context path. *

    The path may be {@code null} in which case the first path segment * of the URL is turned into the contextPath. Otherwise it must conform - * to {@link javax.servlet.http.HttpServletRequest#getContextPath()} + * to {@link jakarta.servlet.http.HttpServletRequest#getContextPath()} * which states that it can be an empty string and otherwise must start * with a "/" character and not end with a "/" character. * @param mockMvc the {@code MockMvc} instance to use (never {@code null}) @@ -105,7 +105,7 @@ public MockMvcWebConnection(MockMvc mockMvc, WebClient webClient, @Nullable Stri /** * Validate the supplied {@code contextPath}. *

    If the value is not {@code null}, it must conform to - * {@link javax.servlet.http.HttpServletRequest#getContextPath()} which + * {@link jakarta.servlet.http.HttpServletRequest#getContextPath()} which * states that it can be an empty string and otherwise must start with * a "/" character and not end with a "/" character. * @param contextPath the path to validate @@ -155,10 +155,10 @@ private MockHttpServletResponse getResponse(RequestBuilder requestBuilder) throw return resultActions.andReturn().getResponse(); } - private void storeCookies(WebRequest webRequest, javax.servlet.http.Cookie[] cookies) { + private void storeCookies(WebRequest webRequest, jakarta.servlet.http.Cookie[] cookies) { Date now = new Date(); CookieManager cookieManager = this.webClient.getCookieManager(); - for (javax.servlet.http.Cookie cookie : cookies) { + for (jakarta.servlet.http.Cookie cookie : cookies) { if (cookie.getDomain() == null) { cookie.setDomain(webRequest.getUrl().getHost()); } @@ -173,7 +173,7 @@ private void storeCookies(WebRequest webRequest, javax.servlet.http.Cookie[] coo } } - private static com.gargoylesoftware.htmlunit.util.Cookie createCookie(javax.servlet.http.Cookie cookie) { + private static com.gargoylesoftware.htmlunit.util.Cookie createCookie(jakarta.servlet.http.Cookie cookie) { Date expires = null; if (cookie.getMaxAge() > -1) { expires = new Date(System.currentTimeMillis() + cookie.getMaxAge() * 1000); diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java index c4ec1cd91733..e7122070f130 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java @@ -30,10 +30,10 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.ServletContext; -import javax.servlet.ServletRequest; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpSession; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpSession; import org.springframework.beans.Mergeable; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -185,7 +185,7 @@ private static URI initUri(String url, Object[] vars) { * the requestURI. This is because most applications don't actually depend * on the name under which they're deployed. If specified here, the context * path must start with a "/" and must not end with a "/". - * @see javax.servlet.http.HttpServletRequest#getContextPath() + * @see jakarta.servlet.http.HttpServletRequest#getContextPath() */ public MockHttpServletRequestBuilder contextPath(String contextPath) { if (StringUtils.hasText(contextPath)) { @@ -207,7 +207,7 @@ public MockHttpServletRequestBuilder contextPath(String contextPath) { * {@code "/accounts/1"} as opposed to {@code "/main/accounts/1"}. * If specified here, the servletPath must start with a "/" and must not * end with a "/". - * @see javax.servlet.http.HttpServletRequest#getServletPath() + * @see jakarta.servlet.http.HttpServletRequest#getServletPath() */ public MockHttpServletRequestBuilder servletPath(String servletPath) { if (StringUtils.hasText(servletPath)) { @@ -224,7 +224,7 @@ public MockHttpServletRequestBuilder servletPath(String servletPath) { * by removing the contextPath and the servletPath from the requestURI and using any * remaining part. If specified here, the pathInfo must start with a "/". *

    If specified, the pathInfo will be used as-is. - * @see javax.servlet.http.HttpServletRequest#getPathInfo() + * @see jakarta.servlet.http.HttpServletRequest#getPathInfo() */ public MockHttpServletRequestBuilder pathInfo(@Nullable String pathInfo) { if (StringUtils.hasText(pathInfo)) { diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java index 73a0a3bd29db..e9a8b694493e 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java @@ -26,8 +26,8 @@ import java.util.Collection; import java.util.List; -import javax.servlet.ServletContext; -import javax.servlet.http.Part; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.Part; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMvcRequestBuilders.java b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMvcRequestBuilders.java index 068320216f64..c9e7dbc74cc3 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMvcRequestBuilders.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMvcRequestBuilders.java @@ -18,7 +18,7 @@ import java.net.URI; -import javax.servlet.DispatcherType; +import jakarta.servlet.DispatcherType; import org.springframework.http.HttpMethod; import org.springframework.mock.web.MockHttpServletRequest; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/ContentResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/ContentResultMatchers.java index f2d9360107f1..c91b2631ced0 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/ContentResultMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/ContentResultMatchers.java @@ -20,10 +20,10 @@ import java.nio.charset.StandardCharsets; import java.util.Map; -import javax.servlet.http.HttpServletResponse; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; +import jakarta.servlet.http.HttpServletResponse; import org.hamcrest.Matcher; import org.w3c.dom.Node; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/CookieResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/CookieResultMatchers.java index a548731f2abc..a8a40a29c448 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/CookieResultMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/CookieResultMatchers.java @@ -16,8 +16,7 @@ package org.springframework.test.web.servlet.result; -import javax.servlet.http.Cookie; - +import jakarta.servlet.http.Cookie; import org.hamcrest.Matcher; import org.springframework.test.web.servlet.MvcResult; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/PrintingResultHandler.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/PrintingResultHandler.java index f0ea1c5b658d..f9539b1a6a0a 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/PrintingResultHandler.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/PrintingResultHandler.java @@ -21,9 +21,9 @@ import java.util.Map; import java.util.stream.Collectors; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; import org.springframework.core.style.ToStringCreator; import org.springframework.http.HttpHeaders; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/RequestResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/RequestResultMatchers.java index 926e3f4349ff..2cd6f3b9fc28 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/RequestResultMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/RequestResultMatchers.java @@ -18,9 +18,8 @@ import java.util.concurrent.Callable; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; import org.hamcrest.Matcher; import org.springframework.lang.Nullable; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/AbstractMockMvcBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/AbstractMockMvcBuilder.java index e5ed43ce30aa..dcf4b06b687e 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/AbstractMockMvcBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/AbstractMockMvcBuilder.java @@ -20,8 +20,8 @@ import java.util.ArrayList; import java.util.List; -import javax.servlet.Filter; -import javax.servlet.ServletContext; +import jakarta.servlet.Filter; +import jakarta.servlet.ServletContext; import org.springframework.lang.Nullable; import org.springframework.mock.web.MockServletConfig; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.java index 45b9f05d04a4..fcd96945c261 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.java @@ -18,7 +18,7 @@ import java.nio.charset.Charset; -import javax.servlet.Filter; +import jakarta.servlet.Filter; import org.springframework.test.web.servlet.DispatcherServletCustomizer; import org.springframework.test.web.servlet.MockMvcBuilder; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/DefaultMockMvcBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/DefaultMockMvcBuilder.java index 4e47244f655c..7b72cc947461 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/DefaultMockMvcBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/DefaultMockMvcBuilder.java @@ -16,7 +16,7 @@ package org.springframework.test.web.servlet.setup; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.context.ApplicationContext; import org.springframework.util.Assert; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/MockMvcBuilders.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/MockMvcBuilders.java index 60bab94c01ef..71b523d7971d 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/MockMvcBuilders.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/MockMvcBuilders.java @@ -45,7 +45,7 @@ private MockMvcBuilders() { *

    The {@link org.springframework.web.servlet.DispatcherServlet DispatcherServlet} * will use the context to discover Spring MVC infrastructure and application * controllers in it. The context must have been configured with a - * {@link javax.servlet.ServletContext ServletContext}. + * {@link jakarta.servlet.ServletContext ServletContext}. */ public static DefaultMockMvcBuilder webAppContextSetup(WebApplicationContext context) { return new DefaultMockMvcBuilder(context); diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/PatternMappingFilterProxy.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/PatternMappingFilterProxy.java index 1966016813c4..2bcb3135b843 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/PatternMappingFilterProxy.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/PatternMappingFilterProxy.java @@ -20,13 +20,13 @@ import java.util.ArrayList; import java.util.List; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.util.Assert; import org.springframework.web.util.UrlPathHelper; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/SharedHttpSessionConfigurer.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/SharedHttpSessionConfigurer.java index 7fcc663134a3..d12bca60d824 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/SharedHttpSessionConfigurer.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/SharedHttpSessionConfigurer.java @@ -16,7 +16,7 @@ package org.springframework.test.web.servlet.setup; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSession; import org.springframework.lang.Nullable; import org.springframework.test.web.servlet.request.RequestPostProcessor; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java index 1675a4940348..ac94d5c103fc 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java @@ -25,7 +25,7 @@ import java.util.Map; import java.util.function.Supplier; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeansException; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java index c5271e8d18e8..368bd0bede23 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.Set; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeansException; diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockHttpServletRequestDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockHttpServletRequestDsl.kt index e997204d3fd0..d00d9fe6c951 100644 --- a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockHttpServletRequestDsl.kt +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockHttpServletRequestDsl.kt @@ -24,7 +24,7 @@ import org.springframework.test.web.servlet.request.RequestPostProcessor import org.springframework.util.MultiValueMap import java.security.Principal import java.util.* -import javax.servlet.http.Cookie +import jakarta.servlet.http.Cookie /** * Provide a [MockHttpServletRequestBuilder] Kotlin DSL in order to be able to write idiomatic Kotlin code. diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMultipartHttpServletRequestDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMultipartHttpServletRequestDsl.kt index 1a2e83745a7d..e2b3ad565cf7 100644 --- a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMultipartHttpServletRequestDsl.kt +++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMultipartHttpServletRequestDsl.kt @@ -18,7 +18,7 @@ package org.springframework.test.web.servlet import org.springframework.mock.web.MockMultipartFile import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder -import javax.servlet.http.Part +import jakarta.servlet.http.Part /** * Provide a [MockMultipartHttpServletRequestBuilder] Kotlin DSL in order to be able to write idiomatic Kotlin code. diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockFilterChainTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockFilterChainTests.java index 4babe4467a32..de0a06343eec 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockFilterChainTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockFilterChainTests.java @@ -18,14 +18,13 @@ import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletRequestTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletRequestTests.java index 6ade7c90a710..19c428eae0c1 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletRequestTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletRequestTests.java @@ -30,8 +30,7 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.http.Cookie; - +import jakarta.servlet.http.Cookie; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java index fe0f90f7b500..bc4ebd8a9ea0 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java @@ -24,9 +24,8 @@ import java.util.Collection; import java.util.Locale; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockHttpSessionTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockHttpSessionTests.java index a27c0f12c402..d20693b2d204 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockHttpSessionTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockHttpSessionTests.java @@ -18,9 +18,8 @@ import java.util.concurrent.atomic.AtomicInteger; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; - +import jakarta.servlet.http.HttpSessionBindingEvent; +import jakarta.servlet.http.HttpSessionBindingListener; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockPageContextTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockPageContextTests.java index d9026333731e..6ab8d15b259d 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockPageContextTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockPageContextTests.java @@ -16,8 +16,7 @@ package org.springframework.mock.web; -import javax.servlet.jsp.PageContext; - +import jakarta.servlet.jsp.PageContext; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java index fd26ff1e25ce..e9ef2635f8b3 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java @@ -21,10 +21,9 @@ import java.util.Map; import java.util.Set; -import javax.servlet.FilterRegistration; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletRegistration; - +import jakarta.servlet.FilterRegistration; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletRegistration; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/context/groovy/GroovySpringContextTests.java b/spring-test/src/test/java/org/springframework/test/context/groovy/GroovySpringContextTests.java index ae020512502a..fd3034b4524d 100644 --- a/spring-test/src/test/java/org/springframework/test/context/groovy/GroovySpringContextTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/groovy/GroovySpringContextTests.java @@ -16,8 +16,7 @@ package org.springframework.test.context.groovy; -import javax.annotation.Resource; - +import jakarta.annotation.Resource; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/spring-test/src/test/java/org/springframework/test/context/hierarchies/web/ControllerIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/hierarchies/web/ControllerIntegrationTests.java index c9a689f1ac74..d12afba4c47c 100644 --- a/spring-test/src/test/java/org/springframework/test/context/hierarchies/web/ControllerIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/hierarchies/web/ControllerIntegrationTests.java @@ -16,8 +16,7 @@ package org.springframework.test.context.hierarchies.web; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/spring-test/src/test/java/org/springframework/test/context/hierarchies/web/DispatcherWacRootWacEarTests.java b/spring-test/src/test/java/org/springframework/test/context/hierarchies/web/DispatcherWacRootWacEarTests.java index bb48aefa72db..b4485ebf1ed9 100644 --- a/spring-test/src/test/java/org/springframework/test/context/hierarchies/web/DispatcherWacRootWacEarTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/hierarchies/web/DispatcherWacRootWacEarTests.java @@ -16,8 +16,7 @@ package org.springframework.test.context.hierarchies.web; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/ConcreteTransactionalJUnit4SpringContextTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/ConcreteTransactionalJUnit4SpringContextTests.java index 5112f3770d35..1c95a609d2b4 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/ConcreteTransactionalJUnit4SpringContextTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/ConcreteTransactionalJUnit4SpringContextTests.java @@ -16,8 +16,7 @@ package org.springframework.test.context.junit4; -import javax.annotation.Resource; - +import jakarta.annotation.Resource; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunnerAppCtxTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunnerAppCtxTests.java index 4f17e973e110..710957ab233d 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunnerAppCtxTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunnerAppCtxTests.java @@ -16,10 +16,9 @@ package org.springframework.test.context.junit4; -import javax.annotation.Resource; -import javax.inject.Inject; -import javax.inject.Named; - +import jakarta.annotation.Resource; +import jakarta.inject.Inject; +import jakarta.inject.Named; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests.java index 6c0dc92e9001..d75539d4ebbc 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests.java @@ -16,8 +16,7 @@ package org.springframework.test.context.junit4.orm; -import javax.persistence.PersistenceException; - +import jakarta.persistence.PersistenceException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.exception.ConstraintViolationException; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/Jsr250LifecycleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/Jsr250LifecycleTests.java index 11e4d9e86961..e7889b92399f 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/Jsr250LifecycleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/Jsr250LifecycleTests.java @@ -16,9 +16,8 @@ package org.springframework.test.context.junit4.spr4868; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.After; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/LifecycleBean.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/LifecycleBean.java index be527d05a90c..fe452ee03fc4 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/LifecycleBean.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/LifecycleBean.java @@ -16,9 +16,8 @@ package org.springframework.test.context.junit4.spr4868; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass1.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass1.java index 4726b44119b0..9567ddd3b863 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass1.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass1.java @@ -16,9 +16,9 @@ package org.springframework.test.context.junit4.spr8849; -import javax.annotation.Resource; import javax.sql.DataSource; +import jakarta.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass2.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass2.java index 2b0c99398d53..0cca42550432 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass2.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass2.java @@ -16,9 +16,9 @@ package org.springframework.test.context.junit4.spr8849; -import javax.annotation.Resource; import javax.sql.DataSource; +import jakarta.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass3.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass3.java index 953ee8e471d2..1d978e8524e5 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass3.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass3.java @@ -16,9 +16,9 @@ package org.springframework.test.context.junit4.spr8849; -import javax.annotation.Resource; import javax.sql.DataSource; +import jakarta.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass4.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass4.java index 4f4f76f4bb76..7a6a189549fc 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass4.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/TestClass4.java @@ -16,9 +16,9 @@ package org.springframework.test.context.junit4.spr8849; -import javax.annotation.Resource; import javax.sql.DataSource; +import jakarta.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr9051/LifecycleBean.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9051/LifecycleBean.java index 64876355d053..2a8c01156c2e 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/spr9051/LifecycleBean.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9051/LifecycleBean.java @@ -16,7 +16,7 @@ package org.springframework.test.context.junit4.spr9051; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; /** * Simple POJO that contains lifecycle callbacks. diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/ConcreteTransactionalTestNGSpringContextTests.java b/spring-test/src/test/java/org/springframework/test/context/testng/ConcreteTransactionalTestNGSpringContextTests.java index 3da61007d1ee..191f03683fa6 100644 --- a/spring-test/src/test/java/org/springframework/test/context/testng/ConcreteTransactionalTestNGSpringContextTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/testng/ConcreteTransactionalTestNGSpringContextTests.java @@ -16,8 +16,7 @@ package org.springframework.test.context.testng; -import javax.annotation.Resource; - +import jakarta.annotation.Resource; import org.testng.annotations.AfterClass; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/transaction/ejb/AbstractEjbTxDaoTestNGTests.java b/spring-test/src/test/java/org/springframework/test/context/testng/transaction/ejb/AbstractEjbTxDaoTestNGTests.java index 98eae227ce6c..3b56ad3f3298 100644 --- a/spring-test/src/test/java/org/springframework/test/context/testng/transaction/ejb/AbstractEjbTxDaoTestNGTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/testng/transaction/ejb/AbstractEjbTxDaoTestNGTests.java @@ -16,10 +16,9 @@ package org.springframework.test.context.testng.transaction.ejb; -import javax.ejb.EJB; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; - +import jakarta.ejb.EJB; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/web/TestNGSpringContextWebTests.java b/spring-test/src/test/java/org/springframework/test/context/testng/web/TestNGSpringContextWebTests.java index 14bead449f18..e919453d2f42 100644 --- a/spring-test/src/test/java/org/springframework/test/context/testng/web/TestNGSpringContextWebTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/testng/web/TestNGSpringContextWebTests.java @@ -18,8 +18,7 @@ import java.io.File; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.testng.annotations.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/AbstractEjbTxDaoTests.java b/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/AbstractEjbTxDaoTests.java index a98ce7135cc5..03183be05c6e 100644 --- a/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/AbstractEjbTxDaoTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/AbstractEjbTxDaoTests.java @@ -16,10 +16,9 @@ package org.springframework.test.context.transaction.ejb; -import javax.ejb.EJB; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; - +import jakarta.ejb.EJB; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/dao/AbstractEjbTxTestEntityDao.java b/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/dao/AbstractEjbTxTestEntityDao.java index ed518cfc257c..f1bd39dcaf94 100644 --- a/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/dao/AbstractEjbTxTestEntityDao.java +++ b/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/dao/AbstractEjbTxTestEntityDao.java @@ -16,9 +16,9 @@ package org.springframework.test.context.transaction.ejb.dao; -import javax.ejb.TransactionAttribute; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; +import jakarta.ejb.TransactionAttribute; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import org.springframework.test.context.transaction.ejb.model.TestEntity; diff --git a/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/dao/RequiredEjbTxTestEntityDao.java b/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/dao/RequiredEjbTxTestEntityDao.java index f87fa0aa97da..667e6acbe87e 100644 --- a/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/dao/RequiredEjbTxTestEntityDao.java +++ b/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/dao/RequiredEjbTxTestEntityDao.java @@ -16,10 +16,10 @@ package org.springframework.test.context.transaction.ejb.dao; -import javax.ejb.Local; -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; +import jakarta.ejb.Local; +import jakarta.ejb.Stateless; +import jakarta.ejb.TransactionAttribute; +import jakarta.ejb.TransactionAttributeType; /** * EJB implementation of {@link TestEntityDao} which declares transaction diff --git a/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/dao/RequiresNewEjbTxTestEntityDao.java b/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/dao/RequiresNewEjbTxTestEntityDao.java index e9957398501d..b7e9281c7c86 100644 --- a/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/dao/RequiresNewEjbTxTestEntityDao.java +++ b/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/dao/RequiresNewEjbTxTestEntityDao.java @@ -16,10 +16,10 @@ package org.springframework.test.context.transaction.ejb.dao; -import javax.ejb.Local; -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; +import jakarta.ejb.Local; +import jakarta.ejb.Stateless; +import jakarta.ejb.TransactionAttribute; +import jakarta.ejb.TransactionAttributeType; /** * EJB implementation of {@link TestEntityDao} which declares transaction diff --git a/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/model/TestEntity.java b/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/model/TestEntity.java index 9f1cd44840bb..79a87ac9908d 100644 --- a/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/model/TestEntity.java +++ b/spring-test/src/test/java/org/springframework/test/context/transaction/ejb/model/TestEntity.java @@ -16,10 +16,10 @@ package org.springframework.test.context.transaction.ejb.model; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; /** * Test entity for EJB transaction support in the TestContext framework. 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 facccee81efc..32a13490a22e 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 @@ -18,8 +18,7 @@ import java.io.File; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.junit.Test; import org.junit.runner.RunWith; 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 4119039364e7..a24e430b87d2 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 @@ -18,8 +18,7 @@ import java.io.File; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-test/src/test/java/org/springframework/test/context/web/ServletContextAwareBean.java b/spring-test/src/test/java/org/springframework/test/context/web/ServletContextAwareBean.java index 3e0e84fc9c40..d9f0109ca0af 100644 --- a/spring-test/src/test/java/org/springframework/test/context/web/ServletContextAwareBean.java +++ b/spring-test/src/test/java/org/springframework/test/context/web/ServletContextAwareBean.java @@ -16,7 +16,7 @@ package org.springframework.test.context.web; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.web.context.ServletContextAware; diff --git a/spring-test/src/test/java/org/springframework/test/context/web/socket/WebSocketServletServerContainerFactoryBeanTests.java b/spring-test/src/test/java/org/springframework/test/context/web/socket/WebSocketServletServerContainerFactoryBeanTests.java index 42fecb9d3afb..b508f44d64b4 100644 --- a/spring-test/src/test/java/org/springframework/test/context/web/socket/WebSocketServletServerContainerFactoryBeanTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/web/socket/WebSocketServletServerContainerFactoryBeanTests.java @@ -16,8 +16,7 @@ package org.springframework.test.context.web.socket; -import javax.websocket.server.ServerContainer; - +import jakarta.websocket.server.ServerContainer; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-test/src/test/java/org/springframework/test/util/subpackage/Component.java b/spring-test/src/test/java/org/springframework/test/util/subpackage/Component.java index f0b41c658ac9..676592741381 100644 --- a/spring-test/src/test/java/org/springframework/test/util/subpackage/Component.java +++ b/spring-test/src/test/java/org/springframework/test/util/subpackage/Component.java @@ -16,8 +16,8 @@ package org.springframework.test.util.subpackage; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.Assert; 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 61e83c129be9..2282b70dc304 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 @@ -16,8 +16,8 @@ package org.springframework.test.web; -import javax.validation.constraints.NotNull; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.validation.constraints.NotNull; +import jakarta.xml.bind.annotation.XmlRootElement; import org.springframework.util.ObjectUtils; diff --git a/spring-test/src/test/java/org/springframework/test/web/client/match/ContentRequestMatchersTests.java b/spring-test/src/test/java/org/springframework/test/web/client/match/ContentRequestMatchersTests.java index b36c9c9a068b..2210fcf08bcd 100644 --- a/spring-test/src/test/java/org/springframework/test/web/client/match/ContentRequestMatchersTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/client/match/ContentRequestMatchersTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ import java.nio.charset.StandardCharsets; import java.util.Collections; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; @@ -38,13 +37,7 @@ */ public class ContentRequestMatchersTests { - private MockClientHttpRequest request; - - - @BeforeEach - public void setUp() { - this.request = new MockClientHttpRequest(); - } + private final MockClientHttpRequest request = new MockClientHttpRequest(); @Test diff --git a/spring-test/src/test/java/org/springframework/test/web/client/match/MultipartRequestMatchersTests.java b/spring-test/src/test/java/org/springframework/test/web/client/match/MultipartRequestMatchersTests.java index 9f70ea77980c..850bcb208daa 100644 --- a/spring-test/src/test/java/org/springframework/test/web/client/match/MultipartRequestMatchersTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/client/match/MultipartRequestMatchersTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ public class MultipartRequestMatchersTests { @BeforeEach - public void setUp() { + public void setup() { this.request.getHeaders().setContentType(MediaType.MULTIPART_FORM_DATA); } diff --git a/spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/XmlContentRequestMatchersIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/XmlContentRequestMatchersIntegrationTests.java index 897a3fc36f67..23994b1b9852 100644 --- a/spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/XmlContentRequestMatchersIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/XmlContentRequestMatchersIntegrationTests.java @@ -22,12 +22,11 @@ import java.util.Arrays; import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; - +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/XpathRequestMatchersIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/XpathRequestMatchersIntegrationTests.java index 6654a579f40e..d48d6d881ad7 100644 --- a/spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/XpathRequestMatchersIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/XpathRequestMatchersIntegrationTests.java @@ -24,12 +24,11 @@ import java.util.List; import java.util.Map; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; - +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/Person.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/Person.java index 23c2115e1d76..7dfd5189ddda 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/Person.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/Person.java @@ -15,10 +15,9 @@ */ package org.springframework.test.web.reactive.server.samples; -import javax.xml.bind.annotation.XmlRootElement; - import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.xml.bind.annotation.XmlRootElement; @XmlRootElement class Person { 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 870c7231e056..fef7d629a2b2 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 @@ -21,11 +21,10 @@ import java.util.Arrays; import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/HelloController.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/HelloController.java index 848aa7042250..d430cdcd80bf 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/HelloController.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/HelloController.java @@ -16,7 +16,7 @@ package org.springframework.test.web.servlet.htmlunit; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; 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 96ebbb4ed529..5e3fdaa3f606 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 @@ -28,11 +28,6 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.ServletContext; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpSession; -import javax.servlet.http.Part; - import com.gargoylesoftware.htmlunit.FormEncodingType; import com.gargoylesoftware.htmlunit.HttpMethod; import com.gargoylesoftware.htmlunit.WebClient; @@ -40,6 +35,10 @@ import com.gargoylesoftware.htmlunit.util.KeyDataPair; import com.gargoylesoftware.htmlunit.util.MimeType; import com.gargoylesoftware.htmlunit.util.NameValuePair; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.Part; import org.apache.commons.io.IOUtils; import org.apache.http.auth.UsernamePasswordCredentials; import org.junit.jupiter.api.BeforeEach; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcConnectionBuilderSupportTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcConnectionBuilderSupportTests.java index 20abbd53e5d5..c2040c84912a 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcConnectionBuilderSupportTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcConnectionBuilderSupportTests.java @@ -19,12 +19,11 @@ import java.io.IOException; import java.net.URL; -import javax.servlet.http.HttpServletRequest; - import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.WebConnection; import com.gargoylesoftware.htmlunit.WebRequest; import com.gargoylesoftware.htmlunit.WebResponse; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebClientBuilderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebClientBuilderTests.java index ea425f63b413..ca50d3d90e2b 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebClientBuilderTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebClientBuilderTests.java @@ -19,14 +19,13 @@ import java.io.IOException; import java.net.URL; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import com.gargoylesoftware.htmlunit.HttpMethod; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.WebRequest; import com.gargoylesoftware.htmlunit.WebResponse; import com.gargoylesoftware.htmlunit.util.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Configuration; @@ -157,13 +156,13 @@ String cookie(@CookieValue(name = COOKIE_NAME, defaultValue = "NA") String cooki @PostMapping(path = "/", produces = "text/plain") String setCookie(@RequestParam String cookie, HttpServletResponse response) { - response.addCookie(new javax.servlet.http.Cookie(COOKIE_NAME, cookie)); + response.addCookie(new jakarta.servlet.http.Cookie(COOKIE_NAME, cookie)); return "Set"; } @DeleteMapping(path = "/", produces = "text/plain") String deleteCookie(HttpServletResponse response) { - javax.servlet.http.Cookie cookie = new javax.servlet.http.Cookie(COOKIE_NAME, ""); + jakarta.servlet.http.Cookie cookie = new jakarta.servlet.http.Cookie(COOKIE_NAME, ""); cookie.setMaxAge(0); response.addCookie(cookie); return "Delete"; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockWebResponseBuilderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockWebResponseBuilderTests.java index eb4797cd0e74..9b6a102a2f4b 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockWebResponseBuilderTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockWebResponseBuilderTests.java @@ -20,11 +20,10 @@ import java.nio.charset.StandardCharsets; import java.util.List; -import javax.servlet.http.Cookie; - import com.gargoylesoftware.htmlunit.WebRequest; import com.gargoylesoftware.htmlunit.WebResponse; import com.gargoylesoftware.htmlunit.util.NameValuePair; +import jakarta.servlet.http.Cookie; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/webdriver/MockMvcHtmlUnitDriverBuilderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/webdriver/MockMvcHtmlUnitDriverBuilderTests.java index ee85328fc552..d817f25194ff 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/webdriver/MockMvcHtmlUnitDriverBuilderTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/webdriver/MockMvcHtmlUnitDriverBuilderTests.java @@ -18,9 +18,8 @@ import java.io.IOException; -import javax.servlet.http.HttpServletRequest; - import com.gargoylesoftware.htmlunit.util.Cookie; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.openqa.selenium.htmlunit.HtmlUnitDriver; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java index b493cbbca4d0..6cdf99d09fce 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java @@ -29,9 +29,8 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.ServletContext; -import javax.servlet.http.Cookie; - +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.Cookie; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilderTests.java index 22263b909596..b58e329a3d61 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilderTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilderTests.java @@ -16,8 +16,7 @@ package org.springframework.test.web.servlet.request; -import javax.servlet.http.Part; - +import jakarta.servlet.http.Part; import org.junit.jupiter.api.Test; import org.springframework.http.HttpMethod; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/result/PrintingResultHandlerTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/result/PrintingResultHandlerTests.java index f91c39fda969..c7c3cab6772f 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/result/PrintingResultHandlerTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/result/PrintingResultHandlerTests.java @@ -22,9 +22,8 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpSession; - +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpSession; import org.junit.jupiter.api.Test; import org.mockito.Mockito; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/context/JavaConfigTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/context/JavaConfigTests.java index 7f27c859c6d7..3026b5af21b1 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/context/JavaConfigTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/context/JavaConfigTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,9 +39,7 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.ViewResolverRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; import static org.mockito.BDDMockito.given; @@ -84,14 +82,6 @@ void person() { .expectBody().json("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"); } - @Test - void tilesDefinitions() { - testClient.get().uri("/") - .exchange() - .expectStatus().isOk() - .expectHeader().valueEquals("Forwarded-Url", "/WEB-INF/layouts/standardLayout.jsp"); - } - @Configuration static class RootConfig { @@ -128,18 +118,6 @@ public void addViewControllers(ViewControllerRegistry registry) { public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } - - @Override - public void configureViewResolvers(ViewResolverRegistry registry) { - registry.tiles(); - } - - @Bean - TilesConfigurer tilesConfigurer() { - TilesConfigurer configurer = new TilesConfigurer(); - configurer.setDefinitions("/WEB-INF/**/tiles.xml"); - return configurer; - } } } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/context/WebAppResourceTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/context/WebAppResourceTests.java index ec356ba0721c..58e58104d602 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/context/WebAppResourceTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/context/WebAppResourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,16 +60,6 @@ public void setup() { this.testClient = MockMvcWebTestClient.bindToApplicationContext(this.wac).build(); } - // TilesConfigurer: resources under "/WEB-INF/**/tiles.xml" - - @Test - public void tilesDefinitions() { - testClient.get().uri("/") - .exchange() - .expectStatus().isOk() - .expectHeader().valueEquals("Forwarded-Url", "/WEB-INF/layouts/standardLayout.jsp"); - } - // Resources served via @Test diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/context/XmlConfigTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/context/XmlConfigTests.java index f3364da57952..84fa33c0d56b 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/context/XmlConfigTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/context/XmlConfigTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,12 +73,4 @@ public void person() { .expectBody().json("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"); } - @Test - public void tilesDefinitions() { - testClient.get().uri("/") - .exchange() - .expectStatus().isOk() - .expectHeader().valueEquals("Forwarded-Url", "/WEB-INF/layouts/standardLayout.jsp"); - } - } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/FilterTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/FilterTests.java index 3016c00d7940..6adae504d183 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/FilterTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/FilterTests.java @@ -20,19 +20,18 @@ import java.security.Principal; import java.util.concurrent.CompletableFuture; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncListener; -import javax.servlet.FilterChain; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; -import javax.validation.Valid; - +import jakarta.servlet.AsyncContext; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; +import jakarta.validation.Valid; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/MultipartControllerTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/MultipartControllerTests.java index b60a0e6f6e37..66a60d16dd6b 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/MultipartControllerTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/MultipartControllerTests.java @@ -23,13 +23,12 @@ import java.util.Map; import java.util.Optional; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.Part; - +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.Part; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/RedirectTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/RedirectTests.java index 18c48affbcf1..0bd139cf9b79 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/RedirectTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/RedirectTests.java @@ -16,8 +16,7 @@ package org.springframework.test.web.servlet.samples.client.standalone; -import javax.validation.Valid; - +import jakarta.validation.Valid; import org.junit.jupiter.api.Test; import org.springframework.stereotype.Controller; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/ResponseBodyTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/ResponseBodyTests.java index 1f8cd1f787c7..691a60e8040e 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/ResponseBodyTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/ResponseBodyTests.java @@ -16,8 +16,7 @@ package org.springframework.test.web.servlet.samples.client.standalone; -import javax.validation.constraints.NotNull; - +import jakarta.validation.constraints.NotNull; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resulthandlers/PrintingResultHandlerSmokeTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resulthandlers/PrintingResultHandlerSmokeTests.java index 629ada4fa9a8..61ccee4fb326 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resulthandlers/PrintingResultHandlerSmokeTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resulthandlers/PrintingResultHandlerSmokeTests.java @@ -18,9 +18,8 @@ import java.nio.charset.StandardCharsets; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resultmatches/ModelAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resultmatches/ModelAssertionTests.java index 76384b3b4370..3794eb416719 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resultmatches/ModelAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resultmatches/ModelAssertionTests.java @@ -16,8 +16,7 @@ package org.springframework.test.web.servlet.samples.client.standalone.resultmatches; -import javax.validation.Valid; - +import jakarta.validation.Valid; import org.junit.jupiter.api.Test; import org.springframework.http.HttpMethod; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resultmatches/XmlContentAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resultmatches/XmlContentAssertionTests.java index a60845993762..029b76861597 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resultmatches/XmlContentAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resultmatches/XmlContentAssertionTests.java @@ -19,12 +19,11 @@ import java.util.Arrays; import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; - +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resultmatches/XpathAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resultmatches/XpathAssertionTests.java index b464c4224907..e7f50190afcf 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resultmatches/XpathAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/resultmatches/XpathAssertionTests.java @@ -21,12 +21,11 @@ import java.util.List; import java.util.Map; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; - +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java index 9cde95fe2ce3..48646aa92a3a 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java @@ -16,8 +16,7 @@ package org.springframework.test.web.servlet.samples.context; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -42,9 +41,7 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.ViewResolverRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -52,7 +49,6 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -130,13 +126,6 @@ public void andExpectAllWithMultipleFailures() { .satisfies(error -> assertThat(error.getSuppressed()).hasSize(2)); } - @Test - public void tilesDefinitions() throws Exception { - this.mockMvc.perform(get("/")) - .andExpect(status().isOk()) - .andExpect(forwardedUrl("/WEB-INF/layouts/standardLayout.jsp")); - } - /** * Verify that the breaking change introduced in SPR-12553 has been reverted. @@ -202,18 +191,6 @@ public void addViewControllers(ViewControllerRegistry registry) { public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } - - @Override - public void configureViewResolvers(ViewResolverRegistry registry) { - registry.tiles(); - } - - @Bean - public TilesConfigurer tilesConfigurer() { - TilesConfigurer configurer = new TilesConfigurer(); - configurer.setDefinitions("/WEB-INF/**/tiles.xml"); - return configurer; - } } } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/WebAppResourceTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/WebAppResourceTests.java index 57c3b1737a8b..b4c46125c7e1 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/WebAppResourceTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/WebAppResourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,14 +60,6 @@ public void setup() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).alwaysExpect(status().isOk()).build(); } - // TilesConfigurer: resources under "/WEB-INF/**/tiles.xml" - - @Test - public void tilesDefinitions() throws Exception { - this.mockMvc.perform(get("/")) - .andExpect(forwardedUrl("/WEB-INF/layouts/standardLayout.jsp")); - } - // Resources served via @Test diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/XmlConfigTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/XmlConfigTests.java index 783aead74799..bda280e7e95c 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/XmlConfigTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/XmlConfigTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,6 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** @@ -75,11 +74,4 @@ public void person() throws Exception { .andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); } - @Test - public void tilesDefinitions() throws Exception { - this.mockMvc.perform(get("/"))// - .andExpect(status().isOk())// - .andExpect(forwardedUrl("/WEB-INF/layouts/standardLayout.jsp")); - } - } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/CustomRequestAttributesRequestContextHolderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/CustomRequestAttributesRequestContextHolderTests.java index acf32025509b..e9aa203f394c 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/CustomRequestAttributesRequestContextHolderTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/CustomRequestAttributesRequestContextHolderTests.java @@ -16,10 +16,9 @@ package org.springframework.test.web.servlet.samples.spr; -import javax.servlet.ServletContext; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/RequestContextHolderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/RequestContextHolderTests.java index 8cdafdf10c88..be54c77e7f07 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/RequestContextHolderTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/RequestContextHolderTests.java @@ -18,11 +18,10 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/FilterTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/FilterTests.java index 93bb514d195b..07b359ee6e39 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/FilterTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/FilterTests.java @@ -20,20 +20,19 @@ import java.security.Principal; import java.util.concurrent.CompletableFuture; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncListener; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; -import javax.validation.Valid; - +import jakarta.servlet.AsyncContext; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; +import jakarta.validation.Valid; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/MultipartControllerTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/MultipartControllerTests.java index a00dd2774e3a..e61d50f0d6e4 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/MultipartControllerTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/MultipartControllerTests.java @@ -23,14 +23,13 @@ import java.util.Map; import java.util.Optional; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.Part; - +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.Part; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/RedirectTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/RedirectTests.java index 0981973439a6..60df4a8fffdc 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/RedirectTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/RedirectTests.java @@ -16,8 +16,7 @@ package org.springframework.test.web.servlet.samples.standalone; -import javax.validation.Valid; - +import jakarta.validation.Valid; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resulthandlers/PrintingResultHandlerIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resulthandlers/PrintingResultHandlerIntegrationTests.java index 9d47134e0fb6..726743039a13 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resulthandlers/PrintingResultHandlerIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resulthandlers/PrintingResultHandlerIntegrationTests.java @@ -18,9 +18,8 @@ import java.io.StringWriter; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.test.web.servlet.result.PrintingResultHandler; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resulthandlers/PrintingResultHandlerSmokeTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resulthandlers/PrintingResultHandlerSmokeTests.java index 1600c095263a..87986b2a0145 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resulthandlers/PrintingResultHandlerSmokeTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resulthandlers/PrintingResultHandlerSmokeTests.java @@ -18,9 +18,8 @@ import java.io.StringWriter; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/ModelAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/ModelAssertionTests.java index a22b760bc82f..1f5e4471e0ac 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/ModelAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/ModelAssertionTests.java @@ -16,8 +16,7 @@ package org.springframework.test.web.servlet.samples.standalone.resultmatchers; -import javax.validation.Valid; - +import jakarta.validation.Valid; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/XmlContentAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/XmlContentAssertionTests.java index 11540766e5e8..a2abe1f75b3c 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/XmlContentAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/XmlContentAssertionTests.java @@ -19,12 +19,11 @@ import java.util.Arrays; import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; - +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/XpathAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/XpathAssertionTests.java index 4bd5d2fc3dd5..3bece04be76d 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/XpathAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/XpathAssertionTests.java @@ -21,12 +21,11 @@ import java.util.List; import java.util.Map; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; - +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/setup/ConditionalDelegatingFilterProxyTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/setup/ConditionalDelegatingFilterProxyTests.java index 9fbc3c94569c..ffaa26a02a48 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/setup/ConditionalDelegatingFilterProxyTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/setup/ConditionalDelegatingFilterProxyTests.java @@ -16,13 +16,12 @@ package org.springframework.test.web.servlet.setup; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/setup/SharedHttpSessionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/setup/SharedHttpSessionTests.java index 31f308cff655..92d194f51395 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/setup/SharedHttpSessionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/setup/SharedHttpSessionTests.java @@ -16,8 +16,7 @@ package org.springframework.test.web.servlet.setup; -import javax.servlet.http.HttpSession; - +import jakarta.servlet.http.HttpSession; import org.junit.jupiter.api.Test; import org.springframework.stereotype.Controller; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilderTests.java index d55800e1817b..463ad1807308 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilderTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilderTests.java @@ -18,14 +18,13 @@ import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ser.impl.UnknownSerializer; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.http.converter.json.SpringHandlerInstantiator; diff --git a/spring-test/src/test/resources/org/springframework/test/web/servlet/samples/context/servlet-context.xml b/spring-test/src/test/resources/org/springframework/test/web/servlet/samples/context/servlet-context.xml index 0c442c5d7b8a..7322877fbb5f 100644 --- a/spring-test/src/test/resources/org/springframework/test/web/servlet/samples/context/servlet-context.xml +++ b/spring-test/src/test/resources/org/springframework/test/web/servlet/samples/context/servlet-context.xml @@ -5,31 +5,16 @@ http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> - + - + - + - - - - - - - - - - /WEB-INF/**/tiles.xml - - - + \ No newline at end of file diff --git a/spring-tx/spring-tx.gradle b/spring-tx/spring-tx.gradle index f3ec8c3f3ac3..293804e78cd6 100644 --- a/spring-tx/spring-tx.gradle +++ b/spring-tx/spring-tx.gradle @@ -7,11 +7,10 @@ dependencies { api(project(":spring-core")) optional(project(":spring-aop")) optional(project(":spring-context")) // for JCA, @EnableTransactionManagement - optional("javax.ejb:javax.ejb-api") - optional("javax.interceptor:javax.interceptor-api") - optional("javax.resource:javax.resource-api") - optional("javax.transaction:javax.transaction-api") - optional("com.ibm.websphere:uow") + optional("jakarta.ejb:jakarta.ejb-api") + optional("jakarta.interceptor:jakarta.interceptor-api") + optional("jakarta.resource:jakarta.resource-api") + optional("jakarta.transaction:jakarta.transaction-api") optional("io.projectreactor:reactor-core") optional("io.vavr:vavr") optional("org.jetbrains.kotlin:kotlin-reflect") @@ -23,6 +22,6 @@ dependencies { testImplementation(testFixtures(project(":spring-core"))) testImplementation("org.aspectj:aspectjweaver") testImplementation("org.codehaus.groovy:groovy") - testImplementation("org.eclipse.persistence:javax.persistence") + testImplementation("jakarta.persistence:jakarta.persistence-api") testImplementation("io.projectreactor:reactor-test") } diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/CannotCreateRecordException.java b/spring-tx/src/main/java/org/springframework/jca/cci/CannotCreateRecordException.java deleted file mode 100644 index 5685b061c97b..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/CannotCreateRecordException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci; - -import javax.resource.ResourceException; - -import org.springframework.dao.DataAccessResourceFailureException; - -/** - * Exception thrown when the creating of a CCI Record failed - * for connector-internal reasons. - * - * @author Juergen Hoeller - * @since 1.2 - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@SuppressWarnings("serial") -public class CannotCreateRecordException extends DataAccessResourceFailureException { - - /** - * Constructor for CannotCreateRecordException. - * @param msg message - * @param ex the root ResourceException cause - */ - public CannotCreateRecordException(String msg, ResourceException ex) { - super(msg, ex); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/CannotGetCciConnectionException.java b/spring-tx/src/main/java/org/springframework/jca/cci/CannotGetCciConnectionException.java deleted file mode 100644 index dcd68cecc409..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/CannotGetCciConnectionException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci; - -import javax.resource.ResourceException; - -import org.springframework.dao.DataAccessResourceFailureException; - -/** - * Fatal exception thrown when we can't connect to an EIS using CCI. - * - * @author Thierry Templier - * @author Juergen Hoeller - * @since 1.2 - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@SuppressWarnings("serial") -public class CannotGetCciConnectionException extends DataAccessResourceFailureException { - - /** - * Constructor for CannotGetCciConnectionException. - * @param msg message - * @param ex the root ResourceException cause - */ - public CannotGetCciConnectionException(String msg, ResourceException ex) { - super(msg, ex); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/CciOperationNotSupportedException.java b/spring-tx/src/main/java/org/springframework/jca/cci/CciOperationNotSupportedException.java deleted file mode 100644 index bc2d9df4be81..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/CciOperationNotSupportedException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci; - -import javax.resource.ResourceException; - -import org.springframework.dao.InvalidDataAccessResourceUsageException; - -/** - * Exception thrown when the connector doesn't support a specific CCI operation. - * - * @author Juergen Hoeller - * @since 1.2 - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@SuppressWarnings("serial") -public class CciOperationNotSupportedException extends InvalidDataAccessResourceUsageException { - - /** - * Constructor for CciOperationNotSupportedException. - * @param msg message - * @param ex the root ResourceException cause - */ - public CciOperationNotSupportedException(String msg, ResourceException ex) { - super(msg, ex); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/InvalidResultSetAccessException.java b/spring-tx/src/main/java/org/springframework/jca/cci/InvalidResultSetAccessException.java deleted file mode 100644 index f7a1895cf9ca..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/InvalidResultSetAccessException.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci; - -import java.sql.SQLException; - -import org.springframework.dao.InvalidDataAccessResourceUsageException; - -/** - * Exception thrown when a ResultSet has been accessed in an invalid fashion. - * Such exceptions always have a {@code java.sql.SQLException} root cause. - * - *

    This typically happens when an invalid ResultSet column index or name - * has been specified. - * - * @author Juergen Hoeller - * @since 1.2 - * @see javax.resource.cci.ResultSet - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@SuppressWarnings("serial") -public class InvalidResultSetAccessException extends InvalidDataAccessResourceUsageException { - - /** - * Constructor for InvalidResultSetAccessException. - * @param msg message - * @param ex the root cause - */ - public InvalidResultSetAccessException(String msg, SQLException ex) { - super(ex.getMessage(), ex); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/RecordTypeNotSupportedException.java b/spring-tx/src/main/java/org/springframework/jca/cci/RecordTypeNotSupportedException.java deleted file mode 100644 index b4e9bacc7a4b..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/RecordTypeNotSupportedException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci; - -import javax.resource.ResourceException; - -import org.springframework.dao.InvalidDataAccessResourceUsageException; - -/** - * Exception thrown when the creating of a CCI Record failed because - * the connector doesn't support the desired CCI Record type. - * - * @author Juergen Hoeller - * @since 1.2 - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@SuppressWarnings("serial") -public class RecordTypeNotSupportedException extends InvalidDataAccessResourceUsageException { - - /** - * Constructor for RecordTypeNotSupportedException. - * @param msg message - * @param ex the root ResourceException cause - */ - public RecordTypeNotSupportedException(String msg, ResourceException ex) { - super(msg, ex); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/CciLocalTransactionManager.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/CciLocalTransactionManager.java deleted file mode 100644 index 4b0ad9d51c03..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/CciLocalTransactionManager.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.connection; - -import javax.resource.NotSupportedException; -import javax.resource.ResourceException; -import javax.resource.cci.Connection; -import javax.resource.cci.ConnectionFactory; -import javax.resource.spi.LocalTransactionException; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; -import org.springframework.transaction.CannotCreateTransactionException; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionException; -import org.springframework.transaction.TransactionSystemException; -import org.springframework.transaction.support.AbstractPlatformTransactionManager; -import org.springframework.transaction.support.DefaultTransactionStatus; -import org.springframework.transaction.support.ResourceTransactionManager; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.util.Assert; - -/** - * {@link org.springframework.transaction.PlatformTransactionManager} implementation - * that manages local transactions for a single CCI ConnectionFactory. - * Binds a CCI Connection from the specified ConnectionFactory to the thread, - * potentially allowing for one thread-bound Connection per ConnectionFactory. - * - *

    Application code is required to retrieve the CCI Connection via - * {@link ConnectionFactoryUtils#getConnection(ConnectionFactory)} instead of a standard - * Java EE-style {@link ConnectionFactory#getConnection()} call. Spring classes such as - * {@link org.springframework.jca.cci.core.CciTemplate} use this strategy implicitly. - * If not used in combination with this transaction manager, the - * {@link ConnectionFactoryUtils} lookup strategy behaves exactly like the native - * DataSource lookup; it can thus be used in a portable fashion. - * - *

    Alternatively, you can allow application code to work with the standard - * Java EE lookup pattern {@link ConnectionFactory#getConnection()}, for example - * for legacy code that is not aware of Spring at all. In that case, define a - * {@link TransactionAwareConnectionFactoryProxy} for your target ConnectionFactory, - * which will automatically participate in Spring-managed transactions. - * - * @author Thierry Templier - * @author Juergen Hoeller - * @since 1.2 - * @see ConnectionFactoryUtils#getConnection(javax.resource.cci.ConnectionFactory) - * @see ConnectionFactoryUtils#releaseConnection - * @see TransactionAwareConnectionFactoryProxy - * @see org.springframework.jca.cci.core.CciTemplate - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@SuppressWarnings("serial") -public class CciLocalTransactionManager extends AbstractPlatformTransactionManager - implements ResourceTransactionManager, InitializingBean { - - @Nullable - private ConnectionFactory connectionFactory; - - - /** - * Create a new CciLocalTransactionManager instance. - * A ConnectionFactory has to be set to be able to use it. - * @see #setConnectionFactory - */ - public CciLocalTransactionManager() { - } - - /** - * Create a new CciLocalTransactionManager instance. - * @param connectionFactory the CCI ConnectionFactory to manage local transactions for - */ - public CciLocalTransactionManager(ConnectionFactory connectionFactory) { - setConnectionFactory(connectionFactory); - afterPropertiesSet(); - } - - - /** - * Set the CCI ConnectionFactory that this instance should manage local - * transactions for. - */ - public void setConnectionFactory(@Nullable ConnectionFactory cf) { - if (cf instanceof TransactionAwareConnectionFactoryProxy) { - // If we got a TransactionAwareConnectionFactoryProxy, we need to perform transactions - // for its underlying target ConnectionFactory, else JMS access code won't see - // properly exposed transactions (i.e. transactions for the target ConnectionFactory). - this.connectionFactory = ((TransactionAwareConnectionFactoryProxy) cf).getTargetConnectionFactory(); - } - else { - this.connectionFactory = cf; - } - } - - /** - * Return the CCI ConnectionFactory that this instance manages local - * transactions for. - */ - @Nullable - public ConnectionFactory getConnectionFactory() { - return this.connectionFactory; - } - - private ConnectionFactory obtainConnectionFactory() { - ConnectionFactory connectionFactory = getConnectionFactory(); - Assert.state(connectionFactory != null, "No ConnectionFactory set"); - return connectionFactory; - } - - @Override - public void afterPropertiesSet() { - if (getConnectionFactory() == null) { - throw new IllegalArgumentException("Property 'connectionFactory' is required"); - } - } - - - @Override - public Object getResourceFactory() { - return obtainConnectionFactory(); - } - - @Override - protected Object doGetTransaction() { - CciLocalTransactionObject txObject = new CciLocalTransactionObject(); - ConnectionHolder conHolder = - (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainConnectionFactory()); - txObject.setConnectionHolder(conHolder); - return txObject; - } - - @Override - protected boolean isExistingTransaction(Object transaction) { - CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction; - // Consider a pre-bound connection as transaction. - return txObject.hasConnectionHolder(); - } - - @Override - protected void doBegin(Object transaction, TransactionDefinition definition) { - CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction; - ConnectionFactory connectionFactory = obtainConnectionFactory(); - Connection con = null; - - try { - con = connectionFactory.getConnection(); - if (logger.isDebugEnabled()) { - logger.debug("Acquired Connection [" + con + "] for local CCI transaction"); - } - - ConnectionHolder connectionHolder = new ConnectionHolder(con); - connectionHolder.setSynchronizedWithTransaction(true); - - con.getLocalTransaction().begin(); - int timeout = determineTimeout(definition); - if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { - connectionHolder.setTimeoutInSeconds(timeout); - } - - txObject.setConnectionHolder(connectionHolder); - TransactionSynchronizationManager.bindResource(connectionFactory, connectionHolder); - } - catch (NotSupportedException ex) { - ConnectionFactoryUtils.releaseConnection(con, connectionFactory); - throw new CannotCreateTransactionException("CCI Connection does not support local transactions", ex); - } - catch (LocalTransactionException ex) { - ConnectionFactoryUtils.releaseConnection(con, connectionFactory); - throw new CannotCreateTransactionException("Could not begin local CCI transaction", ex); - } - catch (Throwable ex) { - ConnectionFactoryUtils.releaseConnection(con, connectionFactory); - throw new TransactionSystemException("Unexpected failure on begin of CCI local transaction", ex); - } - } - - @Override - protected Object doSuspend(Object transaction) { - CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction; - txObject.setConnectionHolder(null); - return TransactionSynchronizationManager.unbindResource(obtainConnectionFactory()); - } - - @Override - protected void doResume(@Nullable Object transaction, Object suspendedResources) { - ConnectionHolder conHolder = (ConnectionHolder) suspendedResources; - TransactionSynchronizationManager.bindResource(obtainConnectionFactory(), conHolder); - } - - protected boolean isRollbackOnly(Object transaction) throws TransactionException { - CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction; - return txObject.getConnectionHolder().isRollbackOnly(); - } - - @Override - protected void doCommit(DefaultTransactionStatus status) { - CciLocalTransactionObject txObject = (CciLocalTransactionObject) status.getTransaction(); - Connection con = txObject.getConnectionHolder().getConnection(); - if (status.isDebug()) { - logger.debug("Committing CCI local transaction on Connection [" + con + "]"); - } - try { - con.getLocalTransaction().commit(); - } - catch (LocalTransactionException ex) { - throw new TransactionSystemException("Could not commit CCI local transaction", ex); - } - catch (ResourceException ex) { - throw new TransactionSystemException("Unexpected failure on commit of CCI local transaction", ex); - } - } - - @Override - protected void doRollback(DefaultTransactionStatus status) { - CciLocalTransactionObject txObject = (CciLocalTransactionObject) status.getTransaction(); - Connection con = txObject.getConnectionHolder().getConnection(); - if (status.isDebug()) { - logger.debug("Rolling back CCI local transaction on Connection [" + con + "]"); - } - try { - con.getLocalTransaction().rollback(); - } - catch (LocalTransactionException ex) { - throw new TransactionSystemException("Could not roll back CCI local transaction", ex); - } - catch (ResourceException ex) { - throw new TransactionSystemException("Unexpected failure on rollback of CCI local transaction", ex); - } - } - - @Override - protected void doSetRollbackOnly(DefaultTransactionStatus status) { - CciLocalTransactionObject txObject = (CciLocalTransactionObject) status.getTransaction(); - if (status.isDebug()) { - logger.debug("Setting CCI local transaction [" + txObject.getConnectionHolder().getConnection() + - "] rollback-only"); - } - txObject.getConnectionHolder().setRollbackOnly(); - } - - @Override - protected void doCleanupAfterCompletion(Object transaction) { - CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction; - ConnectionFactory connectionFactory = obtainConnectionFactory(); - - // Remove the connection holder from the thread. - TransactionSynchronizationManager.unbindResource(connectionFactory); - txObject.getConnectionHolder().clear(); - - Connection con = txObject.getConnectionHolder().getConnection(); - if (logger.isDebugEnabled()) { - logger.debug("Releasing CCI Connection [" + con + "] after transaction"); - } - ConnectionFactoryUtils.releaseConnection(con, connectionFactory); - } - - - /** - * CCI local transaction object, representing a ConnectionHolder. - * Used as transaction object by CciLocalTransactionManager. - * @see ConnectionHolder - */ - private static class CciLocalTransactionObject { - - @Nullable - private ConnectionHolder connectionHolder; - - public void setConnectionHolder(@Nullable ConnectionHolder connectionHolder) { - this.connectionHolder = connectionHolder; - } - - public ConnectionHolder getConnectionHolder() { - Assert.state(this.connectionHolder != null, "No ConnectionHolder available"); - return this.connectionHolder; - } - - public boolean hasConnectionHolder() { - return (this.connectionHolder != null); - } - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionFactoryUtils.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionFactoryUtils.java deleted file mode 100644 index 2f690e35cb6e..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionFactoryUtils.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.connection; - -import javax.resource.ResourceException; -import javax.resource.cci.Connection; -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.ConnectionSpec; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.lang.Nullable; -import org.springframework.transaction.support.ResourceHolderSynchronization; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.util.Assert; - -/** - * Helper class that provides static methods for obtaining CCI Connections - * from a {@link javax.resource.cci.ConnectionFactory}. Includes special - * support for Spring-managed transactional Connections, e.g. managed - * by {@link CciLocalTransactionManager} or - * {@link org.springframework.transaction.jta.JtaTransactionManager}. - * - *

    Used internally by {@link org.springframework.jca.cci.core.CciTemplate}, - * Spring's CCI operation objects and the {@link CciLocalTransactionManager}. - * Can also be used directly in application code. - * - * @author Thierry Templier - * @author Juergen Hoeller - * @since 1.2 - * @see #getConnection - * @see #releaseConnection - * @see CciLocalTransactionManager - * @see org.springframework.transaction.jta.JtaTransactionManager - * @see org.springframework.transaction.support.TransactionSynchronizationManager - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -public abstract class ConnectionFactoryUtils { - - private static final Log logger = LogFactory.getLog(ConnectionFactoryUtils.class); - - - /** - * Obtain a Connection from the given ConnectionFactory. Translates ResourceExceptions - * into the Spring hierarchy of unchecked generic data access exceptions, simplifying - * calling code and making any exception that is thrown more meaningful. - *

    Is aware of a corresponding Connection bound to the current thread, for example - * when using {@link CciLocalTransactionManager}. Will bind a Connection to the thread - * if transaction synchronization is active (e.g. if in a JTA transaction). - * @param cf the ConnectionFactory to obtain Connection from - * @return a CCI Connection from the given ConnectionFactory - * @throws org.springframework.jca.cci.CannotGetCciConnectionException - * if the attempt to get a Connection failed - * @see #releaseConnection - */ - public static Connection getConnection(ConnectionFactory cf) - throws org.springframework.jca.cci.CannotGetCciConnectionException { - - return getConnection(cf, null); - } - - /** - * Obtain a Connection from the given ConnectionFactory. Translates ResourceExceptions - * into the Spring hierarchy of unchecked generic data access exceptions, simplifying - * calling code and making any exception that is thrown more meaningful. - *

    Is aware of a corresponding Connection bound to the current thread, for example - * when using {@link CciLocalTransactionManager}. Will bind a Connection to the thread - * if transaction synchronization is active (e.g. if in a JTA transaction). - * @param cf the ConnectionFactory to obtain Connection from - * @param spec the ConnectionSpec for the desired Connection (may be {@code null}). - * Note: If this is specified, a new Connection will be obtained for every call, - * without participating in a shared transactional Connection. - * @return a CCI Connection from the given ConnectionFactory - * @throws org.springframework.jca.cci.CannotGetCciConnectionException - * if the attempt to get a Connection failed - * @see #releaseConnection - */ - public static Connection getConnection(ConnectionFactory cf, @Nullable ConnectionSpec spec) - throws org.springframework.jca.cci.CannotGetCciConnectionException { - try { - if (spec != null) { - Assert.notNull(cf, "No ConnectionFactory specified"); - return cf.getConnection(spec); - } - else { - return doGetConnection(cf); - } - } - catch (ResourceException ex) { - throw new org.springframework.jca.cci.CannotGetCciConnectionException("Could not get CCI Connection", ex); - } - } - - /** - * Actually obtain a CCI Connection from the given ConnectionFactory. - * Same as {@link #getConnection}, but throwing the original ResourceException. - *

    Is aware of a corresponding Connection bound to the current thread, for example - * when using {@link CciLocalTransactionManager}. Will bind a Connection to the thread - * if transaction synchronization is active (e.g. if in a JTA transaction). - *

    Directly accessed by {@link TransactionAwareConnectionFactoryProxy}. - * @param cf the ConnectionFactory to obtain Connection from - * @return a CCI Connection from the given ConnectionFactory - * @throws ResourceException if thrown by CCI API methods - * @see #doReleaseConnection - */ - public static Connection doGetConnection(ConnectionFactory cf) throws ResourceException { - Assert.notNull(cf, "No ConnectionFactory specified"); - - ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(cf); - if (conHolder != null) { - return conHolder.getConnection(); - } - - logger.debug("Opening CCI Connection"); - Connection con = cf.getConnection(); - - if (TransactionSynchronizationManager.isSynchronizationActive()) { - conHolder = new ConnectionHolder(con); - conHolder.setSynchronizedWithTransaction(true); - TransactionSynchronizationManager.registerSynchronization(new ConnectionSynchronization(conHolder, cf)); - TransactionSynchronizationManager.bindResource(cf, conHolder); - } - - return con; - } - - /** - * Determine whether the given JCA CCI Connection is transactional, that is, - * bound to the current thread by Spring's transaction facilities. - * @param con the Connection to check - * @param cf the ConnectionFactory that the Connection was obtained from - * (may be {@code null}) - * @return whether the Connection is transactional - */ - public static boolean isConnectionTransactional(Connection con, @Nullable ConnectionFactory cf) { - if (cf == null) { - return false; - } - ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(cf); - return (conHolder != null && conHolder.getConnection() == con); - } - - /** - * Close the given Connection, obtained from the given ConnectionFactory, - * if it is not managed externally (that is, not bound to the thread). - * @param con the Connection to close if necessary - * (if this is {@code null}, the call will be ignored) - * @param cf the ConnectionFactory that the Connection was obtained from - * (can be {@code null}) - * @see #getConnection - */ - public static void releaseConnection(@Nullable Connection con, @Nullable ConnectionFactory cf) { - try { - doReleaseConnection(con, cf); - } - catch (ResourceException ex) { - logger.debug("Could not close CCI Connection", ex); - } - catch (Throwable ex) { - // We don't trust the CCI driver: It might throw RuntimeException or Error. - logger.debug("Unexpected exception on closing CCI Connection", ex); - } - } - - /** - * Actually close the given Connection, obtained from the given ConnectionFactory. - * Same as {@link #releaseConnection}, but throwing the original ResourceException. - *

    Directly accessed by {@link TransactionAwareConnectionFactoryProxy}. - * @param con the Connection to close if necessary - * (if this is {@code null}, the call will be ignored) - * @param cf the ConnectionFactory that the Connection was obtained from - * (can be {@code null}) - * @throws ResourceException if thrown by JCA CCI methods - * @see #doGetConnection - */ - public static void doReleaseConnection(@Nullable Connection con, @Nullable ConnectionFactory cf) - throws ResourceException { - - if (con == null || isConnectionTransactional(con, cf)) { - return; - } - con.close(); - } - - - /** - * Callback for resource cleanup at the end of a non-native CCI transaction - * (e.g. when participating in a JTA transaction). - */ - private static class ConnectionSynchronization - extends ResourceHolderSynchronization { - - public ConnectionSynchronization(ConnectionHolder connectionHolder, ConnectionFactory connectionFactory) { - super(connectionHolder, connectionFactory); - } - - @Override - protected void releaseResource(ConnectionHolder resourceHolder, ConnectionFactory resourceKey) { - releaseConnection(resourceHolder.getConnection(), resourceKey); - } - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionHolder.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionHolder.java deleted file mode 100644 index 35e5afcf4d05..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionHolder.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.connection; - -import javax.resource.cci.Connection; - -import org.springframework.transaction.support.ResourceHolderSupport; - -/** - * Resource holder wrapping a CCI {@link Connection}. - * {@link CciLocalTransactionManager} binds instances of this class to the thread, - * for a given {@link javax.resource.cci.ConnectionFactory}. - * - *

    Note: This is an SPI class, not intended to be used by applications. - * - * @author Thierry Templier - * @author Juergen Hoeller - * @since 1.2 - * @see CciLocalTransactionManager - * @see ConnectionFactoryUtils - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -public class ConnectionHolder extends ResourceHolderSupport { - - private final Connection connection; - - - public ConnectionHolder(Connection connection) { - this.connection = connection; - } - - - public Connection getConnection() { - return this.connection; - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java deleted file mode 100644 index 2f80f0cefe57..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.connection; - -import javax.resource.ResourceException; -import javax.resource.cci.Connection; -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.ConnectionSpec; - -import org.springframework.core.NamedThreadLocal; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * An adapter for a target CCI {@link javax.resource.cci.ConnectionFactory}, - * applying the given ConnectionSpec to every standard {@code getConnection()} - * call, that is, implicitly invoking {@code getConnection(ConnectionSpec)} - * on the target. All other methods simply delegate to the corresponding methods - * of the target ConnectionFactory. - * - *

    Can be used to proxy a target JNDI ConnectionFactory that does not have a - * ConnectionSpec configured. Client code can work with the ConnectionFactory - * without passing in a ConnectionSpec on every {@code getConnection()} call. - * - *

    In the following example, client code can simply transparently work with - * the preconfigured "myConnectionFactory", implicitly accessing - * "myTargetConnectionFactory" with the specified user credentials. - * - *

    - * <bean id="myTargetConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    - *   <property name="jndiName" value="java:comp/env/cci/mycf"/>
    - * </bean>
    - *
    - * <bean id="myConnectionFactory" class="org.springframework.jca.cci.connection.ConnectionSpecConnectionFactoryAdapter">
    - *   <property name="targetConnectionFactory" ref="myTargetConnectionFactory"/>
    - *   <property name="connectionSpec">
    - *     <bean class="your.resource.adapter.ConnectionSpecImpl">
    - *       <property name="username" value="myusername"/>
    - *       <property name="password" value="mypassword"/>
    - *     </bean>
    - *   </property>
    - * </bean>
    - * - *

    If the "connectionSpec" is empty, this proxy will simply delegate to the - * standard {@code getConnection()} method of the target ConnectionFactory. - * This can be used to keep a UserCredentialsConnectionFactoryAdapter bean definition - * just for the option of implicitly passing in a ConnectionSpec if the - * particular target ConnectionFactory requires it. - * - * @author Juergen Hoeller - * @since 1.2 - * @see #getConnection - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@SuppressWarnings("serial") -public class ConnectionSpecConnectionFactoryAdapter extends DelegatingConnectionFactory { - - @Nullable - private ConnectionSpec connectionSpec; - - private final ThreadLocal threadBoundSpec = - new NamedThreadLocal<>("Current CCI ConnectionSpec"); - - - /** - * Set the ConnectionSpec that this adapter should use for retrieving Connections. - * Default is none. - */ - public void setConnectionSpec(ConnectionSpec connectionSpec) { - this.connectionSpec = connectionSpec; - } - - /** - * Set a ConnectionSpec for this proxy and the current thread. - * The given ConnectionSpec will be applied to all subsequent - * {@code getConnection()} calls on this ConnectionFactory proxy. - *

    This will override any statically specified "connectionSpec" property. - * @param spec the ConnectionSpec to apply - * @see #removeConnectionSpecFromCurrentThread - */ - public void setConnectionSpecForCurrentThread(ConnectionSpec spec) { - this.threadBoundSpec.set(spec); - } - - /** - * Remove any ConnectionSpec for this proxy from the current thread. - * A statically specified ConnectionSpec applies again afterwards. - * @see #setConnectionSpecForCurrentThread - */ - public void removeConnectionSpecFromCurrentThread() { - this.threadBoundSpec.remove(); - } - - - /** - * Determine whether there is currently a thread-bound ConnectionSpec, - * using it if available, falling back to the statically specified - * "connectionSpec" property else. - * @see #doGetConnection - */ - @Override - public final Connection getConnection() throws ResourceException { - ConnectionSpec threadSpec = this.threadBoundSpec.get(); - if (threadSpec != null) { - return doGetConnection(threadSpec); - } - else { - return doGetConnection(this.connectionSpec); - } - } - - /** - * This implementation delegates to the {@code getConnection(ConnectionSpec)} - * method of the target ConnectionFactory, passing in the specified user credentials. - * If the specified username is empty, it will simply delegate to the standard - * {@code getConnection()} method of the target ConnectionFactory. - * @param spec the ConnectionSpec to apply - * @return the Connection - * @see javax.resource.cci.ConnectionFactory#getConnection(javax.resource.cci.ConnectionSpec) - * @see javax.resource.cci.ConnectionFactory#getConnection() - */ - protected Connection doGetConnection(@Nullable ConnectionSpec spec) throws ResourceException { - ConnectionFactory connectionFactory = getTargetConnectionFactory(); - Assert.state(connectionFactory != null, "No 'targetConnectionFactory' set"); - return (spec != null ? connectionFactory.getConnection(spec) : connectionFactory.getConnection()); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/DelegatingConnectionFactory.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/DelegatingConnectionFactory.java deleted file mode 100644 index 08c9ac207227..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/DelegatingConnectionFactory.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.connection; - -import javax.naming.NamingException; -import javax.naming.Reference; -import javax.resource.ResourceException; -import javax.resource.cci.Connection; -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.ConnectionSpec; -import javax.resource.cci.RecordFactory; -import javax.resource.cci.ResourceAdapterMetaData; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * CCI {@link ConnectionFactory} implementation that delegates all calls - * to a given target {@link ConnectionFactory}. - * - *

    This class is meant to be subclassed, with subclasses overriding only - * those methods (such as {@link #getConnection()}) that should not simply - * delegate to the target {@link ConnectionFactory}. - * - * @author Juergen Hoeller - * @since 1.2 - * @see #getConnection - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@SuppressWarnings("serial") -public class DelegatingConnectionFactory implements ConnectionFactory, InitializingBean { - - @Nullable - private ConnectionFactory targetConnectionFactory; - - - /** - * Set the target ConnectionFactory that this ConnectionFactory should delegate to. - */ - public void setTargetConnectionFactory(@Nullable ConnectionFactory targetConnectionFactory) { - this.targetConnectionFactory = targetConnectionFactory; - } - - /** - * Return the target ConnectionFactory that this ConnectionFactory should delegate to. - */ - @Nullable - public ConnectionFactory getTargetConnectionFactory() { - return this.targetConnectionFactory; - } - - /** - * Obtain the target {@code ConnectionFactory} for actual use (never {@code null}). - * @since 5.0 - */ - protected ConnectionFactory obtainTargetConnectionFactory() { - ConnectionFactory connectionFactory = getTargetConnectionFactory(); - Assert.state(connectionFactory != null, "No 'targetConnectionFactory' set"); - return connectionFactory; - } - - - @Override - public void afterPropertiesSet() { - if (getTargetConnectionFactory() == null) { - throw new IllegalArgumentException("Property 'targetConnectionFactory' is required"); - } - } - - - @Override - public Connection getConnection() throws ResourceException { - return obtainTargetConnectionFactory().getConnection(); - } - - @Override - public Connection getConnection(ConnectionSpec connectionSpec) throws ResourceException { - return obtainTargetConnectionFactory().getConnection(connectionSpec); - } - - @Override - public RecordFactory getRecordFactory() throws ResourceException { - return obtainTargetConnectionFactory().getRecordFactory(); - } - - @Override - public ResourceAdapterMetaData getMetaData() throws ResourceException { - return obtainTargetConnectionFactory().getMetaData(); - } - - @Override - public Reference getReference() throws NamingException { - return obtainTargetConnectionFactory().getReference(); - } - - @Override - public void setReference(Reference reference) { - obtainTargetConnectionFactory().setReference(reference); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/NotSupportedRecordFactory.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/NotSupportedRecordFactory.java deleted file mode 100644 index dc613f6d4c59..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/NotSupportedRecordFactory.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.connection; - -import javax.resource.NotSupportedException; -import javax.resource.ResourceException; -import javax.resource.cci.IndexedRecord; -import javax.resource.cci.MappedRecord; -import javax.resource.cci.RecordFactory; - -/** - * Implementation of the CCI RecordFactory interface that always throws - * NotSupportedException. - * - *

    Useful as a placeholder for a RecordFactory argument (for example as - * defined by the RecordCreator callback), in particular when the connector's - * {@code ConnectionFactory.getRecordFactory()} implementation happens to - * throw NotSupportedException early rather than throwing the exception from - * RecordFactory's methods. - * - * @author Juergen Hoeller - * @since 1.2.4 - * @see org.springframework.jca.cci.core.RecordCreator#createRecord(javax.resource.cci.RecordFactory) - * @see org.springframework.jca.cci.core.CciTemplate#getRecordFactory(javax.resource.cci.ConnectionFactory) - * @see javax.resource.cci.ConnectionFactory#getRecordFactory() - * @see javax.resource.NotSupportedException - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -public class NotSupportedRecordFactory implements RecordFactory { - - @Override - public MappedRecord createMappedRecord(String name) throws ResourceException { - throw new NotSupportedException("The RecordFactory facility is not supported by the connector"); - } - - @Override - public IndexedRecord createIndexedRecord(String name) throws ResourceException { - throw new NotSupportedException("The RecordFactory facility is not supported by the connector"); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/SingleConnectionFactory.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/SingleConnectionFactory.java deleted file mode 100644 index 312fed4d4fa9..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/SingleConnectionFactory.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.connection; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -import javax.resource.NotSupportedException; -import javax.resource.ResourceException; -import javax.resource.cci.Connection; -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.ConnectionSpec; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * A CCI ConnectionFactory adapter that returns the same Connection on all - * {@code getConnection} calls, and ignores calls to - * {@code Connection.close()}. - * - *

    Useful for testing and standalone environments, to keep using the same - * Connection for multiple CciTemplate calls, without having a pooling - * ConnectionFactory, also spanning any number of transactions. - * - *

    You can either pass in a CCI Connection directly, or let this - * factory lazily create a Connection via a given target ConnectionFactory. - * - * @author Juergen Hoeller - * @since 1.2 - * @see #getConnection() - * @see javax.resource.cci.Connection#close() - * @see org.springframework.jca.cci.core.CciTemplate - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@SuppressWarnings("serial") -public class SingleConnectionFactory extends DelegatingConnectionFactory implements DisposableBean { - - protected final Log logger = LogFactory.getLog(getClass()); - - /** Wrapped Connection. */ - @Nullable - private Connection target; - - /** Proxy Connection. */ - @Nullable - private Connection connection; - - /** Synchronization monitor for the shared Connection. */ - private final Object connectionMonitor = new Object(); - - - /** - * Create a new SingleConnectionFactory for bean-style usage. - * @see #setTargetConnectionFactory - */ - public SingleConnectionFactory() { - } - - /** - * Create a new SingleConnectionFactory that always returns the - * given Connection. - * @param target the single Connection - */ - public SingleConnectionFactory(Connection target) { - Assert.notNull(target, "Target Connection must not be null"); - this.target = target; - this.connection = getCloseSuppressingConnectionProxy(target); - } - - /** - * Create a new SingleConnectionFactory that always returns a single - * Connection which it will lazily create via the given target - * ConnectionFactory. - * @param targetConnectionFactory the target ConnectionFactory - */ - public SingleConnectionFactory(ConnectionFactory targetConnectionFactory) { - Assert.notNull(targetConnectionFactory, "Target ConnectionFactory must not be null"); - setTargetConnectionFactory(targetConnectionFactory); - } - - - /** - * Make sure a Connection or ConnectionFactory has been set. - */ - @Override - public void afterPropertiesSet() { - if (this.connection == null && getTargetConnectionFactory() == null) { - throw new IllegalArgumentException("Connection or 'targetConnectionFactory' is required"); - } - } - - - @Override - public Connection getConnection() throws ResourceException { - synchronized (this.connectionMonitor) { - if (this.connection == null) { - initConnection(); - } - return this.connection; - } - } - - @Override - public Connection getConnection(ConnectionSpec connectionSpec) throws ResourceException { - throw new NotSupportedException( - "SingleConnectionFactory does not support custom ConnectionSpec"); - } - - /** - * Close the underlying Connection. - * The provider of this ConnectionFactory needs to care for proper shutdown. - *

    As this bean implements DisposableBean, a bean factory will - * automatically invoke this on destruction of its cached singletons. - */ - @Override - public void destroy() { - resetConnection(); - } - - - /** - * Initialize the single underlying Connection. - *

    Closes and reinitializes the Connection if an underlying - * Connection is present already. - * @throws javax.resource.ResourceException if thrown by CCI API methods - */ - public void initConnection() throws ResourceException { - if (getTargetConnectionFactory() == null) { - throw new IllegalStateException( - "'targetConnectionFactory' is required for lazily initializing a Connection"); - } - synchronized (this.connectionMonitor) { - if (this.target != null) { - closeConnection(this.target); - } - this.target = doCreateConnection(); - prepareConnection(this.target); - if (logger.isDebugEnabled()) { - logger.debug("Established shared CCI Connection: " + this.target); - } - this.connection = getCloseSuppressingConnectionProxy(this.target); - } - } - - /** - * Reset the underlying shared Connection, to be reinitialized on next access. - */ - public void resetConnection() { - synchronized (this.connectionMonitor) { - if (this.target != null) { - closeConnection(this.target); - } - this.target = null; - this.connection = null; - } - } - - /** - * Create a CCI Connection via this template's ConnectionFactory. - * @return the new CCI Connection - * @throws javax.resource.ResourceException if thrown by CCI API methods - */ - protected Connection doCreateConnection() throws ResourceException { - ConnectionFactory connectionFactory = getTargetConnectionFactory(); - Assert.state(connectionFactory != null, "No 'targetConnectionFactory' set"); - return connectionFactory.getConnection(); - } - - /** - * Prepare the given Connection before it is exposed. - *

    The default implementation is empty. Can be overridden in subclasses. - * @param con the Connection to prepare - */ - protected void prepareConnection(Connection con) throws ResourceException { - } - - /** - * Close the given Connection. - * @param con the Connection to close - */ - protected void closeConnection(Connection con) { - try { - con.close(); - } - catch (Throwable ex) { - logger.warn("Could not close shared CCI Connection", ex); - } - } - - /** - * Wrap the given Connection with a proxy that delegates every method call to it - * but suppresses close calls. This is useful for allowing application code to - * handle a special framework Connection just like an ordinary Connection from a - * CCI ConnectionFactory. - * @param target the original Connection to wrap - * @return the wrapped Connection - */ - protected Connection getCloseSuppressingConnectionProxy(Connection target) { - return (Connection) Proxy.newProxyInstance( - Connection.class.getClassLoader(), - new Class[] {Connection.class}, - new CloseSuppressingInvocationHandler(target)); - } - - - /** - * Invocation handler that suppresses close calls on CCI Connections. - */ - private static final class CloseSuppressingInvocationHandler implements InvocationHandler { - - private final Connection target; - - private CloseSuppressingInvocationHandler(Connection target) { - this.target = target; - } - - @Override - @Nullable - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - switch (method.getName()) { - case "equals": - // Only consider equal when proxies are identical. - return (proxy == args[0]); - case "hashCode": - // Use hashCode of Connection proxy. - return System.identityHashCode(proxy); - case "close": - // Handle close method: don't pass the call on. - return null; - } - - try { - return method.invoke(this.target, args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - } - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/TransactionAwareConnectionFactoryProxy.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/TransactionAwareConnectionFactoryProxy.java deleted file mode 100644 index e8fe835594b1..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/TransactionAwareConnectionFactoryProxy.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.connection; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -import javax.resource.ResourceException; -import javax.resource.cci.Connection; -import javax.resource.cci.ConnectionFactory; - -import org.springframework.lang.Nullable; - -/** - * Proxy for a target CCI {@link javax.resource.cci.ConnectionFactory}, adding - * awareness of Spring-managed transactions. Similar to a transactional JNDI - * ConnectionFactory as provided by a Java EE server. - * - *

    Data access code that should remain unaware of Spring's data access support - * can work with this proxy to seamlessly participate in Spring-managed transactions. - * Note that the transaction manager, for example the {@link CciLocalTransactionManager}, - * still needs to work with underlying ConnectionFactory, not with this proxy. - * - *

    Make sure that TransactionAwareConnectionFactoryProxy is the outermost - * ConnectionFactory of a chain of ConnectionFactory proxies/adapters. - * TransactionAwareConnectionFactoryProxy can delegate either directly to the - * target connection pool or to some intermediate proxy/adapter like - * {@link ConnectionSpecConnectionFactoryAdapter}. - * - *

    Delegates to {@link ConnectionFactoryUtils} for automatically participating in - * thread-bound transactions, for example managed by {@link CciLocalTransactionManager}. - * {@code getConnection} calls and {@code close} calls on returned Connections - * will behave properly within a transaction, i.e. always operate on the transactional - * Connection. If not within a transaction, normal ConnectionFactory behavior applies. - * - *

    This proxy allows data access code to work with the plain JCA CCI API and still - * participate in Spring-managed transactions, similar to CCI code in a Java EE/JTA - * environment. However, if possible, use Spring's ConnectionFactoryUtils, CciTemplate or - * CCI operation objects to get transaction participation even without a proxy for - * the target ConnectionFactory, avoiding the need to define such a proxy in the first place. - * - *

    NOTE: This ConnectionFactory proxy needs to return wrapped Connections - * in order to handle close calls properly. Therefore, the returned Connections cannot - * be cast to a native CCI Connection type or to a connection pool implementation type. - * - * @author Juergen Hoeller - * @since 1.2 - * @see javax.resource.cci.ConnectionFactory#getConnection - * @see javax.resource.cci.Connection#close - * @see ConnectionFactoryUtils#doGetConnection - * @see ConnectionFactoryUtils#doReleaseConnection - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@SuppressWarnings("serial") -public class TransactionAwareConnectionFactoryProxy extends DelegatingConnectionFactory { - - /** - * Create a new TransactionAwareConnectionFactoryProxy. - * @see #setTargetConnectionFactory - */ - public TransactionAwareConnectionFactoryProxy() { - } - - /** - * Create a new TransactionAwareConnectionFactoryProxy. - * @param targetConnectionFactory the target ConnectionFactory - */ - public TransactionAwareConnectionFactoryProxy(ConnectionFactory targetConnectionFactory) { - setTargetConnectionFactory(targetConnectionFactory); - afterPropertiesSet(); - } - - - /** - * Delegate to ConnectionFactoryUtils for automatically participating in Spring-managed - * transactions. Throws the original ResourceException, if any. - * @return a transactional Connection if any, a new one else - * @see org.springframework.jca.cci.connection.ConnectionFactoryUtils#doGetConnection - */ - @Override - public Connection getConnection() throws ResourceException { - ConnectionFactory targetConnectionFactory = obtainTargetConnectionFactory(); - Connection con = ConnectionFactoryUtils.doGetConnection(targetConnectionFactory); - return getTransactionAwareConnectionProxy(con, targetConnectionFactory); - } - - /** - * Wrap the given Connection with a proxy that delegates every method call to it - * but delegates {@code close} calls to ConnectionFactoryUtils. - * @param target the original Connection to wrap - * @param cf the ConnectionFactory that the Connection came from - * @return the wrapped Connection - * @see javax.resource.cci.Connection#close() - * @see ConnectionFactoryUtils#doReleaseConnection - */ - protected Connection getTransactionAwareConnectionProxy(Connection target, ConnectionFactory cf) { - return (Connection) Proxy.newProxyInstance( - Connection.class.getClassLoader(), - new Class[] {Connection.class}, - new TransactionAwareInvocationHandler(target, cf)); - } - - - /** - * Invocation handler that delegates close calls on CCI Connections - * to ConnectionFactoryUtils for being aware of thread-bound transactions. - */ - private static class TransactionAwareInvocationHandler implements InvocationHandler { - - private final Connection target; - - private final ConnectionFactory connectionFactory; - - public TransactionAwareInvocationHandler(Connection target, ConnectionFactory cf) { - this.target = target; - this.connectionFactory = cf; - } - - @Override - @Nullable - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - // Invocation on Connection interface coming in... - - switch (method.getName()) { - case "equals": - // Only consider equal when proxies are identical. - return (proxy == args[0]); - case "hashCode": - // Use hashCode of Connection proxy. - return System.identityHashCode(proxy); - case "getLocalTransaction": - if (ConnectionFactoryUtils.isConnectionTransactional(this.target, this.connectionFactory)) { - throw new javax.resource.spi.IllegalStateException( - "Local transaction handling not allowed within a managed transaction"); - } - return this.target.getLocalTransaction(); - case "close": - // Handle close method: only close if not within a transaction. - ConnectionFactoryUtils.doReleaseConnection(this.target, this.connectionFactory); - return null; - } - - // Invoke method on target Connection. - try { - return method.invoke(this.target, args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - } - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/package-info.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/package-info.java deleted file mode 100644 index b90d61e6211c..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/package-info.java +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Provides a utility class for easy ConnectionFactory access, - * a PlatformTransactionManager for local CCI transactions, - * and various simple ConnectionFactory proxies/adapters. - */ -@NonNullApi -@NonNullFields -package org.springframework.jca.cci.connection; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/core/CciOperations.java b/spring-tx/src/main/java/org/springframework/jca/cci/core/CciOperations.java deleted file mode 100644 index 313d16f24a4b..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/core/CciOperations.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.core; - -import javax.resource.cci.InteractionSpec; -import javax.resource.cci.Record; - -import org.springframework.dao.DataAccessException; -import org.springframework.lang.Nullable; - -/** - * Interface that specifies a basic set of CCI operations on an EIS. - * Implemented by CciTemplate. Not often used, but a useful option - * to enhance testability, as it can easily be mocked or stubbed. - * - *

    Alternatively, the standard CCI infrastructure can be mocked. - * However, mocking this interface constitutes significantly less work. - * - * @author Juergen Hoeller - * @since 1.2 - * @see CciTemplate - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -public interface CciOperations { - - /** - * Execute a request on an EIS with CCI, implemented as callback action - * working on a CCI Connection. This allows for implementing arbitrary - * data access operations, within Spring's managed CCI environment: - * that is, participating in Spring-managed transactions and converting - * JCA ResourceExceptions into Spring's DataAccessException hierarchy. - *

    The callback action can return a result object, for example a - * domain object or a collection of domain objects. - * @param action the callback object that specifies the action - * @return the result object returned by the action, if any - * @throws DataAccessException if there is any problem - */ - @Nullable - T execute(ConnectionCallback action) throws DataAccessException; - - /** - * Execute a request on an EIS with CCI, implemented as callback action - * working on a CCI Interaction. This allows for implementing arbitrary - * data access operations on a single Interaction, within Spring's managed - * CCI environment: that is, participating in Spring-managed transactions - * and converting JCA ResourceExceptions into Spring's DataAccessException - * hierarchy. - *

    The callback action can return a result object, for example a - * domain object or a collection of domain objects. - * @param action the callback object that specifies the action - * @return the result object returned by the action, if any - * @throws DataAccessException if there is any problem - */ - @Nullable - T execute(InteractionCallback action) throws DataAccessException; - - /** - * Execute the specified interaction on an EIS with CCI. - * @param spec the CCI InteractionSpec instance that defines - * the interaction (connector-specific) - * @param inputRecord the input record - * @return the output record - * @throws DataAccessException if there is any problem - */ - @Nullable - Record execute(InteractionSpec spec, Record inputRecord) throws DataAccessException; - - /** - * Execute the specified interaction on an EIS with CCI. - * @param spec the CCI InteractionSpec instance that defines - * the interaction (connector-specific) - * @param inputRecord the input record - * @param outputRecord the output record - * @throws DataAccessException if there is any problem - */ - void execute(InteractionSpec spec, Record inputRecord, Record outputRecord) throws DataAccessException; - - /** - * Execute the specified interaction on an EIS with CCI. - * @param spec the CCI InteractionSpec instance that defines - * the interaction (connector-specific) - * @param inputCreator object that creates the input record to use - * @return the output record - * @throws DataAccessException if there is any problem - */ - Record execute(InteractionSpec spec, RecordCreator inputCreator) throws DataAccessException; - - /** - * Execute the specified interaction on an EIS with CCI. - * @param spec the CCI InteractionSpec instance that defines - * the interaction (connector-specific) - * @param inputRecord the input record - * @param outputExtractor object to convert the output record to a result object - * @return the output data extracted with the RecordExtractor object - * @throws DataAccessException if there is any problem - */ - @Nullable - T execute(InteractionSpec spec, Record inputRecord, RecordExtractor outputExtractor) - throws DataAccessException; - - /** - * Execute the specified interaction on an EIS with CCI. - * @param spec the CCI InteractionSpec instance that defines - * the interaction (connector-specific) - * @param inputCreator object that creates the input record to use - * @param outputExtractor object to convert the output record to a result object - * @return the output data extracted with the RecordExtractor object - * @throws DataAccessException if there is any problem - */ - @Nullable - T execute(InteractionSpec spec, RecordCreator inputCreator, RecordExtractor outputExtractor) - throws DataAccessException; - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/core/CciTemplate.java b/spring-tx/src/main/java/org/springframework/jca/cci/core/CciTemplate.java deleted file mode 100644 index 181321e888a3..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/core/CciTemplate.java +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.core; - -import java.sql.SQLException; - -import javax.resource.NotSupportedException; -import javax.resource.ResourceException; -import javax.resource.cci.Connection; -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.ConnectionSpec; -import javax.resource.cci.IndexedRecord; -import javax.resource.cci.Interaction; -import javax.resource.cci.InteractionSpec; -import javax.resource.cci.MappedRecord; -import javax.resource.cci.Record; -import javax.resource.cci.RecordFactory; -import javax.resource.cci.ResultSet; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * This is the central class in the CCI core package. - * It simplifies the use of CCI and helps to avoid common errors. - * It executes core CCI workflow, leaving application code to provide parameters - * to CCI and extract results. This class executes EIS queries or updates, - * catching ResourceExceptions and translating them to the generic exception - * hierarchy defined in the {@code org.springframework.dao} package. - * - *

    Code using this class can pass in and receive {@link javax.resource.cci.Record} - * instances, or alternatively implement callback interfaces for creating input - * Records and extracting result objects from output Records (or CCI ResultSets). - * - *

    Can be used within a service implementation via direct instantiation - * with a ConnectionFactory reference, or get prepared in an application context - * and given to services as bean reference. Note: The ConnectionFactory should - * always be configured as a bean in the application context, in the first case - * given to the service directly, in the second case to the prepared template. - * - * @author Thierry Templier - * @author Juergen Hoeller - * @since 1.2 - * @see RecordCreator - * @see RecordExtractor - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -public class CciTemplate implements CciOperations { - - private final Log logger = LogFactory.getLog(getClass()); - - @Nullable - private ConnectionFactory connectionFactory; - - @Nullable - private ConnectionSpec connectionSpec; - - @Nullable - private RecordCreator outputRecordCreator; - - - /** - * Construct a new CciTemplate for bean usage. - *

    Note: The ConnectionFactory has to be set before using the instance. - * @see #setConnectionFactory - */ - public CciTemplate() { - } - - /** - * Construct a new CciTemplate, given a ConnectionFactory to obtain Connections from. - * Note: This will trigger eager initialization of the exception translator. - * @param connectionFactory the JCA ConnectionFactory to obtain Connections from - */ - public CciTemplate(ConnectionFactory connectionFactory) { - setConnectionFactory(connectionFactory); - afterPropertiesSet(); - } - - /** - * Construct a new CciTemplate, given a ConnectionFactory to obtain Connections from. - * Note: This will trigger eager initialization of the exception translator. - * @param connectionFactory the JCA ConnectionFactory to obtain Connections from - * @param connectionSpec the CCI ConnectionSpec to obtain Connections for - * (may be {@code null}) - */ - public CciTemplate(ConnectionFactory connectionFactory, @Nullable ConnectionSpec connectionSpec) { - setConnectionFactory(connectionFactory); - if (connectionSpec != null) { - setConnectionSpec(connectionSpec); - } - afterPropertiesSet(); - } - - - /** - * Set the CCI ConnectionFactory to obtain Connections from. - */ - public void setConnectionFactory(@Nullable ConnectionFactory connectionFactory) { - this.connectionFactory = connectionFactory; - } - - /** - * Return the CCI ConnectionFactory used by this template. - */ - @Nullable - public ConnectionFactory getConnectionFactory() { - return this.connectionFactory; - } - - private ConnectionFactory obtainConnectionFactory() { - ConnectionFactory connectionFactory = getConnectionFactory(); - Assert.state(connectionFactory != null, "No ConnectionFactory set"); - return connectionFactory; - } - - /** - * Set the CCI ConnectionSpec that this template instance is - * supposed to obtain Connections for. - */ - public void setConnectionSpec(@Nullable ConnectionSpec connectionSpec) { - this.connectionSpec = connectionSpec; - } - - /** - * Return the CCI ConnectionSpec used by this template, if any. - */ - @Nullable - public ConnectionSpec getConnectionSpec() { - return this.connectionSpec; - } - - /** - * Set a RecordCreator that should be used for creating default output Records. - *

    Default is none: When no explicit output Record gets passed into an - * {@code execute} method, CCI's {@code Interaction.execute} variant - * that returns an output Record will be called. - *

    Specify a RecordCreator here if you always need to call CCI's - * {@code Interaction.execute} variant with a passed-in output Record. - * Unless there is an explicitly specified output Record, CciTemplate will - * then invoke this RecordCreator to create a default output Record instance. - * @see javax.resource.cci.Interaction#execute(javax.resource.cci.InteractionSpec, Record) - * @see javax.resource.cci.Interaction#execute(javax.resource.cci.InteractionSpec, Record, Record) - */ - public void setOutputRecordCreator(@Nullable RecordCreator creator) { - this.outputRecordCreator = creator; - } - - /** - * Return a RecordCreator that should be used for creating default output Records. - */ - @Nullable - public RecordCreator getOutputRecordCreator() { - return this.outputRecordCreator; - } - - public void afterPropertiesSet() { - if (getConnectionFactory() == null) { - throw new IllegalArgumentException("Property 'connectionFactory' is required"); - } - } - - - /** - * Create a template derived from this template instance, - * inheriting the ConnectionFactory and other settings but - * overriding the ConnectionSpec used for obtaining Connections. - * @param connectionSpec the CCI ConnectionSpec that the derived template - * instance is supposed to obtain Connections for - * @return the derived template instance - * @see #setConnectionSpec - */ - public CciTemplate getDerivedTemplate(ConnectionSpec connectionSpec) { - CciTemplate derived = new CciTemplate(obtainConnectionFactory(), connectionSpec); - RecordCreator recordCreator = getOutputRecordCreator(); - if (recordCreator != null) { - derived.setOutputRecordCreator(recordCreator); - } - return derived; - } - - - @Override - @Nullable - public T execute(ConnectionCallback action) throws DataAccessException { - Assert.notNull(action, "Callback object must not be null"); - ConnectionFactory connectionFactory = obtainConnectionFactory(); - Connection con = org.springframework.jca.cci.connection.ConnectionFactoryUtils.getConnection( - connectionFactory, getConnectionSpec()); - try { - return action.doInConnection(con, connectionFactory); - } - catch (NotSupportedException ex) { - throw new org.springframework.jca.cci.CciOperationNotSupportedException( - "CCI operation not supported by connector", ex); - } - catch (ResourceException ex) { - throw new DataAccessResourceFailureException("CCI operation failed", ex); - } - catch (SQLException ex) { - throw new org.springframework.jca.cci.InvalidResultSetAccessException( - "Parsing of CCI ResultSet failed", ex); - } - finally { - org.springframework.jca.cci.connection.ConnectionFactoryUtils.releaseConnection( - con, getConnectionFactory()); - } - } - - @Override - @Nullable - public T execute(final InteractionCallback action) throws DataAccessException { - Assert.notNull(action, "Callback object must not be null"); - return execute((ConnectionCallback) (connection, connectionFactory) -> { - Interaction interaction = connection.createInteraction(); - try { - return action.doInInteraction(interaction, connectionFactory); - } - finally { - closeInteraction(interaction); - } - }); - } - - @Override - @Nullable - public Record execute(InteractionSpec spec, Record inputRecord) throws DataAccessException { - return doExecute(spec, inputRecord, null, new SimpleRecordExtractor()); - } - - @Override - public void execute(InteractionSpec spec, Record inputRecord, Record outputRecord) throws DataAccessException { - doExecute(spec, inputRecord, outputRecord, null); - } - - @Override - public Record execute(InteractionSpec spec, RecordCreator inputCreator) throws DataAccessException { - Record output = doExecute(spec, createRecord(inputCreator), null, new SimpleRecordExtractor()); - Assert.state(output != null, "Invalid output record"); - return output; - } - - @Override - public T execute(InteractionSpec spec, Record inputRecord, RecordExtractor outputExtractor) - throws DataAccessException { - - return doExecute(spec, inputRecord, null, outputExtractor); - } - - @Override - public T execute(InteractionSpec spec, RecordCreator inputCreator, RecordExtractor outputExtractor) - throws DataAccessException { - - return doExecute(spec, createRecord(inputCreator), null, outputExtractor); - } - - /** - * Execute the specified interaction on an EIS with CCI. - * All other interaction execution methods go through this. - * @param spec the CCI InteractionSpec instance that defines - * the interaction (connector-specific) - * @param inputRecord the input record - * @param outputRecord output record (can be {@code null}) - * @param outputExtractor object to convert the output record to a result object - * @return the output data extracted with the RecordExtractor object - * @throws DataAccessException if there is any problem - */ - @Nullable - protected T doExecute( - final InteractionSpec spec, final Record inputRecord, @Nullable final Record outputRecord, - @Nullable final RecordExtractor outputExtractor) throws DataAccessException { - - return execute((InteractionCallback) (interaction, connectionFactory) -> { - Record outputRecordToUse = outputRecord; - try { - if (outputRecord != null || getOutputRecordCreator() != null) { - // Use the CCI execute method with output record as parameter. - if (outputRecord == null) { - RecordFactory recordFactory = getRecordFactory(connectionFactory); - outputRecordToUse = getOutputRecordCreator().createRecord(recordFactory); - } - interaction.execute(spec, inputRecord, outputRecordToUse); - } - else { - outputRecordToUse = interaction.execute(spec, inputRecord); - } - return (outputExtractor != null ? outputExtractor.extractData(outputRecordToUse) : null); - } - finally { - if (outputRecordToUse instanceof ResultSet) { - closeResultSet((ResultSet) outputRecordToUse); - } - } - }); - } - - - /** - * Create an indexed Record through the ConnectionFactory's RecordFactory. - * @param name the name of the record - * @return the Record - * @throws DataAccessException if creation of the Record failed - * @see #getRecordFactory(javax.resource.cci.ConnectionFactory) - * @see javax.resource.cci.RecordFactory#createIndexedRecord(String) - */ - public IndexedRecord createIndexedRecord(String name) throws DataAccessException { - try { - RecordFactory recordFactory = getRecordFactory(obtainConnectionFactory()); - return recordFactory.createIndexedRecord(name); - } - catch (NotSupportedException ex) { - throw new org.springframework.jca.cci.RecordTypeNotSupportedException( - "Creation of indexed Record not supported by connector", ex); - } - catch (ResourceException ex) { - throw new org.springframework.jca.cci.CannotCreateRecordException( - "Creation of indexed Record failed", ex); - } - } - - /** - * Create a mapped Record from the ConnectionFactory's RecordFactory. - * @param name record name - * @return the Record - * @throws DataAccessException if creation of the Record failed - * @see #getRecordFactory(javax.resource.cci.ConnectionFactory) - * @see javax.resource.cci.RecordFactory#createMappedRecord(String) - */ - public MappedRecord createMappedRecord(String name) throws DataAccessException { - try { - RecordFactory recordFactory = getRecordFactory(obtainConnectionFactory()); - return recordFactory.createMappedRecord(name); - } - catch (NotSupportedException ex) { - throw new org.springframework.jca.cci.RecordTypeNotSupportedException( - "Creation of mapped Record not supported by connector", ex); - } - catch (ResourceException ex) { - throw new org.springframework.jca.cci.CannotCreateRecordException( - "Creation of mapped Record failed", ex); - } - } - - /** - * Invoke the given RecordCreator, converting JCA ResourceExceptions - * to Spring's DataAccessException hierarchy. - * @param recordCreator the RecordCreator to invoke - * @return the created Record - * @throws DataAccessException if creation of the Record failed - * @see #getRecordFactory(javax.resource.cci.ConnectionFactory) - * @see RecordCreator#createRecord(javax.resource.cci.RecordFactory) - */ - protected Record createRecord(RecordCreator recordCreator) throws DataAccessException { - try { - RecordFactory recordFactory = getRecordFactory(obtainConnectionFactory()); - return recordCreator.createRecord(recordFactory); - } - catch (NotSupportedException ex) { - throw new org.springframework.jca.cci.RecordTypeNotSupportedException( - "Creation of the desired Record type not supported by connector", ex); - } - catch (ResourceException ex) { - throw new org.springframework.jca.cci.CannotCreateRecordException( - "Creation of the desired Record failed", ex); - } - } - - /** - * Return a RecordFactory for the given ConnectionFactory. - *

    Default implementation returns the connector's RecordFactory if - * available, falling back to a NotSupportedRecordFactory placeholder. - * This allows to invoke a RecordCreator callback with a non-null - * RecordFactory reference in any case. - * @param connectionFactory the CCI ConnectionFactory - * @return the CCI RecordFactory for the ConnectionFactory - * @throws ResourceException if thrown by CCI methods - * @see org.springframework.jca.cci.connection.NotSupportedRecordFactory - */ - protected RecordFactory getRecordFactory(ConnectionFactory connectionFactory) throws ResourceException { - try { - return connectionFactory.getRecordFactory(); - } - catch (NotSupportedException ex) { - return new org.springframework.jca.cci.connection.NotSupportedRecordFactory(); - } - } - - - /** - * Close the given CCI Interaction and ignore any thrown exception. - * This is useful for typical finally blocks in manual CCI code. - * @param interaction the CCI Interaction to close - * @see javax.resource.cci.Interaction#close() - */ - private void closeInteraction(@Nullable Interaction interaction) { - if (interaction != null) { - try { - interaction.close(); - } - catch (ResourceException ex) { - logger.trace("Could not close CCI Interaction", ex); - } - catch (Throwable ex) { - // We don't trust the CCI driver: It might throw RuntimeException or Error. - logger.trace("Unexpected exception on closing CCI Interaction", ex); - } - } - } - - /** - * Close the given CCI ResultSet and ignore any thrown exception. - * This is useful for typical finally blocks in manual CCI code. - * @param resultSet the CCI ResultSet to close - * @see javax.resource.cci.ResultSet#close() - */ - private void closeResultSet(@Nullable ResultSet resultSet) { - if (resultSet != null) { - try { - resultSet.close(); - } - catch (SQLException ex) { - logger.trace("Could not close CCI ResultSet", ex); - } - catch (Throwable ex) { - // We don't trust the CCI driver: It might throw RuntimeException or Error. - logger.trace("Unexpected exception on closing CCI ResultSet", ex); - } - } - } - - - private static class SimpleRecordExtractor implements RecordExtractor { - - @Override - public Record extractData(Record record) { - return record; - } - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/core/ConnectionCallback.java b/spring-tx/src/main/java/org/springframework/jca/cci/core/ConnectionCallback.java deleted file mode 100644 index a573f3583e61..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/core/ConnectionCallback.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.core; - -import java.sql.SQLException; - -import javax.resource.ResourceException; -import javax.resource.cci.Connection; -import javax.resource.cci.ConnectionFactory; - -import org.springframework.dao.DataAccessException; -import org.springframework.lang.Nullable; - -/** - * Generic callback interface for code that operates on a CCI Connection. - * Allows to execute any number of operations on a single Connection, - * using any type and number of Interaction. - * - *

    This is particularly useful for delegating to existing data access code - * that expects a Connection to work on and throws ResourceException. For newly - * written code, it is strongly recommended to use CciTemplate's more specific - * {@code execute} variants. - * - * @author Thierry Templier - * @author Juergen Hoeller - * @since 1.2 - * @param the result type - * @see CciTemplate#execute(ConnectionCallback) - * @see CciTemplate#execute(javax.resource.cci.InteractionSpec, javax.resource.cci.Record) - * @see CciTemplate#execute(javax.resource.cci.InteractionSpec, RecordCreator, RecordExtractor) - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@FunctionalInterface -public interface ConnectionCallback { - - /** - * Gets called by {@code CciTemplate.execute} with an active CCI Connection. - * Does not need to care about activating or closing the Connection, or handling - * transactions. - *

    If called without a thread-bound CCI transaction (initiated by - * CciLocalTransactionManager), the code will simply get executed on the CCI - * Connection with its transactional semantics. If CciTemplate is configured - * to use a JTA-aware ConnectionFactory, the CCI Connection and thus the callback - * code will be transactional if a JTA transaction is active. - *

    Allows for returning a result object created within the callback, i.e. - * a domain object or a collection of domain objects. Note that there's special - * support for single step actions: see the {@code CciTemplate.execute} - * variants. A thrown RuntimeException is treated as application exception: - * it gets propagated to the caller of the template. - * @param connection active CCI Connection - * @param connectionFactory the CCI ConnectionFactory that the Connection was - * created with (gives access to RecordFactory and ResourceAdapterMetaData) - * @return a result object, or {@code null} if none - * @throws ResourceException if thrown by a CCI method, to be auto-converted - * to a DataAccessException - * @throws SQLException if thrown by a ResultSet method, to be auto-converted - * to a DataAccessException - * @throws DataAccessException in case of custom exceptions - * @see javax.resource.cci.ConnectionFactory#getRecordFactory() - * @see javax.resource.cci.ConnectionFactory#getMetaData() - * @see CciTemplate#execute(javax.resource.cci.InteractionSpec, RecordCreator, RecordExtractor) - */ - @Nullable - T doInConnection(Connection connection, ConnectionFactory connectionFactory) - throws ResourceException, SQLException, DataAccessException; - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/core/InteractionCallback.java b/spring-tx/src/main/java/org/springframework/jca/cci/core/InteractionCallback.java deleted file mode 100644 index 447a1432eb9e..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/core/InteractionCallback.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.core; - -import java.sql.SQLException; - -import javax.resource.ResourceException; -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.Interaction; - -import org.springframework.dao.DataAccessException; -import org.springframework.lang.Nullable; - -/** - * Generic callback interface for code that operates on a CCI Interaction. - * Allows to execute any number of operations on a single Interaction, for - * example a single execute call or repeated execute calls with varying - * parameters. - * - *

    This is particularly useful for delegating to existing data access code - * that expects an Interaction to work on and throws ResourceException. For newly - * written code, it is strongly recommended to use CciTemplate's more specific - * {@code execute} variants. - * - * @author Thierry Templier - * @author Juergen Hoeller - * @since 1.2 - * @param the result type - * @see CciTemplate#execute(InteractionCallback) - * @see CciTemplate#execute(javax.resource.cci.InteractionSpec, javax.resource.cci.Record) - * @see CciTemplate#execute(javax.resource.cci.InteractionSpec, RecordCreator, RecordExtractor) - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@FunctionalInterface -public interface InteractionCallback { - - /** - * Gets called by {@code CciTemplate.execute} with an active CCI Interaction. - * Does not need to care about activating or closing the Interaction, or - * handling transactions. - *

    If called without a thread-bound CCI transaction (initiated by - * CciLocalTransactionManager), the code will simply get executed on the CCI - * Interaction with its transactional semantics. If CciTemplate is configured - * to use a JTA-aware ConnectionFactory, the CCI Interaction and thus the callback - * code will be transactional if a JTA transaction is active. - *

    Allows for returning a result object created within the callback, i.e. - * a domain object or a collection of domain objects. Note that there's special - * support for single step actions: see the {@code CciTemplate.execute} - * variants. A thrown RuntimeException is treated as application exception: - * it gets propagated to the caller of the template. - * @param interaction active CCI Interaction - * @param connectionFactory the CCI ConnectionFactory that the Connection was - * created with (gives access to RecordFactory and ResourceAdapterMetaData) - * @return a result object, or {@code null} if none - * @throws ResourceException if thrown by a CCI method, to be auto-converted - * to a DataAccessException - * @throws SQLException if thrown by a ResultSet method, to be auto-converted - * to a DataAccessException - * @throws DataAccessException in case of custom exceptions - * @see javax.resource.cci.ConnectionFactory#getRecordFactory() - * @see javax.resource.cci.ConnectionFactory#getMetaData() - * @see CciTemplate#execute(javax.resource.cci.InteractionSpec, RecordCreator, RecordExtractor) - */ - @Nullable - T doInInteraction(Interaction interaction, ConnectionFactory connectionFactory) - throws ResourceException, SQLException, DataAccessException; - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/core/RecordCreator.java b/spring-tx/src/main/java/org/springframework/jca/cci/core/RecordCreator.java deleted file mode 100644 index 18836887e032..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/core/RecordCreator.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.core; - -import javax.resource.ResourceException; -import javax.resource.cci.Record; -import javax.resource.cci.RecordFactory; - -import org.springframework.dao.DataAccessException; - -/** - * Callback interface for creating a CCI Record instance, - * usually based on the passed-in CCI RecordFactory. - * - *

    Used for input Record creation in CciTemplate. Alternatively, - * Record instances can be passed into CciTemplate's corresponding - * {@code execute} methods directly, either instantiated manually - * or created through CciTemplate's Record factory methods. - * - *

    Also used for creating default output Records in CciTemplate. - * This is useful when the JCA connector needs an explicit output Record - * instance, but no output Records should be passed into CciTemplate's - * {@code execute} methods. - * - * @author Thierry Templier - * @author Juergen Hoeller - * @since 1.2 - * @see CciTemplate#execute(javax.resource.cci.InteractionSpec, RecordCreator) - * @see CciTemplate#execute(javax.resource.cci.InteractionSpec, RecordCreator, RecordExtractor) - * @see CciTemplate#createIndexedRecord(String) - * @see CciTemplate#createMappedRecord(String) - * @see CciTemplate#setOutputRecordCreator(RecordCreator) - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@FunctionalInterface -public interface RecordCreator { - - /** - * Create a CCI Record instance, usually based on the passed-in CCI RecordFactory. - *

    For use as input creator with CciTemplate's {@code execute} methods, - * this method should create a populated Record instance. For use as - * output Record creator, it should return an empty Record instance. - * @param recordFactory the CCI RecordFactory (never {@code null}, but not guaranteed to be - * supported by the connector: its create methods might throw NotSupportedException) - * @return the Record instance - * @throws ResourceException if thrown by a CCI method, to be auto-converted - * to a DataAccessException - * @throws DataAccessException in case of custom exceptions - */ - Record createRecord(RecordFactory recordFactory) throws ResourceException, DataAccessException; - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/core/RecordExtractor.java b/spring-tx/src/main/java/org/springframework/jca/cci/core/RecordExtractor.java deleted file mode 100644 index 8c5e9e2b666d..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/core/RecordExtractor.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.core; - -import java.sql.SQLException; - -import javax.resource.ResourceException; -import javax.resource.cci.Record; - -import org.springframework.dao.DataAccessException; -import org.springframework.lang.Nullable; - -/** - * Callback interface for extracting a result object from a CCI Record instance. - * - *

    Used for output object creation in CciTemplate. Alternatively, output - * Records can also be returned to client code as-is. In case of a CCI ResultSet - * as execution result, you will almost always want to implement a RecordExtractor, - * to be able to read the ResultSet in a managed fashion, with the CCI Connection - * still open while reading the ResultSet. - * - *

    Implementations of this interface perform the actual work of extracting - * results, but don't need to worry about exception handling. ResourceExceptions - * will be caught and handled correctly by the CciTemplate class. - * - * @author Thierry Templier - * @author Juergen Hoeller - * @since 1.2 - * @param the result type - * @see CciTemplate#execute(javax.resource.cci.InteractionSpec, Record, RecordExtractor) - * @see CciTemplate#execute(javax.resource.cci.InteractionSpec, RecordCreator, RecordExtractor) - * @see javax.resource.cci.ResultSet - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@FunctionalInterface -public interface RecordExtractor { - - /** - * Process the data in the given Record, creating a corresponding result object. - * @param record the Record to extract data from - * (possibly a CCI ResultSet) - * @return an arbitrary result object, or {@code null} if none - * (the extractor will typically be stateful in the latter case) - * @throws ResourceException if thrown by a CCI method, to be auto-converted - * to a DataAccessException - * @throws SQLException if thrown by a ResultSet method, to be auto-converted - * to a DataAccessException - * @throws DataAccessException in case of custom exceptions - * @see javax.resource.cci.ResultSet - */ - @Nullable - T extractData(Record record) throws ResourceException, SQLException, DataAccessException; - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/core/package-info.java b/spring-tx/src/main/java/org/springframework/jca/cci/core/package-info.java deleted file mode 100644 index 33d36edf29d8..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/core/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides the core JCA CCI support, based on CciTemplate - * and its associated callback interfaces. - */ -@NonNullApi -@NonNullFields -package org.springframework.jca.cci.core; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/core/support/CciDaoSupport.java b/spring-tx/src/main/java/org/springframework/jca/cci/core/support/CciDaoSupport.java deleted file mode 100644 index e650bae60516..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/core/support/CciDaoSupport.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.core.support; - -import javax.resource.cci.Connection; -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.ConnectionSpec; - -import org.springframework.dao.support.DaoSupport; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Convenient super class for CCI-based data access objects. - * - *

    Requires a {@link javax.resource.cci.ConnectionFactory} to be set, - * providing a {@link org.springframework.jca.cci.core.CciTemplate} based - * on it to subclasses through the {@link #getCciTemplate()} method. - * - *

    This base class is mainly intended for CciTemplate usage but can - * also be used when working with a Connection directly or when using - * {@code org.springframework.jca.cci.object} classes. - * - * @author Thierry Templier - * @author Juergen Hoeller - * @since 1.2 - * @see #setConnectionFactory - * @see #getCciTemplate - * @see org.springframework.jca.cci.core.CciTemplate - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -public abstract class CciDaoSupport extends DaoSupport { - - @Nullable - private org.springframework.jca.cci.core.CciTemplate cciTemplate; - - - /** - * Set the ConnectionFactory to be used by this DAO. - */ - public final void setConnectionFactory(ConnectionFactory connectionFactory) { - if (this.cciTemplate == null || connectionFactory != this.cciTemplate.getConnectionFactory()) { - this.cciTemplate = createCciTemplate(connectionFactory); - } - } - - /** - * Create a CciTemplate for the given ConnectionFactory. - * Only invoked if populating the DAO with a ConnectionFactory reference! - *

    Can be overridden in subclasses to provide a CciTemplate instance - * with different configuration, or a custom CciTemplate subclass. - * @param connectionFactory the CCI ConnectionFactory to create a CciTemplate for - * @return the new CciTemplate instance - * @see #setConnectionFactory(javax.resource.cci.ConnectionFactory) - */ - protected org.springframework.jca.cci.core.CciTemplate createCciTemplate(ConnectionFactory connectionFactory) { - return new org.springframework.jca.cci.core.CciTemplate(connectionFactory); - } - - /** - * Return the ConnectionFactory used by this DAO. - */ - @Nullable - public final ConnectionFactory getConnectionFactory() { - return (this.cciTemplate != null ? this.cciTemplate.getConnectionFactory() : null); - } - - /** - * Set the CciTemplate for this DAO explicitly, - * as an alternative to specifying a ConnectionFactory. - */ - public final void setCciTemplate(org.springframework.jca.cci.core.CciTemplate cciTemplate) { - this.cciTemplate = cciTemplate; - } - - /** - * Return the CciTemplate for this DAO, - * pre-initialized with the ConnectionFactory or set explicitly. - */ - @Nullable - public final org.springframework.jca.cci.core.CciTemplate getCciTemplate() { - return this.cciTemplate; - } - - @Override - protected final void checkDaoConfig() { - if (this.cciTemplate == null) { - throw new IllegalArgumentException("'connectionFactory' or 'cciTemplate' is required"); - } - } - - - /** - * Obtain a CciTemplate derived from the main template instance, - * inheriting the ConnectionFactory and other settings but - * overriding the ConnectionSpec used for obtaining Connections. - * @param connectionSpec the CCI ConnectionSpec that the returned - * template instance is supposed to obtain Connections for - * @return the derived template instance - * @see org.springframework.jca.cci.core.CciTemplate#getDerivedTemplate(javax.resource.cci.ConnectionSpec) - */ - protected final org.springframework.jca.cci.core.CciTemplate getCciTemplate(ConnectionSpec connectionSpec) { - org.springframework.jca.cci.core.CciTemplate cciTemplate = getCciTemplate(); - Assert.state(cciTemplate != null, "No CciTemplate set"); - return cciTemplate.getDerivedTemplate(connectionSpec); - } - - /** - * Get a CCI Connection, either from the current transaction or a new one. - * @return the CCI Connection - * @throws org.springframework.jca.cci.CannotGetCciConnectionException - * if the attempt to get a Connection failed - * @see org.springframework.jca.cci.connection.ConnectionFactoryUtils#getConnection(javax.resource.cci.ConnectionFactory) - */ - protected final Connection getConnection() throws org.springframework.jca.cci.CannotGetCciConnectionException { - ConnectionFactory connectionFactory = getConnectionFactory(); - Assert.state(connectionFactory != null, "No ConnectionFactory set"); - return org.springframework.jca.cci.connection.ConnectionFactoryUtils.getConnection(connectionFactory); - } - - /** - * Close the given CCI Connection, created via this bean's ConnectionFactory, - * if it isn't bound to the thread. - * @param con the Connection to close - * @see org.springframework.jca.cci.connection.ConnectionFactoryUtils#releaseConnection - */ - protected final void releaseConnection(Connection con) { - org.springframework.jca.cci.connection.ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory()); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/core/support/CommAreaRecord.java b/spring-tx/src/main/java/org/springframework/jca/cci/core/support/CommAreaRecord.java deleted file mode 100644 index 6f54b8b03cef..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/core/support/CommAreaRecord.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.core.support; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.resource.cci.Record; -import javax.resource.cci.Streamable; - -import org.springframework.util.FileCopyUtils; - -/** - * CCI Record implementation for a COMMAREA, holding a byte array. - * - * @author Thierry Templier - * @author Juergen Hoeller - * @since 1.2 - * @see org.springframework.jca.cci.object.MappingCommAreaOperation - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -@SuppressWarnings("serial") -public class CommAreaRecord implements Record, Streamable { - - private byte[] bytes = new byte[0]; - - private String recordName = ""; - - private String recordShortDescription = ""; - - - /** - * Create a new CommAreaRecord. - * @see #read(java.io.InputStream) - */ - public CommAreaRecord() { - } - - /** - * Create a new CommAreaRecord. - * @param bytes the bytes to fill the record with - */ - public CommAreaRecord(byte[] bytes) { - this.bytes = bytes; - } - - - @Override - public void setRecordName(String recordName) { - this.recordName = recordName; - } - - @Override - public String getRecordName() { - return this.recordName; - } - - @Override - public void setRecordShortDescription(String recordShortDescription) { - this.recordShortDescription = recordShortDescription; - } - - @Override - public String getRecordShortDescription() { - return this.recordShortDescription; - } - - - @Override - public void read(InputStream in) throws IOException { - this.bytes = FileCopyUtils.copyToByteArray(in); - } - - @Override - public void write(OutputStream out) throws IOException { - out.write(this.bytes); - out.flush(); - } - - public byte[] toByteArray() { - return this.bytes; - } - - - @Override - public Object clone() { - return new CommAreaRecord(this.bytes); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/core/support/package-info.java b/spring-tx/src/main/java/org/springframework/jca/cci/core/support/package-info.java deleted file mode 100644 index d7bfd6bc0f22..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/core/support/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Classes supporting the {@code org.springframework.jca.cci.core} package. - * Contains a DAO base class for CciTemplate usage. - */ -@NonNullApi -@NonNullFields -package org.springframework.jca.cci.core.support; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/object/EisOperation.java b/spring-tx/src/main/java/org/springframework/jca/cci/object/EisOperation.java deleted file mode 100644 index 7cbe685ef03f..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/object/EisOperation.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.object; - -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.InteractionSpec; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Base class for EIS operation objects that work with the CCI API. - * Encapsulates a CCI ConnectionFactory and a CCI InteractionSpec. - * - *

    Works with a CciTemplate instance underneath. EIS operation objects - * are an alternative to working with a CciTemplate directly. - * - * @author Juergen Hoeller - * @since 1.2 - * @see #setConnectionFactory - * @see #setInteractionSpec - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -public abstract class EisOperation implements InitializingBean { - - private org.springframework.jca.cci.core.CciTemplate cciTemplate = - new org.springframework.jca.cci.core.CciTemplate(); - - @Nullable - private InteractionSpec interactionSpec; - - - /** - * Set the CciTemplate to be used by this operation. - * Alternatively, specify a CCI ConnectionFactory. - * @see #setConnectionFactory - */ - public void setCciTemplate(org.springframework.jca.cci.core.CciTemplate cciTemplate) { - Assert.notNull(cciTemplate, "CciTemplate must not be null"); - this.cciTemplate = cciTemplate; - } - - /** - * Return the CciTemplate used by this operation. - */ - public org.springframework.jca.cci.core.CciTemplate getCciTemplate() { - return this.cciTemplate; - } - - /** - * Set the CCI ConnectionFactory to be used by this operation. - */ - public void setConnectionFactory(ConnectionFactory connectionFactory) { - this.cciTemplate.setConnectionFactory(connectionFactory); - } - - /** - * Set the CCI InteractionSpec for this operation. - */ - public void setInteractionSpec(@Nullable InteractionSpec interactionSpec) { - this.interactionSpec = interactionSpec; - } - - /** - * Return the CCI InteractionSpec for this operation. - */ - @Nullable - public InteractionSpec getInteractionSpec() { - return this.interactionSpec; - } - - - @Override - public void afterPropertiesSet() { - this.cciTemplate.afterPropertiesSet(); - - if (this.interactionSpec == null) { - throw new IllegalArgumentException("InteractionSpec is required"); - } - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/object/MappingCommAreaOperation.java b/spring-tx/src/main/java/org/springframework/jca/cci/object/MappingCommAreaOperation.java deleted file mode 100644 index 25db832ae20b..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/object/MappingCommAreaOperation.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.object; - -import java.io.IOException; - -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.InteractionSpec; -import javax.resource.cci.Record; -import javax.resource.cci.RecordFactory; - -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataRetrievalFailureException; - -/** - * EIS operation object for access to COMMAREA records. - * Subclass of the generic MappingRecordOperation class. - * - * @author Thierry Templier - * @since 1.2 - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -public abstract class MappingCommAreaOperation extends MappingRecordOperation { - - /** - * Create a new MappingCommAreaQuery. - * @see #setConnectionFactory - * @see #setInteractionSpec - */ - public MappingCommAreaOperation() { - } - - /** - * Create a new MappingCommAreaQuery. - * @param connectionFactory the ConnectionFactory to use to obtain connections - * @param interactionSpec specification to configure the interaction - */ - public MappingCommAreaOperation(ConnectionFactory connectionFactory, InteractionSpec interactionSpec) { - super(connectionFactory, interactionSpec); - } - - - @Override - protected final Record createInputRecord(RecordFactory recordFactory, Object inObject) { - try { - return new org.springframework.jca.cci.core.support.CommAreaRecord(objectToBytes(inObject)); - } - catch (IOException ex) { - throw new DataRetrievalFailureException("I/O exception during bytes conversion", ex); - } - } - - @Override - protected final Object extractOutputData(Record record) throws DataAccessException { - org.springframework.jca.cci.core.support.CommAreaRecord commAreaRecord = - (org.springframework.jca.cci.core.support.CommAreaRecord) record; - try { - return bytesToObject(commAreaRecord.toByteArray()); - } - catch (IOException ex) { - throw new DataRetrievalFailureException("I/O exception during bytes conversion", ex); - } - } - - - /** - * Method used to convert an object into COMMAREA bytes. - * @param inObject the input data - * @return the COMMAREA's bytes - * @throws IOException if thrown by I/O methods - * @throws DataAccessException if conversion failed - */ - protected abstract byte[] objectToBytes(Object inObject) throws IOException, DataAccessException; - - /** - * Method used to convert the COMMAREA's bytes to an object. - * @param bytes the COMMAREA's bytes - * @return the output data - * @throws IOException if thrown by I/O methods - * @throws DataAccessException if conversion failed - */ - protected abstract Object bytesToObject(byte[] bytes) throws IOException, DataAccessException; - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/object/MappingRecordOperation.java b/spring-tx/src/main/java/org/springframework/jca/cci/object/MappingRecordOperation.java deleted file mode 100644 index 148c181a44dd..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/object/MappingRecordOperation.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.object; - -import java.sql.SQLException; - -import javax.resource.ResourceException; -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.InteractionSpec; -import javax.resource.cci.Record; -import javax.resource.cci.RecordFactory; - -import org.springframework.dao.DataAccessException; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * EIS operation object that expects mapped input and output objects, - * converting to and from CCI Records. - * - *

    Concrete subclasses must implement the abstract - * {@code createInputRecord(RecordFactory, Object)} and - * {@code extractOutputData(Record)} methods, to create an input - * Record from an object and to convert an output Record into an object, - * respectively. - * - * @author Thierry Templier - * @author Juergen Hoeller - * @since 1.2 - * @see #createInputRecord(javax.resource.cci.RecordFactory, Object) - * @see #extractOutputData(javax.resource.cci.Record) - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -public abstract class MappingRecordOperation extends EisOperation { - - /** - * Constructor that allows use as a JavaBean. - */ - public MappingRecordOperation() { - } - - /** - * Convenient constructor with ConnectionFactory and specifications - * (connection and interaction). - * @param connectionFactory the ConnectionFactory to use to obtain connections - */ - public MappingRecordOperation(ConnectionFactory connectionFactory, InteractionSpec interactionSpec) { - getCciTemplate().setConnectionFactory(connectionFactory); - setInteractionSpec(interactionSpec); - } - - /** - * Set a RecordCreator that should be used for creating default output Records. - *

    Default is none: CCI's {@code Interaction.execute} variant - * that returns an output Record will be called. - *

    Specify a RecordCreator here if you always need to call CCI's - * {@code Interaction.execute} variant with a passed-in output Record. - * This RecordCreator will then be invoked to create a default output Record instance. - * @see javax.resource.cci.Interaction#execute(javax.resource.cci.InteractionSpec, Record) - * @see javax.resource.cci.Interaction#execute(javax.resource.cci.InteractionSpec, Record, Record) - * @see org.springframework.jca.cci.core.CciTemplate#setOutputRecordCreator - */ - public void setOutputRecordCreator(org.springframework.jca.cci.core.RecordCreator creator) { - getCciTemplate().setOutputRecordCreator(creator); - } - - /** - * Execute the interaction encapsulated by this operation object. - * @param inputObject the input data, to be converted to a Record - * by the {@code createInputRecord} method - * @return the output data extracted with the {@code extractOutputData} method - * @throws DataAccessException if there is any problem - * @see #createInputRecord - * @see #extractOutputData - */ - @Nullable - public Object execute(Object inputObject) throws DataAccessException { - InteractionSpec interactionSpec = getInteractionSpec(); - Assert.state(interactionSpec != null, "No InteractionSpec set"); - return getCciTemplate().execute( - interactionSpec, new RecordCreatorImpl(inputObject), new RecordExtractorImpl()); - } - - - /** - * Subclasses must implement this method to generate an input Record - * from an input object passed into the {@code execute} method. - * @param inputObject the passed-in input object - * @return the CCI input Record - * @throws ResourceException if thrown by a CCI method, to be auto-converted - * to a DataAccessException - * @see #execute(Object) - */ - protected abstract Record createInputRecord(RecordFactory recordFactory, Object inputObject) - throws ResourceException, DataAccessException; - - /** - * Subclasses must implement this method to convert the Record returned - * by CCI execution into a result object for the {@code execute} method. - * @param outputRecord the Record returned by CCI execution - * @return the result object - * @throws ResourceException if thrown by a CCI method, to be auto-converted - * to a DataAccessException - * @see #execute(Object) - */ - protected abstract Object extractOutputData(Record outputRecord) - throws ResourceException, SQLException, DataAccessException; - - - /** - * Implementation of RecordCreator that calls the enclosing - * class's {@code createInputRecord} method. - */ - protected class RecordCreatorImpl implements org.springframework.jca.cci.core.RecordCreator { - - private final Object inputObject; - - public RecordCreatorImpl(Object inObject) { - this.inputObject = inObject; - } - - @Override - public Record createRecord(RecordFactory recordFactory) throws ResourceException, DataAccessException { - return createInputRecord(recordFactory, this.inputObject); - } - } - - - /** - * Implementation of RecordExtractor that calls the enclosing - * class's {@code extractOutputData} method. - */ - protected class RecordExtractorImpl implements org.springframework.jca.cci.core.RecordExtractor { - - @Override - public Object extractData(Record record) throws ResourceException, SQLException, DataAccessException { - return extractOutputData(record); - } - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/object/SimpleRecordOperation.java b/spring-tx/src/main/java/org/springframework/jca/cci/object/SimpleRecordOperation.java deleted file mode 100644 index 5799ca935a89..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/object/SimpleRecordOperation.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci.object; - -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.InteractionSpec; -import javax.resource.cci.Record; - -import org.springframework.dao.DataAccessException; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * EIS operation object that accepts a passed-in CCI input Record - * and returns a corresponding CCI output Record. - * - * @author Juergen Hoeller - * @since 1.2 - * @deprecated as of 5.3, in favor of specific data access APIs - * (or native CCI usage if there is no alternative) - */ -@Deprecated -public class SimpleRecordOperation extends EisOperation { - - /** - * Constructor that allows use as a JavaBean. - */ - public SimpleRecordOperation() { - } - - /** - * Convenient constructor with ConnectionFactory and specifications - * (connection and interaction). - * @param connectionFactory the ConnectionFactory to use to obtain connections - */ - public SimpleRecordOperation(ConnectionFactory connectionFactory, InteractionSpec interactionSpec) { - getCciTemplate().setConnectionFactory(connectionFactory); - setInteractionSpec(interactionSpec); - } - - - /** - * Execute the CCI interaction encapsulated by this operation object. - *

    This method will call CCI's {@code Interaction.execute} variant - * that returns an output Record. - * @param inputRecord the input record - * @return the output record - * @throws DataAccessException if there is any problem - * @see javax.resource.cci.Interaction#execute(javax.resource.cci.InteractionSpec, Record) - */ - @Nullable - public Record execute(Record inputRecord) throws DataAccessException { - InteractionSpec interactionSpec = getInteractionSpec(); - Assert.state(interactionSpec != null, "No InteractionSpec set"); - return getCciTemplate().execute(interactionSpec, inputRecord); - } - - /** - * Execute the CCI interaction encapsulated by this operation object. - *

    This method will call CCI's {@code Interaction.execute} variant - * with a passed-in output Record. - * @param inputRecord the input record - * @param outputRecord the output record - * @throws DataAccessException if there is any problem - * @see javax.resource.cci.Interaction#execute(javax.resource.cci.InteractionSpec, Record, Record) - */ - public void execute(Record inputRecord, Record outputRecord) throws DataAccessException { - InteractionSpec interactionSpec = getInteractionSpec(); - Assert.state(interactionSpec != null, "No InteractionSpec set"); - getCciTemplate().execute(interactionSpec, inputRecord, outputRecord); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/object/package-info.java b/spring-tx/src/main/java/org/springframework/jca/cci/object/package-info.java deleted file mode 100644 index 2c51b175d105..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/object/package-info.java +++ /dev/null @@ -1,13 +0,0 @@ -/** - * The classes in this package represent EIS operations as threadsafe, - * reusable objects. This higher level of CCI abstraction depends on the - * lower-level abstraction in the {@code org.springframework.jca.cci.core} package. - * Exceptions thrown are as in the {@code org.springframework.dao} package, - * meaning that code using this package does not need to worry about error handling. - */ -@NonNullApi -@NonNullFields -package org.springframework.jca.cci.object; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/package-info.java b/spring-tx/src/main/java/org/springframework/jca/cci/package-info.java deleted file mode 100644 index 469cdc926b3b..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/cci/package-info.java +++ /dev/null @@ -1,12 +0,0 @@ -/** - * This package contains Spring's support for the Common Client Interface (CCI), - * as defined by the J2EE Connector Architecture. It is conceptually similar - * to the {@code org.springframework.jdbc} package, providing the same - * levels of data access abstraction. - */ -@NonNullApi -@NonNullFields -package org.springframework.jca.cci; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-tx/src/main/java/org/springframework/jca/context/BootstrapContextAware.java b/spring-tx/src/main/java/org/springframework/jca/context/BootstrapContextAware.java deleted file mode 100644 index 66c6b65c1d38..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/context/BootstrapContextAware.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.context; - -import javax.resource.spi.BootstrapContext; - -import org.springframework.beans.factory.Aware; - -/** - * Interface to be implemented by any object that wishes to be - * notified of the BootstrapContext (typically determined by the - * {@link ResourceAdapterApplicationContext}) that it runs in. - * - * @author Juergen Hoeller - * @author Chris Beams - * @since 2.5 - * @see javax.resource.spi.BootstrapContext - */ -public interface BootstrapContextAware extends Aware { - - /** - * Set the BootstrapContext that this object runs in. - *

    Invoked after population of normal bean properties but before an init - * callback like InitializingBean's {@code afterPropertiesSet} or a - * custom init-method. Invoked after ApplicationContextAware's - * {@code setApplicationContext}. - * @param bootstrapContext the BootstrapContext object to be used by this object - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet - * @see org.springframework.context.ApplicationContextAware#setApplicationContext - */ - void setBootstrapContext(BootstrapContext bootstrapContext); - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/context/BootstrapContextAwareProcessor.java b/spring-tx/src/main/java/org/springframework/jca/context/BootstrapContextAwareProcessor.java deleted file mode 100644 index 1efb9d9a6915..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/context/BootstrapContextAwareProcessor.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.context; - -import javax.resource.spi.BootstrapContext; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.lang.Nullable; - -/** - * {@link org.springframework.beans.factory.config.BeanPostProcessor} - * implementation that passes the BootstrapContext to beans that implement - * the {@link BootstrapContextAware} interface. - * - *

    {@link ResourceAdapterApplicationContext} automatically registers - * this processor with its underlying bean factory. - * - * @author Juergen Hoeller - * @since 2.5 - * @see BootstrapContextAware - */ -class BootstrapContextAwareProcessor implements BeanPostProcessor { - - @Nullable - private final BootstrapContext bootstrapContext; - - - /** - * Create a new BootstrapContextAwareProcessor for the given context. - */ - public BootstrapContextAwareProcessor(@Nullable BootstrapContext bootstrapContext) { - this.bootstrapContext = bootstrapContext; - } - - - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (this.bootstrapContext != null && bean instanceof BootstrapContextAware) { - ((BootstrapContextAware) bean).setBootstrapContext(this.bootstrapContext); - } - return bean; - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - return bean; - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/context/ResourceAdapterApplicationContext.java b/spring-tx/src/main/java/org/springframework/jca/context/ResourceAdapterApplicationContext.java deleted file mode 100644 index 4154e2230469..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/context/ResourceAdapterApplicationContext.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.context; - -import javax.resource.spi.BootstrapContext; -import javax.resource.spi.work.WorkManager; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.util.Assert; - -/** - * {@link org.springframework.context.ApplicationContext} implementation - * for a JCA ResourceAdapter. Needs to be initialized with the JCA - * {@link javax.resource.spi.BootstrapContext}, passing it on to - * Spring-managed beans that implement {@link BootstrapContextAware}. - * - * @author Juergen Hoeller - * @since 2.5 - * @see SpringContextResourceAdapter - * @see BootstrapContextAware - */ -public class ResourceAdapterApplicationContext extends GenericApplicationContext { - - private final BootstrapContext bootstrapContext; - - - /** - * Create a new ResourceAdapterApplicationContext for the given BootstrapContext. - * @param bootstrapContext the JCA BootstrapContext that the ResourceAdapter - * has been started with - */ - public ResourceAdapterApplicationContext(BootstrapContext bootstrapContext) { - Assert.notNull(bootstrapContext, "BootstrapContext must not be null"); - this.bootstrapContext = bootstrapContext; - } - - - @Override - protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - beanFactory.addBeanPostProcessor(new BootstrapContextAwareProcessor(this.bootstrapContext)); - beanFactory.ignoreDependencyInterface(BootstrapContextAware.class); - beanFactory.registerResolvableDependency(BootstrapContext.class, this.bootstrapContext); - - // JCA WorkManager resolved lazily - may not be available. - beanFactory.registerResolvableDependency(WorkManager.class, - (ObjectFactory) this.bootstrapContext::getWorkManager); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/context/SpringContextResourceAdapter.java b/spring-tx/src/main/java/org/springframework/jca/context/SpringContextResourceAdapter.java deleted file mode 100644 index 3c99117f6450..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/context/SpringContextResourceAdapter.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.context; - -import javax.resource.NotSupportedException; -import javax.resource.ResourceException; -import javax.resource.spi.ActivationSpec; -import javax.resource.spi.BootstrapContext; -import javax.resource.spi.ResourceAdapter; -import javax.resource.spi.ResourceAdapterInternalException; -import javax.resource.spi.endpoint.MessageEndpointFactory; -import javax.transaction.xa.XAResource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.StandardEnvironment; -import org.springframework.lang.Nullable; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; - -/** - * JCA 1.7 {@link javax.resource.spi.ResourceAdapter} implementation - * that loads a Spring {@link org.springframework.context.ApplicationContext}, - * starting and stopping Spring-managed beans as part of the ResourceAdapter's - * lifecycle. - * - *

    Ideal for application contexts that do not need any HTTP entry points - * but rather just consist of message endpoints and scheduled jobs etc. - * Beans in such a context may use application server resources such as the - * JTA transaction manager and JNDI-bound JDBC DataSources and JMS - * ConnectionFactory instances, and may also register with the platform's - * JMX server - all through Spring's standard transaction management and - * JNDI and JMX support facilities. - * - *

    If the need for scheduling asynchronous work arises, consider using - * Spring's {@link org.springframework.jca.work.WorkManagerTaskExecutor} - * as a standard bean definition, to be injected into application beans - * through dependency injection. This WorkManagerTaskExecutor will automatically - * use the JCA WorkManager from the BootstrapContext that has been provided - * to this ResourceAdapter. - * - *

    The JCA {@link javax.resource.spi.BootstrapContext} may also be - * accessed directly, through application components that implement the - * {@link BootstrapContextAware} interface. When deployed using this - * ResourceAdapter, the BootstrapContext is guaranteed to be passed on - * to such components. - * - *

    This ResourceAdapter is to be defined in a "META-INF/ra.xml" file - * within a Java EE ".rar" deployment unit like as follows: - * - *

    - * <?xml version="1.0" encoding="UTF-8"?>
    - * <connector xmlns="http://java.sun.com/xml/ns/j2ee"
    - *		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    - *		 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee https://java.sun.com/xml/ns/j2ee/connector_1_5.xsd"
    - *		 version="1.5">
    - *	 <vendor-name>Spring Framework</vendor-name>
    - *	 <eis-type>Spring Connector</eis-type>
    - *	 <resourceadapter-version>1.0</resourceadapter-version>
    - *	 <resourceadapter>
    - *		 <resourceadapter-class>org.springframework.jca.context.SpringContextResourceAdapter</resourceadapter-class>
    - *		 <config-property>
    - *			 <config-property-name>ContextConfigLocation</config-property-name>
    - *			 <config-property-type>java.lang.String</config-property-type>
    - *			 <config-property-value>META-INF/applicationContext.xml</config-property-value>
    - *		 </config-property>
    - *	 </resourceadapter>
    - * </connector>
    - * - * Note that "META-INF/applicationContext.xml" is the default context config - * location, so it doesn't have to specified unless you intend to specify - * different/additional config files. So in the default case, you may remove - * the entire {@code config-property} section above. - * - *

    For simple deployment needs, all you need to do is the following: - * Package all application classes into a RAR file (which is just a standard - * JAR file with a different file extension), add all required library jars - * into the root of the RAR archive, add a "META-INF/ra.xml" deployment - * descriptor as shown above as well as the corresponding Spring XML bean - * definition file(s) (typically "META-INF/applicationContext.xml"), - * and drop the resulting RAR file into your application server's - * deployment directory! - * - * @author Juergen Hoeller - * @since 2.5 - * @see #setContextConfigLocation - * @see #loadBeanDefinitions - * @see ResourceAdapterApplicationContext - */ -public class SpringContextResourceAdapter implements ResourceAdapter { - - /** - * Any number of these characters are considered delimiters between - * multiple context config paths in a single String value. - * @see #setContextConfigLocation - */ - public static final String CONFIG_LOCATION_DELIMITERS = ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS; - - /** - * The default {@code applicationContext.xml} location. - */ - public static final String DEFAULT_CONTEXT_CONFIG_LOCATION = "META-INF/applicationContext.xml"; - - - protected final Log logger = LogFactory.getLog(getClass()); - - private String contextConfigLocation = DEFAULT_CONTEXT_CONFIG_LOCATION; - - @Nullable - private ConfigurableApplicationContext applicationContext; - - - /** - * Set the location of the context configuration files, within the - * resource adapter's deployment unit. This can be a delimited - * String that consists of multiple resource location, separated - * by commas, semicolons, whitespace, or line breaks. - *

    This can be specified as "ContextConfigLocation" config - * property in the {@code ra.xml} deployment descriptor. - *

    The default is "classpath:META-INF/applicationContext.xml". - */ - public void setContextConfigLocation(String contextConfigLocation) { - this.contextConfigLocation = contextConfigLocation; - } - - /** - * Return the specified context configuration files. - */ - protected String getContextConfigLocation() { - return this.contextConfigLocation; - } - - /** - * Return a new {@link StandardEnvironment}. - *

    Subclasses may override this method in order to supply - * a custom {@link ConfigurableEnvironment} implementation. - */ - protected ConfigurableEnvironment createEnvironment() { - return new StandardEnvironment(); - } - - /** - * This implementation loads a Spring ApplicationContext through the - * {@link #createApplicationContext} template method. - */ - @Override - public void start(BootstrapContext bootstrapContext) throws ResourceAdapterInternalException { - if (logger.isDebugEnabled()) { - logger.debug("Starting SpringContextResourceAdapter with BootstrapContext: " + bootstrapContext); - } - this.applicationContext = createApplicationContext(bootstrapContext); - } - - /** - * Build a Spring ApplicationContext for the given JCA BootstrapContext. - *

    The default implementation builds a {@link ResourceAdapterApplicationContext} - * and delegates to {@link #loadBeanDefinitions} for actually parsing the - * specified configuration files. - * @param bootstrapContext this ResourceAdapter's BootstrapContext - * @return the Spring ApplicationContext instance - */ - protected ConfigurableApplicationContext createApplicationContext(BootstrapContext bootstrapContext) { - ResourceAdapterApplicationContext applicationContext = - new ResourceAdapterApplicationContext(bootstrapContext); - - // Set ResourceAdapter's ClassLoader as bean class loader. - applicationContext.setClassLoader(getClass().getClassLoader()); - - // Extract individual config locations. - String[] configLocations = - StringUtils.tokenizeToStringArray(getContextConfigLocation(), CONFIG_LOCATION_DELIMITERS); - - loadBeanDefinitions(applicationContext, configLocations); - applicationContext.refresh(); - - return applicationContext; - } - - /** - * Load the bean definitions into the given registry, - * based on the specified configuration files. - * @param registry the registry to load into - * @param configLocations the parsed config locations - * @see #setContextConfigLocation - */ - protected void loadBeanDefinitions(BeanDefinitionRegistry registry, String[] configLocations) { - new XmlBeanDefinitionReader(registry).loadBeanDefinitions(configLocations); - } - - /** - * This implementation closes the Spring ApplicationContext. - */ - @Override - public void stop() { - logger.debug("Stopping SpringContextResourceAdapter"); - if (this.applicationContext != null) { - this.applicationContext.close(); - } - } - - - /** - * This implementation always throws a NotSupportedException. - */ - @Override - public void endpointActivation(MessageEndpointFactory messageEndpointFactory, ActivationSpec activationSpec) - throws ResourceException { - - throw new NotSupportedException("SpringContextResourceAdapter does not support message endpoints"); - } - - /** - * This implementation does nothing. - */ - @Override - public void endpointDeactivation(MessageEndpointFactory messageEndpointFactory, ActivationSpec activationSpec) { - } - - /** - * This implementation always returns {@code null}. - */ - @Override - @Nullable - public XAResource[] getXAResources(ActivationSpec[] activationSpecs) throws ResourceException { - return null; - } - - - @Override - public boolean equals(@Nullable Object other) { - return (this == other || (other instanceof SpringContextResourceAdapter && - ObjectUtils.nullSafeEquals(getContextConfigLocation(), - ((SpringContextResourceAdapter) other).getContextConfigLocation()))); - } - - @Override - public int hashCode() { - return ObjectUtils.nullSafeHashCode(getContextConfigLocation()); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/context/package-info.java b/spring-tx/src/main/java/org/springframework/jca/context/package-info.java deleted file mode 100644 index 172bca88efe2..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/context/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Integration package that allows for deploying a Spring application context - * as a JCA 1.7 compliant RAR file. - */ -@NonNullApi -@NonNullFields -package org.springframework.jca.context; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-tx/src/main/java/org/springframework/jca/endpoint/AbstractMessageEndpointFactory.java b/spring-tx/src/main/java/org/springframework/jca/endpoint/AbstractMessageEndpointFactory.java index 46ee354a773d..bada813d61e2 100644 --- a/spring-tx/src/main/java/org/springframework/jca/endpoint/AbstractMessageEndpointFactory.java +++ b/spring-tx/src/main/java/org/springframework/jca/endpoint/AbstractMessageEndpointFactory.java @@ -18,15 +18,15 @@ import java.lang.reflect.Method; -import javax.resource.ResourceException; -import javax.resource.spi.ApplicationServerInternalException; -import javax.resource.spi.UnavailableException; -import javax.resource.spi.endpoint.MessageEndpoint; -import javax.resource.spi.endpoint.MessageEndpointFactory; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; import javax.transaction.xa.XAResource; +import jakarta.resource.ResourceException; +import jakarta.resource.spi.ApplicationServerInternalException; +import jakarta.resource.spi.UnavailableException; +import jakarta.resource.spi.endpoint.MessageEndpoint; +import jakarta.resource.spi.endpoint.MessageEndpointFactory; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -38,7 +38,7 @@ /** * Abstract base implementation of the JCA 1.7 - * {@link javax.resource.spi.endpoint.MessageEndpointFactory} interface, + * {@link jakarta.resource.spi.endpoint.MessageEndpointFactory} interface, * providing transaction management capabilities as well as ClassLoader * exposure for endpoint invocations. * @@ -68,7 +68,7 @@ public abstract class AbstractMessageEndpointFactory implements MessageEndpointF * invocations, enlisting the endpoint resource in each such transaction. *

    The passed-in object may be a transaction manager which implements * Spring's {@link org.springframework.transaction.jta.TransactionFactory} - * interface, or a plain {@link javax.transaction.TransactionManager}. + * interface, or a plain {@link jakarta.transaction.TransactionManager}. *

    If no transaction manager is specified, the endpoint invocation * will simply not be wrapped in an XA transaction. Check out your * resource provider's ActivationSpec documentation for local @@ -86,7 +86,7 @@ else if (transactionManager instanceof TransactionManager) { else { throw new IllegalArgumentException("Transaction manager [" + transactionManager + "] is neither a [org.springframework.transaction.jta.TransactionFactory} nor a " + - "[javax.transaction.TransactionManager]"); + "[jakarta.transaction.TransactionManager]"); } } diff --git a/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointFactory.java b/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointFactory.java index 15cb289dce3d..996f366ee6c4 100644 --- a/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointFactory.java +++ b/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointFactory.java @@ -16,11 +16,11 @@ package org.springframework.jca.endpoint; -import javax.resource.ResourceException; -import javax.resource.spi.UnavailableException; -import javax.resource.spi.endpoint.MessageEndpoint; import javax.transaction.xa.XAResource; +import jakarta.resource.ResourceException; +import jakarta.resource.spi.UnavailableException; +import jakarta.resource.spi.endpoint.MessageEndpoint; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; @@ -32,10 +32,10 @@ /** * Generic implementation of the JCA 1.7 - * {@link javax.resource.spi.endpoint.MessageEndpointFactory} interface, + * {@link jakarta.resource.spi.endpoint.MessageEndpointFactory} interface, * providing transaction management capabilities for any kind of message - * listener object (e.g. {@link javax.jms.MessageListener} objects or - * {@link javax.resource.cci.MessageListener} objects. + * listener object (e.g. {@link jakarta.jms.MessageListener} objects or + * {@link jakarta.resource.cci.MessageListener} objects. * *

    Uses AOP proxies for concrete endpoint instances, simply wrapping * the specified message listener object and exposing all of its implemented @@ -44,7 +44,7 @@ *

    Typically used with Spring's {@link GenericMessageEndpointManager}, * but not tied to it. As a consequence, this endpoint factory could * also be used with programmatic endpoint management on a native - * {@link javax.resource.spi.ResourceAdapter} instance. + * {@link jakarta.resource.spi.ResourceAdapter} instance. * * @author Juergen Hoeller * @since 2.5 @@ -60,8 +60,8 @@ public class GenericMessageEndpointFactory extends AbstractMessageEndpointFactor /** * Specify the message listener object that the endpoint should expose - * (e.g. a {@link javax.jms.MessageListener} objects or - * {@link javax.resource.cci.MessageListener} implementation). + * (e.g. a {@link jakarta.jms.MessageListener} objects or + * {@link jakarta.resource.cci.MessageListener} implementation). */ public void setMessageListener(Object messageListener) { this.messageListener = messageListener; diff --git a/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java b/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java index f97dcc9bc909..090c2a20a52e 100644 --- a/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java +++ b/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java @@ -16,10 +16,10 @@ package org.springframework.jca.endpoint; -import javax.resource.ResourceException; -import javax.resource.spi.ActivationSpec; -import javax.resource.spi.ResourceAdapter; -import javax.resource.spi.endpoint.MessageEndpointFactory; +import jakarta.resource.ResourceException; +import jakarta.resource.spi.ActivationSpec; +import jakarta.resource.spi.ResourceAdapter; +import jakarta.resource.spi.endpoint.MessageEndpointFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; @@ -48,7 +48,7 @@ * <property name="activationSpec"> * <bean class="org.apache.activemq.ra.ActiveMQActivationSpec"> * <property name="destination" value="myQueue"/> - * <property name="destinationType" value="javax.jms.Queue"/> + * <property name="destinationType" value="jakarta.jms.Queue"/> * </bean> * </property> * </bean> @@ -56,7 +56,7 @@ * In this example, Spring's own {@link GenericMessageEndpointFactory} is used * to point to a standard message listener object that happens to be supported * by the specified target ResourceAdapter: in this case, a JMS - * {@link javax.jms.MessageListener} object as supported by the ActiveMQ + * {@link jakarta.jms.MessageListener} object as supported by the ActiveMQ * message broker, defined as a Spring bean: * *

    @@ -84,7 +84,7 @@
      * For a different target resource, the configuration would simply point to a
      * different ResourceAdapter and a different ActivationSpec object (which are
      * both specific to the resource provider), and possibly a different message
    - * listener (e.g. a CCI {@link javax.resource.cci.MessageListener} for a
    + * listener (e.g. a CCI {@link jakarta.resource.cci.MessageListener} for a
      * resource adapter which is based on the JCA Common Client Interface).
      *
      * 

    The asynchronous execution strategy can be customized through the @@ -97,7 +97,7 @@ * as built by the specified MessageEndpointFactory. {@link GenericMessageEndpointFactory} * supports XA transaction participation through its "transactionManager" property, * typically with a Spring {@link org.springframework.transaction.jta.JtaTransactionManager} - * or a plain {@link javax.transaction.TransactionManager} implementation specified there. + * or a plain {@link jakarta.transaction.TransactionManager} implementation specified there. * *

      * <bean class="org.springframework.jca.endpoint.GenericMessageEndpointManager">
    @@ -111,7 +111,7 @@
      * 	 <property name="activationSpec">
      *     <bean class="org.apache.activemq.ra.ActiveMQActivationSpec">
      *       <property name="destination" value="myQueue"/>
    - *       <property name="destinationType" value="javax.jms.Queue"/>
    + *       <property name="destinationType" value="jakarta.jms.Queue"/>
      *     </bean>
      *   </property>
      * </bean>
    @@ -133,7 +133,7 @@
      * 	 <property name="activationSpec">
      *     <bean class="org.apache.activemq.ra.ActiveMQActivationSpec">
      *       <property name="destination" value="myQueue"/>
    - *       <property name="destinationType" value="javax.jms.Queue"/>
    + *       <property name="destinationType" value="jakarta.jms.Queue"/>
      *       <property name="useRAManagedTransaction" value="true"/>
      *     </bean>
      *   </property>
    @@ -141,10 +141,10 @@
      *
      * @author Juergen Hoeller
      * @since 2.5
    - * @see javax.resource.spi.ResourceAdapter#endpointActivation
    - * @see javax.resource.spi.ResourceAdapter#endpointDeactivation
    - * @see javax.resource.spi.endpoint.MessageEndpointFactory
    - * @see javax.resource.spi.ActivationSpec
    + * @see jakarta.resource.spi.ResourceAdapter#endpointActivation
    + * @see jakarta.resource.spi.ResourceAdapter#endpointDeactivation
    + * @see jakarta.resource.spi.endpoint.MessageEndpointFactory
    + * @see jakarta.resource.spi.ActivationSpec
      */
     public class GenericMessageEndpointManager implements SmartLifecycle, InitializingBean, DisposableBean {
     
    diff --git a/spring-tx/src/main/java/org/springframework/jca/support/LocalConnectionFactoryBean.java b/spring-tx/src/main/java/org/springframework/jca/support/LocalConnectionFactoryBean.java
    index fd7d1bd05417..fe49bafdf5e8 100644
    --- a/spring-tx/src/main/java/org/springframework/jca/support/LocalConnectionFactoryBean.java
    +++ b/spring-tx/src/main/java/org/springframework/jca/support/LocalConnectionFactoryBean.java
    @@ -16,9 +16,9 @@
     
     package org.springframework.jca.support;
     
    -import javax.resource.ResourceException;
    -import javax.resource.spi.ConnectionManager;
    -import javax.resource.spi.ManagedConnectionFactory;
    +import jakarta.resource.ResourceException;
    +import jakarta.resource.spi.ConnectionManager;
    +import jakarta.resource.spi.ManagedConnectionFactory;
     
     import org.springframework.beans.factory.FactoryBean;
     import org.springframework.beans.factory.InitializingBean;
    @@ -29,13 +29,13 @@
      * a local JCA connection factory in "non-managed" mode (as defined by the
      * Java Connector Architecture specification). This is a direct alternative
      * to a {@link org.springframework.jndi.JndiObjectFactoryBean} definition that
    - * obtains a connection factory handle from a Java EE server's naming environment.
    + * obtains a connection factory handle from a Jakarta EE server's naming environment.
      *
      * 

    The type of the connection factory is dependent on the actual connector: * the connector can either expose its native API (such as a JDBC - * {@link javax.sql.DataSource} or a JMS {@link javax.jms.ConnectionFactory}) + * {@link javax.sql.DataSource} or a JMS {@link jakarta.jms.ConnectionFactory}) * or follow the standard Common Client Interface (CCI), as defined by the JCA spec. - * The exposed interface in the CCI case is {@link javax.resource.cci.ConnectionFactory}. + * The exposed interface in the CCI case is {@link jakarta.resource.cci.ConnectionFactory}. * *

    In order to use this FactoryBean, you must specify the connector's * {@link #setManagedConnectionFactory "managedConnectionFactory"} (usually @@ -46,7 +46,7 @@ * *

    NOTE: In non-managed mode, a connector is not deployed on an * application server, or more specifically not interacting with an application - * server. Consequently, it cannot use a Java EE server's system contracts: + * server. Consequently, it cannot use a Jakarta EE server's system contracts: * connection management, transaction management, and security management. * A custom ConnectionManager implementation has to be used for applying those * services in conjunction with a standalone transaction coordinator etc. @@ -65,8 +65,8 @@ * @since 1.2 * @see #setManagedConnectionFactory * @see #setConnectionManager - * @see javax.resource.cci.ConnectionFactory - * @see javax.resource.cci.Connection#getLocalTransaction + * @see jakarta.resource.cci.ConnectionFactory + * @see jakarta.resource.cci.Connection#getLocalTransaction * @see org.springframework.jca.cci.connection.CciLocalTransactionManager */ public class LocalConnectionFactoryBean implements FactoryBean, InitializingBean { @@ -91,11 +91,11 @@ public class LocalConnectionFactoryBean implements FactoryBean, Initiali * EntityManagerFactory. *

    Note that the ManagerConnectionFactory implementation might expect * a reference to its JCA 1.7 ResourceAdapter, expressed through the - * {@link javax.resource.spi.ResourceAdapterAssociation} interface. + * {@link jakarta.resource.spi.ResourceAdapterAssociation} interface. * Simply inject the corresponding ResourceAdapter instance into its * "resourceAdapter" bean property in this case, before passing the * ManagerConnectionFactory into this LocalConnectionFactoryBean. - * @see javax.resource.spi.ManagedConnectionFactory#createConnectionFactory() + * @see jakarta.resource.spi.ManagedConnectionFactory#createConnectionFactory() */ public void setManagedConnectionFactory(ManagedConnectionFactory managedConnectionFactory) { this.managedConnectionFactory = managedConnectionFactory; @@ -107,7 +107,7 @@ public void setManagedConnectionFactory(ManagedConnectionFactory managedConnecti *

    A ConnectionManager implementation for local usage is often * included with a JCA connector. Such an included ConnectionManager * might be set as default, with no need to explicitly specify one. - * @see javax.resource.spi.ManagedConnectionFactory#createConnectionFactory(javax.resource.spi.ConnectionManager) + * @see jakarta.resource.spi.ManagedConnectionFactory#createConnectionFactory(jakarta.resource.spi.ConnectionManager) */ public void setConnectionManager(ConnectionManager connectionManager) { this.connectionManager = connectionManager; diff --git a/spring-tx/src/main/java/org/springframework/jca/support/ResourceAdapterFactoryBean.java b/spring-tx/src/main/java/org/springframework/jca/support/ResourceAdapterFactoryBean.java index 7904e0bc614a..9969c97d571d 100644 --- a/spring-tx/src/main/java/org/springframework/jca/support/ResourceAdapterFactoryBean.java +++ b/spring-tx/src/main/java/org/springframework/jca/support/ResourceAdapterFactoryBean.java @@ -16,11 +16,11 @@ package org.springframework.jca.support; -import javax.resource.ResourceException; -import javax.resource.spi.BootstrapContext; -import javax.resource.spi.ResourceAdapter; -import javax.resource.spi.XATerminator; -import javax.resource.spi.work.WorkManager; +import jakarta.resource.ResourceException; +import jakarta.resource.spi.BootstrapContext; +import jakarta.resource.spi.ResourceAdapter; +import jakarta.resource.spi.XATerminator; +import jakarta.resource.spi.work.WorkManager; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.DisposableBean; @@ -30,8 +30,8 @@ /** * {@link org.springframework.beans.factory.FactoryBean} that bootstraps - * the specified JCA 1.7 {@link javax.resource.spi.ResourceAdapter}, - * starting it with a local {@link javax.resource.spi.BootstrapContext} + * the specified JCA 1.7 {@link jakarta.resource.spi.ResourceAdapter}, + * starting it with a local {@link jakarta.resource.spi.BootstrapContext} * and exposing it for bean references. It will also stop the ResourceAdapter * on context shutdown. This corresponds to 'non-managed' bootstrap in a * local environment, according to the JCA 1.7 specification. @@ -45,8 +45,8 @@ * @see #setResourceAdapter * @see #setBootstrapContext * @see #setWorkManager - * @see javax.resource.spi.ResourceAdapter#start(javax.resource.spi.BootstrapContext) - * @see javax.resource.spi.ResourceAdapter#stop() + * @see jakarta.resource.spi.ResourceAdapter#start(jakarta.resource.spi.BootstrapContext) + * @see jakarta.resource.spi.ResourceAdapter#stop() */ public class ResourceAdapterFactoryBean implements FactoryBean, InitializingBean, DisposableBean { @@ -114,7 +114,7 @@ public void setXaTerminator(XATerminator xaTerminator) { /** * Builds the BootstrapContext and starts the ResourceAdapter with it. - * @see javax.resource.spi.ResourceAdapter#start(javax.resource.spi.BootstrapContext) + * @see jakarta.resource.spi.ResourceAdapter#start(jakarta.resource.spi.BootstrapContext) */ @Override public void afterPropertiesSet() throws ResourceException { @@ -147,7 +147,7 @@ public boolean isSingleton() { /** * Stops the ResourceAdapter. - * @see javax.resource.spi.ResourceAdapter#stop() + * @see jakarta.resource.spi.ResourceAdapter#stop() */ @Override public void destroy() { diff --git a/spring-tx/src/main/java/org/springframework/jca/support/SimpleBootstrapContext.java b/spring-tx/src/main/java/org/springframework/jca/support/SimpleBootstrapContext.java index 8ca15b9d901b..c607a6f2660a 100644 --- a/spring-tx/src/main/java/org/springframework/jca/support/SimpleBootstrapContext.java +++ b/spring-tx/src/main/java/org/springframework/jca/support/SimpleBootstrapContext.java @@ -18,18 +18,18 @@ import java.util.Timer; -import javax.resource.spi.BootstrapContext; -import javax.resource.spi.UnavailableException; -import javax.resource.spi.XATerminator; -import javax.resource.spi.work.WorkContext; -import javax.resource.spi.work.WorkManager; -import javax.transaction.TransactionSynchronizationRegistry; +import jakarta.resource.spi.BootstrapContext; +import jakarta.resource.spi.UnavailableException; +import jakarta.resource.spi.XATerminator; +import jakarta.resource.spi.work.WorkContext; +import jakarta.resource.spi.work.WorkManager; +import jakarta.transaction.TransactionSynchronizationRegistry; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Simple implementation of the JCA 1.7 {@link javax.resource.spi.BootstrapContext} + * Simple implementation of the JCA 1.7 {@link jakarta.resource.spi.BootstrapContext} * interface, used for bootstrapping a JCA ResourceAdapter in a local environment. * *

    Delegates to the given WorkManager and XATerminator, if any. Creates simple @@ -37,7 +37,7 @@ * * @author Juergen Hoeller * @since 2.0.3 - * @see javax.resource.spi.ResourceAdapter#start(javax.resource.spi.BootstrapContext) + * @see jakarta.resource.spi.ResourceAdapter#start(jakarta.resource.spi.BootstrapContext) * @see ResourceAdapterFactoryBean */ public class SimpleBootstrapContext implements BootstrapContext { diff --git a/spring-tx/src/main/java/org/springframework/jca/work/DelegatingWork.java b/spring-tx/src/main/java/org/springframework/jca/work/DelegatingWork.java deleted file mode 100644 index da52a8536506..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/work/DelegatingWork.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.work; - -import javax.resource.spi.work.Work; - -import org.springframework.util.Assert; - -/** - * Simple Work adapter that delegates to a given Runnable. - * - * @author Juergen Hoeller - * @since 2.0.3 - * @see javax.resource.spi.work.Work - * @see Runnable - */ -public class DelegatingWork implements Work { - - private final Runnable delegate; - - - /** - * Create a new DelegatingWork. - * @param delegate the Runnable implementation to delegate to - */ - public DelegatingWork(Runnable delegate) { - Assert.notNull(delegate, "Delegate must not be null"); - this.delegate = delegate; - } - - /** - * Return the wrapped Runnable implementation. - */ - public final Runnable getDelegate() { - return this.delegate; - } - - - /** - * Delegates execution to the underlying Runnable. - */ - @Override - public void run() { - this.delegate.run(); - } - - /** - * This implementation is empty, since we expect the Runnable - * to terminate based on some specific shutdown signal. - */ - @Override - public void release() { - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/work/SimpleTaskWorkManager.java b/spring-tx/src/main/java/org/springframework/jca/work/SimpleTaskWorkManager.java deleted file mode 100644 index 90b8214df344..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/work/SimpleTaskWorkManager.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.work; - -import javax.resource.spi.work.ExecutionContext; -import javax.resource.spi.work.Work; -import javax.resource.spi.work.WorkAdapter; -import javax.resource.spi.work.WorkCompletedException; -import javax.resource.spi.work.WorkEvent; -import javax.resource.spi.work.WorkException; -import javax.resource.spi.work.WorkListener; -import javax.resource.spi.work.WorkManager; -import javax.resource.spi.work.WorkRejectedException; - -import org.springframework.core.task.AsyncTaskExecutor; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.core.task.SyncTaskExecutor; -import org.springframework.core.task.TaskExecutor; -import org.springframework.core.task.TaskRejectedException; -import org.springframework.core.task.TaskTimeoutException; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Simple JCA 1.7 {@link javax.resource.spi.work.WorkManager} implementation that - * delegates to a Spring {@link org.springframework.core.task.TaskExecutor}. - * Provides simple task execution including start timeouts, but without support - * for a JCA ExecutionContext (i.e. without support for imported transactions). - * - *

    Uses a {@link org.springframework.core.task.SyncTaskExecutor} for {@link #doWork} - * calls and a {@link org.springframework.core.task.SimpleAsyncTaskExecutor} - * for {@link #startWork} and {@link #scheduleWork} calls, by default. - * These default task executors can be overridden through configuration. - * - *

    NOTE: This WorkManager does not provide thread pooling by default! - * Specify a {@link org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor} - * (or any other thread-pooling TaskExecutor) as "asyncTaskExecutor" in order to - * achieve actual thread pooling. - * - *

    This WorkManager automatically detects a specified - * {@link org.springframework.core.task.AsyncTaskExecutor} implementation - * and uses its extended timeout functionality where appropriate. - * JCA WorkListeners are fully supported in any case. - * - * @author Juergen Hoeller - * @since 2.0.3 - * @see #setSyncTaskExecutor - * @see #setAsyncTaskExecutor - */ -public class SimpleTaskWorkManager implements WorkManager { - - @Nullable - private TaskExecutor syncTaskExecutor = new SyncTaskExecutor(); - - @Nullable - private AsyncTaskExecutor asyncTaskExecutor = new SimpleAsyncTaskExecutor(); - - - /** - * Specify the TaskExecutor to use for synchronous work execution - * (i.e. {@link #doWork} calls). - *

    Default is a {@link org.springframework.core.task.SyncTaskExecutor}. - */ - public void setSyncTaskExecutor(TaskExecutor syncTaskExecutor) { - this.syncTaskExecutor = syncTaskExecutor; - } - - /** - * Specify the TaskExecutor to use for asynchronous work execution - * (i.e. {@link #startWork} and {@link #scheduleWork} calls). - *

    This will typically (but not necessarily) be an - * {@link org.springframework.core.task.AsyncTaskExecutor} implementation. - * Default is a {@link org.springframework.core.task.SimpleAsyncTaskExecutor}. - */ - public void setAsyncTaskExecutor(AsyncTaskExecutor asyncTaskExecutor) { - this.asyncTaskExecutor = asyncTaskExecutor; - } - - - @Override - public void doWork(Work work) throws WorkException { - doWork(work, WorkManager.INDEFINITE, null, null); - } - - @Override - public void doWork(Work work, long startTimeout, @Nullable ExecutionContext executionContext, @Nullable WorkListener workListener) - throws WorkException { - - Assert.state(this.syncTaskExecutor != null, "No 'syncTaskExecutor' set"); - executeWork(this.syncTaskExecutor, work, startTimeout, false, executionContext, workListener); - } - - @Override - public long startWork(Work work) throws WorkException { - return startWork(work, WorkManager.INDEFINITE, null, null); - } - - @Override - public long startWork(Work work, long startTimeout, @Nullable ExecutionContext executionContext, @Nullable WorkListener workListener) - throws WorkException { - - Assert.state(this.asyncTaskExecutor != null, "No 'asyncTaskExecutor' set"); - return executeWork(this.asyncTaskExecutor, work, startTimeout, true, executionContext, workListener); - } - - @Override - public void scheduleWork(Work work) throws WorkException { - scheduleWork(work, WorkManager.INDEFINITE, null, null); - } - - @Override - public void scheduleWork(Work work, long startTimeout, @Nullable ExecutionContext executionContext, @Nullable WorkListener workListener) - throws WorkException { - - Assert.state(this.asyncTaskExecutor != null, "No 'asyncTaskExecutor' set"); - executeWork(this.asyncTaskExecutor, work, startTimeout, false, executionContext, workListener); - } - - - /** - * Execute the given Work on the specified TaskExecutor. - * @param taskExecutor the TaskExecutor to use - * @param work the Work to execute - * @param startTimeout the time duration within which the Work is supposed to start - * @param blockUntilStarted whether to block until the Work has started - * @param executionContext the JCA ExecutionContext for the given Work - * @param workListener the WorkListener to clal for the given Work - * @return the time elapsed from Work acceptance until start of execution - * (or -1 if not applicable or not known) - * @throws WorkException if the TaskExecutor did not accept the Work - */ - protected long executeWork(TaskExecutor taskExecutor, Work work, long startTimeout, boolean blockUntilStarted, - @Nullable ExecutionContext executionContext, @Nullable WorkListener workListener) throws WorkException { - - if (executionContext != null && executionContext.getXid() != null) { - throw new WorkException("SimpleTaskWorkManager does not supported imported XIDs: " + executionContext.getXid()); - } - WorkListener workListenerToUse = workListener; - if (workListenerToUse == null) { - workListenerToUse = new WorkAdapter(); - } - - boolean isAsync = (taskExecutor instanceof AsyncTaskExecutor); - DelegatingWorkAdapter workHandle = new DelegatingWorkAdapter(work, workListenerToUse, !isAsync); - try { - if (isAsync) { - ((AsyncTaskExecutor) taskExecutor).execute(workHandle, startTimeout); - } - else { - taskExecutor.execute(workHandle); - } - } - catch (TaskTimeoutException ex) { - WorkException wex = new WorkRejectedException("TaskExecutor rejected Work because of timeout: " + work, ex); - wex.setErrorCode(WorkException.START_TIMED_OUT); - workListenerToUse.workRejected(new WorkEvent(this, WorkEvent.WORK_REJECTED, work, wex)); - throw wex; - } - catch (TaskRejectedException ex) { - WorkException wex = new WorkRejectedException("TaskExecutor rejected Work: " + work, ex); - wex.setErrorCode(WorkException.INTERNAL); - workListenerToUse.workRejected(new WorkEvent(this, WorkEvent.WORK_REJECTED, work, wex)); - throw wex; - } - catch (Throwable ex) { - WorkException wex = new WorkException("TaskExecutor failed to execute Work: " + work, ex); - wex.setErrorCode(WorkException.INTERNAL); - throw wex; - } - if (isAsync) { - workListenerToUse.workAccepted(new WorkEvent(this, WorkEvent.WORK_ACCEPTED, work, null)); - } - - if (blockUntilStarted) { - long acceptanceTime = System.currentTimeMillis(); - synchronized (workHandle.monitor) { - try { - while (!workHandle.started) { - workHandle.monitor.wait(); - } - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - return (System.currentTimeMillis() - acceptanceTime); - } - else { - return WorkManager.UNKNOWN; - } - } - - - /** - * Work adapter that supports start timeouts and WorkListener callbacks - * for a given Work that it delegates to. - */ - private static class DelegatingWorkAdapter implements Work { - - private final Work work; - - private final WorkListener workListener; - - private final boolean acceptOnExecution; - - public final Object monitor = new Object(); - - public boolean started = false; - - public DelegatingWorkAdapter(Work work, WorkListener workListener, boolean acceptOnExecution) { - this.work = work; - this.workListener = workListener; - this.acceptOnExecution = acceptOnExecution; - } - - @Override - public void run() { - if (this.acceptOnExecution) { - this.workListener.workAccepted(new WorkEvent(this, WorkEvent.WORK_ACCEPTED, this.work, null)); - } - synchronized (this.monitor) { - this.started = true; - this.monitor.notify(); - } - this.workListener.workStarted(new WorkEvent(this, WorkEvent.WORK_STARTED, this.work, null)); - try { - this.work.run(); - } - catch (RuntimeException | Error ex) { - this.workListener.workCompleted( - new WorkEvent(this, WorkEvent.WORK_COMPLETED, this.work, new WorkCompletedException(ex))); - throw ex; - } - this.workListener.workCompleted(new WorkEvent(this, WorkEvent.WORK_COMPLETED, this.work, null)); - } - - @Override - public void release() { - this.work.release(); - } - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/work/WorkManagerTaskExecutor.java b/spring-tx/src/main/java/org/springframework/jca/work/WorkManagerTaskExecutor.java deleted file mode 100644 index e4fe06bfeb35..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/work/WorkManagerTaskExecutor.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.work; - -import java.util.concurrent.Callable; -import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; - -import javax.naming.NamingException; -import javax.resource.spi.BootstrapContext; -import javax.resource.spi.work.ExecutionContext; -import javax.resource.spi.work.Work; -import javax.resource.spi.work.WorkException; -import javax.resource.spi.work.WorkListener; -import javax.resource.spi.work.WorkManager; -import javax.resource.spi.work.WorkRejectedException; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.task.AsyncListenableTaskExecutor; -import org.springframework.core.task.TaskDecorator; -import org.springframework.core.task.TaskRejectedException; -import org.springframework.core.task.TaskTimeoutException; -import org.springframework.jca.context.BootstrapContextAware; -import org.springframework.jndi.JndiLocatorSupport; -import org.springframework.lang.Nullable; -import org.springframework.scheduling.SchedulingException; -import org.springframework.scheduling.SchedulingTaskExecutor; -import org.springframework.util.Assert; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureTask; - -/** - * {@link org.springframework.core.task.TaskExecutor} implementation - * that delegates to a JCA 1.7 WorkManager, implementing the - * {@link javax.resource.spi.work.WorkManager} interface. - * - *

    This is mainly intended for use within a JCA ResourceAdapter implementation, - * but may also be used in a standalone environment, delegating to a locally - * embedded WorkManager implementation (such as Geronimo's). - * - *

    Also implements the JCA 1.7 WorkManager interface itself, delegating all - * calls to the target WorkManager. Hence, a caller can choose whether it wants - * to talk to this executor through the Spring TaskExecutor interface or the - * WorkManager interface. - * - *

    This adapter is also capable of obtaining a JCA WorkManager from JNDI. - * This is for example appropriate on the Geronimo application server, where - * WorkManager GBeans (e.g. Geronimo's default "DefaultWorkManager" GBean) - * can be linked into the Java EE environment through "gbean-ref" entries - * in the {@code geronimo-web.xml} deployment descriptor. - * - * @author Juergen Hoeller - * @since 2.0.3 - * @see #setWorkManager - * @see javax.resource.spi.work.WorkManager#scheduleWork - */ -public class WorkManagerTaskExecutor extends JndiLocatorSupport - implements AsyncListenableTaskExecutor, SchedulingTaskExecutor, WorkManager, BootstrapContextAware, InitializingBean { - - @Nullable - private WorkManager workManager; - - @Nullable - private String workManagerName; - - private boolean blockUntilStarted = false; - - private boolean blockUntilCompleted = false; - - @Nullable - private WorkListener workListener; - - @Nullable - private TaskDecorator taskDecorator; - - - /** - * Create a new WorkManagerTaskExecutor, expecting bean-style configuration. - * @see #setWorkManager - */ - public WorkManagerTaskExecutor() { - } - - /** - * Create a new WorkManagerTaskExecutor for the given WorkManager. - * @param workManager the JCA WorkManager to delegate to - */ - public WorkManagerTaskExecutor(WorkManager workManager) { - setWorkManager(workManager); - } - - - /** - * Specify the JCA WorkManager instance to delegate to. - */ - public void setWorkManager(WorkManager workManager) { - Assert.notNull(workManager, "WorkManager must not be null"); - this.workManager = workManager; - } - - /** - * Set the JNDI name of the JCA WorkManager. - *

    This can either be a fully qualified JNDI name, - * or the JNDI name relative to the current environment - * naming context if "resourceRef" is set to "true". - * @see #setWorkManager - * @see #setResourceRef - */ - public void setWorkManagerName(String workManagerName) { - this.workManagerName = workManagerName; - } - - /** - * Specify the JCA BootstrapContext that contains the - * WorkManager to delegate to. - */ - @Override - public void setBootstrapContext(BootstrapContext bootstrapContext) { - Assert.notNull(bootstrapContext, "BootstrapContext must not be null"); - this.workManager = bootstrapContext.getWorkManager(); - } - - /** - * Set whether to let {@link #execute} block until the work - * has been actually started. - *

    Uses the JCA {@code startWork} operation underneath, - * instead of the default {@code scheduleWork}. - * @see javax.resource.spi.work.WorkManager#startWork - * @see javax.resource.spi.work.WorkManager#scheduleWork - */ - public void setBlockUntilStarted(boolean blockUntilStarted) { - this.blockUntilStarted = blockUntilStarted; - } - - /** - * Set whether to let {@link #execute} block until the work - * has been completed. - *

    Uses the JCA {@code doWork} operation underneath, - * instead of the default {@code scheduleWork}. - * @see javax.resource.spi.work.WorkManager#doWork - * @see javax.resource.spi.work.WorkManager#scheduleWork - */ - public void setBlockUntilCompleted(boolean blockUntilCompleted) { - this.blockUntilCompleted = blockUntilCompleted; - } - - /** - * Specify a JCA WorkListener to apply, if any. - *

    This shared WorkListener instance will be passed on to the - * WorkManager by all {@link #execute} calls on this TaskExecutor. - */ - public void setWorkListener(@Nullable WorkListener workListener) { - this.workListener = workListener; - } - - /** - * Specify a custom {@link TaskDecorator} to be applied to any {@link Runnable} - * about to be executed. - *

    Note that such a decorator is not necessarily being applied to the - * user-supplied {@code Runnable}/{@code Callable} but rather to the actual - * execution callback (which may be a wrapper around the user-supplied task). - *

    The primary use case is to set some execution context around the task's - * invocation, or to provide some monitoring/statistics for task execution. - *

    NOTE: Exception handling in {@code TaskDecorator} implementations - * is limited to plain {@code Runnable} execution via {@code execute} calls. - * In case of {@code #submit} calls, the exposed {@code Runnable} will be a - * {@code FutureTask} which does not propagate any exceptions; you might - * have to cast it and call {@code Future#get} to evaluate exceptions. - * @since 4.3 - */ - public void setTaskDecorator(TaskDecorator taskDecorator) { - this.taskDecorator = taskDecorator; - } - - @Override - public void afterPropertiesSet() throws NamingException { - if (this.workManager == null) { - if (this.workManagerName != null) { - this.workManager = lookup(this.workManagerName, WorkManager.class); - } - else { - this.workManager = getDefaultWorkManager(); - } - } - } - - /** - * Obtain a default WorkManager to delegate to. - * Called if no explicit WorkManager or WorkManager JNDI name has been specified. - *

    The default implementation returns a {@link SimpleTaskWorkManager}. - * Can be overridden in subclasses. - */ - protected WorkManager getDefaultWorkManager() { - return new SimpleTaskWorkManager(); - } - - private WorkManager obtainWorkManager() { - Assert.state(this.workManager != null, "No WorkManager specified"); - return this.workManager; - } - - - //------------------------------------------------------------------------- - // Implementation of the Spring SchedulingTaskExecutor interface - //------------------------------------------------------------------------- - - @Override - public void execute(Runnable task) { - execute(task, TIMEOUT_INDEFINITE); - } - - @Override - public void execute(Runnable task, long startTimeout) { - Work work = new DelegatingWork(this.taskDecorator != null ? this.taskDecorator.decorate(task) : task); - try { - if (this.blockUntilCompleted) { - if (startTimeout != TIMEOUT_INDEFINITE || this.workListener != null) { - obtainWorkManager().doWork(work, startTimeout, null, this.workListener); - } - else { - obtainWorkManager().doWork(work); - } - } - else if (this.blockUntilStarted) { - if (startTimeout != TIMEOUT_INDEFINITE || this.workListener != null) { - obtainWorkManager().startWork(work, startTimeout, null, this.workListener); - } - else { - obtainWorkManager().startWork(work); - } - } - else { - if (startTimeout != TIMEOUT_INDEFINITE || this.workListener != null) { - obtainWorkManager().scheduleWork(work, startTimeout, null, this.workListener); - } - else { - obtainWorkManager().scheduleWork(work); - } - } - } - catch (WorkRejectedException ex) { - if (WorkException.START_TIMED_OUT.equals(ex.getErrorCode())) { - throw new TaskTimeoutException("JCA WorkManager rejected task because of timeout: " + task, ex); - } - else { - throw new TaskRejectedException("JCA WorkManager rejected task: " + task, ex); - } - } - catch (WorkException ex) { - throw new SchedulingException("Could not schedule task on JCA WorkManager", ex); - } - } - - @Override - public Future submit(Runnable task) { - FutureTask future = new FutureTask<>(task, null); - execute(future, TIMEOUT_INDEFINITE); - return future; - } - - @Override - public Future submit(Callable task) { - FutureTask future = new FutureTask<>(task); - execute(future, TIMEOUT_INDEFINITE); - return future; - } - - @Override - public ListenableFuture submitListenable(Runnable task) { - ListenableFutureTask future = new ListenableFutureTask<>(task, null); - execute(future, TIMEOUT_INDEFINITE); - return future; - } - - @Override - public ListenableFuture submitListenable(Callable task) { - ListenableFutureTask future = new ListenableFutureTask<>(task); - execute(future, TIMEOUT_INDEFINITE); - return future; - } - - - //------------------------------------------------------------------------- - // Implementation of the JCA WorkManager interface - //------------------------------------------------------------------------- - - @Override - public void doWork(Work work) throws WorkException { - obtainWorkManager().doWork(work); - } - - @Override - public void doWork(Work work, long delay, ExecutionContext executionContext, WorkListener workListener) - throws WorkException { - - obtainWorkManager().doWork(work, delay, executionContext, workListener); - } - - @Override - public long startWork(Work work) throws WorkException { - return obtainWorkManager().startWork(work); - } - - @Override - public long startWork(Work work, long delay, ExecutionContext executionContext, WorkListener workListener) - throws WorkException { - - return obtainWorkManager().startWork(work, delay, executionContext, workListener); - } - - @Override - public void scheduleWork(Work work) throws WorkException { - obtainWorkManager().scheduleWork(work); - } - - @Override - public void scheduleWork(Work work, long delay, ExecutionContext executionContext, WorkListener workListener) - throws WorkException { - - obtainWorkManager().scheduleWork(work, delay, executionContext, workListener); - } - -} diff --git a/spring-tx/src/main/java/org/springframework/jca/work/package-info.java b/spring-tx/src/main/java/org/springframework/jca/work/package-info.java deleted file mode 100644 index a797e7215078..000000000000 --- a/spring-tx/src/main/java/org/springframework/jca/work/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Convenience classes for scheduling based on the JCA WorkManager facility, - * as supported within ResourceAdapters. - */ -@NonNullApi -@NonNullFields -package org.springframework.jca.work; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java b/spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java index 1e2a44e8fe11..1aa8901f3f7e 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java +++ b/spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java @@ -86,8 +86,8 @@ public interface TransactionDefinition { *

    NOTE: Actual transaction suspension will not work out-of-the-box * on all transaction managers. This in particular applies to * {@link org.springframework.transaction.jta.JtaTransactionManager}, - * which requires the {@code javax.transaction.TransactionManager} to be - * made available it to it (which is server-specific in standard Java EE). + * which requires the {@code jakarta.transaction.TransactionManager} to be + * made available it to it (which is server-specific in standard Jakarta EE). *

    A {@code PROPAGATION_REQUIRES_NEW} scope always defines its own * transaction synchronizations. Existing synchronizations will be suspended * and resumed appropriately. @@ -101,8 +101,8 @@ public interface TransactionDefinition { *

    NOTE: Actual transaction suspension will not work out-of-the-box * on all transaction managers. This in particular applies to * {@link org.springframework.transaction.jta.JtaTransactionManager}, - * which requires the {@code javax.transaction.TransactionManager} to be - * made available it to it (which is server-specific in standard Java EE). + * which requires the {@code jakarta.transaction.TransactionManager} to be + * made available it to it (which is server-specific in standard Jakarta EE). *

    Note that transaction synchronization is not available within a * {@code PROPAGATION_NOT_SUPPORTED} scope. Existing synchronizations * will be suspended and resumed appropriately. diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java index 4f8e46f6e96a..13f16a20e93e 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java +++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java @@ -37,8 +37,8 @@ * *

    This class reads Spring's JDK 1.5+ {@link Transactional} annotation and * exposes corresponding transaction attributes to Spring's transaction infrastructure. - * Also supports JTA 1.2's {@link javax.transaction.Transactional} and EJB3's - * {@link javax.ejb.TransactionAttribute} annotation (if present). + * Also supports JTA 1.2's {@link jakarta.transaction.Transactional} and EJB3's + * {@link jakarta.ejb.TransactionAttribute} annotation (if present). * This class may also serve as base class for a custom TransactionAttributeSource, * or get customized through {@link TransactionAnnotationParser} strategies. * @@ -62,8 +62,8 @@ public class AnnotationTransactionAttributeSource extends AbstractFallbackTransa static { ClassLoader classLoader = AnnotationTransactionAttributeSource.class.getClassLoader(); - jta12Present = ClassUtils.isPresent("javax.transaction.Transactional", classLoader); - ejb3Present = ClassUtils.isPresent("javax.ejb.TransactionAttribute", classLoader); + jta12Present = ClassUtils.isPresent("jakarta.transaction.Transactional", classLoader); + ejb3Present = ClassUtils.isPresent("jakarta.ejb.TransactionAttribute", classLoader); } private final boolean publicMethodsOnly; @@ -74,7 +74,7 @@ public class AnnotationTransactionAttributeSource extends AbstractFallbackTransa /** * Create a default AnnotationTransactionAttributeSource, supporting * public methods that carry the {@code Transactional} annotation - * or the EJB3 {@link javax.ejb.TransactionAttribute} annotation. + * or the EJB3 {@link jakarta.ejb.TransactionAttribute} annotation. */ public AnnotationTransactionAttributeSource() { this(true); @@ -83,7 +83,7 @@ public AnnotationTransactionAttributeSource() { /** * Create a custom AnnotationTransactionAttributeSource, supporting * public methods that carry the {@code Transactional} annotation - * or the EJB3 {@link javax.ejb.TransactionAttribute} annotation. + * or the EJB3 {@link jakarta.ejb.TransactionAttribute} annotation. * @param publicMethodsOnly whether to support public methods that carry * the {@code Transactional} annotation only (typically for use * with proxy-based AOP), or protected/private methods as well diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/Ejb3TransactionAnnotationParser.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/Ejb3TransactionAnnotationParser.java index 8fd2db23d51e..ae8e5d237420 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/annotation/Ejb3TransactionAnnotationParser.java +++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/Ejb3TransactionAnnotationParser.java @@ -19,8 +19,8 @@ import java.io.Serializable; import java.lang.reflect.AnnotatedElement; -import javax.ejb.ApplicationException; -import javax.ejb.TransactionAttributeType; +import jakarta.ejb.ApplicationException; +import jakarta.ejb.TransactionAttributeType; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.lang.Nullable; @@ -28,7 +28,7 @@ import org.springframework.transaction.interceptor.TransactionAttribute; /** - * Strategy implementation for parsing EJB3's {@link javax.ejb.TransactionAttribute} + * Strategy implementation for parsing EJB3's {@link jakarta.ejb.TransactionAttribute} * annotation. * * @author Juergen Hoeller @@ -39,13 +39,13 @@ public class Ejb3TransactionAnnotationParser implements TransactionAnnotationPar @Override public boolean isCandidateClass(Class targetClass) { - return AnnotationUtils.isCandidateClass(targetClass, javax.ejb.TransactionAttribute.class); + return AnnotationUtils.isCandidateClass(targetClass, jakarta.ejb.TransactionAttribute.class); } @Override @Nullable public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) { - javax.ejb.TransactionAttribute ann = element.getAnnotation(javax.ejb.TransactionAttribute.class); + jakarta.ejb.TransactionAttribute ann = element.getAnnotation(jakarta.ejb.TransactionAttribute.class); if (ann != null) { return parseTransactionAnnotation(ann); } @@ -54,7 +54,7 @@ public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) } } - public TransactionAttribute parseTransactionAnnotation(javax.ejb.TransactionAttribute ann) { + public TransactionAttribute parseTransactionAnnotation(jakarta.ejb.TransactionAttribute ann) { return new Ejb3TransactionAttribute(ann.value()); } diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/JtaTransactionAnnotationParser.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/JtaTransactionAnnotationParser.java index ccc018f6be6c..9e3b956848db 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/annotation/JtaTransactionAnnotationParser.java +++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/JtaTransactionAnnotationParser.java @@ -31,7 +31,7 @@ import org.springframework.transaction.interceptor.TransactionAttribute; /** - * Strategy implementation for parsing JTA 1.2's {@link javax.transaction.Transactional} annotation. + * Strategy implementation for parsing JTA 1.2's {@link jakarta.transaction.Transactional} annotation. * * @author Juergen Hoeller * @since 4.0 @@ -41,14 +41,14 @@ public class JtaTransactionAnnotationParser implements TransactionAnnotationPars @Override public boolean isCandidateClass(Class targetClass) { - return AnnotationUtils.isCandidateClass(targetClass, javax.transaction.Transactional.class); + return AnnotationUtils.isCandidateClass(targetClass, jakarta.transaction.Transactional.class); } @Override @Nullable public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) { AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes( - element, javax.transaction.Transactional.class); + element, jakarta.transaction.Transactional.class); if (attributes != null) { return parseTransactionAnnotation(attributes); } @@ -57,7 +57,7 @@ public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) } } - public TransactionAttribute parseTransactionAnnotation(javax.transaction.Transactional ann) { + public TransactionAttribute parseTransactionAnnotation(jakarta.transaction.Transactional ann) { return parseTransactionAnnotation(AnnotationUtils.getAnnotationAttributes(ann, false, false)); } diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/Propagation.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/Propagation.java index 1e235ce8770f..18e43cf16e8f 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/annotation/Propagation.java +++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/Propagation.java @@ -61,8 +61,8 @@ public enum Propagation { *

    NOTE: Actual transaction suspension will not work out-of-the-box * on all transaction managers. This in particular applies to * {@link org.springframework.transaction.jta.JtaTransactionManager}, - * which requires the {@code javax.transaction.TransactionManager} to be - * made available to it (which is server-specific in standard Java EE). + * which requires the {@code jakarta.transaction.TransactionManager} to be + * made available to it (which is server-specific in standard Jakarta EE). * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW), @@ -73,8 +73,8 @@ public enum Propagation { *

    NOTE: Actual transaction suspension will not work out-of-the-box * on all transaction managers. This in particular applies to * {@link org.springframework.transaction.jta.JtaTransactionManager}, - * which requires the {@code javax.transaction.TransactionManager} to be - * made available to it (which is server-specific in standard Java EE). + * which requires the {@code jakarta.transaction.TransactionManager} to be + * made available to it (which is server-specific in standard Jakarta EE). * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED), diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionAnnotationParser.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionAnnotationParser.java index e486fbbdaaf0..0e9ee83a568d 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionAnnotationParser.java +++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionAnnotationParser.java @@ -25,8 +25,8 @@ * Strategy interface for parsing known transaction annotation types. * {@link AnnotationTransactionAttributeSource} delegates to such * parsers for supporting specific annotation types such as Spring's own - * {@link Transactional}, JTA 1.2's {@link javax.transaction.Transactional} - * or EJB3's {@link javax.ejb.TransactionAttribute}. + * {@link Transactional}, JTA 1.2's {@link jakarta.transaction.Transactional} + * or EJB3's {@link jakarta.ejb.TransactionAttribute}. * * @author Juergen Hoeller * @since 2.5 diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionManagementConfigurationSelector.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionManagementConfigurationSelector.java index 5e16f915f81c..22551ceed15b 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionManagementConfigurationSelector.java +++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionManagementConfigurationSelector.java @@ -57,7 +57,7 @@ protected String[] selectImports(AdviceMode adviceMode) { } private String determineTransactionAspectClass() { - return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ? + return (ClassUtils.isPresent("jakarta.transaction.Transactional", getClass().getClassLoader()) ? TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME : TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME); } diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java index 42537572223f..d399e8b04eb2 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java +++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java @@ -188,7 +188,7 @@ * a transaction rollback. *

    This can be a substring of a fully qualified class name, with no wildcard * support at present. For example, a value of {@code "ServletException"} would - * match {@code javax.servlet.ServletException} and its subclasses. + * match {@code jakarta.servlet.ServletException} and its subclasses. *

    NB: Consider carefully how specific the pattern is and whether * to include package information (which isn't mandatory). For example, * {@code "Exception"} will match nearly anything and will probably hide other diff --git a/spring-tx/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java b/spring-tx/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java index 8d6ba603deb1..d7dca39ef5dc 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java +++ b/spring-tx/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java @@ -65,7 +65,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { if ("aspectj".equals(mode)) { // mode="aspectj" registerTransactionAspect(element, parserContext); - if (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader())) { + if (ClassUtils.isPresent("jakarta.transaction.Transactional", getClass().getClassLoader())) { registerJtaTransactionAspect(element, parserContext); } } diff --git a/spring-tx/src/main/java/org/springframework/transaction/config/JtaTransactionManagerBeanDefinitionParser.java b/spring-tx/src/main/java/org/springframework/transaction/config/JtaTransactionManagerBeanDefinitionParser.java index cae08558e4a1..055b127e662b 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/config/JtaTransactionManagerBeanDefinitionParser.java +++ b/spring-tx/src/main/java/org/springframework/transaction/config/JtaTransactionManagerBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,23 +21,20 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.transaction.jta.JtaTransactionManager; /** - * Parser for the <tx:jta-transaction-manager/> XML configuration element, - * autodetecting WebLogic and WebSphere servers and exposing the corresponding - * {@link org.springframework.transaction.jta.JtaTransactionManager} subclass. + * Parser for the <tx:jta-transaction-manager/> XML configuration element. * * @author Juergen Hoeller * @author Christian Dupuis * @since 2.5 - * @see org.springframework.transaction.jta.WebLogicJtaTransactionManager - * @see org.springframework.transaction.jta.WebSphereUowTransactionManager */ public class JtaTransactionManagerBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { @Override - protected String getBeanClassName(Element element) { - return JtaTransactionManagerFactoryBean.resolveJtaTransactionManagerClassName(); + protected Class getBeanClass(Element element) { + return JtaTransactionManager.class; } @Override diff --git a/spring-tx/src/main/java/org/springframework/transaction/config/JtaTransactionManagerFactoryBean.java b/spring-tx/src/main/java/org/springframework/transaction/config/JtaTransactionManagerFactoryBean.java index 09fe5062f3f6..a1cc1b87c6e8 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/config/JtaTransactionManagerFactoryBean.java +++ b/spring-tx/src/main/java/org/springframework/transaction/config/JtaTransactionManagerFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,62 +16,23 @@ package org.springframework.transaction.config; -import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.lang.Nullable; import org.springframework.transaction.TransactionSystemException; import org.springframework.transaction.jta.JtaTransactionManager; -import org.springframework.util.ClassUtils; /** - * A {@link FactoryBean} equivalent to the <tx:jta-transaction-manager/> XML element, - * autodetecting WebLogic and WebSphere servers and exposing the corresponding - * {@link org.springframework.transaction.jta.JtaTransactionManager} subclass. + * A {@link FactoryBean} equivalent to the <tx:jta-transaction-manager/> XML element. * * @author Juergen Hoeller * @since 4.1.1 - * @see org.springframework.transaction.jta.WebLogicJtaTransactionManager - * @see org.springframework.transaction.jta.WebSphereUowTransactionManager + * @deprecated as of 6.0, in favor of a straight {@link JtaTransactionManager} definition */ +@Deprecated public class JtaTransactionManagerFactoryBean implements FactoryBean, InitializingBean { - private static final String WEBLOGIC_JTA_TRANSACTION_MANAGER_CLASS_NAME = - "org.springframework.transaction.jta.WebLogicJtaTransactionManager"; - - private static final String WEBSPHERE_TRANSACTION_MANAGER_CLASS_NAME = - "org.springframework.transaction.jta.WebSphereUowTransactionManager"; - - private static final String JTA_TRANSACTION_MANAGER_CLASS_NAME = - "org.springframework.transaction.jta.JtaTransactionManager"; - - - private static final boolean weblogicPresent; - - private static final boolean webspherePresent; - - static { - ClassLoader classLoader = JtaTransactionManagerFactoryBean.class.getClassLoader(); - weblogicPresent = ClassUtils.isPresent("weblogic.transaction.UserTransaction", classLoader); - webspherePresent = ClassUtils.isPresent("com.ibm.wsspi.uow.UOWManager", classLoader); - } - - - private final JtaTransactionManager transactionManager; - - - @SuppressWarnings("unchecked") - public JtaTransactionManagerFactoryBean() { - String className = resolveJtaTransactionManagerClassName(); - try { - Class clazz = (Class) - ClassUtils.forName(className, JtaTransactionManagerFactoryBean.class.getClassLoader()); - this.transactionManager = BeanUtils.instantiateClass(clazz); - } - catch (ClassNotFoundException ex) { - throw new IllegalStateException("Failed to load JtaTransactionManager class: " + className, ex); - } - } + private final JtaTransactionManager transactionManager = new JtaTransactionManager(); @Override @@ -95,17 +56,4 @@ public boolean isSingleton() { return true; } - - static String resolveJtaTransactionManagerClassName() { - if (weblogicPresent) { - return WEBLOGIC_JTA_TRANSACTION_MANAGER_CLASS_NAME; - } - else if (webspherePresent) { - return WEBSPHERE_TRANSACTION_MANAGER_CLASS_NAME; - } - else { - return JTA_TRANSACTION_MANAGER_CLASS_NAME; - } - } - } diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/RollbackRuleAttribute.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/RollbackRuleAttribute.java index 07a59cc1131b..e0552d41f21a 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/RollbackRuleAttribute.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/RollbackRuleAttribute.java @@ -74,7 +74,7 @@ public RollbackRuleAttribute(Class clazz) { * for the given {@code exceptionName}. *

    This can be a substring, with no wildcard support at present. A value * of "ServletException" would match - * {@code javax.servlet.ServletException} and subclasses, for example. + * {@code jakarta.servlet.ServletException} and subclasses, for example. *

    NB: Consider carefully how specific the pattern is, and * whether to include package information (which is not mandatory). For * example, "Exception" will match nearly anything, and will probably hide diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/JtaAfterCompletionSynchronization.java b/spring-tx/src/main/java/org/springframework/transaction/jta/JtaAfterCompletionSynchronization.java index 807a19fcf712..15eb93ce5053 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/JtaAfterCompletionSynchronization.java +++ b/spring-tx/src/main/java/org/springframework/transaction/jta/JtaAfterCompletionSynchronization.java @@ -18,8 +18,8 @@ import java.util.List; -import javax.transaction.Status; -import javax.transaction.Synchronization; +import jakarta.transaction.Status; +import jakarta.transaction.Synchronization; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationUtils; diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionManager.java b/spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionManager.java index c993fbf31fe4..6488332e75af 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionManager.java +++ b/spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,17 +23,18 @@ import java.util.Properties; import javax.naming.NamingException; -import javax.transaction.HeuristicMixedException; -import javax.transaction.HeuristicRollbackException; -import javax.transaction.InvalidTransactionException; -import javax.transaction.NotSupportedException; -import javax.transaction.RollbackException; -import javax.transaction.Status; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; -import javax.transaction.TransactionSynchronizationRegistry; -import javax.transaction.UserTransaction; + +import jakarta.transaction.HeuristicMixedException; +import jakarta.transaction.HeuristicRollbackException; +import jakarta.transaction.InvalidTransactionException; +import jakarta.transaction.NotSupportedException; +import jakarta.transaction.RollbackException; +import jakarta.transaction.Status; +import jakarta.transaction.SystemException; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; +import jakarta.transaction.TransactionSynchronizationRegistry; +import jakarta.transaction.UserTransaction; import org.springframework.beans.factory.InitializingBean; import org.springframework.jndi.JndiTemplate; @@ -56,7 +57,7 @@ /** * {@link org.springframework.transaction.PlatformTransactionManager} implementation * for JTA, delegating to a backend JTA provider. This is typically used to delegate - * to a Java EE server's transaction coordinator, but may also be configured with a + * to a Jakarta EE server's transaction coordinator, but may also be configured with a * local JTA provider which is embedded within the application. * *

    This transaction manager is appropriate for handling distributed transactions, @@ -67,8 +68,8 @@ * HibernateTransactionManager is appropriate, for example. * *

    For typical JTA transactions (REQUIRED, SUPPORTS, MANDATORY, NEVER), a plain - * JtaTransactionManager definition is all you need, portable across all Java EE servers. - * This corresponds to the functionality of the JTA UserTransaction, for which Java EE + * JtaTransactionManager definition is all you need, portable across all Jakarta EE servers. + * This corresponds to the functionality of the JTA UserTransaction, for which Jakarta EE * specifies a standard JNDI name ("java:comp/UserTransaction"). There is no need to * configure a server-specific TransactionManager lookup for this kind of JTA usage. * @@ -77,26 +78,17 @@ * autodetected by JtaTransactionManager, provided that the "autodetectTransactionManager" * flag is set to "true" (which it is by default). * - *

    Note: Support for the JTA TransactionManager interface is not required by Java EE. - * Almost all Java EE servers expose it, but do so as extension to EE. There might be some + *

    Note: Support for the JTA TransactionManager interface is not required by Jakarta EE. + * Almost all Jakarta EE servers expose it, but do so as extension to EE. There might be some * issues with compatibility, despite the TransactionManager interface being part of JTA. - * As a consequence, Spring provides various vendor-specific PlatformTransactionManagers, - * which are recommended to be used if appropriate: {@link WebLogicJtaTransactionManager} - * and {@link WebSphereUowTransactionManager}. For all other Java EE servers, the - * standard JtaTransactionManager is sufficient. * *

    This pure JtaTransactionManager class supports timeouts but not per-transaction * isolation levels. Custom subclasses may override the {@link #doJtaBegin} method for - * specific JTA extensions in order to provide this functionality; Spring includes a - * corresponding {@link WebLogicJtaTransactionManager} class for WebLogic Server. Such - * adapters for specific Java EE transaction coordinators may also expose transaction - * names for monitoring; with standard JTA, transaction names will simply be ignored. - * - *

    Consider using Spring's {@code tx:jta-transaction-manager} configuration - * element for automatically picking the appropriate JTA platform transaction manager - * (automatically detecting WebLogic and WebSphere). + * specific JTA extensions in order to provide this functionality. Such adapters for + * specific Jakarta EE transaction coordinators may also expose transaction names for + * monitoring; with standard JTA, transaction names will simply be ignored. * - *

    JTA 1.1 adds the TransactionSynchronizationRegistry facility, as public Java EE 5 + *

    JTA 1.1 adds the TransactionSynchronizationRegistry facility, as public Jakarta EE * API in addition to the standard JTA UserTransaction handle. As of Spring 2.5, this * JtaTransactionManager autodetects the TransactionSynchronizationRegistry and uses * it for registering Spring-managed synchronizations when participating in an existing @@ -108,21 +100,20 @@ * * @author Juergen Hoeller * @since 24.03.2003 - * @see javax.transaction.UserTransaction - * @see javax.transaction.TransactionManager - * @see javax.transaction.TransactionSynchronizationRegistry + * @see jakarta.transaction.UserTransaction + * @see jakarta.transaction.TransactionManager + * @see jakarta.transaction.TransactionSynchronizationRegistry * @see #setUserTransactionName * @see #setUserTransaction * @see #setTransactionManagerName * @see #setTransactionManager - * @see WebLogicJtaTransactionManager */ @SuppressWarnings("serial") public class JtaTransactionManager extends AbstractPlatformTransactionManager implements TransactionFactory, InitializingBean, Serializable { /** - * Default JNDI location for the JTA UserTransaction. Many Java EE servers + * Default JNDI location for the JTA UserTransaction. Many Jakarta EE servers * also provide support for the JTA TransactionManager interface there. * @see #setUserTransactionName * @see #setAutodetectTransactionManager @@ -141,7 +132,7 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager "java:pm/TransactionManager", "java:/TransactionManager"}; /** - * Standard Java EE 5 JNDI location for the JTA TransactionSynchronizationRegistry. + * Standard Jakarta EE JNDI location for the JTA TransactionSynchronizationRegistry. * Autodetected when available. */ public static final String DEFAULT_TRANSACTION_SYNCHRONIZATION_REGISTRY_NAME = @@ -265,7 +256,7 @@ public Properties getJndiEnvironment() { /** * Set the JTA UserTransaction to use as direct reference. - *

    Typically just used for local JTA setups; in a Java EE environment, + *

    Typically just used for local JTA setups; in a Jakarta EE environment, * the UserTransaction will always be fetched from JNDI. * @see #setUserTransactionName * @see #setAutodetectUserTransaction @@ -284,7 +275,7 @@ public UserTransaction getUserTransaction() { /** * Set the JNDI name of the JTA UserTransaction. - *

    Note that the UserTransaction will be autodetected at the Java EE + *

    Note that the UserTransaction will be autodetected at the Jakarta EE * default location "java:comp/UserTransaction" if not specified explicitly. * @see #DEFAULT_USER_TRANSACTION_NAME * @see #setUserTransaction @@ -296,7 +287,7 @@ public void setUserTransactionName(String userTransactionName) { /** * Set whether to autodetect the JTA UserTransaction at its default - * JNDI location "java:comp/UserTransaction", as specified by Java EE. + * JNDI location "java:comp/UserTransaction", as specified by Jakarta EE. * Will proceed without UserTransaction if none found. *

    Default is "true", autodetecting the UserTransaction unless * it has been specified explicitly. Turn this flag off to allow for @@ -381,7 +372,7 @@ public void setAutodetectTransactionManager(boolean autodetectTransactionManager *

    A TransactionSynchronizationRegistry allows for interposed registration * of transaction synchronizations, as an alternative to the regular registration * methods on the JTA TransactionManager API. Also, it is an official part of the - * Java EE 5 platform, in contrast to the JTA TransactionManager itself. + * Jakarta EE platform, in contrast to the JTA TransactionManager itself. *

    Note that the TransactionSynchronizationRegistry will be autodetected in JNDI and * also from the UserTransaction/TransactionManager object if implemented there as well. * @see #setTransactionSynchronizationRegistryName @@ -402,7 +393,7 @@ public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry( /** * Set the JNDI name of the JTA 1.1 TransactionSynchronizationRegistry. *

    Note that the TransactionSynchronizationRegistry will be autodetected - * at the Java EE 5 default location "java:comp/TransactionSynchronizationRegistry" + * at the Jakarta EE default location "java:comp/TransactionSynchronizationRegistry" * if not specified explicitly. * @see #DEFAULT_TRANSACTION_SYNCHRONIZATION_REGISTRY_NAME */ @@ -741,7 +732,7 @@ protected TransactionManager findTransactionManager(@Nullable UserTransaction ut /** * Find the JTA 1.1 TransactionSynchronizationRegistry through autodetection: * checking whether the UserTransaction object or TransactionManager object - * implements it, and checking Java EE 5's standard JNDI location. + * implements it, and checking Jakarta EE's standard JNDI location. *

    The default implementation simply returns {@code null}. * @param ut the JTA UserTransaction object * @param tm the JTA TransactionManager object @@ -834,7 +825,7 @@ protected boolean isExistingTransaction(Object transaction) { *

    JTA implementations might support nested transactions via further * {@code UserTransaction.begin()} invocations, but never support savepoints. * @see #doBegin - * @see javax.transaction.UserTransaction#begin() + * @see jakarta.transaction.UserTransaction#begin() */ @Override protected boolean useSavepointForNestedTransaction() { @@ -874,8 +865,8 @@ protected void doBegin(Object transaction, TransactionDefinition definition) { * @see #applyIsolationLevel * @see #applyTimeout * @see JtaTransactionObject#getUserTransaction() - * @see javax.transaction.UserTransaction#setTransactionTimeout - * @see javax.transaction.UserTransaction#begin + * @see jakarta.transaction.UserTransaction#setTransactionTimeout + * @see jakarta.transaction.UserTransaction#begin */ protected void doJtaBegin(JtaTransactionObject txObject, TransactionDefinition definition) throws NotSupportedException, SystemException { @@ -918,7 +909,7 @@ protected void applyIsolationLevel(JtaTransactionObject txObject, int isolationL * @throws SystemException if thrown by the JTA implementation * @see #doJtaBegin * @see JtaTransactionObject#getUserTransaction() - * @see javax.transaction.UserTransaction#setTransactionTimeout(int) + * @see jakarta.transaction.UserTransaction#setTransactionTimeout(int) */ protected void applyTimeout(JtaTransactionObject txObject, int timeout) throws SystemException { if (timeout > TransactionDefinition.TIMEOUT_DEFAULT) { @@ -948,7 +939,7 @@ protected Object doSuspend(Object transaction) { * @return the suspended JTA Transaction object * @throws SystemException if thrown by JTA methods * @see #getTransactionManager() - * @see javax.transaction.TransactionManager#suspend() + * @see jakarta.transaction.TransactionManager#suspend() */ protected Object doJtaSuspend(JtaTransactionObject txObject) throws SystemException { if (getTransactionManager() == null) { @@ -984,7 +975,7 @@ protected void doResume(@Nullable Object transaction, Object suspendedResources) * @throws InvalidTransactionException if thrown by JTA methods * @throws SystemException if thrown by JTA methods * @see #getTransactionManager() - * @see javax.transaction.TransactionManager#resume(javax.transaction.Transaction) + * @see jakarta.transaction.TransactionManager#resume(jakarta.transaction.Transaction) */ protected void doJtaResume(@Nullable JtaTransactionObject txObject, Object suspendedTransaction) throws InvalidTransactionException, SystemException { @@ -1144,8 +1135,8 @@ protected void registerAfterCompletionWithExistingTransaction( * @throws RollbackException if thrown by JTA methods * @throws SystemException if thrown by JTA methods * @see #getTransactionManager() - * @see javax.transaction.Transaction#registerSynchronization - * @see javax.transaction.TransactionSynchronizationRegistry#registerInterposedSynchronization + * @see jakarta.transaction.Transaction#registerSynchronization + * @see jakarta.transaction.TransactionSynchronizationRegistry#registerInterposedSynchronization */ protected void doRegisterAfterCompletionWithJtaTransaction( JtaTransactionObject txObject, List synchronizations) diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionObject.java b/spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionObject.java index 4bbc8ff46ac0..b92453fa92ac 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionObject.java +++ b/spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionObject.java @@ -16,16 +16,16 @@ package org.springframework.transaction.jta; -import javax.transaction.Status; -import javax.transaction.SystemException; -import javax.transaction.UserTransaction; +import jakarta.transaction.Status; +import jakarta.transaction.SystemException; +import jakarta.transaction.UserTransaction; import org.springframework.transaction.TransactionSystemException; import org.springframework.transaction.support.SmartTransactionObject; import org.springframework.transaction.support.TransactionSynchronizationUtils; /** - * JTA transaction object, representing a {@link javax.transaction.UserTransaction}. + * JTA transaction object, representing a {@link jakarta.transaction.UserTransaction}. * Used as transaction object by Spring's {@link JtaTransactionManager}. * *

    Note: This is an SPI class, not intended to be used by applications. @@ -33,7 +33,7 @@ * @author Juergen Hoeller * @since 1.1 * @see JtaTransactionManager - * @see javax.transaction.UserTransaction + * @see jakarta.transaction.UserTransaction */ public class JtaTransactionObject implements SmartTransactionObject { diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/ManagedTransactionAdapter.java b/spring-tx/src/main/java/org/springframework/transaction/jta/ManagedTransactionAdapter.java index 47a804abc84e..6d5542b14d87 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/ManagedTransactionAdapter.java +++ b/spring-tx/src/main/java/org/springframework/transaction/jta/ManagedTransactionAdapter.java @@ -16,21 +16,22 @@ package org.springframework.transaction.jta; -import javax.transaction.HeuristicMixedException; -import javax.transaction.HeuristicRollbackException; -import javax.transaction.RollbackException; -import javax.transaction.Synchronization; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; import javax.transaction.xa.XAResource; +import jakarta.transaction.HeuristicMixedException; +import jakarta.transaction.HeuristicRollbackException; +import jakarta.transaction.RollbackException; +import jakarta.transaction.Synchronization; +import jakarta.transaction.SystemException; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; + import org.springframework.util.Assert; /** * Adapter for a managed JTA Transaction handle, taking a JTA - * {@link javax.transaction.TransactionManager} reference and creating - * a JTA {@link javax.transaction.Transaction} handle for it. + * {@link jakarta.transaction.TransactionManager} reference and creating + * a JTA {@link jakarta.transaction.Transaction} handle for it. * * @author Juergen Hoeller * @since 3.0.2 diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/SimpleTransactionFactory.java b/spring-tx/src/main/java/org/springframework/transaction/jta/SimpleTransactionFactory.java index bd0828a9c370..f0977ac25e39 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/SimpleTransactionFactory.java +++ b/spring-tx/src/main/java/org/springframework/transaction/jta/SimpleTransactionFactory.java @@ -16,25 +16,25 @@ package org.springframework.transaction.jta; -import javax.transaction.NotSupportedException; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; +import jakarta.transaction.NotSupportedException; +import jakarta.transaction.SystemException; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** * Default implementation of the {@link TransactionFactory} strategy interface, - * simply wrapping a standard JTA {@link javax.transaction.TransactionManager}. + * simply wrapping a standard JTA {@link jakarta.transaction.TransactionManager}. * *

    Does not support transaction names; simply ignores any specified name. * * @author Juergen Hoeller * @since 2.5 - * @see javax.transaction.TransactionManager#setTransactionTimeout(int) - * @see javax.transaction.TransactionManager#begin() - * @see javax.transaction.TransactionManager#getTransaction() + * @see jakarta.transaction.TransactionManager#setTransactionTimeout(int) + * @see jakarta.transaction.TransactionManager#begin() + * @see jakarta.transaction.TransactionManager#getTransaction() */ public class SimpleTransactionFactory implements TransactionFactory { diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java b/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java index d2f8282ef15a..aa718d7aed61 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java +++ b/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,10 @@ package org.springframework.transaction.jta; -import javax.transaction.Status; -import javax.transaction.Synchronization; -import javax.transaction.TransactionManager; -import javax.transaction.UserTransaction; - +import jakarta.transaction.Status; +import jakarta.transaction.Synchronization; +import jakarta.transaction.TransactionManager; +import jakarta.transaction.UserTransaction; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -30,7 +29,7 @@ import org.springframework.util.Assert; /** - * Adapter that implements the JTA {@link javax.transaction.Synchronization} + * Adapter that implements the JTA {@link jakarta.transaction.Synchronization} * interface delegating to an underlying Spring * {@link org.springframework.transaction.support.TransactionSynchronization}. * @@ -40,7 +39,7 @@ * * @author Juergen Hoeller * @since 2.0 - * @see javax.transaction.Transaction#registerSynchronization + * @see jakarta.transaction.Transaction#registerSynchronization * @see org.springframework.transaction.support.TransactionSynchronization */ public class SpringJtaSynchronizationAdapter implements Synchronization { @@ -82,9 +81,7 @@ public SpringJtaSynchronizationAdapter(TransactionSynchronization springSynchron @Nullable UserTransaction jtaUserTransaction) { this(springSynchronization); - if (jtaUserTransaction != null && !jtaUserTransaction.getClass().getName().startsWith("weblogic.")) { - this.jtaTransaction = jtaUserTransaction; - } + this.jtaTransaction = jtaUserTransaction; } /** @@ -104,9 +101,7 @@ public SpringJtaSynchronizationAdapter( TransactionSynchronization springSynchronization, @Nullable TransactionManager jtaTransactionManager) { this(springSynchronization); - if (jtaTransactionManager != null && !jtaTransactionManager.getClass().getName().startsWith("weblogic.")) { - this.jtaTransaction = new UserTransactionAdapter(jtaTransactionManager); - } + this.jtaTransaction = new UserTransactionAdapter(jtaTransactionManager); } diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/TransactionFactory.java b/spring-tx/src/main/java/org/springframework/transaction/jta/TransactionFactory.java index 9317e9bb8ebb..b0ac31420835 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/TransactionFactory.java +++ b/spring-tx/src/main/java/org/springframework/transaction/jta/TransactionFactory.java @@ -16,24 +16,24 @@ package org.springframework.transaction.jta; -import javax.transaction.NotSupportedException; -import javax.transaction.SystemException; -import javax.transaction.Transaction; +import jakarta.transaction.NotSupportedException; +import jakarta.transaction.SystemException; +import jakarta.transaction.Transaction; import org.springframework.lang.Nullable; /** - * Strategy interface for creating JTA {@link javax.transaction.Transaction} + * Strategy interface for creating JTA {@link jakarta.transaction.Transaction} * objects based on specified transactional characteristics. * *

    The default implementation, {@link SimpleTransactionFactory}, simply - * wraps a standard JTA {@link javax.transaction.TransactionManager}. + * wraps a standard JTA {@link jakarta.transaction.TransactionManager}. * This strategy interface allows for more sophisticated implementations * that adapt to vendor-specific JTA extensions. * * @author Juergen Hoeller * @since 2.5 - * @see javax.transaction.TransactionManager#getTransaction() + * @see jakarta.transaction.TransactionManager#getTransaction() * @see SimpleTransactionFactory * @see JtaTransactionManager */ @@ -58,8 +58,8 @@ public interface TransactionFactory { * {@link org.springframework.jca.endpoint.AbstractMessageEndpointFactory} * in order to differentiate between invalid configuration and valid * ResourceAdapter-managed transactions. - * @see javax.resource.spi.ResourceAdapter#endpointActivation - * @see javax.resource.spi.endpoint.MessageEndpointFactory#isDeliveryTransacted + * @see jakarta.resource.spi.ResourceAdapter#endpointActivation + * @see jakarta.resource.spi.endpoint.MessageEndpointFactory#isDeliveryTransacted */ boolean supportsResourceAdapterManagedTransactions(); diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/UserTransactionAdapter.java b/spring-tx/src/main/java/org/springframework/transaction/jta/UserTransactionAdapter.java index 8302071f0e32..faf610fcced1 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/UserTransactionAdapter.java +++ b/spring-tx/src/main/java/org/springframework/transaction/jta/UserTransactionAdapter.java @@ -16,20 +16,20 @@ package org.springframework.transaction.jta; -import javax.transaction.HeuristicMixedException; -import javax.transaction.HeuristicRollbackException; -import javax.transaction.NotSupportedException; -import javax.transaction.RollbackException; -import javax.transaction.SystemException; -import javax.transaction.TransactionManager; -import javax.transaction.UserTransaction; +import jakarta.transaction.HeuristicMixedException; +import jakarta.transaction.HeuristicRollbackException; +import jakarta.transaction.NotSupportedException; +import jakarta.transaction.RollbackException; +import jakarta.transaction.SystemException; +import jakarta.transaction.TransactionManager; +import jakarta.transaction.UserTransaction; import org.springframework.util.Assert; /** * Adapter for a JTA UserTransaction handle, taking a JTA - * {@link javax.transaction.TransactionManager} reference and creating - * a JTA {@link javax.transaction.UserTransaction} handle for it. + * {@link jakarta.transaction.TransactionManager} reference and creating + * a JTA {@link jakarta.transaction.UserTransaction} handle for it. * *

    The JTA UserTransaction interface is an exact subset of the JTA * TransactionManager interface. Unfortunately, it does not serve as diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/WebLogicJtaTransactionManager.java b/spring-tx/src/main/java/org/springframework/transaction/jta/WebLogicJtaTransactionManager.java deleted file mode 100644 index 9d2cc38a723b..000000000000 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/WebLogicJtaTransactionManager.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.transaction.jta; - -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import javax.transaction.InvalidTransactionException; -import javax.transaction.NotSupportedException; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; -import javax.transaction.UserTransaction; - -import org.springframework.lang.Nullable; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionSystemException; -import org.springframework.util.Assert; - -/** - * Special {@link JtaTransactionManager} variant for BEA WebLogic (9.0 and higher). - * Supports the full power of Spring's transaction definitions on WebLogic's - * transaction coordinator, beyond standard JTA: transaction names, - * per-transaction isolation levels, and proper resuming of transactions in all cases. - * - *

    Uses WebLogic's special {@code begin(name)} method to start a JTA transaction, - * in order to make Spring-driven transactions visible in WebLogic's transaction - * monitor. In case of Spring's declarative transactions, the exposed name will - * (by default) be the fully-qualified class name + "." + method name. - * - *

    Supports a per-transaction isolation level through WebLogic's corresponding - * JTA transaction property "ISOLATION LEVEL". This will apply the specified isolation - * level (e.g. ISOLATION_SERIALIZABLE) to all JDBC Connections that participate in the - * given transaction. - * - *

    Invokes WebLogic's special {@code forceResume} method if standard JTA resume - * failed, to also resume if the target transaction was marked rollback-only. - * If you're not relying on this feature of transaction suspension in the first - * place, Spring's standard JtaTransactionManager will behave properly too. - * - *

    By default, the JTA UserTransaction and TransactionManager handles are - * fetched directly from WebLogic's {@code TransactionHelper}. This can be - * overridden by specifying "userTransaction"/"userTransactionName" and - * "transactionManager"/"transactionManagerName", passing in existing handles - * or specifying corresponding JNDI locations to look up. - * - *

    NOTE: This JtaTransactionManager is intended to refine specific transaction - * demarcation behavior on Spring's side. It will happily co-exist with independently - * configured WebLogic transaction strategies in your persistence provider, with no - * need to specifically connect those setups in any way. - * - * @author Juergen Hoeller - * @since 1.1 - * @see org.springframework.transaction.TransactionDefinition#getName - * @see org.springframework.transaction.TransactionDefinition#getIsolationLevel - * @see weblogic.transaction.UserTransaction#begin(String) - * @see weblogic.transaction.Transaction#setProperty - * @see weblogic.transaction.TransactionManager#forceResume - * @see weblogic.transaction.TransactionHelper - */ -@SuppressWarnings("serial") -public class WebLogicJtaTransactionManager extends JtaTransactionManager { - - private static final String USER_TRANSACTION_CLASS_NAME = "weblogic.transaction.UserTransaction"; - - private static final String CLIENT_TRANSACTION_MANAGER_CLASS_NAME = "weblogic.transaction.ClientTransactionManager"; - - private static final String TRANSACTION_CLASS_NAME = "weblogic.transaction.Transaction"; - - private static final String TRANSACTION_HELPER_CLASS_NAME = "weblogic.transaction.TransactionHelper"; - - private static final String ISOLATION_LEVEL_KEY = "ISOLATION LEVEL"; - - - private boolean weblogicUserTransactionAvailable; - - @Nullable - private Method beginWithNameMethod; - - @Nullable - private Method beginWithNameAndTimeoutMethod; - - private boolean weblogicTransactionManagerAvailable; - - @Nullable - private Method forceResumeMethod; - - @Nullable - private Method setPropertyMethod; - - @Nullable - private Object transactionHelper; - - - @Override - public void afterPropertiesSet() throws TransactionSystemException { - super.afterPropertiesSet(); - loadWebLogicTransactionClasses(); - } - - @Override - @Nullable - protected UserTransaction retrieveUserTransaction() throws TransactionSystemException { - Object helper = loadWebLogicTransactionHelper(); - try { - logger.trace("Retrieving JTA UserTransaction from WebLogic TransactionHelper"); - Method getUserTransactionMethod = helper.getClass().getMethod("getUserTransaction"); - return (UserTransaction) getUserTransactionMethod.invoke(this.transactionHelper); - } - catch (InvocationTargetException ex) { - throw new TransactionSystemException( - "WebLogic's TransactionHelper.getUserTransaction() method failed", ex.getTargetException()); - } - catch (Exception ex) { - throw new TransactionSystemException( - "Could not invoke WebLogic's TransactionHelper.getUserTransaction() method", ex); - } - } - - @Override - @Nullable - protected TransactionManager retrieveTransactionManager() throws TransactionSystemException { - Object helper = loadWebLogicTransactionHelper(); - try { - logger.trace("Retrieving JTA TransactionManager from WebLogic TransactionHelper"); - Method getTransactionManagerMethod = helper.getClass().getMethod("getTransactionManager"); - return (TransactionManager) getTransactionManagerMethod.invoke(this.transactionHelper); - } - catch (InvocationTargetException ex) { - throw new TransactionSystemException( - "WebLogic's TransactionHelper.getTransactionManager() method failed", ex.getTargetException()); - } - catch (Exception ex) { - throw new TransactionSystemException( - "Could not invoke WebLogic's TransactionHelper.getTransactionManager() method", ex); - } - } - - private Object loadWebLogicTransactionHelper() throws TransactionSystemException { - Object helper = this.transactionHelper; - if (helper == null) { - try { - Class transactionHelperClass = getClass().getClassLoader().loadClass(TRANSACTION_HELPER_CLASS_NAME); - Method getTransactionHelperMethod = transactionHelperClass.getMethod("getTransactionHelper"); - helper = getTransactionHelperMethod.invoke(null); - this.transactionHelper = helper; - logger.trace("WebLogic TransactionHelper found"); - } - catch (InvocationTargetException ex) { - throw new TransactionSystemException( - "WebLogic's TransactionHelper.getTransactionHelper() method failed", ex.getTargetException()); - } - catch (Exception ex) { - throw new TransactionSystemException( - "Could not initialize WebLogicJtaTransactionManager because WebLogic API classes are not available", - ex); - } - } - return helper; - } - - private void loadWebLogicTransactionClasses() throws TransactionSystemException { - try { - Class userTransactionClass = getClass().getClassLoader().loadClass(USER_TRANSACTION_CLASS_NAME); - this.weblogicUserTransactionAvailable = userTransactionClass.isInstance(getUserTransaction()); - if (this.weblogicUserTransactionAvailable) { - this.beginWithNameMethod = userTransactionClass.getMethod("begin", String.class); - this.beginWithNameAndTimeoutMethod = userTransactionClass.getMethod("begin", String.class, int.class); - logger.debug("Support for WebLogic transaction names available"); - } - else { - logger.debug("Support for WebLogic transaction names not available"); - } - - // Obtain WebLogic ClientTransactionManager interface. - Class transactionManagerClass = - getClass().getClassLoader().loadClass(CLIENT_TRANSACTION_MANAGER_CLASS_NAME); - logger.trace("WebLogic ClientTransactionManager found"); - - this.weblogicTransactionManagerAvailable = transactionManagerClass.isInstance(getTransactionManager()); - if (this.weblogicTransactionManagerAvailable) { - Class transactionClass = getClass().getClassLoader().loadClass(TRANSACTION_CLASS_NAME); - this.forceResumeMethod = transactionManagerClass.getMethod("forceResume", Transaction.class); - this.setPropertyMethod = transactionClass.getMethod("setProperty", String.class, Serializable.class); - logger.debug("Support for WebLogic forceResume available"); - } - else { - logger.debug("Support for WebLogic forceResume not available"); - } - } - catch (Exception ex) { - throw new TransactionSystemException( - "Could not initialize WebLogicJtaTransactionManager because WebLogic API classes are not available", - ex); - } - } - - private TransactionManager obtainTransactionManager() { - TransactionManager tm = getTransactionManager(); - Assert.state(tm != null, "No TransactionManager set"); - return tm; - } - - - @Override - protected void doJtaBegin(JtaTransactionObject txObject, TransactionDefinition definition) - throws NotSupportedException, SystemException { - - int timeout = determineTimeout(definition); - - // Apply transaction name (if any) to WebLogic transaction. - if (this.weblogicUserTransactionAvailable && definition.getName() != null) { - try { - if (timeout > TransactionDefinition.TIMEOUT_DEFAULT) { - /* - weblogic.transaction.UserTransaction wut = (weblogic.transaction.UserTransaction) ut; - wut.begin(definition.getName(), timeout); - */ - Assert.state(this.beginWithNameAndTimeoutMethod != null, "WebLogic JTA API not initialized"); - this.beginWithNameAndTimeoutMethod.invoke(txObject.getUserTransaction(), definition.getName(), timeout); - } - else { - /* - weblogic.transaction.UserTransaction wut = (weblogic.transaction.UserTransaction) ut; - wut.begin(definition.getName()); - */ - Assert.state(this.beginWithNameMethod != null, "WebLogic JTA API not initialized"); - this.beginWithNameMethod.invoke(txObject.getUserTransaction(), definition.getName()); - } - } - catch (InvocationTargetException ex) { - throw new TransactionSystemException( - "WebLogic's UserTransaction.begin() method failed", ex.getTargetException()); - } - catch (Exception ex) { - throw new TransactionSystemException( - "Could not invoke WebLogic's UserTransaction.begin() method", ex); - } - } - else { - // No WebLogic UserTransaction available or no transaction name specified - // -> standard JTA begin call. - applyTimeout(txObject, timeout); - txObject.getUserTransaction().begin(); - } - - // Specify isolation level, if any, through corresponding WebLogic transaction property. - if (this.weblogicTransactionManagerAvailable) { - if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { - try { - Transaction tx = obtainTransactionManager().getTransaction(); - Integer isolationLevel = definition.getIsolationLevel(); - /* - weblogic.transaction.Transaction wtx = (weblogic.transaction.Transaction) tx; - wtx.setProperty(ISOLATION_LEVEL_KEY, isolationLevel); - */ - Assert.state(this.setPropertyMethod != null, "WebLogic JTA API not initialized"); - this.setPropertyMethod.invoke(tx, ISOLATION_LEVEL_KEY, isolationLevel); - } - catch (InvocationTargetException ex) { - throw new TransactionSystemException( - "WebLogic's Transaction.setProperty(String, Serializable) method failed", ex.getTargetException()); - } - catch (Exception ex) { - throw new TransactionSystemException( - "Could not invoke WebLogic's Transaction.setProperty(String, Serializable) method", ex); - } - } - } - else { - applyIsolationLevel(txObject, definition.getIsolationLevel()); - } - } - - @Override - protected void doJtaResume(@Nullable JtaTransactionObject txObject, Object suspendedTransaction) - throws InvalidTransactionException, SystemException { - - try { - obtainTransactionManager().resume((Transaction) suspendedTransaction); - } - catch (InvalidTransactionException ex) { - if (!this.weblogicTransactionManagerAvailable) { - throw ex; - } - - if (logger.isDebugEnabled()) { - logger.debug("Standard JTA resume threw InvalidTransactionException: " + ex.getMessage() + - " - trying WebLogic JTA forceResume"); - } - /* - weblogic.transaction.TransactionManager wtm = - (weblogic.transaction.TransactionManager) getTransactionManager(); - wtm.forceResume(suspendedTransaction); - */ - try { - Assert.state(this.forceResumeMethod != null, "WebLogic JTA API not initialized"); - this.forceResumeMethod.invoke(getTransactionManager(), suspendedTransaction); - } - catch (InvocationTargetException ex2) { - throw new TransactionSystemException( - "WebLogic's TransactionManager.forceResume(Transaction) method failed", ex2.getTargetException()); - } - catch (Exception ex2) { - throw new TransactionSystemException( - "Could not access WebLogic's TransactionManager.forceResume(Transaction) method", ex2); - } - } - } - - @Override - public Transaction createTransaction(@Nullable String name, int timeout) throws NotSupportedException, SystemException { - if (this.weblogicUserTransactionAvailable && name != null) { - try { - if (timeout >= 0) { - Assert.state(this.beginWithNameAndTimeoutMethod != null, "WebLogic JTA API not initialized"); - this.beginWithNameAndTimeoutMethod.invoke(getUserTransaction(), name, timeout); - } - else { - Assert.state(this.beginWithNameMethod != null, "WebLogic JTA API not initialized"); - this.beginWithNameMethod.invoke(getUserTransaction(), name); - } - } - catch (InvocationTargetException ex) { - if (ex.getTargetException() instanceof NotSupportedException) { - throw (NotSupportedException) ex.getTargetException(); - } - else if (ex.getTargetException() instanceof SystemException) { - throw (SystemException) ex.getTargetException(); - } - else if (ex.getTargetException() instanceof RuntimeException) { - throw (RuntimeException) ex.getTargetException(); - } - else { - throw new SystemException( - "WebLogic's begin() method failed with an unexpected error: " + ex.getTargetException()); - } - } - catch (Exception ex) { - throw new SystemException("Could not invoke WebLogic's UserTransaction.begin() method: " + ex); - } - return new ManagedTransactionAdapter(obtainTransactionManager()); - } - - else { - // No name specified - standard JTA is sufficient. - return super.createTransaction(name, timeout); - } - } - -} diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/WebSphereUowTransactionManager.java b/spring-tx/src/main/java/org/springframework/transaction/jta/WebSphereUowTransactionManager.java deleted file mode 100644 index 256cc9652950..000000000000 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/WebSphereUowTransactionManager.java +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.transaction.jta; - -import java.util.List; - -import javax.naming.NamingException; - -import com.ibm.websphere.uow.UOWSynchronizationRegistry; -import com.ibm.wsspi.uow.UOWAction; -import com.ibm.wsspi.uow.UOWActionException; -import com.ibm.wsspi.uow.UOWException; -import com.ibm.wsspi.uow.UOWManager; -import com.ibm.wsspi.uow.UOWManagerFactory; - -import org.springframework.lang.Nullable; -import org.springframework.transaction.IllegalTransactionStateException; -import org.springframework.transaction.InvalidTimeoutException; -import org.springframework.transaction.NestedTransactionNotSupportedException; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionException; -import org.springframework.transaction.TransactionSystemException; -import org.springframework.transaction.support.CallbackPreferringPlatformTransactionManager; -import org.springframework.transaction.support.DefaultTransactionStatus; -import org.springframework.transaction.support.SmartTransactionObject; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionSynchronization; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.transaction.support.TransactionSynchronizationUtils; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -/** - * WebSphere-specific PlatformTransactionManager implementation that delegates - * to a {@link com.ibm.wsspi.uow.UOWManager} instance, obtained from WebSphere's - * JNDI environment. This allows Spring to leverage the full power of the WebSphere - * transaction coordinator, including transaction suspension, in a manner that is - * perfectly compliant with officially supported WebSphere API. - * - *

    The {@link CallbackPreferringPlatformTransactionManager} interface - * implemented by this class indicates that callers should preferably pass in - * a {@link TransactionCallback} through the {@link #execute} method, which - * will be handled through the callback-based WebSphere UOWManager API instead - * of through standard JTA API (UserTransaction / TransactionManager). This avoids - * the use of the non-public {@code javax.transaction.TransactionManager} - * API on WebSphere, staying within supported WebSphere API boundaries. - * - *

    This transaction manager implementation derives from Spring's standard - * {@link JtaTransactionManager}, inheriting the capability to support programmatic - * transaction demarcation via {@code getTransaction} / {@code commit} / - * {@code rollback} calls through a JTA UserTransaction handle, for callers - * that do not use the TransactionCallback-based {@link #execute} method. However, - * transaction suspension is not supported in this {@code getTransaction} - * style (unless you explicitly specify a {@link #setTransactionManager} reference, - * despite the official WebSphere recommendations). Use the {@link #execute} style - * for any code that might require transaction suspension. - * - *

    This transaction manager is compatible with WebSphere 6.1.0.9 and above. - * The default JNDI location for the UOWManager is "java:comp/websphere/UOWManager". - * If the location happens to differ according to your WebSphere documentation, - * simply specify the actual location through this transaction manager's - * "uowManagerName" bean property. - * - *

    NOTE: This JtaTransactionManager is intended to refine specific transaction - * demarcation behavior on Spring's side. It will happily co-exist with independently - * configured WebSphere transaction strategies in your persistence provider, with no - * need to specifically connect those setups in any way. - * - * @author Juergen Hoeller - * @since 2.5 - * @see #setUowManager - * @see #setUowManagerName - * @see com.ibm.wsspi.uow.UOWManager - */ -@SuppressWarnings("serial") -public class WebSphereUowTransactionManager extends JtaTransactionManager - implements CallbackPreferringPlatformTransactionManager { - - /** - * Default JNDI location for the WebSphere UOWManager. - * @see #setUowManagerName - */ - public static final String DEFAULT_UOW_MANAGER_NAME = "java:comp/websphere/UOWManager"; - - - @Nullable - private UOWManager uowManager; - - @Nullable - private String uowManagerName; - - - /** - * Create a new WebSphereUowTransactionManager. - */ - public WebSphereUowTransactionManager() { - setAutodetectTransactionManager(false); - } - - /** - * Create a new WebSphereUowTransactionManager for the given UOWManager. - * @param uowManager the WebSphere UOWManager to use as direct reference - */ - public WebSphereUowTransactionManager(UOWManager uowManager) { - this(); - this.uowManager = uowManager; - } - - - /** - * Set the WebSphere UOWManager to use as direct reference. - *

    Typically just used for test setups; in a Java EE environment, - * the UOWManager will always be fetched from JNDI. - * @see #setUserTransactionName - */ - public void setUowManager(UOWManager uowManager) { - this.uowManager = uowManager; - } - - /** - * Set the JNDI name of the WebSphere UOWManager. - * The default "java:comp/websphere/UOWManager" is used if not set. - * @see #DEFAULT_USER_TRANSACTION_NAME - * @see #setUowManager - */ - public void setUowManagerName(String uowManagerName) { - this.uowManagerName = uowManagerName; - } - - - @Override - public void afterPropertiesSet() throws TransactionSystemException { - initUserTransactionAndTransactionManager(); - - // Fetch UOWManager handle from JNDI, if necessary. - if (this.uowManager == null) { - if (this.uowManagerName != null) { - this.uowManager = lookupUowManager(this.uowManagerName); - } - else { - this.uowManager = lookupDefaultUowManager(); - } - } - } - - /** - * Look up the WebSphere UOWManager in JNDI via the configured name. - * @param uowManagerName the JNDI name of the UOWManager - * @return the UOWManager object - * @throws TransactionSystemException if the JNDI lookup failed - * @see #setJndiTemplate - * @see #setUowManagerName - */ - protected UOWManager lookupUowManager(String uowManagerName) throws TransactionSystemException { - try { - if (logger.isDebugEnabled()) { - logger.debug("Retrieving WebSphere UOWManager from JNDI location [" + uowManagerName + "]"); - } - return getJndiTemplate().lookup(uowManagerName, UOWManager.class); - } - catch (NamingException ex) { - throw new TransactionSystemException( - "WebSphere UOWManager is not available at JNDI location [" + uowManagerName + "]", ex); - } - } - - /** - * Obtain the WebSphere UOWManager from the default JNDI location - * "java:comp/websphere/UOWManager". - * @return the UOWManager object - * @throws TransactionSystemException if the JNDI lookup failed - * @see #setJndiTemplate - */ - protected UOWManager lookupDefaultUowManager() throws TransactionSystemException { - try { - logger.debug("Retrieving WebSphere UOWManager from default JNDI location [" + DEFAULT_UOW_MANAGER_NAME + "]"); - return getJndiTemplate().lookup(DEFAULT_UOW_MANAGER_NAME, UOWManager.class); - } - catch (NamingException ex) { - logger.debug("WebSphere UOWManager is not available at default JNDI location [" + - DEFAULT_UOW_MANAGER_NAME + "] - falling back to UOWManagerFactory lookup"); - return UOWManagerFactory.getUOWManager(); - } - } - - private UOWManager obtainUOWManager() { - Assert.state(this.uowManager != null, "No UOWManager set"); - return this.uowManager; - } - - - /** - * Registers the synchronizations as interposed JTA Synchronization on the UOWManager. - */ - @Override - protected void doRegisterAfterCompletionWithJtaTransaction( - JtaTransactionObject txObject, List synchronizations) { - - obtainUOWManager().registerInterposedSynchronization(new JtaAfterCompletionSynchronization(synchronizations)); - } - - /** - * Returns {@code true} since WebSphere ResourceAdapters (as exposed in JNDI) - * implicitly perform transaction enlistment if the MessageEndpointFactory's - * {@code isDeliveryTransacted} method returns {@code true}. - * In that case we'll simply skip the {@link #createTransaction} call. - * @see javax.resource.spi.endpoint.MessageEndpointFactory#isDeliveryTransacted - * @see org.springframework.jca.endpoint.AbstractMessageEndpointFactory - * @see TransactionFactory#createTransaction - */ - @Override - public boolean supportsResourceAdapterManagedTransactions() { - return true; - } - - - @Override - @Nullable - public T execute(@Nullable TransactionDefinition definition, TransactionCallback callback) - throws TransactionException { - - // Use defaults if no transaction definition given. - TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults()); - - if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) { - throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout()); - } - - UOWManager uowManager = obtainUOWManager(); - int pb = def.getPropagationBehavior(); - boolean existingTx = (uowManager.getUOWStatus() != UOWSynchronizationRegistry.UOW_STATUS_NONE && - uowManager.getUOWType() != UOWSynchronizationRegistry.UOW_TYPE_LOCAL_TRANSACTION); - - int uowType = UOWSynchronizationRegistry.UOW_TYPE_GLOBAL_TRANSACTION; - boolean joinTx = false; - boolean newSynch = false; - - if (existingTx) { - if (pb == TransactionDefinition.PROPAGATION_NEVER) { - throw new IllegalTransactionStateException( - "Transaction propagation 'never' but existing transaction found"); - } - if (pb == TransactionDefinition.PROPAGATION_NESTED) { - throw new NestedTransactionNotSupportedException( - "Transaction propagation 'nested' not supported for WebSphere UOW transactions"); - } - if (pb == TransactionDefinition.PROPAGATION_SUPPORTS || - pb == TransactionDefinition.PROPAGATION_REQUIRED || - pb == TransactionDefinition.PROPAGATION_MANDATORY) { - joinTx = true; - newSynch = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); - } - else if (pb == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) { - uowType = UOWSynchronizationRegistry.UOW_TYPE_LOCAL_TRANSACTION; - newSynch = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS); - } - else { - newSynch = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); - } - } - else { - if (pb == TransactionDefinition.PROPAGATION_MANDATORY) { - throw new IllegalTransactionStateException( - "Transaction propagation 'mandatory' but no existing transaction found"); - } - if (pb == TransactionDefinition.PROPAGATION_SUPPORTS || - pb == TransactionDefinition.PROPAGATION_NOT_SUPPORTED || - pb == TransactionDefinition.PROPAGATION_NEVER) { - uowType = UOWSynchronizationRegistry.UOW_TYPE_LOCAL_TRANSACTION; - newSynch = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS); - } - else { - newSynch = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); - } - } - - boolean debug = logger.isDebugEnabled(); - if (debug) { - logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def); - } - SuspendedResourcesHolder suspendedResources = (!joinTx ? suspend(null) : null); - UOWActionAdapter action = null; - try { - boolean actualTransaction = (uowType == UOWManager.UOW_TYPE_GLOBAL_TRANSACTION); - if (actualTransaction && def.getTimeout() > TransactionDefinition.TIMEOUT_DEFAULT) { - uowManager.setUOWTimeout(uowType, def.getTimeout()); - } - if (debug) { - logger.debug("Invoking WebSphere UOW action: type=" + uowType + ", join=" + joinTx); - } - action = new UOWActionAdapter<>(def, callback, actualTransaction, !joinTx, newSynch, debug); - uowManager.runUnderUOW(uowType, joinTx, action); - if (debug) { - logger.debug("Returned from WebSphere UOW action: type=" + uowType + ", join=" + joinTx); - } - return action.getResult(); - } - catch (UOWException | UOWActionException ex) { - TransactionSystemException tse = - new TransactionSystemException("UOWManager transaction processing failed", ex); - Throwable appEx = action.getException(); - if (appEx != null) { - logger.error("Application exception overridden by rollback exception", appEx); - tse.initApplicationException(appEx); - } - throw tse; - } - finally { - if (suspendedResources != null) { - resume(null, suspendedResources); - } - } - } - - - /** - * Adapter that executes the given Spring transaction within the WebSphere UOWAction shape. - */ - private class UOWActionAdapter implements UOWAction, SmartTransactionObject { - - private final TransactionDefinition definition; - - private final TransactionCallback callback; - - private final boolean actualTransaction; - - private final boolean newTransaction; - - private final boolean newSynchronization; - - private boolean debug; - - @Nullable - private T result; - - @Nullable - private Throwable exception; - - public UOWActionAdapter(TransactionDefinition definition, TransactionCallback callback, - boolean actualTransaction, boolean newTransaction, boolean newSynchronization, boolean debug) { - - this.definition = definition; - this.callback = callback; - this.actualTransaction = actualTransaction; - this.newTransaction = newTransaction; - this.newSynchronization = newSynchronization; - this.debug = debug; - } - - @Override - public void run() { - UOWManager uowManager = obtainUOWManager(); - DefaultTransactionStatus status = prepareTransactionStatus( - this.definition, (this.actualTransaction ? this : null), - this.newTransaction, this.newSynchronization, this.debug, null); - try { - this.result = this.callback.doInTransaction(status); - triggerBeforeCommit(status); - } - catch (Throwable ex) { - this.exception = ex; - if (status.isDebug()) { - logger.debug("Rolling back on application exception from transaction callback", ex); - } - uowManager.setRollbackOnly(); - } - finally { - if (status.isLocalRollbackOnly()) { - if (status.isDebug()) { - logger.debug("Transaction callback has explicitly requested rollback"); - } - uowManager.setRollbackOnly(); - } - triggerBeforeCompletion(status); - if (status.isNewSynchronization()) { - List synchronizations = TransactionSynchronizationManager.getSynchronizations(); - TransactionSynchronizationManager.clear(); - if (!synchronizations.isEmpty()) { - uowManager.registerInterposedSynchronization(new JtaAfterCompletionSynchronization(synchronizations)); - } - } - } - } - - @Nullable - public T getResult() { - if (this.exception != null) { - ReflectionUtils.rethrowRuntimeException(this.exception); - } - return this.result; - } - - @Nullable - public Throwable getException() { - return this.exception; - } - - @Override - public boolean isRollbackOnly() { - return obtainUOWManager().getRollbackOnly(); - } - - @Override - public void flush() { - TransactionSynchronizationUtils.triggerFlush(); - } - } - -} diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java b/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java index 74dc7a3d5a1e..0d21f4c89397 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java @@ -1152,8 +1152,8 @@ protected void doResume(@Nullable Object transaction, Object suspendedResources) * @see DefaultTransactionStatus#isLocalRollbackOnly() * @see org.springframework.transaction.TransactionStatus#setRollbackOnly() * @see org.springframework.transaction.UnexpectedRollbackException - * @see javax.transaction.UserTransaction#commit() - * @see javax.transaction.RollbackException + * @see jakarta.transaction.UserTransaction#commit() + * @see jakarta.transaction.RollbackException */ protected boolean shouldCommitOnGlobalRollbackOnly() { return false; diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/SmartTransactionObject.java b/spring-tx/src/main/java/org/springframework/transaction/support/SmartTransactionObject.java index 923e00480456..90d0662c10d5 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/SmartTransactionObject.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/SmartTransactionObject.java @@ -36,8 +36,8 @@ public interface SmartTransactionObject extends Flushable { /** * Return whether the transaction is internally marked as rollback-only. * Can, for example, check the JTA UserTransaction. - * @see javax.transaction.UserTransaction#getStatus - * @see javax.transaction.Status#STATUS_MARKED_ROLLBACK + * @see jakarta.transaction.UserTransaction#getStatus + * @see jakarta.transaction.Status#STATUS_MARKED_ROLLBACK */ boolean isRollbackOnly(); diff --git a/spring-tx/src/test/java/org/springframework/dao/annotation/PersistenceExceptionTranslationAdvisorTests.java b/spring-tx/src/test/java/org/springframework/dao/annotation/PersistenceExceptionTranslationAdvisorTests.java index dff65b71ed11..c052cea1463a 100644 --- a/spring-tx/src/test/java/org/springframework/dao/annotation/PersistenceExceptionTranslationAdvisorTests.java +++ b/spring-tx/src/test/java/org/springframework/dao/annotation/PersistenceExceptionTranslationAdvisorTests.java @@ -21,8 +21,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.persistence.PersistenceException; - +import jakarta.persistence.PersistenceException; import org.junit.jupiter.api.Test; import org.springframework.aop.framework.ProxyFactory; diff --git a/spring-tx/src/test/java/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessorTests.java b/spring-tx/src/test/java/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessorTests.java index a09559481132..46e125464da4 100644 --- a/spring-tx/src/test/java/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessorTests.java +++ b/spring-tx/src/test/java/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessorTests.java @@ -16,8 +16,7 @@ package org.springframework.dao.annotation; -import javax.persistence.PersistenceException; - +import jakarta.persistence.PersistenceException; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; diff --git a/spring-tx/src/test/java/org/springframework/jca/cci/CciLocalTransactionTests.java b/spring-tx/src/test/java/org/springframework/jca/cci/CciLocalTransactionTests.java deleted file mode 100644 index d45b326c090a..000000000000 --- a/spring-tx/src/test/java/org/springframework/jca/cci/CciLocalTransactionTests.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci; - -import javax.resource.ResourceException; -import javax.resource.cci.Connection; -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.Interaction; -import javax.resource.cci.InteractionSpec; -import javax.resource.cci.LocalTransaction; -import javax.resource.cci.Record; - -import org.junit.jupiter.api.Test; - -import org.springframework.dao.DataRetrievalFailureException; -import org.springframework.jca.cci.connection.CciLocalTransactionManager; -import org.springframework.jca.cci.core.CciTemplate; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionCallbackWithoutResult; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.transaction.support.TransactionTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * @author Thierry Templier - * @author Chris Beams - */ -@Deprecated -public class CciLocalTransactionTests { - - /** - * Test if a transaction ( begin / commit ) is executed on the - * LocalTransaction when CciLocalTransactionManager is specified as - * transaction manager. - */ - @Test - public void testLocalTransactionCommit() throws ResourceException { - final ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - LocalTransaction localTransaction = mock(LocalTransaction.class); - final Record record = mock(Record.class); - final InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.getLocalTransaction()).willReturn(localTransaction); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, record, record)).willReturn(true); - given(connection.getLocalTransaction()).willReturn(localTransaction); - - CciLocalTransactionManager tm = new CciLocalTransactionManager(); - tm.setConnectionFactory(connectionFactory); - TransactionTemplate tt = new TransactionTemplate(tm); - - tt.execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus status) { - assertThat(TransactionSynchronizationManager.hasResource(connectionFactory)).as("Has thread connection").isTrue(); - CciTemplate ct = new CciTemplate(connectionFactory); - ct.execute(interactionSpec, record, record); - } - }); - - verify(localTransaction).begin(); - verify(interaction).close(); - verify(localTransaction).commit(); - verify(connection).close(); - } - - /** - * Test if a transaction ( begin / rollback ) is executed on the - * LocalTransaction when CciLocalTransactionManager is specified as - * transaction manager and a non-checked exception is thrown. - */ - @Test - public void testLocalTransactionRollback() throws ResourceException { - final ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - LocalTransaction localTransaction = mock(LocalTransaction.class); - final Record record = mock(Record.class); - final InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.getLocalTransaction()).willReturn(localTransaction); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, record, record)).willReturn(true); - given(connection.getLocalTransaction()).willReturn(localTransaction); - - CciLocalTransactionManager tm = new CciLocalTransactionManager(); - tm.setConnectionFactory(connectionFactory); - TransactionTemplate tt = new TransactionTemplate(tm); - - try { - tt.execute(new TransactionCallback() { - @Override - public Void doInTransaction(TransactionStatus status) { - assertThat(TransactionSynchronizationManager.hasResource(connectionFactory)).as("Has thread connection").isTrue(); - CciTemplate ct = new CciTemplate(connectionFactory); - ct.execute(interactionSpec, record, record); - throw new DataRetrievalFailureException("error"); - } - }); - } - catch (Exception ex) { - } - - verify(localTransaction).begin(); - verify(interaction).close(); - verify(localTransaction).rollback(); - verify(connection).close(); - } -} diff --git a/spring-tx/src/test/java/org/springframework/jca/cci/CciTemplateTests.java b/spring-tx/src/test/java/org/springframework/jca/cci/CciTemplateTests.java deleted file mode 100644 index a67028f162a8..000000000000 --- a/spring-tx/src/test/java/org/springframework/jca/cci/CciTemplateTests.java +++ /dev/null @@ -1,545 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci; - -import java.sql.SQLException; - -import javax.resource.NotSupportedException; -import javax.resource.ResourceException; -import javax.resource.cci.Connection; -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.ConnectionSpec; -import javax.resource.cci.IndexedRecord; -import javax.resource.cci.Interaction; -import javax.resource.cci.InteractionSpec; -import javax.resource.cci.MappedRecord; -import javax.resource.cci.Record; -import javax.resource.cci.RecordFactory; -import javax.resource.cci.ResultSet; - -import org.junit.jupiter.api.Test; - -import org.springframework.jca.cci.connection.ConnectionSpecConnectionFactoryAdapter; -import org.springframework.jca.cci.connection.NotSupportedRecordFactory; -import org.springframework.jca.cci.core.CciTemplate; -import org.springframework.jca.cci.core.ConnectionCallback; -import org.springframework.jca.cci.core.InteractionCallback; -import org.springframework.jca.cci.core.RecordCreator; -import org.springframework.jca.cci.core.RecordExtractor; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * @author Thierry Templier - * @author Juergen Hoeller - * @author Chris Beams - */ -@Deprecated -public class CciTemplateTests { - - @Test - public void testCreateIndexedRecord() throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - RecordFactory recordFactory = mock(RecordFactory.class); - IndexedRecord indexedRecord = mock(IndexedRecord.class); - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(recordFactory.createIndexedRecord("name")).willReturn(indexedRecord); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.createIndexedRecord("name"); - - verify(recordFactory).createIndexedRecord("name"); - } - - @Test - public void testCreateMappedRecord() throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - RecordFactory recordFactory = mock(RecordFactory.class); - MappedRecord mappedRecord = mock(MappedRecord.class); - - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(recordFactory.createMappedRecord("name")).willReturn(mappedRecord); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.createMappedRecord("name"); - - verify(recordFactory).createMappedRecord("name"); - } - - @Test - public void testTemplateExecuteInputOutput() throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, inputRecord, outputRecord)).willReturn(true); - - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.execute(interactionSpec, inputRecord, outputRecord); - - verify(interaction).execute(interactionSpec, inputRecord, outputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testTemplateExecuteWithCreatorAndRecordFactoryNotSupported() - throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - - Record inputRecord = mock(Record.class); - final Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connectionFactory.getRecordFactory()).willThrow(new NotSupportedException("not supported")); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, inputRecord, outputRecord)).willReturn(true); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.setOutputRecordCreator(new RecordCreator() { - @Override - public Record createRecord(RecordFactory recordFactory) { - boolean condition = recordFactory instanceof NotSupportedRecordFactory; - assertThat(condition).isTrue(); - return outputRecord; - } - }); - ct.execute(interactionSpec, inputRecord); - - verify(interaction).execute(interactionSpec, inputRecord, outputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testTemplateExecuteInputTrueWithCreator2() - throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - RecordFactory recordFactory = mock(RecordFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - RecordCreator creator = mock(RecordCreator.class); - - Record inputRecord = mock(Record.class); - final Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(connection.createInteraction()).willReturn(interaction); - given(creator.createRecord(recordFactory)).willReturn(outputRecord); - given(interaction.execute(interactionSpec, inputRecord, outputRecord)).willReturn(true); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.setOutputRecordCreator(creator); - ct.execute(interactionSpec, inputRecord); - - verify(interaction).execute(interactionSpec, inputRecord, outputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testTemplateExecuteInputFalse() throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, inputRecord)).willReturn(outputRecord); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.execute(interactionSpec, inputRecord); - - verify(interaction).execute(interactionSpec, inputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @SuppressWarnings("unchecked") - @Test - public void testTemplateExecuteInputExtractorTrueWithCreator() - throws ResourceException, SQLException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - RecordFactory recordFactory = mock(RecordFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - RecordExtractor extractor = mock(RecordExtractor.class); - RecordCreator creator = mock(RecordCreator.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(creator.createRecord(recordFactory)).willReturn(outputRecord); - given(interaction.execute(interactionSpec, inputRecord, outputRecord)).willReturn(true); - given(extractor.extractData(outputRecord)).willReturn(new Object()); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.setOutputRecordCreator(creator); - ct.execute(interactionSpec, inputRecord, extractor); - - verify(extractor).extractData(outputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @SuppressWarnings("unchecked") - @Test - public void testTemplateExecuteInputExtractorFalse() - throws ResourceException, SQLException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - RecordExtractor extractor = mock(RecordExtractor.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, inputRecord)).willReturn(outputRecord); - given(extractor.extractData(outputRecord)).willReturn(new Object()); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.execute(interactionSpec, inputRecord, extractor); - - verify(extractor).extractData(outputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testTemplateExecuteInputGeneratorTrueWithCreator() - throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - RecordFactory recordFactory = mock(RecordFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - RecordCreator generator = mock(RecordCreator.class); - RecordCreator creator = mock(RecordCreator.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(generator.createRecord(recordFactory)).willReturn(inputRecord); - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(creator.createRecord(recordFactory)).willReturn(outputRecord); - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(interaction.execute(interactionSpec, inputRecord, outputRecord)).willReturn(true); - - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.setOutputRecordCreator(creator); - ct.execute(interactionSpec, generator); - - verify(interaction).execute(interactionSpec, inputRecord, outputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testTemplateExecuteInputGeneratorFalse() - throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - RecordFactory recordFactory = mock(RecordFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - RecordCreator generator = mock(RecordCreator.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(generator.createRecord(recordFactory)).willReturn(inputRecord); - given(interaction.execute(interactionSpec, inputRecord)).willReturn(outputRecord); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.execute(interactionSpec, generator); - - verify(interaction).execute(interactionSpec, inputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @SuppressWarnings("unchecked") - @Test - public void testTemplateExecuteInputGeneratorExtractorTrueWithCreator() - throws ResourceException, SQLException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - RecordFactory recordFactory = mock(RecordFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - RecordCreator generator = mock(RecordCreator.class); - RecordExtractor extractor = mock(RecordExtractor.class); - RecordCreator creator = mock(RecordCreator.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - Object obj = new Object(); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(creator.createRecord(recordFactory)).willReturn(outputRecord); - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(generator.createRecord(recordFactory)).willReturn(inputRecord); - given(interaction.execute(interactionSpec, inputRecord, outputRecord)).willReturn(true); - given(extractor.extractData(outputRecord)).willReturn(obj); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.setOutputRecordCreator(creator); - assertThat(ct.execute(interactionSpec, generator, extractor)).isEqualTo(obj); - - verify(interaction).close(); - verify(connection).close(); - } - - @SuppressWarnings("unchecked") - @Test - public void testTemplateExecuteInputGeneratorExtractorFalse() - throws ResourceException, SQLException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - RecordFactory recordFactory = mock(RecordFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - RecordCreator generator = mock(RecordCreator.class); - RecordExtractor extractor = mock(RecordExtractor.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(generator.createRecord(recordFactory)).willReturn(inputRecord); - given(interaction.execute(interactionSpec, inputRecord)).willReturn(outputRecord); - given(extractor.extractData(outputRecord)).willReturn(new Object()); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.execute(interactionSpec, generator, extractor); - - verify(extractor).extractData(outputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testTemplateExecuteInputOutputConnectionSpec() throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - ConnectionSpec connectionSpec = mock(ConnectionSpec.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getConnection(connectionSpec)).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, inputRecord, outputRecord)).willReturn(true); - - ConnectionSpecConnectionFactoryAdapter adapter = new ConnectionSpecConnectionFactoryAdapter(); - adapter.setTargetConnectionFactory(connectionFactory); - adapter.setConnectionSpec(connectionSpec); - CciTemplate ct = new CciTemplate(adapter); - ct.execute(interactionSpec, inputRecord, outputRecord); - - verify(interaction).execute(interactionSpec, inputRecord, outputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @SuppressWarnings("unchecked") - @Test - public void testTemplateExecuteInputOutputResultsSetFalse() - throws ResourceException, SQLException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - RecordFactory recordFactory = mock(RecordFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - Record record = mock(Record.class); - ResultSet resultset = mock(ResultSet.class); - RecordCreator generator = mock(RecordCreator.class); - RecordExtractor extractor = mock(RecordExtractor.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(generator.createRecord(recordFactory)).willReturn(record); - given(interaction.execute(interactionSpec, record)).willReturn(resultset); - given(extractor.extractData(resultset)).willReturn(new Object()); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.execute(interactionSpec, generator, extractor); - - verify(extractor).extractData(resultset); - verify(resultset).close(); - verify(interaction).close(); - verify(connection).close(); - } - - @SuppressWarnings("unchecked") - @Test - public void testTemplateExecuteConnectionCallback() - throws ResourceException, SQLException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - ConnectionCallback connectionCallback = mock(ConnectionCallback.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connectionCallback.doInConnection(connection, connectionFactory)).willReturn(new Object()); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.execute(connectionCallback); - - verify(connectionCallback).doInConnection(connection, connectionFactory); - verify(connection).close(); - } - - @SuppressWarnings("unchecked") - @Test - public void testTemplateExecuteInteractionCallback() - throws ResourceException, SQLException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - InteractionCallback interactionCallback = mock(InteractionCallback.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(interactionCallback.doInInteraction(interaction,connectionFactory)).willReturn(new Object()); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.execute(interactionCallback); - - verify(interactionCallback).doInInteraction(interaction,connectionFactory); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testTemplateExecuteInputTrueTrueWithCreator() - throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - RecordCreator creator = mock(RecordCreator.class); - - Record inputOutputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, inputOutputRecord, inputOutputRecord)).willReturn(true); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.setOutputRecordCreator(creator); - ct.execute(interactionSpec, inputOutputRecord, inputOutputRecord); - - verify(interaction).execute(interactionSpec, inputOutputRecord, inputOutputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testTemplateExecuteInputTrueTrue() throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - Record inputOutputRecord = mock(Record.class); - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, inputOutputRecord, inputOutputRecord)).willReturn(true); - - CciTemplate ct = new CciTemplate(connectionFactory); - ct.execute(interactionSpec, inputOutputRecord, inputOutputRecord); - - verify(interaction).execute(interactionSpec, inputOutputRecord, inputOutputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testTemplateExecuteInputFalseTrue() throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - Record inputOutputRecord = mock(Record.class); - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, inputOutputRecord)).willReturn(null); - - CciTemplate ct = new CciTemplate(connectionFactory); - Record tmpOutputRecord = ct.execute(interactionSpec, inputOutputRecord); - assertThat(tmpOutputRecord).isNull(); - - verify(interaction).execute(interactionSpec, inputOutputRecord); - verify(interaction).close(); - verify(connection).close(); - } - -} diff --git a/spring-tx/src/test/java/org/springframework/jca/cci/EisOperationTests.java b/spring-tx/src/test/java/org/springframework/jca/cci/EisOperationTests.java deleted file mode 100644 index 30f6febbda29..000000000000 --- a/spring-tx/src/test/java/org/springframework/jca/cci/EisOperationTests.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jca.cci; - -import javax.resource.ResourceException; -import javax.resource.cci.Connection; -import javax.resource.cci.ConnectionFactory; -import javax.resource.cci.Interaction; -import javax.resource.cci.InteractionSpec; -import javax.resource.cci.Record; -import javax.resource.cci.RecordFactory; - -import org.junit.jupiter.api.Test; - -import org.springframework.jca.cci.core.RecordCreator; -import org.springframework.jca.cci.object.MappingRecordOperation; -import org.springframework.jca.cci.object.SimpleRecordOperation; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * @author Thierry Templier - * @author Chris Beams - */ -@Deprecated -public class EisOperationTests { - - @Test - public void testSimpleRecordOperation() throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - SimpleRecordOperation query = new SimpleRecordOperation(connectionFactory, interactionSpec); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, inputRecord)).willReturn(outputRecord); - - query.execute(inputRecord); - - verify(interaction).execute(interactionSpec, inputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testSimpleRecordOperationWithExplicitOutputRecord() throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - SimpleRecordOperation operation = new SimpleRecordOperation(connectionFactory, interactionSpec); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, inputRecord, outputRecord)).willReturn(true); - - operation.execute(inputRecord, outputRecord); - - verify(interaction).execute(interactionSpec, inputRecord, outputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testSimpleRecordOperationWithInputOutputRecord() throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - - Record inputOutputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - SimpleRecordOperation query = new SimpleRecordOperation(connectionFactory, interactionSpec); - - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, inputOutputRecord, inputOutputRecord)).willReturn(true); - - query.execute(inputOutputRecord, inputOutputRecord); - - verify(interaction).execute(interactionSpec, inputOutputRecord, inputOutputRecord); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testMappingRecordOperation() throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - RecordFactory recordFactory = mock(RecordFactory.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - QueryCallDetector callDetector = mock(QueryCallDetector.class); - - MappingRecordOperationImpl query = new MappingRecordOperationImpl(connectionFactory, interactionSpec); - query.setCallDetector(callDetector); - - Object inObj = new Object(); - Object outObj = new Object(); - - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(callDetector.callCreateInputRecord(recordFactory, inObj)).willReturn(inputRecord); - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(interaction.execute(interactionSpec, inputRecord)).willReturn(outputRecord); - given(callDetector.callExtractOutputData(outputRecord)).willReturn(outObj); - - assertThat(query.execute(inObj)).isSameAs(outObj); - verify(interaction).close(); - verify(connection).close(); - } - - @Test - public void testMappingRecordOperationWithOutputRecordCreator() throws ResourceException { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); - Connection connection = mock(Connection.class); - Interaction interaction = mock(Interaction.class); - RecordFactory recordFactory = mock(RecordFactory.class); - - Record inputRecord = mock(Record.class); - Record outputRecord = mock(Record.class); - - RecordCreator outputCreator = mock(RecordCreator.class); - - InteractionSpec interactionSpec = mock(InteractionSpec.class); - - QueryCallDetector callDetector = mock(QueryCallDetector.class); - - MappingRecordOperationImpl query = new MappingRecordOperationImpl(connectionFactory, interactionSpec); - query.setOutputRecordCreator(outputCreator); - query.setCallDetector(callDetector); - - Object inObj = new Object(); - Object outObj = new Object(); - - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(callDetector.callCreateInputRecord(recordFactory, inObj)).willReturn(inputRecord); - given(connectionFactory.getConnection()).willReturn(connection); - given(connection.createInteraction()).willReturn(interaction); - given(connectionFactory.getRecordFactory()).willReturn(recordFactory); - given(outputCreator.createRecord(recordFactory)).willReturn(outputRecord); - given(interaction.execute(interactionSpec, inputRecord, outputRecord)).willReturn(true); - given(callDetector.callExtractOutputData(outputRecord)).willReturn(outObj); - - assertThat(query.execute(inObj)).isSameAs(outObj); - verify(interaction).close(); - verify(connection).close(); - } - - - private class MappingRecordOperationImpl extends MappingRecordOperation { - - private QueryCallDetector callDetector; - - public MappingRecordOperationImpl(ConnectionFactory connectionFactory, InteractionSpec interactionSpec) { - super(connectionFactory, interactionSpec); - } - - public void setCallDetector(QueryCallDetector callDetector) { - this.callDetector = callDetector; - } - - @Override - protected Record createInputRecord(RecordFactory recordFactory, Object inputObject) { - return this.callDetector.callCreateInputRecord(recordFactory, inputObject); - } - - @Override - protected Object extractOutputData(Record outputRecord) throws ResourceException { - return this.callDetector.callExtractOutputData(outputRecord); - } - } - - - private interface QueryCallDetector { - - Record callCreateInputRecord(RecordFactory recordFactory, Object inputObject); - - Object callExtractOutputData(Record outputRecord); - } - -} diff --git a/spring-tx/src/test/java/org/springframework/jca/support/LocalConnectionFactoryBeanTests.java b/spring-tx/src/test/java/org/springframework/jca/support/LocalConnectionFactoryBeanTests.java index 37511b7dfaae..0ab4b95edda6 100644 --- a/spring-tx/src/test/java/org/springframework/jca/support/LocalConnectionFactoryBeanTests.java +++ b/spring-tx/src/test/java/org/springframework/jca/support/LocalConnectionFactoryBeanTests.java @@ -16,9 +16,8 @@ package org.springframework.jca.support; -import javax.resource.spi.ConnectionManager; -import javax.resource.spi.ManagedConnectionFactory; - +import jakarta.resource.spi.ConnectionManager; +import jakarta.resource.spi.ManagedConnectionFactory; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-tx/src/test/java/org/springframework/transaction/JndiJtaTransactionManagerTests.java b/spring-tx/src/test/java/org/springframework/transaction/JndiJtaTransactionManagerTests.java index 2319d34261fc..611792ba826c 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/JndiJtaTransactionManagerTests.java +++ b/spring-tx/src/test/java/org/springframework/transaction/JndiJtaTransactionManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,9 @@ package org.springframework.transaction; -import javax.transaction.Status; -import javax.transaction.TransactionManager; -import javax.transaction.UserTransaction; - +import jakarta.transaction.Status; +import jakarta.transaction.TransactionManager; +import jakarta.transaction.UserTransaction; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; diff --git a/spring-tx/src/test/java/org/springframework/transaction/JtaTransactionManagerTests.java b/spring-tx/src/test/java/org/springframework/transaction/JtaTransactionManagerTests.java index 8666e6155bf2..84955e4cdeab 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/JtaTransactionManagerTests.java +++ b/spring-tx/src/test/java/org/springframework/transaction/JtaTransactionManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,16 +16,15 @@ package org.springframework.transaction; -import javax.transaction.HeuristicMixedException; -import javax.transaction.HeuristicRollbackException; -import javax.transaction.NotSupportedException; -import javax.transaction.RollbackException; -import javax.transaction.Status; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; -import javax.transaction.UserTransaction; - +import jakarta.transaction.HeuristicMixedException; +import jakarta.transaction.HeuristicRollbackException; +import jakarta.transaction.NotSupportedException; +import jakarta.transaction.RollbackException; +import jakarta.transaction.Status; +import jakarta.transaction.SystemException; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; +import jakarta.transaction.UserTransaction; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; diff --git a/spring-tx/src/test/java/org/springframework/transaction/MockJtaTransaction.java b/spring-tx/src/test/java/org/springframework/transaction/MockJtaTransaction.java index 2adbfa549bce..0b45ade6c55c 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/MockJtaTransaction.java +++ b/spring-tx/src/test/java/org/springframework/transaction/MockJtaTransaction.java @@ -16,15 +16,16 @@ package org.springframework.transaction; -import javax.transaction.Status; -import javax.transaction.Synchronization; import javax.transaction.xa.XAResource; +import jakarta.transaction.Status; +import jakarta.transaction.Synchronization; + /** * @author Juergen Hoeller * @since 31.08.2004 */ -public class MockJtaTransaction implements javax.transaction.Transaction { +public class MockJtaTransaction implements jakarta.transaction.Transaction { private Synchronization synchronization; diff --git a/spring-tx/src/test/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSourceTests.java b/spring-tx/src/test/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSourceTests.java index d94dc4bf495d..aa02845750a2 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSourceTests.java +++ b/spring-tx/src/test/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSourceTests.java @@ -22,10 +22,9 @@ import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; -import javax.ejb.TransactionAttributeType; - import groovy.lang.GroovyObject; import groovy.lang.MetaClass; +import jakarta.ejb.TransactionAttributeType; import org.junit.jupiter.api.Test; import org.springframework.aop.framework.Advised; @@ -745,7 +744,7 @@ static class Ejb3AnnotatedBean1 implements ITestBean1 { private int age; @Override - @javax.ejb.TransactionAttribute(TransactionAttributeType.SUPPORTS) + @jakarta.ejb.TransactionAttribute(TransactionAttributeType.SUPPORTS) public String getName() { return name; } @@ -756,7 +755,7 @@ public void setName(String name) { } @Override - @javax.ejb.TransactionAttribute + @jakarta.ejb.TransactionAttribute public int getAge() { return age; } @@ -768,7 +767,7 @@ public void setAge(int age) { } - @javax.ejb.TransactionAttribute(TransactionAttributeType.SUPPORTS) + @jakarta.ejb.TransactionAttribute(TransactionAttributeType.SUPPORTS) static class Ejb3AnnotatedBean2 implements ITestBean1 { private String name; @@ -786,7 +785,7 @@ public void setName(String name) { } @Override - @javax.ejb.TransactionAttribute + @jakarta.ejb.TransactionAttribute public int getAge() { return age; } @@ -798,10 +797,10 @@ public void setAge(int age) { } - @javax.ejb.TransactionAttribute(TransactionAttributeType.SUPPORTS) + @jakarta.ejb.TransactionAttribute(TransactionAttributeType.SUPPORTS) interface ITestEjb { - @javax.ejb.TransactionAttribute + @jakarta.ejb.TransactionAttribute int getAge(); void setAge(int age); @@ -847,7 +846,7 @@ static class JtaAnnotatedBean1 implements ITestBean1 { private int age; @Override - @javax.transaction.Transactional(javax.transaction.Transactional.TxType.SUPPORTS) + @jakarta.transaction.Transactional(jakarta.transaction.Transactional.TxType.SUPPORTS) public String getName() { return name; } @@ -858,7 +857,7 @@ public void setName(String name) { } @Override - @javax.transaction.Transactional + @jakarta.transaction.Transactional public int getAge() { return age; } @@ -870,7 +869,7 @@ public void setAge(int age) { } - @javax.transaction.Transactional(javax.transaction.Transactional.TxType.SUPPORTS) + @jakarta.transaction.Transactional(jakarta.transaction.Transactional.TxType.SUPPORTS) static class JtaAnnotatedBean2 implements ITestBean1 { private String name; @@ -888,7 +887,7 @@ public void setName(String name) { } @Override - @javax.transaction.Transactional + @jakarta.transaction.Transactional public int getAge() { return age; } @@ -900,10 +899,10 @@ public void setAge(int age) { } - @javax.transaction.Transactional(javax.transaction.Transactional.TxType.SUPPORTS) + @jakarta.transaction.Transactional(jakarta.transaction.Transactional.TxType.SUPPORTS) interface ITestJta { - @javax.transaction.Transactional + @jakarta.transaction.Transactional int getAge(); void setAge(int age); diff --git a/spring-tx/src/test/java/org/springframework/transaction/jta/MockUOWManager.java b/spring-tx/src/test/java/org/springframework/transaction/jta/MockUOWManager.java deleted file mode 100644 index 05c80273d3ba..000000000000 --- a/spring-tx/src/test/java/org/springframework/transaction/jta/MockUOWManager.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.transaction.jta; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.transaction.Synchronization; - -import com.ibm.wsspi.uow.UOWAction; -import com.ibm.wsspi.uow.UOWActionException; -import com.ibm.wsspi.uow.UOWException; -import com.ibm.wsspi.uow.UOWManager; - -/** - * @author Juergen Hoeller - */ -public class MockUOWManager implements UOWManager { - - private int type = UOW_TYPE_GLOBAL_TRANSACTION; - - private boolean joined; - - private int timeout; - - private boolean rollbackOnly; - - private int status = UOW_STATUS_NONE; - - private final Map resources = new HashMap<>(); - - private final List synchronizations = new ArrayList<>(); - - - @Override - public void runUnderUOW(int type, boolean join, UOWAction action) throws UOWActionException, UOWException { - this.type = type; - this.joined = join; - try { - this.status = UOW_STATUS_ACTIVE; - action.run(); - this.status = (this.rollbackOnly ? UOW_STATUS_ROLLEDBACK : UOW_STATUS_COMMITTED); - } - catch (Error | RuntimeException ex) { - this.status = UOW_STATUS_ROLLEDBACK; - throw ex; - } - catch (Exception ex) { - this.status = UOW_STATUS_ROLLEDBACK; - throw new UOWActionException(ex); - } - } - - @Override - public int getUOWType() { - return this.type; - } - - public boolean getJoined() { - return this.joined; - } - - @Override - public long getLocalUOWId() { - return 0; - } - - @Override - public void setUOWTimeout(int uowType, int timeout) { - this.timeout = timeout; - } - - @Override - public int getUOWTimeout() { - return this.timeout; - } - - @Override - public void setRollbackOnly() { - this.rollbackOnly = true; - } - - @Override - public boolean getRollbackOnly() { - return this.rollbackOnly; - } - - public void setUOWStatus(int status) { - this.status = status; - } - - @Override - public int getUOWStatus() { - return this.status; - } - - @Override - public void putResource(Object key, Object value) { - this.resources.put(key, value); - } - - @Override - public Object getResource(Object key) throws NullPointerException { - return this.resources.get(key); - } - - @Override - public void registerInterposedSynchronization(Synchronization sync) { - this.synchronizations.add(sync); - } - - public List getSynchronizations() { - return this.synchronizations; - } - -} diff --git a/spring-tx/src/test/java/org/springframework/transaction/jta/WebSphereUowTransactionManagerTests.java b/spring-tx/src/test/java/org/springframework/transaction/jta/WebSphereUowTransactionManagerTests.java deleted file mode 100644 index 06b4675f3a54..000000000000 --- a/spring-tx/src/test/java/org/springframework/transaction/jta/WebSphereUowTransactionManagerTests.java +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.transaction.jta; - -import javax.transaction.RollbackException; -import javax.transaction.Status; -import javax.transaction.UserTransaction; - -import com.ibm.wsspi.uow.UOWAction; -import com.ibm.wsspi.uow.UOWException; -import com.ibm.wsspi.uow.UOWManager; -import org.junit.jupiter.api.Test; - -import org.springframework.context.testfixture.jndi.ExpectedLookupTemplate; -import org.springframework.dao.OptimisticLockingFailureException; -import org.springframework.transaction.IllegalTransactionStateException; -import org.springframework.transaction.NestedTransactionNotSupportedException; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.TransactionSystemException; -import org.springframework.transaction.support.DefaultTransactionDefinition; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionSynchronizationManager; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * @author Juergen Hoeller - */ -public class WebSphereUowTransactionManagerTests { - - @Test - public void uowManagerFoundInJndi() { - MockUOWManager manager = new MockUOWManager(); - ExpectedLookupTemplate jndiTemplate = - new ExpectedLookupTemplate(WebSphereUowTransactionManager.DEFAULT_UOW_MANAGER_NAME, manager); - WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(); - ptm.setJndiTemplate(jndiTemplate); - ptm.afterPropertiesSet(); - - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - assertThat(ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - return "result"; - } - })).isEqualTo("result"); - - assertThat(manager.getUOWType()).isEqualTo(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION); - assertThat(manager.getJoined()).isFalse(); - assertThat(manager.getRollbackOnly()).isFalse(); - } - - @Test - public void uowManagerAndUserTransactionFoundInJndi() throws Exception { - UserTransaction ut = mock(UserTransaction.class); - given(ut.getStatus()).willReturn( Status.STATUS_NO_TRANSACTION, Status.STATUS_ACTIVE, Status.STATUS_ACTIVE); - - MockUOWManager manager = new MockUOWManager(); - ExpectedLookupTemplate jndiTemplate = new ExpectedLookupTemplate(); - jndiTemplate.addObject(WebSphereUowTransactionManager.DEFAULT_USER_TRANSACTION_NAME, ut); - jndiTemplate.addObject(WebSphereUowTransactionManager.DEFAULT_UOW_MANAGER_NAME, manager); - WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(); - ptm.setJndiTemplate(jndiTemplate); - ptm.afterPropertiesSet(); - - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - TransactionStatus ts = ptm.getTransaction(definition); - ptm.commit(ts); - assertThat(ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - return "result"; - } - })).isEqualTo("result"); - - assertThat(manager.getUOWType()).isEqualTo(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION); - assertThat(manager.getJoined()).isFalse(); - assertThat(manager.getRollbackOnly()).isFalse(); - verify(ut).begin(); - verify(ut).commit(); - } - - @Test - public void propagationMandatoryFailsInCaseOfNoExistingTransaction() { - MockUOWManager manager = new MockUOWManager(); - WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_MANDATORY); - - assertThatExceptionOfType(IllegalTransactionStateException.class).isThrownBy(() -> - ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - return "result"; - } - })); - } - - @Test - public void newTransactionSynchronizationUsingPropagationSupports() { - doTestNewTransactionSynchronization( - TransactionDefinition.PROPAGATION_SUPPORTS, WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS); - } - - @Test - public void newTransactionSynchronizationUsingPropagationNotSupported() { - doTestNewTransactionSynchronization( - TransactionDefinition.PROPAGATION_NOT_SUPPORTED, WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS); - } - - @Test - public void newTransactionSynchronizationUsingPropagationNever() { - doTestNewTransactionSynchronization( - TransactionDefinition.PROPAGATION_NEVER, WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS); - } - - @Test - public void newTransactionSynchronizationUsingPropagationSupportsAndSynchOnActual() { - doTestNewTransactionSynchronization( - TransactionDefinition.PROPAGATION_SUPPORTS, WebSphereUowTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION); - } - - @Test - public void newTransactionSynchronizationUsingPropagationNotSupportedAndSynchOnActual() { - doTestNewTransactionSynchronization( - TransactionDefinition.PROPAGATION_NOT_SUPPORTED, WebSphereUowTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION); - } - - @Test - public void newTransactionSynchronizationUsingPropagationNeverAndSynchOnActual() { - doTestNewTransactionSynchronization( - TransactionDefinition.PROPAGATION_NEVER, WebSphereUowTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION); - } - - @Test - public void newTransactionSynchronizationUsingPropagationSupportsAndSynchNever() { - doTestNewTransactionSynchronization( - TransactionDefinition.PROPAGATION_SUPPORTS, WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER); - } - - @Test - public void newTransactionSynchronizationUsingPropagationNotSupportedAndSynchNever() { - doTestNewTransactionSynchronization( - TransactionDefinition.PROPAGATION_NOT_SUPPORTED, WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER); - } - - @Test - public void newTransactionSynchronizationUsingPropagationNeverAndSynchNever() { - doTestNewTransactionSynchronization( - TransactionDefinition.PROPAGATION_NEVER, WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER); - } - - private void doTestNewTransactionSynchronization(int propagationBehavior, final int synchMode) { - MockUOWManager manager = new MockUOWManager(); - WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - ptm.setTransactionSynchronization(synchMode); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setPropagationBehavior(propagationBehavior); - definition.setReadOnly(true); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - if (synchMode == WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isTrue(); - } - else { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - } - return "result"; - } - })).isEqualTo("result"); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(manager.getUOWTimeout()).isEqualTo(0); - assertThat(manager.getUOWType()).isEqualTo(UOWManager.UOW_TYPE_LOCAL_TRANSACTION); - assertThat(manager.getJoined()).isFalse(); - assertThat(manager.getRollbackOnly()).isFalse(); - } - - @Test - public void newTransactionWithCommitUsingPropagationRequired() { - doTestNewTransactionWithCommit( - TransactionDefinition.PROPAGATION_REQUIRED, WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS); - } - - @Test - public void newTransactionWithCommitUsingPropagationRequiresNew() { - doTestNewTransactionWithCommit( - TransactionDefinition.PROPAGATION_REQUIRES_NEW, WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS); - } - - @Test - public void newTransactionWithCommitUsingPropagationNested() { - doTestNewTransactionWithCommit( - TransactionDefinition.PROPAGATION_NESTED, WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS); - } - - @Test - public void newTransactionWithCommitUsingPropagationRequiredAndSynchOnActual() { - doTestNewTransactionWithCommit( - TransactionDefinition.PROPAGATION_REQUIRED, WebSphereUowTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION); - } - - @Test - public void newTransactionWithCommitUsingPropagationRequiresNewAndSynchOnActual() { - doTestNewTransactionWithCommit( - TransactionDefinition.PROPAGATION_REQUIRES_NEW, WebSphereUowTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION); - } - - @Test - public void newTransactionWithCommitUsingPropagationNestedAndSynchOnActual() { - doTestNewTransactionWithCommit( - TransactionDefinition.PROPAGATION_NESTED, WebSphereUowTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION); - } - - @Test - public void newTransactionWithCommitUsingPropagationRequiredAndSynchNever() { - doTestNewTransactionWithCommit( - TransactionDefinition.PROPAGATION_REQUIRED, WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER); - } - - @Test - public void newTransactionWithCommitUsingPropagationRequiresNewAndSynchNever() { - doTestNewTransactionWithCommit( - TransactionDefinition.PROPAGATION_REQUIRES_NEW, WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER); - } - - @Test - public void newTransactionWithCommitUsingPropagationNestedAndSynchNever() { - doTestNewTransactionWithCommit( - TransactionDefinition.PROPAGATION_NESTED, WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER); - } - - private void doTestNewTransactionWithCommit(int propagationBehavior, final int synchMode) { - MockUOWManager manager = new MockUOWManager(); - WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - ptm.setTransactionSynchronization(synchMode); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setPropagationBehavior(propagationBehavior); - definition.setReadOnly(true); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - if (synchMode != WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isTrue(); - } - else { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - } - return "result"; - } - })).isEqualTo("result"); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(manager.getUOWTimeout()).isEqualTo(0); - assertThat(manager.getUOWType()).isEqualTo(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION); - assertThat(manager.getJoined()).isFalse(); - assertThat(manager.getRollbackOnly()).isFalse(); - } - - @Test - public void newTransactionWithCommitAndTimeout() { - MockUOWManager manager = new MockUOWManager(); - WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setTimeout(10); - definition.setReadOnly(true); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isTrue(); - return "result"; - } - })).isEqualTo("result"); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(manager.getUOWTimeout()).isEqualTo(10); - assertThat(manager.getUOWType()).isEqualTo(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION); - assertThat(manager.getJoined()).isFalse(); - assertThat(manager.getRollbackOnly()).isFalse(); - } - - @Test - public void newTransactionWithCommitException() { - final RollbackException rex = new RollbackException(); - MockUOWManager manager = new MockUOWManager() { - @Override - public void runUnderUOW(int type, boolean join, UOWAction action) throws UOWException { - throw new UOWException(rex); - } - }; - WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThatExceptionOfType(TransactionSystemException.class).isThrownBy(() -> - ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - return "result"; - } - })) - .withCauseInstanceOf(UOWException.class) - .satisfies(ex -> { - assertThat(ex.getRootCause()).isSameAs(rex); - assertThat(ex.getMostSpecificCause()).isSameAs(rex); - }); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(manager.getUOWTimeout()).isEqualTo(0); - } - - @Test - public void newTransactionWithRollback() { - MockUOWManager manager = new MockUOWManager(); - WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThatExceptionOfType(OptimisticLockingFailureException.class).isThrownBy(() -> - ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - throw new OptimisticLockingFailureException(""); - } - })); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(manager.getUOWTimeout()).isEqualTo(0); - assertThat(manager.getUOWType()).isEqualTo(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION); - assertThat(manager.getJoined()).isFalse(); - assertThat(manager.getRollbackOnly()).isTrue(); - } - - @Test - public void newTransactionWithRollbackOnly() { - MockUOWManager manager = new MockUOWManager(); - WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - status.setRollbackOnly(); - return "result"; - } - })).isEqualTo("result"); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(manager.getUOWTimeout()).isEqualTo(0); - assertThat(manager.getUOWType()).isEqualTo(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION); - assertThat(manager.getJoined()).isFalse(); - assertThat(manager.getRollbackOnly()).isTrue(); - } - - @Test - public void existingNonSpringTransaction() { - MockUOWManager manager = new MockUOWManager(); - manager.setUOWStatus(UOWManager.UOW_STATUS_ACTIVE); - WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - return "result"; - } - })).isEqualTo("result"); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(manager.getUOWTimeout()).isEqualTo(0); - assertThat(manager.getUOWType()).isEqualTo(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION); - assertThat(manager.getJoined()).isTrue(); - assertThat(manager.getRollbackOnly()).isFalse(); - } - - @Test - public void propagationNeverFailsInCaseOfExistingTransaction() { - MockUOWManager manager = new MockUOWManager(); - manager.setUOWStatus(UOWManager.UOW_STATUS_ACTIVE); - WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NEVER); - - assertThatExceptionOfType(IllegalTransactionStateException.class).isThrownBy(() -> - ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - return "result"; - } - })); - } - - @Test - public void propagationNestedFailsInCaseOfExistingTransaction() { - MockUOWManager manager = new MockUOWManager(); - manager.setUOWStatus(UOWManager.UOW_STATUS_ACTIVE); - WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED); - - assertThatExceptionOfType(NestedTransactionNotSupportedException.class).isThrownBy(() -> - ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - return "result"; - } - })); - } - - @Test - public void existingTransactionWithParticipationUsingPropagationRequired() { - doTestExistingTransactionWithParticipation(TransactionDefinition.PROPAGATION_REQUIRED); - } - - @Test - public void existingTransactionWithParticipationUsingPropagationSupports() { - doTestExistingTransactionWithParticipation(TransactionDefinition.PROPAGATION_SUPPORTS); - } - - @Test - public void existingTransactionWithParticipationUsingPropagationMandatory() { - doTestExistingTransactionWithParticipation(TransactionDefinition.PROPAGATION_MANDATORY); - } - - private void doTestExistingTransactionWithParticipation(int propagationBehavior) { - MockUOWManager manager = new MockUOWManager(); - final WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - final DefaultTransactionDefinition definition2 = new DefaultTransactionDefinition(); - definition2.setPropagationBehavior(propagationBehavior); - definition2.setReadOnly(true); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - assertThat(ptm.execute(definition2, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status1) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - return "result2"; - } - })).isEqualTo("result2"); - return "result"; - } - })).isEqualTo("result"); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(manager.getUOWTimeout()).isEqualTo(0); - assertThat(manager.getUOWType()).isEqualTo(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION); - assertThat(manager.getJoined()).isTrue(); - assertThat(manager.getRollbackOnly()).isFalse(); - } - - @Test - public void existingTransactionWithSuspensionUsingPropagationRequiresNew() { - doTestExistingTransactionWithSuspension(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - } - - @Test - public void existingTransactionWithSuspensionUsingPropagationNotSupported() { - doTestExistingTransactionWithSuspension(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); - } - - private void doTestExistingTransactionWithSuspension(final int propagationBehavior) { - MockUOWManager manager = new MockUOWManager(); - final WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - final DefaultTransactionDefinition definition2 = new DefaultTransactionDefinition(); - definition2.setPropagationBehavior(propagationBehavior); - definition2.setReadOnly(true); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - assertThat(ptm.execute(definition2, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status1) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isEqualTo((propagationBehavior == TransactionDefinition.PROPAGATION_REQUIRES_NEW)); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isTrue(); - return "result2"; - } - })).isEqualTo("result2"); - return "result"; - } - })).isEqualTo("result"); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(manager.getUOWTimeout()).isEqualTo(0); - if (propagationBehavior == TransactionDefinition.PROPAGATION_REQUIRES_NEW) { - assertThat(manager.getUOWType()).isEqualTo(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION); - } - else { - assertThat(manager.getUOWType()).isEqualTo(UOWManager.UOW_TYPE_LOCAL_TRANSACTION); - } - assertThat(manager.getJoined()).isFalse(); - assertThat(manager.getRollbackOnly()).isFalse(); - } - - @Test - public void existingTransactionUsingPropagationNotSupported() { - MockUOWManager manager = new MockUOWManager(); - final WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager); - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - final DefaultTransactionDefinition definition2 = new DefaultTransactionDefinition(); - definition2.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); - definition2.setReadOnly(true); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(ptm.execute(definition, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - assertThat(ptm.execute(definition2, new TransactionCallback() { - @Override - public String doInTransaction(TransactionStatus status1) { - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isTrue(); - return "result2"; - } - })).isEqualTo("result2"); - return "result"; - } - })).isEqualTo("result"); - - assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse(); - assertThat(TransactionSynchronizationManager.isCurrentTransactionReadOnly()).isFalse(); - - assertThat(manager.getUOWTimeout()).isEqualTo(0); - assertThat(manager.getUOWType()).isEqualTo(UOWManager.UOW_TYPE_LOCAL_TRANSACTION); - assertThat(manager.getJoined()).isFalse(); - assertThat(manager.getRollbackOnly()).isFalse(); - } - -} diff --git a/spring-tx/src/test/java/org/springframework/transaction/support/JtaTransactionManagerSerializationTests.java b/spring-tx/src/test/java/org/springframework/transaction/support/JtaTransactionManagerSerializationTests.java index d5390e33cb0a..296e08a6cacf 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/support/JtaTransactionManagerSerializationTests.java +++ b/spring-tx/src/test/java/org/springframework/transaction/support/JtaTransactionManagerSerializationTests.java @@ -16,9 +16,8 @@ package org.springframework.transaction.support; -import javax.transaction.TransactionManager; -import javax.transaction.UserTransaction; - +import jakarta.transaction.TransactionManager; +import jakarta.transaction.UserTransaction; import org.junit.jupiter.api.Test; import org.springframework.context.testfixture.jndi.SimpleNamingContextBuilder; diff --git a/spring-web/spring-web.gradle b/spring-web/spring-web.gradle index 716ecb4cecf3..f0e341db5d0a 100644 --- a/spring-web/spring-web.gradle +++ b/spring-web/spring-web.gradle @@ -10,16 +10,14 @@ dependencies { optional(project(":spring-aop")) optional(project(":spring-context")) optional(project(":spring-oxm")) - optional("javax.servlet:javax.servlet-api") // Servlet 4 for mapping type - optional("javax.servlet.jsp:javax.servlet.jsp-api") - optional("javax.el:javax.el-api") - optional("javax.faces:javax.faces-api") - optional("javax.json.bind:javax.json.bind-api") - optional("javax.mail:javax.mail-api") - optional("javax.validation:validation-api") - optional("javax.xml.bind:jaxb-api") - optional("javax.xml.ws:jaxws-api") - optional("org.glassfish.main:javax.jws") + optional("jakarta.servlet:jakarta.servlet-api") + optional("jakarta.servlet.jsp:jakarta.servlet.jsp-api") + optional("jakarta.el:jakarta.el-api") + optional("jakarta.faces:jakarta.faces-api") + optional("jakarta.json.bind:jakarta.json.bind-api") + optional("jakarta.mail:jakarta.mail-api") + optional("jakarta.validation:jakarta.validation-api") + optional("jakarta.xml.bind:jakarta.xml.bind-api") optional("io.reactivex.rxjava3:rxjava") optional("io.netty:netty-buffer") optional("io.netty:netty-handler") @@ -29,10 +27,10 @@ dependencies { optional("io.undertow:undertow-core") optional("org.apache.tomcat.embed:tomcat-embed-core") optional("org.eclipse.jetty:jetty-server") { - exclude group: "javax.servlet", module: "javax.servlet-api" + exclude group: "jakarta.servlet", module: "jakarta.servlet-api" } optional("org.eclipse.jetty:jetty-servlet") { - exclude group: "javax.servlet", module: "javax.servlet-api" + exclude group: "jakarta.servlet", module: "jakarta.servlet-api" } optional("org.eclipse.jetty:jetty-reactive-httpclient") optional('org.apache.httpcomponents.client5:httpclient5') @@ -40,8 +38,6 @@ dependencies { optional("com.squareup.okhttp3:okhttp") optional("org.apache.httpcomponents:httpclient") optional("org.apache.httpcomponents:httpasyncclient") - optional("commons-fileupload:commons-fileupload") - optional("org.synchronoss.cloud:nio-multipart-parser") optional("com.fasterxml.woodstox:woodstox-core") optional("com.fasterxml:aalto-xml") optional("com.fasterxml.jackson.core:jackson-databind") @@ -52,7 +48,6 @@ dependencies { optional("com.google.protobuf:protobuf-java-util") optional("com.googlecode.protobuf-java-format:protobuf-java-format") optional("com.rometools:rome") - optional("com.caucho:hessian") optional("org.codehaus.groovy:groovy") optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") @@ -61,9 +56,7 @@ dependencies { testImplementation(testFixtures(project(":spring-context"))) testImplementation(testFixtures(project(":spring-core"))) testImplementation("io.projectreactor:reactor-test") - testImplementation("org.apache.taglibs:taglibs-standard-jstlel") testImplementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8") - testImplementation("com.fasterxml.jackson.datatype:jackson-datatype-joda") testImplementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") testImplementation("com.fasterxml.jackson.module:jackson-module-kotlin") testImplementation("org.apache.tomcat:tomcat-util") @@ -76,16 +69,15 @@ dependencies { testImplementation("org.xmlunit:xmlunit-assertj") testImplementation("org.xmlunit:xmlunit-matchers") testImplementation("io.projectreactor.tools:blockhound") - testRuntimeOnly("com.sun.mail:javax.mail") + testRuntimeOnly("com.sun.mail:jakarta.mail") testRuntimeOnly("com.sun.xml.bind:jaxb-core") testRuntimeOnly("com.sun.xml.bind:jaxb-impl") - testRuntimeOnly("javax.json:javax.json-api") - testRuntimeOnly("org.apache.johnzon:johnzon-jsonb") - testFixturesApi("javax.servlet:javax.servlet-api") + testRuntimeOnly("jakarta.json:jakarta.json-api") + testRuntimeOnly("org.eclipse:yasson") + testFixturesApi("jakarta.servlet:jakarta.servlet-api") testFixturesApi("org.junit.jupiter:junit-jupiter-api") testFixturesApi("org.junit.jupiter:junit-jupiter-params") testFixturesImplementation("io.projectreactor:reactor-test") - testFixturesImplementation("org.apache.taglibs:taglibs-standard-jstlel") testFixturesImplementation("org.assertj:assertj-core") testFixturesImplementation("org.bouncycastle:bcpkix-jdk15on") { because("needed by Netty's SelfSignedCertificate on JDK 15+") diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpRequest.java index 8aabf8957927..80ad419ef499 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpRequest.java @@ -54,7 +54,6 @@ class JettyClientHttpRequest extends AbstractClientHttpRequest { private final ReactiveRequest.Builder builder; - public JettyClientHttpRequest(Request jettyRequest, DataBufferFactory bufferFactory) { this.jettyRequest = jettyRequest; this.bufferFactory = bufferFactory; @@ -137,10 +136,12 @@ protected void applyCookies() { @Override protected void applyHeaders() { HttpHeaders headers = getHeaders(); - headers.forEach((key, value) -> value.forEach(v -> this.jettyRequest.header(key, v))); - if (!headers.containsKey(HttpHeaders.ACCEPT)) { - this.jettyRequest.header(HttpHeaders.ACCEPT, "*/*"); - } + this.jettyRequest.headers(fields -> { + headers.forEach((key, value) -> value.forEach(v -> fields.add(key, v))); + if (!headers.containsKey(HttpHeaders.ACCEPT)) { + fields.add(HttpHeaders.ACCEPT, "*/*"); + } + }); } public ReactiveRequest toReactiveRequest() { diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpResponse.java b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpResponse.java index 5d88c83ddf67..22cde72ac286 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpResponse.java @@ -16,13 +16,11 @@ package org.springframework.http.client.reactive; -import java.lang.reflect.Method; import java.net.HttpCookie; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.reactive.client.ReactiveResponse; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; @@ -32,11 +30,9 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseCookie; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.util.ReflectionUtils; /** * {@link ClientHttpResponse} implementation for the Jetty ReactiveStreams HTTP client. @@ -50,10 +46,6 @@ class JettyClientHttpResponse implements ClientHttpResponse { private static final Pattern SAMESITE_PATTERN = Pattern.compile("(?i).*SameSite=(Strict|Lax|None).*"); - private static final ClassLoader classLoader = JettyClientHttpResponse.class.getClassLoader(); - - private static final boolean jetty10Present; - private final ReactiveResponse reactiveResponse; @@ -62,25 +54,11 @@ class JettyClientHttpResponse implements ClientHttpResponse { private final HttpHeaders headers; - static { - try { - Class httpFieldsClass = classLoader.loadClass("org.eclipse.jetty.http.HttpFields"); - jetty10Present = httpFieldsClass.isInterface(); - } - catch (ClassNotFoundException ex) { - throw new IllegalStateException("No compatible Jetty version found", ex); - } - } - - public JettyClientHttpResponse(ReactiveResponse reactiveResponse, Publisher content) { this.reactiveResponse = reactiveResponse; this.content = Flux.from(content); - MultiValueMap headers = (jetty10Present ? - Jetty10HttpFieldsHelper.getHttpHeaders(reactiveResponse) : - new JettyHeadersAdapter(reactiveResponse.getHeaders())); - + MultiValueMap headers = new JettyHeadersAdapter(reactiveResponse.getHeaders()); this.headers = HttpHeaders.readOnlyHttpHeaders(headers); } @@ -132,40 +110,4 @@ public HttpHeaders getHeaders() { return this.headers; } - - private static class Jetty10HttpFieldsHelper { - - private static final Method getHeadersMethod; - - private static final Method getNameMethod; - - private static final Method getValueMethod; - - static { - try { - getHeadersMethod = Response.class.getMethod("getHeaders"); - Class type = classLoader.loadClass("org.eclipse.jetty.http.HttpField"); - getNameMethod = type.getMethod("getName"); - getValueMethod = type.getMethod("getValue"); - } - catch (ClassNotFoundException | NoSuchMethodException ex) { - throw new IllegalStateException("No compatible Jetty version found", ex); - } - } - - public static HttpHeaders getHttpHeaders(ReactiveResponse response) { - HttpHeaders headers = new HttpHeaders(); - Iterable iterator = (Iterable) - ReflectionUtils.invokeMethod(getHeadersMethod, response.getResponse()); - Assert.notNull(iterator, "Iterator must not be null"); - for (Object field : iterator) { - String name = (String) ReflectionUtils.invokeMethod(getNameMethod, field); - Assert.notNull(name, "Header name must not be null"); - String value = (String) ReflectionUtils.invokeMethod(getValueMethod, field); - headers.add(name, value); - } - return headers; - } - } - } diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyHeadersAdapter.java index f44362c9c3a2..6d42dc76204e 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyHeadersAdapter.java @@ -39,6 +39,7 @@ *

    There is a duplicate of this class in the server package! * * @author Rossen Stoyanchev + * @author Juergen Hoeller * @since 5.3 */ class JettyHeadersAdapter implements MultiValueMap { @@ -58,7 +59,10 @@ public String getFirst(String key) { @Override public void add(String key, @Nullable String value) { - this.headers.add(key, value); + if (!(this.headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } + ((HttpFields.Mutable) this.headers).add(key, value); } @Override @@ -73,7 +77,10 @@ public void addAll(MultiValueMap values) { @Override public void set(String key, @Nullable String value) { - this.headers.put(key, value); + if (!(this.headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } + ((HttpFields.Mutable) this.headers).put(key, value); } @Override @@ -105,7 +112,7 @@ public boolean isEmpty() { @Override public boolean containsKey(Object key) { - return (key instanceof String && this.headers.containsKey((String) key)); + return (key instanceof String && this.headers.contains((String) key)); } @Override @@ -126,17 +133,23 @@ public List get(Object key) { @Nullable @Override public List put(String key, List value) { + if (!(this.headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } List oldValues = get(key); - this.headers.put(key, value); + ((HttpFields.Mutable) this.headers).put(key, value); return oldValues; } @Nullable @Override public List remove(Object key) { + if (!(this.headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } if (key instanceof String) { List oldValues = get(key); - this.headers.remove((String) key); + ((HttpFields.Mutable) this.headers).remove((String) key); return oldValues; } return null; @@ -149,7 +162,10 @@ public void putAll(Map> map) { @Override public void clear() { - this.headers.clear(); + if (!(this.headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } + ((HttpFields.Mutable) this.headers).clear(); } @Override @@ -221,8 +237,11 @@ public List getValue() { @Override public List setValue(List value) { + if (!(headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } List previousValues = headers.getValuesList(this.key); - headers.put(this.key, value); + ((HttpFields.Mutable) headers).put(this.key, value); return previousValues; } } @@ -266,13 +285,16 @@ public String next() { @Override public void remove() { + if (!(headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } if (this.currentName == null) { throw new IllegalStateException("No current Header in iterator"); } - if (!headers.containsKey(this.currentName)) { + if (!headers.contains(this.currentName)) { throw new IllegalStateException("Header not present: " + this.currentName); } - headers.remove(this.currentName); + ((HttpFields.Mutable) headers).remove(this.currentName); } } diff --git a/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java b/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java index 4bbefc8c939c..c6f9222a19c0 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java +++ b/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,13 +84,6 @@ interface ServerDefaultCodecs extends DefaultCodecs { /** * Configure the {@code HttpMessageReader} to use for multipart requests. - *

    By default, if - * Synchronoss NIO Multipart - * is present, this is set to - * {@link org.springframework.http.codec.multipart.MultipartHttpMessageReader - * MultipartHttpMessageReader} created with an instance of - * {@link org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader - * SynchronossPartHttpMessageReader}. *

    Note that {@link #maxInMemorySize(int)} and/or * {@link #enableLoggingRequestDetails(boolean)}, if configured, will be * applied to the given reader, if applicable. diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java deleted file mode 100644 index 032b787d887b..000000000000 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.codec.multipart; - -import java.io.IOException; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.ReadableByteChannel; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.OpenOption; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; - -import org.synchronoss.cloud.nio.multipart.DefaultPartBodyStreamStorageFactory; -import org.synchronoss.cloud.nio.multipart.Multipart; -import org.synchronoss.cloud.nio.multipart.MultipartContext; -import org.synchronoss.cloud.nio.multipart.MultipartUtils; -import org.synchronoss.cloud.nio.multipart.NioMultipartParser; -import org.synchronoss.cloud.nio.multipart.NioMultipartParserListener; -import org.synchronoss.cloud.nio.multipart.PartBodyStreamStorageFactory; -import org.synchronoss.cloud.nio.stream.storage.StreamStorage; -import reactor.core.publisher.BaseSubscriber; -import reactor.core.publisher.Flux; -import reactor.core.publisher.FluxSink; -import reactor.core.publisher.Mono; -import reactor.core.publisher.SignalType; -import reactor.core.scheduler.Schedulers; - -import org.springframework.core.ResolvableType; -import org.springframework.core.codec.DecodingException; -import org.springframework.core.codec.Hints; -import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.core.io.buffer.DataBufferLimitException; -import org.springframework.core.io.buffer.DataBufferUtils; -import org.springframework.core.io.buffer.DefaultDataBufferFactory; -import org.springframework.core.log.LogFormatUtils; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ReactiveHttpInputMessage; -import org.springframework.http.codec.HttpMessageReader; -import org.springframework.http.codec.LoggingCodecSupport; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * {@code HttpMessageReader} for parsing {@code "multipart/form-data"} requests - * to a stream of {@link Part}'s using the Synchronoss NIO Multipart library. - * - *

    This reader can be provided to {@link MultipartHttpMessageReader} in order - * to aggregate all parts into a Map. - * - * @author Sebastien Deleuze - * @author Rossen Stoyanchev - * @author Arjen Poutsma - * @author Brian Clozel - * @since 5.0 - * @see Synchronoss NIO Multipart - * @see MultipartHttpMessageReader - */ -public class SynchronossPartHttpMessageReader extends LoggingCodecSupport implements HttpMessageReader { - - private static final String FILE_STORAGE_DIRECTORY_PREFIX = "synchronoss-file-upload-"; - - private int maxInMemorySize = 256 * 1024; - - private long maxDiskUsagePerPart = -1; - - private int maxParts = -1; - - private final AtomicReference fileStorageDirectory = new AtomicReference<>(); - - - /** - * Configure the maximum amount of memory that is allowed to use per part. - * When the limit is exceeded: - *

      - *
    • file parts are written to a temporary file. - *
    • non-file parts are rejected with {@link DataBufferLimitException}. - *
    - *

    By default this is set to 256K. - * @param byteCount the in-memory limit in bytes; if set to -1 this limit is - * not enforced, and all parts may be written to disk and are limited only - * by the {@link #setMaxDiskUsagePerPart(long) maxDiskUsagePerPart} property. - * @since 5.1.11 - */ - public void setMaxInMemorySize(int byteCount) { - this.maxInMemorySize = byteCount; - } - - /** - * Get the {@link #setMaxInMemorySize configured} maximum in-memory size. - * @since 5.1.11 - */ - public int getMaxInMemorySize() { - return this.maxInMemorySize; - } - - /** - * Configure the maximum amount of disk space allowed for file parts. - *

    By default this is set to -1. - * @param maxDiskUsagePerPart the disk limit in bytes, or -1 for unlimited - * @since 5.1.11 - */ - public void setMaxDiskUsagePerPart(long maxDiskUsagePerPart) { - this.maxDiskUsagePerPart = maxDiskUsagePerPart; - } - - /** - * Get the {@link #setMaxDiskUsagePerPart configured} maximum disk usage. - * @since 5.1.11 - */ - public long getMaxDiskUsagePerPart() { - return this.maxDiskUsagePerPart; - } - - /** - * Specify the maximum number of parts allowed in a given multipart request. - * @since 5.1.11 - */ - public void setMaxParts(int maxParts) { - this.maxParts = maxParts; - } - - /** - * Return the {@link #setMaxParts configured} limit on the number of parts. - * @since 5.1.11 - */ - public int getMaxParts() { - return this.maxParts; - } - - /** - * Set the directory used to store parts larger than - * {@link #setMaxInMemorySize(int) maxInMemorySize}. By default, a new - * temporary directory is created. - * @throws IOException if an I/O error occurs, or the parent directory - * does not exist - * @since 5.3.7 - */ - public void setFileStorageDirectory(Path fileStorageDirectory) throws IOException { - Assert.notNull(fileStorageDirectory, "FileStorageDirectory must not be null"); - if (!Files.exists(fileStorageDirectory)) { - Files.createDirectory(fileStorageDirectory); - } - this.fileStorageDirectory.set(fileStorageDirectory); - } - - - @Override - public List getReadableMediaTypes() { - return MultipartHttpMessageReader.MIME_TYPES; - } - - @Override - public boolean canRead(ResolvableType elementType, @Nullable MediaType mediaType) { - if (Part.class.equals(elementType.toClass())) { - if (mediaType == null) { - return true; - } - for (MediaType supportedMediaType : getReadableMediaTypes()) { - if (supportedMediaType.isCompatibleWith(mediaType)) { - return true; - } - } - } - return false; - } - - @Override - public Flux read(ResolvableType elementType, ReactiveHttpInputMessage message, Map hints) { - return getFileStorageDirectory().flatMapMany(directory -> - Flux.create(new SynchronossPartGenerator(message, directory)) - .doOnNext(part -> { - if (!Hints.isLoggingSuppressed(hints)) { - LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " + - (isEnableLoggingRequestDetails() ? - LogFormatUtils.formatValue(part, !traceOn) : - "parts '" + part.name() + "' (content masked)")); - } - })); - } - - @Override - public Mono readMono(ResolvableType elementType, ReactiveHttpInputMessage message, Map hints) { - return Mono.error(new UnsupportedOperationException("Cannot read multipart request body into single Part")); - } - - private Mono getFileStorageDirectory() { - return Mono.defer(() -> { - Path directory = this.fileStorageDirectory.get(); - if (directory != null) { - return Mono.just(directory); - } - else { - return Mono.fromCallable(() -> { - Path tempDirectory = Files.createTempDirectory(FILE_STORAGE_DIRECTORY_PREFIX); - if (this.fileStorageDirectory.compareAndSet(null, tempDirectory)) { - return tempDirectory; - } - else { - try { - Files.delete(tempDirectory); - } - catch (IOException ignored) { - } - return this.fileStorageDirectory.get(); - } - }).subscribeOn(Schedulers.boundedElastic()); - } - }); - } - - - /** - * Subscribe to the input stream and feed the Synchronoss parser. Then listen - * for parser output, creating parts, and pushing them into the FluxSink. - */ - private class SynchronossPartGenerator extends BaseSubscriber implements Consumer> { - - private final ReactiveHttpInputMessage inputMessage; - - private final LimitedPartBodyStreamStorageFactory storageFactory = new LimitedPartBodyStreamStorageFactory(); - - private final Path fileStorageDirectory; - - @Nullable - private NioMultipartParserListener listener; - - @Nullable - private NioMultipartParser parser; - - public SynchronossPartGenerator(ReactiveHttpInputMessage inputMessage, Path fileStorageDirectory) { - this.inputMessage = inputMessage; - this.fileStorageDirectory = fileStorageDirectory; - } - - @Override - public void accept(FluxSink sink) { - HttpHeaders headers = this.inputMessage.getHeaders(); - MediaType mediaType = headers.getContentType(); - Assert.state(mediaType != null, "No content type set"); - - int length = getContentLength(headers); - Charset charset = Optional.ofNullable(mediaType.getCharset()).orElse(StandardCharsets.UTF_8); - MultipartContext context = new MultipartContext(mediaType.toString(), length, charset.name()); - - this.listener = new FluxSinkAdapterListener(sink, context, this.storageFactory); - - this.parser = Multipart - .multipart(context) - .saveTemporaryFilesTo(this.fileStorageDirectory.toString()) - .usePartBodyStreamStorageFactory(this.storageFactory) - .forNIO(this.listener); - - this.inputMessage.getBody().subscribe(this); - } - - @Override - protected void hookOnNext(DataBuffer buffer) { - Assert.state(this.parser != null && this.listener != null, "Not initialized yet"); - - int size = buffer.readableByteCount(); - this.storageFactory.increaseByteCount(size); - byte[] resultBytes = new byte[size]; - buffer.read(resultBytes); - - try { - this.parser.write(resultBytes); - } - catch (IOException ex) { - cancel(); - int index = this.storageFactory.getCurrentPartIndex(); - this.listener.onError("Parser error for part [" + index + "]", ex); - } - finally { - DataBufferUtils.release(buffer); - } - } - - @Override - protected void hookOnError(Throwable ex) { - if (this.listener != null) { - int index = this.storageFactory.getCurrentPartIndex(); - this.listener.onError("Failure while parsing part[" + index + "]", ex); - } - } - - @Override - protected void hookOnComplete() { - if (this.listener != null) { - this.listener.onAllPartsFinished(); - } - } - - @Override - protected void hookFinally(SignalType type) { - try { - if (this.parser != null) { - this.parser.close(); - } - } - catch (IOException ex) { - // ignore - } - } - - private int getContentLength(HttpHeaders headers) { - // Until this is fixed https://github.com/synchronoss/nio-multipart/issues/10 - long length = headers.getContentLength(); - return (int) length == length ? (int) length : -1; - } - } - - - private class LimitedPartBodyStreamStorageFactory implements PartBodyStreamStorageFactory { - - private final PartBodyStreamStorageFactory storageFactory = (maxInMemorySize > 0 ? - new DefaultPartBodyStreamStorageFactory(maxInMemorySize) : - new DefaultPartBodyStreamStorageFactory()); - - private int index = 1; - - private boolean isFilePart; - - private long partSize; - - public int getCurrentPartIndex() { - return this.index; - } - - @Override - public StreamStorage newStreamStorageForPartBody(Map> headers, int index) { - this.index = index; - this.isFilePart = (MultipartUtils.getFileName(headers) != null); - this.partSize = 0; - if (maxParts > 0 && index > maxParts) { - throw new DecodingException("Too many parts: Part[" + index + "] but maxParts=" + maxParts); - } - return this.storageFactory.newStreamStorageForPartBody(headers, index); - } - - public void increaseByteCount(long byteCount) { - this.partSize += byteCount; - if (maxInMemorySize > 0 && !this.isFilePart && this.partSize >= maxInMemorySize) { - throw new DataBufferLimitException("Part[" + this.index + "] " + - "exceeded the in-memory limit of " + maxInMemorySize + " bytes"); - } - if (maxDiskUsagePerPart > 0 && this.isFilePart && this.partSize > maxDiskUsagePerPart) { - throw new DecodingException("Part[" + this.index + "] " + - "exceeded the disk usage limit of " + maxDiskUsagePerPart + " bytes"); - } - } - - public void partFinished() { - this.index++; - this.isFilePart = false; - this.partSize = 0; - } - } - - - /** - * Listen for parser output and adapt to {@code Flux>}. - */ - private static class FluxSinkAdapterListener implements NioMultipartParserListener { - - private final FluxSink sink; - - private final MultipartContext context; - - private final LimitedPartBodyStreamStorageFactory storageFactory; - - private final AtomicInteger terminated = new AtomicInteger(); - - FluxSinkAdapterListener( - FluxSink sink, MultipartContext context, LimitedPartBodyStreamStorageFactory factory) { - - this.sink = sink; - this.context = context; - this.storageFactory = factory; - } - - @Override - public void onPartFinished(StreamStorage storage, Map> headers) { - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.putAll(headers); - this.storageFactory.partFinished(); - this.sink.next(createPart(storage, httpHeaders)); - } - - private Part createPart(StreamStorage storage, HttpHeaders httpHeaders) { - String filename = MultipartUtils.getFileName(httpHeaders); - if (filename != null) { - return new SynchronossFilePart(httpHeaders, filename, storage); - } - else if (MultipartUtils.isFormField(httpHeaders, this.context)) { - String value = MultipartUtils.readFormParameterValue(storage, httpHeaders); - return new SynchronossFormFieldPart(httpHeaders, value); - } - else { - return new SynchronossPart(httpHeaders, storage); - } - } - - @Override - public void onError(String message, Throwable cause) { - if (this.terminated.getAndIncrement() == 0) { - this.sink.error(new DecodingException(message, cause)); - } - } - - @Override - public void onAllPartsFinished() { - if (this.terminated.getAndIncrement() == 0) { - this.sink.complete(); - } - } - - @Override - public void onNestedPartStarted(Map> headersFromParentPart) { - } - - @Override - public void onNestedPartFinished() { - } - } - - - private abstract static class AbstractSynchronossPart implements Part { - - private final String name; - - private final HttpHeaders headers; - - AbstractSynchronossPart(HttpHeaders headers) { - Assert.notNull(headers, "HttpHeaders is required"); - this.name = MultipartUtils.getFieldName(headers); - this.headers = headers; - } - - @Override - public String name() { - return this.name; - } - - @Override - public HttpHeaders headers() { - return this.headers; - } - - @Override - public String toString() { - return "Part '" + this.name + "', headers=" + this.headers; - } - } - - - private static class SynchronossPart extends AbstractSynchronossPart { - - private final StreamStorage storage; - - SynchronossPart(HttpHeaders headers, StreamStorage storage) { - super(headers); - Assert.notNull(storage, "StreamStorage is required"); - this.storage = storage; - } - - @Override - @SuppressWarnings("resource") - public Flux content() { - return DataBufferUtils.readInputStream( - getStorage()::getInputStream, DefaultDataBufferFactory.sharedInstance, 4096); - } - - protected StreamStorage getStorage() { - return this.storage; - } - } - - - private static class SynchronossFilePart extends SynchronossPart implements FilePart { - - private static final OpenOption[] FILE_CHANNEL_OPTIONS = - {StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE}; - - private final String filename; - - SynchronossFilePart(HttpHeaders headers, String filename, StreamStorage storage) { - super(headers, storage); - this.filename = filename; - } - - @Override - public String filename() { - return this.filename; - } - - @Override - public Mono transferTo(Path dest) { - ReadableByteChannel input = null; - FileChannel output = null; - try { - input = Channels.newChannel(getStorage().getInputStream()); - output = FileChannel.open(dest, FILE_CHANNEL_OPTIONS); - long size = (input instanceof FileChannel ? ((FileChannel) input).size() : Long.MAX_VALUE); - long totalWritten = 0; - while (totalWritten < size) { - long written = output.transferFrom(input, totalWritten, size - totalWritten); - if (written <= 0) { - break; - } - totalWritten += written; - } - } - catch (IOException ex) { - return Mono.error(ex); - } - finally { - if (input != null) { - try { - input.close(); - } - catch (IOException ignored) { - } - } - if (output != null) { - try { - output.close(); - } - catch (IOException ignored) { - } - } - } - return Mono.empty(); - } - - @Override - public String toString() { - return "Part '" + name() + "', filename='" + this.filename + "'"; - } - } - - - private static class SynchronossFormFieldPart extends AbstractSynchronossPart implements FormFieldPart { - - private final String content; - - SynchronossFormFieldPart(HttpHeaders headers, String content) { - super(headers); - this.content = content; - } - - @Override - public String value() { - return this.content; - } - - @Override - public Flux content() { - byte[] bytes = this.content.getBytes(getCharset()); - return Flux.just(DefaultDataBufferFactory.sharedInstance.wrap(bytes)); - } - - private Charset getCharset() { - String name = MultipartUtils.getCharEncoding(headers()); - return (name != null ? Charset.forName(name) : StandardCharsets.UTF_8); - } - - @Override - public String toString() { - return "Part '" + name() + "=" + this.content + "'"; - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java b/spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java index f23b17428d51..02055814b2eb 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java +++ b/spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java @@ -58,7 +58,6 @@ import org.springframework.http.codec.multipart.DefaultPartHttpMessageReader; import org.springframework.http.codec.multipart.MultipartHttpMessageReader; import org.springframework.http.codec.multipart.MultipartHttpMessageWriter; -import org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader; import org.springframework.http.codec.protobuf.ProtobufDecoder; import org.springframework.http.codec.protobuf.ProtobufEncoder; import org.springframework.http.codec.protobuf.ProtobufHttpMessageWriter; @@ -103,7 +102,7 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader); jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader); - jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader); + jaxb2Present = ClassUtils.isPresent("jakarta.xml.bind.Binder", classLoader); protobufPresent = ClassUtils.isPresent("com.google.protobuf.Message", classLoader); synchronossMultipartPresent = ClassUtils.isPresent("org.synchronoss.cloud.nio.multipart.NioMultipartParser", classLoader); nettyByteBufPresent = ClassUtils.isPresent("io.netty.buffer.ByteBuf", classLoader); @@ -417,11 +416,6 @@ else if (codec instanceof EncoderHttpMessageWriter) { if (codec instanceof DefaultPartHttpMessageReader) { ((DefaultPartHttpMessageReader) codec).setMaxInMemorySize(size); } - if (synchronossMultipartPresent) { - if (codec instanceof SynchronossPartHttpMessageReader) { - ((SynchronossPartHttpMessageReader) codec).setMaxInMemorySize(size); - } - } } Boolean enable = this.enableLoggingRequestDetails; @@ -435,11 +429,6 @@ else if (codec instanceof EncoderHttpMessageWriter) { if (codec instanceof DefaultPartHttpMessageReader) { ((DefaultPartHttpMessageReader) codec).setEnableLoggingRequestDetails(enable); } - if (synchronossMultipartPresent) { - if (codec instanceof SynchronossPartHttpMessageReader) { - ((SynchronossPartHttpMessageReader) codec).setEnableLoggingRequestDetails(enable); - } - } if (codec instanceof FormHttpMessageWriter) { ((FormHttpMessageWriter) codec).setEnableLoggingRequestDetails(enable); } diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java index 2221880c49ff..f30d0a5289fa 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,19 +24,19 @@ import java.util.function.Function; import javax.xml.XMLConstants; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.JAXBException; -import javax.xml.bind.UnmarshalException; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchema; -import javax.xml.bind.annotation.XmlType; import javax.xml.namespace.QName; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.XMLEvent; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.UnmarshalException; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlSchema; +import jakarta.xml.bind.annotation.XmlType; import org.reactivestreams.Publisher; import reactor.core.Exceptions; import reactor.core.publisher.Flux; @@ -175,7 +175,6 @@ public Flux decode(Publisher inputStream, ResolvableType ele } @Override - @SuppressWarnings({"rawtypes", "unchecked", "cast"}) // XMLEventReader is Iterator on JDK 9 public Mono decodeToMono(Publisher input, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map hints) { @@ -184,12 +183,11 @@ public Mono decodeToMono(Publisher input, ResolvableType ele } @Override - @SuppressWarnings({"rawtypes", "unchecked", "cast"}) // XMLEventReader is Iterator on JDK 9 public Object decode(DataBuffer dataBuffer, ResolvableType targetType, @Nullable MimeType mimeType, @Nullable Map hints) throws DecodingException { try { - Iterator eventReader = inputFactory.createXMLEventReader(dataBuffer.asInputStream()); + Iterator eventReader = inputFactory.createXMLEventReader(dataBuffer.asInputStream()); List events = new ArrayList<>(); eventReader.forEachRemaining(event -> events.add((XMLEvent) event)); return unmarshal(events, targetType.toClass()); diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java index b29b610bb518..678e6c64ae70 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java @@ -21,12 +21,11 @@ import java.util.Map; import java.util.function.Function; -import javax.xml.bind.JAXBException; -import javax.xml.bind.MarshalException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.MarshalException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -48,8 +47,8 @@ /** * Encode from single value to a byte stream containing XML elements. * - *

    {@link javax.xml.bind.annotation.XmlElements @XmlElements} and - * {@link javax.xml.bind.annotation.XmlElement @XmlElement} can be used + *

    {@link jakarta.xml.bind.annotation.XmlElements @XmlElements} and + * {@link jakarta.xml.bind.annotation.XmlElement @XmlElement} can be used * to specify how collections should be marshalled. * * @author Sebastien Deleuze diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java b/spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java index 49441c498c38..f5eee44d743d 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java @@ -19,10 +19,10 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; import org.springframework.core.codec.CodecException; 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 8458ba1d6512..c113194183e6 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 @@ -29,7 +29,7 @@ import java.util.List; import java.util.Map; -import javax.mail.internet.MimeUtility; +import jakarta.mail.internet.MimeUtility; import org.springframework.core.io.Resource; import org.springframework.http.HttpEntity; @@ -287,7 +287,7 @@ private void applyDefaultCharset() { /** * Set the character set to use when writing multipart data to encode file * names. Encoding is based on the {@code encoded-word} syntax defined in - * RFC 2047 and relies on {@code MimeUtility} from {@code javax.mail}. + * RFC 2047 and relies on {@code MimeUtility} from {@code jakarta.mail}. *

    As of 5.0 by default part headers, including {@code Content-Disposition} * (and its filename parameter) will be encoded based on the setting of * {@link #setCharset(Charset)} or {@code UTF-8} by default. diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/JsonbHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/JsonbHttpMessageConverter.java index bdbc7221cfda..95c826783550 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/JsonbHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/JsonbHttpMessageConverter.java @@ -21,9 +21,9 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import javax.json.bind.Jsonb; -import javax.json.bind.JsonbBuilder; -import javax.json.bind.JsonbConfig; +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; +import jakarta.json.bind.JsonbConfig; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -39,8 +39,8 @@ * * @author Juergen Hoeller * @since 5.0 - * @see javax.json.bind.Jsonb - * @see javax.json.bind.JsonbBuilder + * @see jakarta.json.bind.Jsonb + * @see jakarta.json.bind.JsonbBuilder * @see #setJsonb */ public class JsonbHttpMessageConverter extends AbstractJsonHttpMessageConverter { diff --git a/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java index 78d64e5da471..850f6e88a73a 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java @@ -62,13 +62,13 @@ public class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConv static { ClassLoader classLoader = AllEncompassingFormHttpMessageConverter.class.getClassLoader(); - jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader); + jaxb2Present = ClassUtils.isPresent("jakarta.xml.bind.Binder", classLoader); jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader); jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader); jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader); gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader); - jsonbPresent = ClassUtils.isPresent("javax.json.bind.Jsonb", classLoader); + jsonbPresent = ClassUtils.isPresent("jakarta.json.bind.Jsonb", classLoader); kotlinSerializationJsonPresent = ClassUtils.isPresent("kotlinx.serialization.json.Json", classLoader); } diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java index 811536c31657..11890fa419bb 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java @@ -19,10 +19,10 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; import org.springframework.http.converter.HttpMessageConversionException; diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java index ab3850c42bf7..c2e3bfdc10ad 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java @@ -26,17 +26,18 @@ import java.util.SortedSet; import java.util.TreeSet; -import javax.xml.bind.JAXBException; -import javax.xml.bind.UnmarshalException; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.transform.Result; import javax.xml.transform.Source; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.UnmarshalException; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; + import org.springframework.http.HttpHeaders; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java index ae4dbd9b6999..c41fb18b8545 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,20 +18,20 @@ import java.io.StringReader; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.JAXBException; -import javax.xml.bind.MarshalException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.PropertyException; -import javax.xml.bind.UnmarshalException; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.MarshalException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.PropertyException; +import jakarta.xml.bind.UnmarshalException; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -149,7 +149,7 @@ protected Object readFromSource(Class clazz, HttpHeaders headers, Source sour } } - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") protected Source processSource(Source source) { if (source instanceof StreamSource) { StreamSource streamSource = (StreamSource) source; diff --git a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java index 866b2422456f..0a0d1b4fa39a 100644 --- a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java +++ b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java @@ -19,11 +19,11 @@ import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.AsyncContext; +import jakarta.servlet.AsyncEvent; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java index b136e3fbcf2f..f7b3e9e99f0d 100644 --- a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java @@ -35,7 +35,7 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -234,7 +234,7 @@ private static boolean isFormPost(HttpServletRequest request) { } /** - * Use {@link javax.servlet.ServletRequest#getParameterMap()} to reconstruct the + * Use {@link jakarta.servlet.ServletRequest#getParameterMap()} to reconstruct the * body of a form 'POST' providing a predictable outcome as opposed to reading * from the body, which can fail if any other code has used the ServletRequest * to access a parameter, thus causing the input stream to be "consumed". diff --git a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpResponse.java index 64436ffb1d85..1822b10f2be2 100644 --- a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpResponse.java @@ -23,7 +23,7 @@ import java.util.Collections; import java.util.List; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHeadersAdapter.java index 357662872860..b8d73163cea6 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHeadersAdapter.java @@ -39,6 +39,7 @@ *

    There is a duplicate of this class in the client package! * * @author Brian Clozel + * @author Juergen Hoeller * @since 5.1.1 */ class JettyHeadersAdapter implements MultiValueMap { @@ -58,7 +59,10 @@ public String getFirst(String key) { @Override public void add(String key, @Nullable String value) { - this.headers.add(key, value); + if (!(this.headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } + ((HttpFields.Mutable) this.headers).add(key, value); } @Override @@ -73,7 +77,10 @@ public void addAll(MultiValueMap values) { @Override public void set(String key, @Nullable String value) { - this.headers.put(key, value); + if (!(this.headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } + ((HttpFields.Mutable) this.headers).put(key, value); } @Override @@ -105,7 +112,7 @@ public boolean isEmpty() { @Override public boolean containsKey(Object key) { - return (key instanceof String && this.headers.containsKey((String) key)); + return (key instanceof String && this.headers.contains((String) key)); } @Override @@ -126,17 +133,23 @@ public List get(Object key) { @Nullable @Override public List put(String key, List value) { + if (!(this.headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } List oldValues = get(key); - this.headers.put(key, value); + ((HttpFields.Mutable) this.headers).put(key, value); return oldValues; } @Nullable @Override public List remove(Object key) { + if (!(this.headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } if (key instanceof String) { List oldValues = get(key); - this.headers.remove((String) key); + ((HttpFields.Mutable) this.headers).remove((String) key); return oldValues; } return null; @@ -149,7 +162,10 @@ public void putAll(Map> map) { @Override public void clear() { - this.headers.clear(); + if (!(this.headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } + ((HttpFields.Mutable) this.headers).clear(); } @Override @@ -221,8 +237,11 @@ public List getValue() { @Override public List setValue(List value) { + if (!(headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } List previousValues = headers.getValuesList(this.key); - headers.put(this.key, value); + ((HttpFields.Mutable) headers).put(this.key, value); return previousValues; } } @@ -266,13 +285,16 @@ public String next() { @Override public void remove() { + if (!(headers instanceof HttpFields.Mutable)) { + throw new IllegalStateException("Immutable headers"); + } if (this.currentName == null) { throw new IllegalStateException("No current Header in iterator"); } - if (!headers.containsKey(this.currentName)) { + if (!headers.contains(this.currentName)) { throw new IllegalStateException("Header not present: " + this.currentName); } - headers.remove(this.currentName); + ((HttpFields.Mutable) headers).remove(this.currentName); } } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java index 89a315068359..8f5f23be086a 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java @@ -21,13 +21,12 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; -import javax.servlet.AsyncContext; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - +import jakarta.servlet.AsyncContext; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.server.HttpOutput; import org.eclipse.jetty.server.Request; @@ -38,7 +37,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; import org.springframework.util.MultiValueMap; /** @@ -52,10 +50,6 @@ */ public class JettyHttpHandlerAdapter extends ServletHttpHandlerAdapter { - private static final boolean jetty10Present = ClassUtils.isPresent( - "org.eclipse.jetty.http.CookieCutter", JettyHttpHandlerAdapter.class.getClassLoader()); - - public JettyHttpHandlerAdapter(HttpHandler httpHandler) { super(httpHandler); } @@ -65,11 +59,6 @@ public JettyHttpHandlerAdapter(HttpHandler httpHandler) { protected ServletServerHttpRequest createRequest(HttpServletRequest request, AsyncContext context) throws IOException, URISyntaxException { - // TODO: need to compile against Jetty 10 to use HttpFields (class->interface) - if (jetty10Present) { - return super.createRequest(request, context); - } - Assert.notNull(getServletPath(), "Servlet path is not initialized"); return new JettyServerHttpRequest( request, context, getServletPath(), getDataBufferFactory(), getBufferSize()); @@ -79,15 +68,8 @@ protected ServletServerHttpRequest createRequest(HttpServletRequest request, Asy protected ServletServerHttpResponse createResponse(HttpServletResponse response, AsyncContext context, ServletServerHttpRequest request) throws IOException { - // TODO: need to compile against Jetty 10 to use HttpFields (class->interface) - if (jetty10Present) { - return new BaseJettyServerHttpResponse( - response, context, getDataBufferFactory(), getBufferSize(), request); - } - else { - return new JettyServerHttpResponse( - response, context, getDataBufferFactory(), getBufferSize(), request); - } + return new JettyServerHttpResponse( + response, context, getDataBufferFactory(), getBufferSize(), request); } @@ -120,39 +102,10 @@ else if (request instanceof HttpServletRequestWrapper) { "] to org.eclipse.jetty.server.Request"); } } - - - } - - - private static class BaseJettyServerHttpResponse extends ServletServerHttpResponse { - - BaseJettyServerHttpResponse(HttpServletResponse response, AsyncContext asyncContext, - DataBufferFactory bufferFactory, int bufferSize, ServletServerHttpRequest request) - throws IOException { - - super(response, asyncContext, bufferFactory, bufferSize, request); - } - - BaseJettyServerHttpResponse(HttpHeaders headers, HttpServletResponse response, AsyncContext asyncContext, - DataBufferFactory bufferFactory, int bufferSize, ServletServerHttpRequest request) - throws IOException { - - super(headers, response, asyncContext, bufferFactory, bufferSize, request); - } - - @Override - protected int writeToOutputStream(DataBuffer dataBuffer) throws IOException { - ByteBuffer input = dataBuffer.asByteBuffer(); - int len = input.remaining(); - ServletResponse response = getNativeResponse(); - ((HttpOutput) response.getOutputStream()).write(input); - return len; - } } - private static final class JettyServerHttpResponse extends BaseJettyServerHttpResponse { + private static final class JettyServerHttpResponse extends ServletServerHttpResponse { JettyServerHttpResponse(HttpServletResponse response, AsyncContext asyncContext, DataBufferFactory bufferFactory, int bufferSize, ServletServerHttpRequest request) @@ -182,6 +135,15 @@ else if (response instanceof HttpServletResponseWrapper) { } } + @Override + protected int writeToOutputStream(DataBuffer dataBuffer) throws IOException { + ByteBuffer input = dataBuffer.asByteBuffer(); + int len = input.remaining(); + ServletResponse response = getNativeResponse(); + ((HttpOutput) response.getOutputStream()).write(input); + return len; + } + @Override protected void applyHeaders() { HttpServletResponse response = getNativeResponse(); diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java index c38837c7ed03..0fe306911e78 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java @@ -21,20 +21,19 @@ import java.util.Collection; import java.util.concurrent.atomic.AtomicBoolean; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; -import javax.servlet.DispatcherType; -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.AsyncContext; +import jakarta.servlet.AsyncEvent; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRegistration; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java index a84ddc6d6e3d..93be805e7ff7 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java @@ -26,14 +26,13 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.AsyncContext; +import jakarta.servlet.AsyncEvent; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import reactor.core.publisher.Flux; @@ -203,12 +202,12 @@ protected SslInfo initSslInfo() { @Nullable private String getSslSessionId() { - return (String) this.request.getAttribute("javax.servlet.request.ssl_session_id"); + return (String) this.request.getAttribute("jakarta.servlet.request.ssl_session_id"); } @Nullable private X509Certificate[] getX509Certificates() { - String name = "javax.servlet.request.X509Certificate"; + String name = "jakarta.servlet.request.X509Certificate"; return (X509Certificate[]) this.request.getAttribute(name); } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java index ab7dd93c8d39..949be403dd4e 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java @@ -21,13 +21,12 @@ import java.nio.charset.Charset; import java.util.List; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; -import javax.servlet.ServletOutputStream; -import javax.servlet.WriteListener; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.AsyncContext; +import jakarta.servlet.AsyncEvent; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.WriteListener; +import jakarta.servlet.http.HttpServletResponse; import org.reactivestreams.Processor; import org.reactivestreams.Publisher; diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java index 7920c7ffd8b4..f9a8e7277c5c 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java @@ -22,15 +22,14 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; -import javax.servlet.AsyncContext; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - +import jakarta.servlet.AsyncContext; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.apache.catalina.connector.CoyoteInputStream; import org.apache.catalina.connector.CoyoteOutputStream; import org.apache.catalina.connector.RequestFacade; diff --git a/spring-web/src/main/java/org/springframework/web/HttpMediaTypeException.java b/spring-web/src/main/java/org/springframework/web/HttpMediaTypeException.java index 91c572147f8f..0cd03ddb2042 100644 --- a/spring-web/src/main/java/org/springframework/web/HttpMediaTypeException.java +++ b/spring-web/src/main/java/org/springframework/web/HttpMediaTypeException.java @@ -19,7 +19,7 @@ import java.util.Collections; import java.util.List; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; import org.springframework.http.MediaType; diff --git a/spring-web/src/main/java/org/springframework/web/HttpRequestHandler.java b/spring-web/src/main/java/org/springframework/web/HttpRequestHandler.java index 187d9dd8c544..542e60809448 100644 --- a/spring-web/src/main/java/org/springframework/web/HttpRequestHandler.java +++ b/spring-web/src/main/java/org/springframework/web/HttpRequestHandler.java @@ -18,15 +18,15 @@ import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; /** * Plain handler interface for components that process HTTP requests, - * analogous to a Servlet. Only declares {@link javax.servlet.ServletException} + * analogous to a Servlet. Only declares {@link jakarta.servlet.ServletException} * and {@link java.io.IOException}, to allow for usage within any - * {@link javax.servlet.http.HttpServlet}. This interface is essentially the + * {@link jakarta.servlet.http.HttpServlet}. This interface is essentially the * direct equivalent of an HttpServlet, reduced to a central handle method. * *

    The easiest way to expose an HttpRequestHandler bean in Spring style diff --git a/spring-web/src/main/java/org/springframework/web/HttpRequestMethodNotSupportedException.java b/spring-web/src/main/java/org/springframework/web/HttpRequestMethodNotSupportedException.java index 0e61da306db7..4e1168d84deb 100644 --- a/spring-web/src/main/java/org/springframework/web/HttpRequestMethodNotSupportedException.java +++ b/spring-web/src/main/java/org/springframework/web/HttpRequestMethodNotSupportedException.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.Set; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; import org.springframework.http.HttpMethod; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/HttpSessionRequiredException.java b/spring-web/src/main/java/org/springframework/web/HttpSessionRequiredException.java index 83a00b0de5a8..eaffd9d96b76 100644 --- a/spring-web/src/main/java/org/springframework/web/HttpSessionRequiredException.java +++ b/spring-web/src/main/java/org/springframework/web/HttpSessionRequiredException.java @@ -16,7 +16,7 @@ package org.springframework.web; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/SpringServletContainerInitializer.java b/spring-web/src/main/java/org/springframework/web/SpringServletContainerInitializer.java index da3cd91c3d8c..9b50031d97a0 100644 --- a/spring-web/src/main/java/org/springframework/web/SpringServletContainerInitializer.java +++ b/spring-web/src/main/java/org/springframework/web/SpringServletContainerInitializer.java @@ -23,10 +23,10 @@ import java.util.ServiceLoader; import java.util.Set; -import javax.servlet.ServletContainerInitializer; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.annotation.HandlesTypes; +import jakarta.servlet.ServletContainerInitializer; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.HandlesTypes; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.lang.Nullable; @@ -43,7 +43,7 @@ * method invoked by any Servlet 3.0-compliant container during container startup assuming * that the {@code spring-web} module JAR is present on the classpath. This occurs through * the JAR Services API {@link ServiceLoader#load(Class)} method detecting the - * {@code spring-web} module's {@code META-INF/services/javax.servlet.ServletContainerInitializer} + * {@code spring-web} module's {@code META-INF/services/jakarta.servlet.ServletContainerInitializer} * service provider configuration file. See the * * JAR Services API documentation as well as section 8.2.4 of the Servlet 3.0 diff --git a/spring-web/src/main/java/org/springframework/web/WebApplicationInitializer.java b/spring-web/src/main/java/org/springframework/web/WebApplicationInitializer.java index 337f53291e7a..ef326acbe8dd 100644 --- a/spring-web/src/main/java/org/springframework/web/WebApplicationInitializer.java +++ b/spring-web/src/main/java/org/springframework/web/WebApplicationInitializer.java @@ -16,8 +16,8 @@ package org.springframework.web; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; /** * Interface to be implemented in Servlet 3.0+ environments in order to configure the diff --git a/spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java index 5413a34a5a0d..37385a7fd6e6 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java +++ b/spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java @@ -42,7 +42,7 @@ * *

    The method {@link #handleNoMatch} allow sub-classes to plug in additional * ways of looking up media types (e.g. through the Java Activation framework, - * or {@link javax.servlet.ServletContext#getMimeType}. Media types resolved + * or {@link jakarta.servlet.ServletContext#getMimeType}. Media types resolved * via base classes are then added to the base class * {@link MappingMediaTypeFileExtensionResolver}, i.e. cached for new lookups. * diff --git a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java index c23db8e97c9c..a7c2358dd5e9 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.Properties; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; diff --git a/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java index 3fc337b377b6..66a0354c1e50 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java +++ b/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java @@ -19,7 +19,7 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.Resource; import org.springframework.http.MediaType; diff --git a/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java index f2a549589665..485727d718db 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java +++ b/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java @@ -18,7 +18,7 @@ import java.util.Map; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.core.io.Resource; import org.springframework.http.MediaType; diff --git a/spring-web/src/main/java/org/springframework/web/bind/ServletRequestDataBinder.java b/spring-web/src/main/java/org/springframework/web/bind/ServletRequestDataBinder.java index 16bf30ee01fc..db74e0020d3b 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/ServletRequestDataBinder.java +++ b/spring-web/src/main/java/org/springframework/web/bind/ServletRequestDataBinder.java @@ -16,8 +16,8 @@ package org.springframework.web.bind; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.MutablePropertyValues; import org.springframework.http.HttpMethod; @@ -56,7 +56,7 @@ * * @author Rod Johnson * @author Juergen Hoeller - * @see #bind(javax.servlet.ServletRequest) + * @see #bind(jakarta.servlet.ServletRequest) * @see #registerCustomEditor * @see #setAllowedFields * @see #setRequiredFields diff --git a/spring-web/src/main/java/org/springframework/web/bind/ServletRequestParameterPropertyValues.java b/spring-web/src/main/java/org/springframework/web/bind/ServletRequestParameterPropertyValues.java index 6d1b17de2c28..f127baee8492 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/ServletRequestParameterPropertyValues.java +++ b/spring-web/src/main/java/org/springframework/web/bind/ServletRequestParameterPropertyValues.java @@ -16,7 +16,7 @@ package org.springframework.web.bind; -import javax.servlet.ServletRequest; +import jakarta.servlet.ServletRequest; import org.springframework.beans.MutablePropertyValues; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/bind/ServletRequestUtils.java b/spring-web/src/main/java/org/springframework/web/bind/ServletRequestUtils.java index 9537758b7930..f02c11fd830d 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/ServletRequestUtils.java +++ b/spring-web/src/main/java/org/springframework/web/bind/ServletRequestUtils.java @@ -16,7 +16,7 @@ package org.springframework.web.bind; -import javax.servlet.ServletRequest; +import jakarta.servlet.ServletRequest; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/bind/UnsatisfiedServletRequestParameterException.java b/spring-web/src/main/java/org/springframework/web/bind/UnsatisfiedServletRequestParameterException.java index 65002541148b..feecdeef80fd 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/UnsatisfiedServletRequestParameterException.java +++ b/spring-web/src/main/java/org/springframework/web/bind/UnsatisfiedServletRequestParameterException.java @@ -107,7 +107,7 @@ public final List getParamConditionGroups() { /** * Return the actual parameter Map associated with the ServletRequest. - * @see javax.servlet.ServletRequest#getParameterMap() + * @see jakarta.servlet.ServletRequest#getParameterMap() */ public final Map getActualParams() { return this.actualParams; diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerAdvice.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerAdvice.java index decfce3eb1af..24cca20a9399 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerAdvice.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerAdvice.java @@ -36,7 +36,7 @@ * as Spring beans or auto-detected via classpath scanning. All such beans are * sorted based on {@link org.springframework.core.Ordered Ordered} semantics or * {@link org.springframework.core.annotation.Order @Order} / - * {@link javax.annotation.Priority @Priority} declarations, with {@code Ordered} + * {@link jakarta.annotation.Priority @Priority} declarations, with {@code Ordered} * semantics taking precedence over {@code @Order} / {@code @Priority} declarations. * {@code @ControllerAdvice} beans are then applied in that order at runtime. * Note, however, that {@code @ControllerAdvice} beans that implement diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/CookieValue.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/CookieValue.java index 33e23a166a4e..9e8f3dae56e9 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/CookieValue.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/CookieValue.java @@ -27,12 +27,12 @@ /** * Annotation to indicate that a method parameter is bound to an HTTP cookie. * - *

    The method parameter may be declared as type {@link javax.servlet.http.Cookie} + *

    The method parameter may be declared as type {@link jakarta.servlet.http.Cookie} * or as cookie value type (String, int, etc.). * *

    Note that with spring-webmvc 5.3.x and earlier, the cookie value is URL * decoded. This will be changed in 6.0 but in the meantime, applications can - * also declare parameters of type {@link javax.servlet.http.Cookie} to access + * also declare parameters of type {@link jakarta.servlet.http.Cookie} to access * the raw value. * * @author Juergen Hoeller diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/ExceptionHandler.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/ExceptionHandler.java index 3f48fa431185..bf66c33ed053 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/ExceptionHandler.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/ExceptionHandler.java @@ -38,8 +38,8 @@ * exposed, whereas previously only an immediate cause was considered. *

  • Request and/or response objects (typically from the Servlet API). * You may choose any specific request/response type, e.g. - * {@link javax.servlet.ServletRequest} / {@link javax.servlet.http.HttpServletRequest}. - *
  • Session object: typically {@link javax.servlet.http.HttpSession}. + * {@link jakarta.servlet.ServletRequest} / {@link jakarta.servlet.http.HttpServletRequest}. + *
  • Session object: typically {@link jakarta.servlet.http.HttpSession}. * An argument of this type will enforce the presence of a corresponding session. * As a consequence, such an argument will never be {@code null}. * Note that session access may not be thread-safe, in particular in a @@ -88,7 +88,7 @@ * {@linkplain org.springframework.http.converter.HttpMessageConverter message converters}. *
  • {@code void} if the method handles the response itself (by * writing the response content directly, declaring an argument of type - * {@link javax.servlet.ServletResponse} / {@link javax.servlet.http.HttpServletResponse} + * {@link jakarta.servlet.ServletResponse} / {@link jakarta.servlet.http.HttpServletResponse} * for that purpose) or if the view name is supposed to be implicitly determined * through a {@link org.springframework.web.servlet.RequestToViewNameTranslator} * (not declaring a response argument in the handler method signature). diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java index eb3f0d962e13..6d59dd4aec05 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java @@ -176,7 +176,7 @@ * If specified at both levels, the method level consumes condition overrides * the type level condition. * @see org.springframework.http.MediaType - * @see javax.servlet.http.HttpServletRequest#getContentType() + * @see jakarta.servlet.http.HttpServletRequest#getContentType() */ String[] consumes() default {}; diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestPart.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestPart.java index 0f8b430e54a5..b84f09ffd72f 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestPart.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestPart.java @@ -34,7 +34,7 @@ * with a method argument. * *

    Supported method argument types include {@link MultipartFile} in conjunction with - * Spring's {@link MultipartResolver} abstraction, {@code javax.servlet.http.Part} in + * Spring's {@link MultipartResolver} abstraction, {@code jakarta.servlet.http.Part} in * conjunction with Servlet 3.0 multipart requests, or otherwise for any other method * argument, the content of the part is passed through an {@link HttpMessageConverter} * taking into consideration the 'Content-Type' header of the request part. This is diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/ResponseStatus.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/ResponseStatus.java index 999348c91b7e..f69fef63fc73 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/ResponseStatus.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/ResponseStatus.java @@ -53,7 +53,7 @@ * @author Sam Brannen * @since 3.0 * @see org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - * @see javax.servlet.http.HttpServletResponse#sendError(int, String) + * @see jakarta.servlet.http.HttpServletResponse#sendError(int, String) */ @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @@ -71,8 +71,8 @@ *

    Default is {@link HttpStatus#INTERNAL_SERVER_ERROR}, which should * typically be changed to something more appropriate. * @since 4.2 - * @see javax.servlet.http.HttpServletResponse#setStatus(int) - * @see javax.servlet.http.HttpServletResponse#sendError(int) + * @see jakarta.servlet.http.HttpServletResponse#setStatus(int) + * @see jakarta.servlet.http.HttpServletResponse#sendError(int) */ @AliasFor("value") HttpStatus code() default HttpStatus.INTERNAL_SERVER_ERROR; @@ -81,7 +81,7 @@ * The reason to be used for the response. *

    Defaults to an empty string which will be ignored. Set the reason to a * non-empty value to have it used for the response. - * @see javax.servlet.http.HttpServletResponse#sendError(int, String) + * @see jakarta.servlet.http.HttpServletResponse#sendError(int, String) */ String reason() default ""; diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/SessionAttribute.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/SessionAttribute.java index ca06dd1bdaea..7d6775308ee8 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/SessionAttribute.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/SessionAttribute.java @@ -33,7 +33,7 @@ * *

    For use cases that require adding or removing session attributes consider * injecting {@code org.springframework.web.context.request.WebRequest} or - * {@code javax.servlet.http.HttpSession} into the controller method. + * {@code jakarta.servlet.http.HttpSession} into the controller method. * *

    For temporary storage of model attributes in the session as part of the * workflow for a controller, consider using {@link SessionAttributes} instead. diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/SpringWebConstraintValidatorFactory.java b/spring-web/src/main/java/org/springframework/web/bind/support/SpringWebConstraintValidatorFactory.java index b795b3eb7187..dcbc1a4c7a86 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/support/SpringWebConstraintValidatorFactory.java +++ b/spring-web/src/main/java/org/springframework/web/bind/support/SpringWebConstraintValidatorFactory.java @@ -16,8 +16,8 @@ package org.springframework.web.bind.support; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorFactory; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorFactory; import org.springframework.web.context.ContextLoader; import org.springframework.web.context.WebApplicationContext; diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java b/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java index 76ea4abddab4..23e747a17c88 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java +++ b/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java @@ -16,7 +16,7 @@ package org.springframework.web.bind.support; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.MutablePropertyValues; import org.springframework.http.HttpHeaders; @@ -104,7 +104,7 @@ public WebRequestDataBinder(@Nullable Object target, String objectName) { * @param request the request with parameters to bind (can be multipart) * @see org.springframework.web.multipart.MultipartRequest * @see org.springframework.web.multipart.MultipartFile - * @see javax.servlet.http.Part + * @see jakarta.servlet.http.Part * @see #bind(org.springframework.beans.PropertyValues) */ public void bind(WebRequest request) { diff --git a/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java b/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java index 22662632475f..3d1bcb5b0a71 100644 --- a/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java +++ b/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java @@ -121,14 +121,14 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat static { ClassLoader classLoader = RestTemplate.class.getClassLoader(); romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", classLoader); - jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader); + jaxb2Present = ClassUtils.isPresent("jakarta.xml.bind.Binder", classLoader); jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader); jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader); jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader); jackson2CborPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory", classLoader); gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader); - jsonbPresent = ClassUtils.isPresent("javax.json.bind.Jsonb", classLoader); + jsonbPresent = ClassUtils.isPresent("jakarta.json.bind.Jsonb", classLoader); kotlinSerializationJsonPresent = ClassUtils.isPresent("kotlinx.serialization.json.Json", classLoader); } diff --git a/spring-web/src/main/java/org/springframework/web/context/AbstractContextLoaderInitializer.java b/spring-web/src/main/java/org/springframework/web/context/AbstractContextLoaderInitializer.java index 6cb40688e34e..01fae7c0aeac 100644 --- a/spring-web/src/main/java/org/springframework/web/context/AbstractContextLoaderInitializer.java +++ b/spring-web/src/main/java/org/springframework/web/context/AbstractContextLoaderInitializer.java @@ -16,9 +16,8 @@ package org.springframework.web.context; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-web/src/main/java/org/springframework/web/context/ConfigurableWebApplicationContext.java b/spring-web/src/main/java/org/springframework/web/context/ConfigurableWebApplicationContext.java index c08b195fcdb3..831bad5cf1aa 100644 --- a/spring-web/src/main/java/org/springframework/web/context/ConfigurableWebApplicationContext.java +++ b/spring-web/src/main/java/org/springframework/web/context/ConfigurableWebApplicationContext.java @@ -16,8 +16,8 @@ package org.springframework.web.context; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.lang.Nullable; @@ -47,7 +47,7 @@ public interface ConfigurableWebApplicationContext extends WebApplicationContext /** * Name of the ServletConfig environment bean in the factory. - * @see javax.servlet.ServletConfig + * @see jakarta.servlet.ServletConfig */ String SERVLET_CONFIG_BEAN_NAME = "servletConfig"; diff --git a/spring-web/src/main/java/org/springframework/web/context/ConfigurableWebEnvironment.java b/spring-web/src/main/java/org/springframework/web/context/ConfigurableWebEnvironment.java index 6d92f54530a2..d077036403a7 100644 --- a/spring-web/src/main/java/org/springframework/web/context/ConfigurableWebEnvironment.java +++ b/spring-web/src/main/java/org/springframework/web/context/ConfigurableWebEnvironment.java @@ -16,8 +16,8 @@ package org.springframework.web.context; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/context/ContextCleanupListener.java b/spring-web/src/main/java/org/springframework/web/context/ContextCleanupListener.java index 4225e0aba187..02034d0a19f7 100644 --- a/spring-web/src/main/java/org/springframework/web/context/ContextCleanupListener.java +++ b/spring-web/src/main/java/org/springframework/web/context/ContextCleanupListener.java @@ -18,10 +18,9 @@ import java.util.Enumeration; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java b/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java index dfd4b0196caa..722fb7a17000 100644 --- a/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java +++ b/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java @@ -23,8 +23,7 @@ import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java b/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java index 3c4d40722258..3f57d6764536 100644 --- a/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java +++ b/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java @@ -16,8 +16,8 @@ package org.springframework.web.context; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; /** * Bootstrap listener to start up and shut down Spring's root {@link WebApplicationContext}. @@ -59,7 +59,7 @@ public ContextLoaderListener() { /** * Create a new {@code ContextLoaderListener} with the given application context. This * constructor is useful in Servlet 3.0+ environments where instance-based - * registration of listeners is possible through the {@link javax.servlet.ServletContext#addListener} + * registration of listeners is possible through the {@link jakarta.servlet.ServletContext#addListener} * API. *

    The context may or may not yet be {@linkplain * org.springframework.context.ConfigurableApplicationContext#refresh() refreshed}. If it diff --git a/spring-web/src/main/java/org/springframework/web/context/ServletConfigAware.java b/spring-web/src/main/java/org/springframework/web/context/ServletConfigAware.java index aaa5a9039096..60f399c1c3c5 100644 --- a/spring-web/src/main/java/org/springframework/web/context/ServletConfigAware.java +++ b/spring-web/src/main/java/org/springframework/web/context/ServletConfigAware.java @@ -16,7 +16,7 @@ package org.springframework.web.context; -import javax.servlet.ServletConfig; +import jakarta.servlet.ServletConfig; import org.springframework.beans.factory.Aware; diff --git a/spring-web/src/main/java/org/springframework/web/context/ServletContextAware.java b/spring-web/src/main/java/org/springframework/web/context/ServletContextAware.java index 709cce1c6ace..ebb47e56b5bb 100644 --- a/spring-web/src/main/java/org/springframework/web/context/ServletContextAware.java +++ b/spring-web/src/main/java/org/springframework/web/context/ServletContextAware.java @@ -16,7 +16,7 @@ package org.springframework.web.context; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.beans.factory.Aware; diff --git a/spring-web/src/main/java/org/springframework/web/context/WebApplicationContext.java b/spring-web/src/main/java/org/springframework/web/context/WebApplicationContext.java index b2c15d545c9a..cef050984829 100644 --- a/spring-web/src/main/java/org/springframework/web/context/WebApplicationContext.java +++ b/spring-web/src/main/java/org/springframework/web/context/WebApplicationContext.java @@ -16,7 +16,7 @@ package org.springframework.web.context; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.context.ApplicationContext; import org.springframework.lang.Nullable; @@ -74,7 +74,7 @@ public interface WebApplicationContext extends ApplicationContext { /** * Name of the ServletContext environment bean in the factory. - * @see javax.servlet.ServletContext + * @see jakarta.servlet.ServletContext */ String SERVLET_CONTEXT_BEAN_NAME = "servletContext"; @@ -82,17 +82,17 @@ public interface WebApplicationContext extends ApplicationContext { * Name of the ServletContext init-params environment bean in the factory. *

    Note: Possibly merged with ServletConfig parameters. * ServletConfig parameters override ServletContext parameters of the same name. - * @see javax.servlet.ServletContext#getInitParameterNames() - * @see javax.servlet.ServletContext#getInitParameter(String) - * @see javax.servlet.ServletConfig#getInitParameterNames() - * @see javax.servlet.ServletConfig#getInitParameter(String) + * @see jakarta.servlet.ServletContext#getInitParameterNames() + * @see jakarta.servlet.ServletContext#getInitParameter(String) + * @see jakarta.servlet.ServletConfig#getInitParameterNames() + * @see jakarta.servlet.ServletConfig#getInitParameter(String) */ String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters"; /** * Name of the ServletContext attributes environment bean in the factory. - * @see javax.servlet.ServletContext#getAttributeNames() - * @see javax.servlet.ServletContext#getAttribute(String) + * @see jakarta.servlet.ServletContext#getAttributeNames() + * @see jakarta.servlet.ServletContext#getAttribute(String) */ String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes"; diff --git a/spring-web/src/main/java/org/springframework/web/context/request/DestructionCallbackBindingListener.java b/spring-web/src/main/java/org/springframework/web/context/request/DestructionCallbackBindingListener.java index 69e280bd7d9a..57ef0b4110fd 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/DestructionCallbackBindingListener.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/DestructionCallbackBindingListener.java @@ -18,8 +18,8 @@ import java.io.Serializable; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; +import jakarta.servlet.http.HttpSessionBindingEvent; +import jakarta.servlet.http.HttpSessionBindingListener; /** * Adapter that implements the Servlet HttpSessionBindingListener interface, diff --git a/spring-web/src/main/java/org/springframework/web/context/request/FacesRequestAttributes.java b/spring-web/src/main/java/org/springframework/web/context/request/FacesRequestAttributes.java index 9937a0c076fd..14df22d3b0e1 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/FacesRequestAttributes.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/FacesRequestAttributes.java @@ -19,9 +19,8 @@ import java.lang.reflect.Method; import java.util.Map; -import javax.faces.context.ExternalContext; -import javax.faces.context.FacesContext; - +import jakarta.faces.context.ExternalContext; +import jakarta.faces.context.FacesContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -31,7 +30,7 @@ import org.springframework.web.util.WebUtils; /** - * {@link RequestAttributes} adapter for a JSF {@link javax.faces.context.FacesContext}. + * {@link RequestAttributes} adapter for a JSF {@link jakarta.faces.context.FacesContext}. * Used as default in a JSF environment, wrapping the current FacesContext. * *

    NOTE: In contrast to {@link ServletRequestAttributes}, this variant does @@ -44,9 +43,9 @@ * * @author Juergen Hoeller * @since 2.5.2 - * @see javax.faces.context.FacesContext#getExternalContext() - * @see javax.faces.context.ExternalContext#getRequestMap() - * @see javax.faces.context.ExternalContext#getSessionMap() + * @see jakarta.faces.context.FacesContext#getExternalContext() + * @see jakarta.faces.context.ExternalContext#getRequestMap() + * @see jakarta.faces.context.ExternalContext#getSessionMap() * @see RequestContextHolder#currentRequestAttributes() */ public class FacesRequestAttributes implements RequestAttributes { @@ -62,7 +61,7 @@ public class FacesRequestAttributes implements RequestAttributes { /** * Create a new FacesRequestAttributes adapter for the given FacesContext. * @param facesContext the current FacesContext - * @see javax.faces.context.FacesContext#getCurrentInstance() + * @see jakarta.faces.context.FacesContext#getCurrentInstance() */ public FacesRequestAttributes(FacesContext facesContext) { Assert.notNull(facesContext, "FacesContext must not be null"); @@ -79,7 +78,7 @@ protected final FacesContext getFacesContext() { /** * Return the JSF ExternalContext that this adapter operates on. - * @see javax.faces.context.FacesContext#getExternalContext() + * @see jakarta.faces.context.FacesContext#getExternalContext() */ protected final ExternalContext getExternalContext() { return getFacesContext().getExternalContext(); diff --git a/spring-web/src/main/java/org/springframework/web/context/request/FacesWebRequest.java b/spring-web/src/main/java/org/springframework/web/context/request/FacesWebRequest.java index d3d56213fa8d..733a6e8405e6 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/FacesWebRequest.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/FacesWebRequest.java @@ -21,14 +21,14 @@ import java.util.Locale; import java.util.Map; -import javax.faces.context.ExternalContext; -import javax.faces.context.FacesContext; +import jakarta.faces.context.ExternalContext; +import jakarta.faces.context.FacesContext; import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; /** - * {@link WebRequest} adapter for a JSF {@link javax.faces.context.FacesContext}. + * {@link WebRequest} adapter for a JSF {@link jakarta.faces.context.FacesContext}. * *

    Requires JSF 2.0 or higher, as of Spring 4.0. * @@ -40,7 +40,7 @@ public class FacesWebRequest extends FacesRequestAttributes implements NativeWeb /** * Create a new FacesWebRequest adapter for the given FacesContext. * @param facesContext the current FacesContext - * @see javax.faces.context.FacesContext#getCurrentInstance() + * @see jakarta.faces.context.FacesContext#getCurrentInstance() */ public FacesWebRequest(FacesContext facesContext) { super(facesContext); diff --git a/spring-web/src/main/java/org/springframework/web/context/request/NativeWebRequest.java b/spring-web/src/main/java/org/springframework/web/context/request/NativeWebRequest.java index cf2e3247fb74..8d90775760a0 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/NativeWebRequest.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/NativeWebRequest.java @@ -32,13 +32,13 @@ public interface NativeWebRequest extends WebRequest { /** * Return the underlying native request object. - * @see javax.servlet.http.HttpServletRequest + * @see jakarta.servlet.http.HttpServletRequest */ Object getNativeRequest(); /** * Return the underlying native response object, if any. - * @see javax.servlet.http.HttpServletResponse + * @see jakarta.servlet.http.HttpServletResponse */ @Nullable Object getNativeResponse(); @@ -48,7 +48,7 @@ public interface NativeWebRequest extends WebRequest { * @param requiredType the desired type of request object * @return the matching request object, or {@code null} if none * of that type is available - * @see javax.servlet.http.HttpServletRequest + * @see jakarta.servlet.http.HttpServletRequest */ @Nullable T getNativeRequest(@Nullable Class requiredType); @@ -58,7 +58,7 @@ public interface NativeWebRequest extends WebRequest { * @param requiredType the desired type of response object * @return the matching response object, or {@code null} if none * of that type is available - * @see javax.servlet.http.HttpServletResponse + * @see jakarta.servlet.http.HttpServletResponse */ @Nullable T getNativeResponse(@Nullable Class requiredType); diff --git a/spring-web/src/main/java/org/springframework/web/context/request/RequestContextHolder.java b/spring-web/src/main/java/org/springframework/web/context/request/RequestContextHolder.java index a52c9915afcc..ba63120383d8 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/RequestContextHolder.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/RequestContextHolder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ package org.springframework.web.context.request; -import javax.faces.context.FacesContext; +import jakarta.faces.context.FacesContext; import org.springframework.core.NamedInheritableThreadLocal; import org.springframework.core.NamedThreadLocal; @@ -45,7 +45,7 @@ public abstract class RequestContextHolder { private static final boolean jsfPresent = - ClassUtils.isPresent("javax.faces.context.FacesContext", RequestContextHolder.class.getClassLoader()); + ClassUtils.isPresent("jakarta.faces.context.FacesContext", RequestContextHolder.class.getClassLoader()); private static final ThreadLocal requestAttributesHolder = new NamedThreadLocal<>("Request attributes"); @@ -119,7 +119,7 @@ public static RequestAttributes getRequestAttributes() { * @see #setRequestAttributes * @see ServletRequestAttributes * @see FacesRequestAttributes - * @see javax.faces.context.FacesContext#getCurrentInstance() + * @see jakarta.faces.context.FacesContext#getCurrentInstance() */ public static RequestAttributes currentRequestAttributes() throws IllegalStateException { RequestAttributes attributes = getRequestAttributes(); @@ -147,8 +147,14 @@ private static class FacesRequestAttributesFactory { @Nullable public static RequestAttributes getFacesRequestAttributes() { - FacesContext facesContext = FacesContext.getCurrentInstance(); - return (facesContext != null ? new FacesRequestAttributes(facesContext) : null); + try { + FacesContext facesContext = FacesContext.getCurrentInstance(); + return (facesContext != null ? new FacesRequestAttributes(facesContext) : null); + } + catch (NoClassDefFoundError err) { + // typically for com/sun/faces/util/Util if only the JSF API jar is present + return null; + } } } diff --git a/spring-web/src/main/java/org/springframework/web/context/request/RequestContextListener.java b/spring-web/src/main/java/org/springframework/web/context/request/RequestContextListener.java index ef42dba98eee..d6d1e3c3e801 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/RequestContextListener.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/RequestContextListener.java @@ -16,9 +16,9 @@ package org.springframework.web.context.request; -import javax.servlet.ServletRequestEvent; -import javax.servlet.ServletRequestListener; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.ServletRequestEvent; +import jakarta.servlet.ServletRequestListener; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.context.i18n.LocaleContextHolder; @@ -37,7 +37,7 @@ * * @author Juergen Hoeller * @since 2.0 - * @see javax.servlet.ServletRequestListener + * @see jakarta.servlet.ServletRequestListener * @see org.springframework.context.i18n.LocaleContextHolder * @see RequestContextHolder * @see org.springframework.web.filter.RequestContextFilter diff --git a/spring-web/src/main/java/org/springframework/web/context/request/ServletRequestAttributes.java b/spring-web/src/main/java/org/springframework/web/context/request/ServletRequestAttributes.java index 88a46f8d84fb..a767b0b98f52 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/ServletRequestAttributes.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/ServletRequestAttributes.java @@ -21,9 +21,9 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -39,8 +39,8 @@ * * @author Juergen Hoeller * @since 2.0 - * @see javax.servlet.ServletRequest#getAttribute - * @see javax.servlet.http.HttpSession#getAttribute + * @see jakarta.servlet.ServletRequest#getAttribute + * @see jakarta.servlet.http.HttpSession#getAttribute */ public class ServletRequestAttributes extends AbstractRequestAttributes { diff --git a/spring-web/src/main/java/org/springframework/web/context/request/ServletWebRequest.java b/spring-web/src/main/java/org/springframework/web/context/request/ServletWebRequest.java index 5fef231f283b..1b2917cf5ae0 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/ServletWebRequest.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/ServletWebRequest.java @@ -29,9 +29,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -43,7 +43,7 @@ import org.springframework.web.util.WebUtils; /** - * {@link WebRequest} adapter for an {@link javax.servlet.http.HttpServletRequest}. + * {@link WebRequest} adapter for an {@link jakarta.servlet.http.HttpServletRequest}. * * @author Juergen Hoeller * @author Brian Clozel diff --git a/spring-web/src/main/java/org/springframework/web/context/request/WebRequest.java b/spring-web/src/main/java/org/springframework/web/context/request/WebRequest.java index 6985a3e564bf..fe8cdf480531 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/WebRequest.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/WebRequest.java @@ -39,7 +39,7 @@ public interface WebRequest extends RequestAttributes { * Return the request header of the given name, or {@code null} if none. *

    Retrieves the first header value in case of a multi-value header. * @since 3.0 - * @see javax.servlet.http.HttpServletRequest#getHeader(String) + * @see jakarta.servlet.http.HttpServletRequest#getHeader(String) */ @Nullable String getHeader(String headerName); @@ -49,7 +49,7 @@ public interface WebRequest extends RequestAttributes { * or {@code null} if none. *

    A single-value header will be exposed as an array with a single element. * @since 3.0 - * @see javax.servlet.http.HttpServletRequest#getHeaders(String) + * @see jakarta.servlet.http.HttpServletRequest#getHeaders(String) */ @Nullable String[] getHeaderValues(String headerName); @@ -57,14 +57,14 @@ public interface WebRequest extends RequestAttributes { /** * Return a Iterator over request header names. * @since 3.0 - * @see javax.servlet.http.HttpServletRequest#getHeaderNames() + * @see jakarta.servlet.http.HttpServletRequest#getHeaderNames() */ Iterator getHeaderNames(); /** * Return the request parameter of the given name, or {@code null} if none. *

    Retrieves the first parameter value in case of a multi-value parameter. - * @see javax.servlet.http.HttpServletRequest#getParameter(String) + * @see jakarta.servlet.http.HttpServletRequest#getParameter(String) */ @Nullable String getParameter(String paramName); @@ -73,7 +73,7 @@ public interface WebRequest extends RequestAttributes { * Return the request parameter values for the given parameter name, * or {@code null} if none. *

    A single-value parameter will be exposed as an array with a single element. - * @see javax.servlet.http.HttpServletRequest#getParameterValues(String) + * @see jakarta.servlet.http.HttpServletRequest#getParameterValues(String) */ @Nullable String[] getParameterValues(String paramName); @@ -81,7 +81,7 @@ public interface WebRequest extends RequestAttributes { /** * Return a Iterator over request parameter names. * @since 3.0 - * @see javax.servlet.http.HttpServletRequest#getParameterNames() + * @see jakarta.servlet.http.HttpServletRequest#getParameterNames() */ Iterator getParameterNames(); @@ -89,47 +89,47 @@ public interface WebRequest extends RequestAttributes { * Return a immutable Map of the request parameters, with parameter names as map keys * and parameter values as map values. The map values will be of type String array. *

    A single-value parameter will be exposed as an array with a single element. - * @see javax.servlet.http.HttpServletRequest#getParameterMap() + * @see jakarta.servlet.http.HttpServletRequest#getParameterMap() */ Map getParameterMap(); /** * Return the primary Locale for this request. - * @see javax.servlet.http.HttpServletRequest#getLocale() + * @see jakarta.servlet.http.HttpServletRequest#getLocale() */ Locale getLocale(); /** * Return the context path for this request * (usually the base path that the current web application is mapped to). - * @see javax.servlet.http.HttpServletRequest#getContextPath() + * @see jakarta.servlet.http.HttpServletRequest#getContextPath() */ String getContextPath(); /** * Return the remote user for this request, if any. - * @see javax.servlet.http.HttpServletRequest#getRemoteUser() + * @see jakarta.servlet.http.HttpServletRequest#getRemoteUser() */ @Nullable String getRemoteUser(); /** * Return the user principal for this request, if any. - * @see javax.servlet.http.HttpServletRequest#getUserPrincipal() + * @see jakarta.servlet.http.HttpServletRequest#getUserPrincipal() */ @Nullable Principal getUserPrincipal(); /** * Determine whether the user is in the given role for this request. - * @see javax.servlet.http.HttpServletRequest#isUserInRole(String) + * @see jakarta.servlet.http.HttpServletRequest#isUserInRole(String) */ boolean isUserInRole(String role); /** * Return whether this request has been sent over a secure transport * mechanism (such as SSL). - * @see javax.servlet.http.HttpServletRequest#isSecure() + * @see jakarta.servlet.http.HttpServletRequest#isSecure() */ boolean isSecure(); diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequest.java b/spring-web/src/main/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequest.java index 06e4721cb97e..18d29550bfd8 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequest.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequest.java @@ -22,11 +22,11 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.AsyncContext; +import jakarta.servlet.AsyncEvent; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.util.Assert; import org.springframework.web.context.request.ServletWebRequest; diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java b/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java index 960ead38d050..9b7e1c484689 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java @@ -24,8 +24,7 @@ import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -99,7 +98,7 @@ public final class WebAsyncManager { /** * Package-private constructor. - * @see WebAsyncUtils#getAsyncManager(javax.servlet.ServletRequest) + * @see WebAsyncUtils#getAsyncManager(jakarta.servlet.ServletRequest) * @see WebAsyncUtils#getAsyncManager(org.springframework.web.context.request.WebRequest) */ WebAsyncManager() { diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncUtils.java b/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncUtils.java index abd2336ab1d9..2798bb2158e4 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncUtils.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncUtils.java @@ -16,9 +16,9 @@ package org.springframework.web.context.request.async; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.WebRequest; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/AbstractRefreshableWebApplicationContext.java b/spring-web/src/main/java/org/springframework/web/context/support/AbstractRefreshableWebApplicationContext.java index 6c47fc938fe8..86ac23e6b2f9 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/AbstractRefreshableWebApplicationContext.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/AbstractRefreshableWebApplicationContext.java @@ -16,8 +16,8 @@ package org.springframework.web.context.support; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.support.AbstractRefreshableConfigApplicationContext; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.java b/spring-web/src/main/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.java index 5de3b4352b2e..ae2ffee7e658 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.java @@ -38,7 +38,7 @@ * implementation which accepts component classes as input — in particular * {@link org.springframework.context.annotation.Configuration @Configuration}-annotated * classes, but also plain {@link org.springframework.stereotype.Component @Component} - * classes and JSR-330 compliant classes using {@code javax.inject} annotations. + * classes and JSR-330 compliant classes using {@code jakarta.inject} annotations. * *

    Allows for registering classes one by one (specifying class names as config * location) as well as for classpath scanning (specifying base packages as config location). diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ContextExposingHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/context/support/ContextExposingHttpServletRequest.java index fc6f1af7a5f2..55b32a46cab4 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ContextExposingHttpServletRequest.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ContextExposingHttpServletRequest.java @@ -19,8 +19,8 @@ import java.util.HashSet; import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java b/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java index c8a39cb2908b..75a599d231a8 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java @@ -16,8 +16,8 @@ package org.springframework.web.context.support; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/HttpRequestHandlerServlet.java b/spring-web/src/main/java/org/springframework/web/context/support/HttpRequestHandlerServlet.java index 97be4db90667..a97b402c36ab 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/HttpRequestHandlerServlet.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/HttpRequestHandlerServlet.java @@ -18,10 +18,10 @@ import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/LiveBeansViewServlet.java b/spring-web/src/main/java/org/springframework/web/context/support/LiveBeansViewServlet.java index 39cb3f8991dc..0a500097f143 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/LiveBeansViewServlet.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/LiveBeansViewServlet.java @@ -18,10 +18,10 @@ import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/RequestHandledEvent.java b/spring-web/src/main/java/org/springframework/web/context/support/RequestHandledEvent.java index 1550875714d1..30d32153ebb0 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/RequestHandledEvent.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/RequestHandledEvent.java @@ -104,7 +104,7 @@ public String getSessionId() { /** * Return the name of the user that was associated with the request * (usually the UserPrincipal). - * @see javax.servlet.http.HttpServletRequest#getUserPrincipal() + * @see jakarta.servlet.http.HttpServletRequest#getUserPrincipal() */ @Nullable public String getUserName() { diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletConfigPropertySource.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletConfigPropertySource.java index 01fd5d064dd2..72266c0bb96c 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletConfigPropertySource.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletConfigPropertySource.java @@ -16,7 +16,7 @@ package org.springframework.web.context.support; -import javax.servlet.ServletConfig; +import jakarta.servlet.ServletConfig; import org.springframework.core.env.EnumerablePropertySource; import org.springframework.core.env.PropertySource; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAttributeExporter.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAttributeExporter.java index 8e8ac5518216..b1422251ab71 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAttributeExporter.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAttributeExporter.java @@ -18,8 +18,7 @@ import java.util.Map; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -43,7 +42,7 @@ * * @author Juergen Hoeller * @since 1.1.4 - * @see javax.servlet.ServletContext#getAttribute + * @see jakarta.servlet.ServletContext#getAttribute * @see WebApplicationContextUtils#getWebApplicationContext */ public class ServletContextAttributeExporter implements ServletContextAware { diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAttributeFactoryBean.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAttributeFactoryBean.java index c835219b66aa..6830e27c2b82 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAttributeFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAttributeFactoryBean.java @@ -16,7 +16,7 @@ package org.springframework.web.context.support; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.beans.factory.FactoryBean; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAwareProcessor.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAwareProcessor.java index 0146649cc3df..239edb45f6ea 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAwareProcessor.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAwareProcessor.java @@ -16,8 +16,8 @@ package org.springframework.web.context.support; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextLiveBeansView.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextLiveBeansView.java index cb9e40f58aed..f8da1abc2dcb 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextLiveBeansView.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextLiveBeansView.java @@ -20,7 +20,7 @@ import java.util.LinkedHashSet; import java.util.Set; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.util.Assert; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextParameterFactoryBean.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextParameterFactoryBean.java index 74f5ef0d2bb3..3269917dcd35 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextParameterFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextParameterFactoryBean.java @@ -16,7 +16,7 @@ package org.springframework.web.context.support; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.beans.factory.FactoryBean; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextPropertySource.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextPropertySource.java index 468d1c3c04f7..ca100504c796 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextPropertySource.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextPropertySource.java @@ -16,7 +16,7 @@ package org.springframework.web.context.support; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.core.env.EnumerablePropertySource; import org.springframework.core.env.PropertySource; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java index 9f19b76d9971..3942fa0deab7 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java @@ -23,7 +23,7 @@ import java.net.MalformedURLException; import java.net.URL; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.core.io.AbstractFileResolvingResource; import org.springframework.core.io.ContextResource; @@ -36,7 +36,7 @@ /** * {@link org.springframework.core.io.Resource} implementation for - * {@link javax.servlet.ServletContext} resources, interpreting + * {@link jakarta.servlet.ServletContext} resources, interpreting * relative paths within the web application root directory. * *

    Always supports stream access and URL access, but only allows @@ -45,9 +45,9 @@ * * @author Juergen Hoeller * @since 28.12.2003 - * @see javax.servlet.ServletContext#getResourceAsStream - * @see javax.servlet.ServletContext#getResource - * @see javax.servlet.ServletContext#getRealPath + * @see jakarta.servlet.ServletContext#getResourceAsStream + * @see jakarta.servlet.ServletContext#getResource + * @see jakarta.servlet.ServletContext#getRealPath */ public class ServletContextResource extends AbstractFileResolvingResource implements ContextResource { @@ -96,7 +96,7 @@ public final String getPath() { /** * This implementation checks {@code ServletContext.getResource}. - * @see javax.servlet.ServletContext#getResource(String) + * @see jakarta.servlet.ServletContext#getResource(String) */ @Override public boolean exists() { @@ -112,7 +112,7 @@ public boolean exists() { /** * This implementation delegates to {@code ServletContext.getResourceAsStream}, * which returns {@code null} in case of a non-readable resource (e.g. a directory). - * @see javax.servlet.ServletContext#getResourceAsStream(String) + * @see jakarta.servlet.ServletContext#getResourceAsStream(String) */ @Override public boolean isReadable() { @@ -150,7 +150,7 @@ public boolean isFile() { /** * This implementation delegates to {@code ServletContext.getResourceAsStream}, * but throws a FileNotFoundException if no resource found. - * @see javax.servlet.ServletContext#getResourceAsStream(String) + * @see jakarta.servlet.ServletContext#getResourceAsStream(String) */ @Override public InputStream getInputStream() throws IOException { @@ -164,7 +164,7 @@ public InputStream getInputStream() throws IOException { /** * This implementation delegates to {@code ServletContext.getResource}, * but throws a FileNotFoundException if no resource found. - * @see javax.servlet.ServletContext#getResource(String) + * @see jakarta.servlet.ServletContext#getResource(String) */ @Override public URL getURL() throws IOException { @@ -180,8 +180,8 @@ public URL getURL() throws IOException { * This implementation resolves "file:" URLs or alternatively delegates to * {@code ServletContext.getRealPath}, throwing a FileNotFoundException * if not found or not resolvable. - * @see javax.servlet.ServletContext#getResource(String) - * @see javax.servlet.ServletContext#getRealPath(String) + * @see jakarta.servlet.ServletContext#getResource(String) + * @see jakarta.servlet.ServletContext#getRealPath(String) */ @Override public File getFile() throws IOException { diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResourceLoader.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResourceLoader.java index 159878877600..fd36e66dfe71 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResourceLoader.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResourceLoader.java @@ -16,7 +16,7 @@ package org.springframework.web.context.support; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResourcePatternResolver.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResourcePatternResolver.java index 0f48ec38021a..c9bd0c447e9a 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResourcePatternResolver.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResourcePatternResolver.java @@ -23,8 +23,7 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -52,7 +51,7 @@ public class ServletContextResourcePatternResolver extends PathMatchingResourceP /** * Create a new ServletContextResourcePatternResolver. * @param servletContext the ServletContext to load resources with - * @see ServletContextResourceLoader#ServletContextResourceLoader(javax.servlet.ServletContext) + * @see ServletContextResourceLoader#ServletContextResourceLoader(jakarta.servlet.ServletContext) */ public ServletContextResourcePatternResolver(ServletContext servletContext) { super(new ServletContextResourceLoader(servletContext)); @@ -75,7 +74,7 @@ public ServletContextResourcePatternResolver(ResourceLoader resourceLoader) { * In case of other resources, delegates to the superclass version. * @see #doRetrieveMatchingServletContextResources * @see ServletContextResource - * @see javax.servlet.ServletContext#getResourcePaths + * @see jakarta.servlet.ServletContext#getResourcePaths */ @Override protected Set doFindPathMatchingFileResources(Resource rootDirResource, String subPattern) @@ -104,7 +103,7 @@ protected Set doFindPathMatchingFileResources(Resource rootDirResource * @param result the Set of matching Resources to add to * @throws IOException if directory contents could not be retrieved * @see ServletContextResource - * @see javax.servlet.ServletContext#getResourcePaths + * @see jakarta.servlet.ServletContext#getResourcePaths */ protected void doRetrieveMatchingServletContextResources( ServletContext servletContext, String fullPattern, String dir, Set result) diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextScope.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextScope.java index 5da0d5298e27..3365318dfe58 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextScope.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextScope.java @@ -19,7 +19,7 @@ import java.util.LinkedHashMap; import java.util.Map; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.ObjectFactory; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/SpringBeanAutowiringSupport.java b/spring-web/src/main/java/org/springframework/web/context/support/SpringBeanAutowiringSupport.java index bd3451328086..8ffbc9fdc8b9 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/SpringBeanAutowiringSupport.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/SpringBeanAutowiringSupport.java @@ -16,8 +16,7 @@ package org.springframework.web.context.support; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -101,7 +100,7 @@ public static void processInjectionBasedOnCurrentContext(Object target) { *

    Intended for use as a delegate. * @param target the target object to process * @param servletContext the ServletContext to find the Spring web application context in - * @see WebApplicationContextUtils#getWebApplicationContext(javax.servlet.ServletContext) + * @see WebApplicationContextUtils#getWebApplicationContext(jakarta.servlet.ServletContext) */ public static void processInjectionBasedOnServletContext(Object target, ServletContext servletContext) { Assert.notNull(target, "Target object must not be null"); diff --git a/spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java b/spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java index 3ec9b92be64a..28cfb4e8c38e 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java @@ -16,8 +16,8 @@ package org.springframework.web.context.support; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; import org.springframework.core.env.Environment; import org.springframework.core.env.MutablePropertySources; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/StaticWebApplicationContext.java b/spring-web/src/main/java/org/springframework/web/context/support/StaticWebApplicationContext.java index 1a011a89dddb..2e0c6a5b9b48 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/StaticWebApplicationContext.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/StaticWebApplicationContext.java @@ -16,8 +16,8 @@ package org.springframework.web.context.support; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.support.StaticApplicationContext; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationContextUtils.java b/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationContextUtils.java index d9bfe57b1523..cf43e49a5300 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationContextUtils.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationContextUtils.java @@ -22,13 +22,13 @@ import java.util.HashMap; import java.util.Map; -import javax.faces.context.ExternalContext; -import javax.faces.context.FacesContext; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.faces.context.ExternalContext; +import jakarta.faces.context.FacesContext; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpSession; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; @@ -66,7 +66,7 @@ public abstract class WebApplicationContextUtils { private static final boolean jsfPresent = - ClassUtils.isPresent("javax.faces.context.FacesContext", RequestContextHolder.class.getClassLoader()); + ClassUtils.isPresent("jakarta.faces.context.FacesContext", RequestContextHolder.class.getClassLoader()); /** diff --git a/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationObjectSupport.java b/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationObjectSupport.java index e0d213f09cd5..10d22569ccc9 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationObjectSupport.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationObjectSupport.java @@ -18,7 +18,7 @@ import java.io.File; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ApplicationObjectSupport; @@ -70,7 +70,7 @@ protected boolean isContextRequired() { } /** - * Calls {@link #initServletContext(javax.servlet.ServletContext)} if the + * Calls {@link #initServletContext(jakarta.servlet.ServletContext)} if the * given ApplicationContext is a {@link WebApplicationContext}. */ @Override @@ -89,7 +89,7 @@ protected void initApplicationContext(ApplicationContext context) { * on the ServletContext that this application object runs in. *

    The default implementation is empty. Called by * {@link #initApplicationContext(org.springframework.context.ApplicationContext)} - * as well as {@link #setServletContext(javax.servlet.ServletContext)}. + * as well as {@link #setServletContext(jakarta.servlet.ServletContext)}. * @param servletContext the ServletContext that this application object runs in * (never {@code null}) */ @@ -147,7 +147,7 @@ protected final ServletContext getServletContext() throws IllegalStateException * as provided by the servlet container. * @return the File representing the temporary directory * @throws IllegalStateException if not running within a ServletContext - * @see org.springframework.web.util.WebUtils#getTempDir(javax.servlet.ServletContext) + * @see org.springframework.web.util.WebUtils#getTempDir(jakarta.servlet.ServletContext) */ protected final File getTempDir() throws IllegalStateException { ServletContext servletContext = getServletContext(); diff --git a/spring-web/src/main/java/org/springframework/web/cors/CorsConfigurationSource.java b/spring-web/src/main/java/org/springframework/web/cors/CorsConfigurationSource.java index 27934a126f5e..c2111bb5b8a1 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/CorsConfigurationSource.java +++ b/spring-web/src/main/java/org/springframework/web/cors/CorsConfigurationSource.java @@ -16,7 +16,7 @@ package org.springframework.web.cors; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/cors/CorsProcessor.java b/spring-web/src/main/java/org/springframework/web/cors/CorsProcessor.java index e162d77ebf7c..4b19c35d96ad 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/CorsProcessor.java +++ b/spring-web/src/main/java/org/springframework/web/cors/CorsProcessor.java @@ -18,8 +18,8 @@ import java.io.IOException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/cors/CorsUtils.java b/spring-web/src/main/java/org/springframework/web/cors/CorsUtils.java index eec489d6cc27..e01a1a8bc2aa 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/CorsUtils.java +++ b/spring-web/src/main/java/org/springframework/web/cors/CorsUtils.java @@ -16,7 +16,7 @@ package org.springframework.web.cors; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-web/src/main/java/org/springframework/web/cors/DefaultCorsProcessor.java b/spring-web/src/main/java/org/springframework/web/cors/DefaultCorsProcessor.java index 37d3fb8c9dd9..cc7aa88f752b 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/DefaultCorsProcessor.java +++ b/spring-web/src/main/java/org/springframework/web/cors/DefaultCorsProcessor.java @@ -22,9 +22,8 @@ import java.util.Collection; import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-web/src/main/java/org/springframework/web/cors/UrlBasedCorsConfigurationSource.java b/spring-web/src/main/java/org/springframework/web/cors/UrlBasedCorsConfigurationSource.java index 5aec15b6d6f7..cad0948f50a6 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/UrlBasedCorsConfigurationSource.java +++ b/spring-web/src/main/java/org/springframework/web/cors/UrlBasedCorsConfigurationSource.java @@ -20,7 +20,7 @@ import java.util.LinkedHashMap; import java.util.Map; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.server.PathContainer; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java b/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java index 271193cc6382..a91fbc2b16f9 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java @@ -21,11 +21,11 @@ import java.util.Enumeration; import java.util.function.Predicate; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import org.springframework.http.HttpHeaders; import org.springframework.http.server.ServletServerHttpRequest; diff --git a/spring-web/src/main/java/org/springframework/web/filter/CharacterEncodingFilter.java b/spring-web/src/main/java/org/springframework/web/filter/CharacterEncodingFilter.java index be97ae84aa9f..d217feaaf83f 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/CharacterEncodingFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/CharacterEncodingFilter.java @@ -18,10 +18,10 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -41,8 +41,8 @@ * @since 15.03.2004 * @see #setEncoding * @see #setForceEncoding - * @see javax.servlet.http.HttpServletRequest#setCharacterEncoding - * @see javax.servlet.http.HttpServletResponse#setCharacterEncoding + * @see jakarta.servlet.http.HttpServletRequest#setCharacterEncoding + * @see jakarta.servlet.http.HttpServletResponse#setCharacterEncoding */ public class CharacterEncodingFilter extends OncePerRequestFilter { @@ -107,7 +107,7 @@ public CharacterEncodingFilter(String encoding, boolean forceRequestEncoding, bo /** * Set the encoding to use for requests. This encoding will be passed into a - * {@link javax.servlet.http.HttpServletRequest#setCharacterEncoding} call. + * {@link jakarta.servlet.http.HttpServletRequest#setCharacterEncoding} call. *

    Whether this encoding will override existing request encodings * (and whether it will be applied as default response encoding as well) * depends on the {@link #setForceEncoding "forceEncoding"} flag. @@ -129,7 +129,7 @@ public String getEncoding() { * Set whether the configured {@link #setEncoding encoding} of this filter * is supposed to override existing request and response encodings. *

    Default is "false", i.e. do not modify the encoding if - * {@link javax.servlet.http.HttpServletRequest#getCharacterEncoding()} + * {@link jakarta.servlet.http.HttpServletRequest#getCharacterEncoding()} * returns a non-null value. Switch this to "true" to enforce the specified * encoding in any case, applying it as default response encoding as well. *

    This is the equivalent to setting both {@link #setForceRequestEncoding(boolean)} @@ -146,7 +146,7 @@ public void setForceEncoding(boolean forceEncoding) { * Set whether the configured {@link #setEncoding encoding} of this filter * is supposed to override existing request encodings. *

    Default is "false", i.e. do not modify the encoding if - * {@link javax.servlet.http.HttpServletRequest#getCharacterEncoding()} + * {@link jakarta.servlet.http.HttpServletRequest#getCharacterEncoding()} * returns a non-null value. Switch this to "true" to enforce the specified * encoding in any case. * @since 4.3 diff --git a/spring-web/src/main/java/org/springframework/web/filter/CommonsRequestLoggingFilter.java b/spring-web/src/main/java/org/springframework/web/filter/CommonsRequestLoggingFilter.java index 564a47040bef..1329e138f426 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/CommonsRequestLoggingFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/CommonsRequestLoggingFilter.java @@ -16,7 +16,7 @@ package org.springframework.web.filter; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; /** * Simple request logging filter that writes the request URI diff --git a/spring-web/src/main/java/org/springframework/web/filter/CompositeFilter.java b/spring-web/src/main/java/org/springframework/web/filter/CompositeFilter.java index f8ec4e37a0bd..a4700f5a3efe 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/CompositeFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/CompositeFilter.java @@ -20,12 +20,12 @@ import java.util.ArrayList; import java.util.List; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; /** * A generic composite servlet {@link Filter} that just delegates its behavior diff --git a/spring-web/src/main/java/org/springframework/web/filter/CorsFilter.java b/spring-web/src/main/java/org/springframework/web/filter/CorsFilter.java index 4d0826f22a9c..725dfebddbbf 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/CorsFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/CorsFilter.java @@ -18,10 +18,10 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.util.Assert; import org.springframework.web.cors.CorsConfiguration; @@ -32,7 +32,7 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource; /** - * {@link javax.servlet.Filter} to handle CORS pre-flight requests and intercept + * {@link jakarta.servlet.Filter} to handle CORS pre-flight requests and intercept * CORS simple and actual requests with a {@link CorsProcessor}, and to update * the response, e.g. with CORS response headers, based on the policy matched * through the provided {@link CorsConfigurationSource}. @@ -40,7 +40,7 @@ *

    This is an alternative to configuring CORS in the Spring MVC Java config * and the Spring MVC XML namespace. It is useful for applications depending * only on spring-web (not on spring-webmvc) or for security constraints that - * require CORS checks to be performed at {@link javax.servlet.Filter} level. + * require CORS checks to be performed at {@link jakarta.servlet.Filter} level. * *

    This filter could be used in conjunction with {@link DelegatingFilterProxy} * in order to help with its initialization. diff --git a/spring-web/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java b/spring-web/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java index bfbe62739dce..dff469446ad2 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java +++ b/spring-web/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java @@ -18,11 +18,11 @@ import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.lang.Nullable; @@ -71,13 +71,13 @@ * @since 1.2 * @see #setTargetBeanName * @see #setTargetFilterLifecycle - * @see javax.servlet.Filter#doFilter - * @see javax.servlet.Filter#init - * @see javax.servlet.Filter#destroy + * @see jakarta.servlet.Filter#doFilter + * @see jakarta.servlet.Filter#init + * @see jakarta.servlet.Filter#destroy * @see #DelegatingFilterProxy(Filter) * @see #DelegatingFilterProxy(String) * @see #DelegatingFilterProxy(String, WebApplicationContext) - * @see javax.servlet.ServletContext#addFilter(String, Filter) + * @see jakarta.servlet.ServletContext#addFilter(String, Filter) * @see org.springframework.web.WebApplicationInitializer */ public class DelegatingFilterProxy extends GenericFilterBean { @@ -293,7 +293,7 @@ public void destroy() { * @return the {@code WebApplicationContext} for this proxy, or {@code null} if not found * @see #DelegatingFilterProxy(String, WebApplicationContext) * @see #getContextAttribute() - * @see WebApplicationContextUtils#getWebApplicationContext(javax.servlet.ServletContext) + * @see WebApplicationContextUtils#getWebApplicationContext(jakarta.servlet.ServletContext) * @see WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE */ @Nullable @@ -330,7 +330,7 @@ protected WebApplicationContext findWebApplicationContext() { * @see #getTargetBeanName() * @see #isTargetFilterLifecycle() * @see #getFilterConfig() - * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) + * @see jakarta.servlet.Filter#init(jakarta.servlet.FilterConfig) */ protected Filter initDelegate(WebApplicationContext wac) throws ServletException { String targetBeanName = getTargetBeanName(); @@ -363,7 +363,7 @@ protected void invokeDelegate( * Default implementation simply calls {@code Filter.destroy} on it. * @param delegate the Filter delegate (never {@code null}) * @see #isTargetFilterLifecycle() - * @see javax.servlet.Filter#destroy() + * @see jakarta.servlet.Filter#destroy() */ protected void destroyDelegate(Filter delegate) { if (isTargetFilterLifecycle()) { diff --git a/spring-web/src/main/java/org/springframework/web/filter/FormContentFilter.java b/spring-web/src/main/java/org/springframework/web/filter/FormContentFilter.java index 50ca13750784..a66a2ba49eca 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/FormContentFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/FormContentFilter.java @@ -29,11 +29,11 @@ import java.util.Map; import java.util.Set; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpInputMessage; import org.springframework.http.MediaType; diff --git a/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java b/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java index 4b0b2db90283..27db5087a245 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java @@ -26,12 +26,12 @@ import java.util.Set; import java.util.function.Supplier; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.springframework.http.HttpStatus; import org.springframework.http.server.ServerHttpRequest; diff --git a/spring-web/src/main/java/org/springframework/web/filter/GenericFilterBean.java b/spring-web/src/main/java/org/springframework/web/filter/GenericFilterBean.java index da36fb123b32..f9c79d6bff5f 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/GenericFilterBean.java +++ b/spring-web/src/main/java/org/springframework/web/filter/GenericFilterBean.java @@ -20,11 +20,10 @@ import java.util.HashSet; import java.util.Set; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -53,7 +52,7 @@ import org.springframework.web.util.NestedServletException; /** - * Simple base implementation of {@link javax.servlet.Filter} which treats + * Simple base implementation of {@link jakarta.servlet.Filter} which treats * its config parameters ({@code init-param} entries within the * {@code filter} tag in {@code web.xml}) as bean properties. * @@ -64,7 +63,7 @@ * setter will simply be ignored. * *

    This filter leaves actual filtering to subclasses, which have to - * implement the {@link javax.servlet.Filter#doFilter} method. + * implement the {@link jakarta.servlet.Filter#doFilter} method. * *

    This generic filter base class has no dependency on the Spring * {@link org.springframework.context.ApplicationContext} concept. @@ -167,7 +166,7 @@ public void setServletContext(ServletContext servletContext) { *

    Only relevant in case of initialization as bean, where the * standard {@code init(FilterConfig)} method won't be called. * @see #initFilterBean() - * @see #init(javax.servlet.FilterConfig) + * @see #init(jakarta.servlet.FilterConfig) */ @Override public void afterPropertiesSet() throws ServletException { @@ -275,7 +274,7 @@ protected void initFilterBean() throws ServletException { *

    Public to resemble the {@code getFilterConfig()} method * of the Servlet Filter version that shipped with WebLogic 6.1. * @return the FilterConfig instance, or {@code null} if none available - * @see javax.servlet.GenericServlet#getServletConfig() + * @see jakarta.servlet.GenericServlet#getServletConfig() */ @Nullable public FilterConfig getFilterConfig() { @@ -289,8 +288,8 @@ public FilterConfig getFilterConfig() { * If initialized as bean in a Spring application context, * it falls back to the bean name as defined in the bean factory. * @return the filter name, or {@code null} if none available - * @see javax.servlet.GenericServlet#getServletName() - * @see javax.servlet.FilterConfig#getFilterName() + * @see jakarta.servlet.GenericServlet#getServletName() + * @see jakarta.servlet.FilterConfig#getFilterName() * @see #setBeanName */ @Nullable @@ -306,8 +305,8 @@ protected String getFilterName() { * it falls back to the ServletContext that the bean factory runs in. * @return the ServletContext instance * @throws IllegalStateException if no ServletContext is available - * @see javax.servlet.GenericServlet#getServletContext() - * @see javax.servlet.FilterConfig#getServletContext() + * @see jakarta.servlet.GenericServlet#getServletContext() + * @see jakarta.servlet.FilterConfig#getServletContext() * @see #setServletContext */ protected ServletContext getServletContext() { diff --git a/spring-web/src/main/java/org/springframework/web/filter/HiddenHttpMethodFilter.java b/spring-web/src/main/java/org/springframework/web/filter/HiddenHttpMethodFilter.java index 0ed01daa40cb..a2abd162f2cb 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/HiddenHttpMethodFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/HiddenHttpMethodFilter.java @@ -22,11 +22,11 @@ import java.util.List; import java.util.Locale; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpMethod; import org.springframework.util.Assert; @@ -34,7 +34,7 @@ import org.springframework.web.util.WebUtils; /** - * {@link javax.servlet.Filter} that converts posted method parameters into HTTP methods, + * {@link jakarta.servlet.Filter} that converts posted method parameters into HTTP methods, * retrievable via {@link HttpServletRequest#getMethod()}. Since browsers currently only * support GET and POST, a common technique - used by the Prototype library, for instance - * is to use a normal POST with an additional hidden form field ({@code _method}) diff --git a/spring-web/src/main/java/org/springframework/web/filter/HttpPutFormContentFilter.java b/spring-web/src/main/java/org/springframework/web/filter/HttpPutFormContentFilter.java index 2e6c04aa264a..acb0c0fbfe23 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/HttpPutFormContentFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/HttpPutFormContentFilter.java @@ -29,11 +29,11 @@ import java.util.Map; import java.util.Set; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpInputMessage; import org.springframework.http.MediaType; @@ -46,7 +46,7 @@ import org.springframework.util.StringUtils; /** - * {@link javax.servlet.Filter} that makes form encoded data available through + * {@link jakarta.servlet.Filter} that makes form encoded data available through * the {@code ServletRequest.getParameter*()} family of methods during HTTP PUT * or PATCH requests. * diff --git a/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java b/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java index 0f5e1a3831ad..953bda7f8692 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java @@ -18,13 +18,13 @@ import java.io.IOException; -import javax.servlet.DispatcherType; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.context.request.async.WebAsyncManager; import org.springframework.web.context.request.async.WebAsyncUtils; @@ -36,8 +36,8 @@ * method with HttpServletRequest and HttpServletResponse arguments. * *

    As of Servlet 3.0, a filter may be invoked as part of a - * {@link javax.servlet.DispatcherType#REQUEST REQUEST} or - * {@link javax.servlet.DispatcherType#ASYNC ASYNC} dispatches that occur in + * {@link jakarta.servlet.DispatcherType#REQUEST REQUEST} or + * {@link jakarta.servlet.DispatcherType#ASYNC ASYNC} dispatches that occur in * separate threads. A filter can be configured in {@code web.xml} whether it * should be involved in async dispatches. However, in some cases servlet * containers assume different default configuration. Therefore sub-classes can @@ -54,7 +54,7 @@ * the last one for the given request. * *

    Yet another dispatch type that also occurs in its own thread is - * {@link javax.servlet.DispatcherType#ERROR ERROR}. Subclasses can override + * {@link jakarta.servlet.DispatcherType#ERROR ERROR}. Subclasses can override * {@link #shouldNotFilterErrorDispatch()} if they wish to declare statically * if they should be invoked once during error dispatches. * @@ -136,7 +136,7 @@ private boolean skipDispatch(HttpServletRequest request) { } /** - * The dispatcher type {@code javax.servlet.DispatcherType.ASYNC} introduced + * The dispatcher type {@code jakarta.servlet.DispatcherType.ASYNC} introduced * in Servlet 3.0 means a filter can be invoked in more than one thread over * the course of a single request. This method returns {@code true} if the * filter is currently executing within an asynchronous dispatch. @@ -189,7 +189,7 @@ protected boolean shouldNotFilter(HttpServletRequest request) throws ServletExce } /** - * The dispatcher type {@code javax.servlet.DispatcherType.ASYNC} introduced + * The dispatcher type {@code jakarta.servlet.DispatcherType.ASYNC} introduced * in Servlet 3.0 means a filter can be invoked in more than one thread * over the course of a single request. Some filters only need to filter * the initial thread (e.g. request wrapping) while others may need diff --git a/spring-web/src/main/java/org/springframework/web/filter/RelativeRedirectFilter.java b/spring-web/src/main/java/org/springframework/web/filter/RelativeRedirectFilter.java index 25df286a0c48..86868520031b 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/RelativeRedirectFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/RelativeRedirectFilter.java @@ -18,10 +18,10 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpStatus; import org.springframework.util.Assert; diff --git a/spring-web/src/main/java/org/springframework/web/filter/RelativeRedirectResponseWrapper.java b/spring-web/src/main/java/org/springframework/web/filter/RelativeRedirectResponseWrapper.java index baf4ab53ce9b..5f1fc11be844 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/RelativeRedirectResponseWrapper.java +++ b/spring-web/src/main/java/org/springframework/web/filter/RelativeRedirectResponseWrapper.java @@ -15,8 +15,8 @@ */ package org.springframework.web.filter; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; diff --git a/spring-web/src/main/java/org/springframework/web/filter/RequestContextFilter.java b/spring-web/src/main/java/org/springframework/web/filter/RequestContextFilter.java index 8bb6a821bb2e..3a57d72e9172 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/RequestContextFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/RequestContextFilter.java @@ -18,10 +18,10 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.web.context.request.RequestContextHolder; diff --git a/spring-web/src/main/java/org/springframework/web/filter/ServletContextRequestLoggingFilter.java b/spring-web/src/main/java/org/springframework/web/filter/ServletContextRequestLoggingFilter.java index 40cf7681e20d..35bd66ce58bb 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/ServletContextRequestLoggingFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/ServletContextRequestLoggingFilter.java @@ -16,7 +16,7 @@ package org.springframework.web.filter; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; /** * Simple request logging filter that writes the request URI @@ -29,7 +29,7 @@ * @see #setBeforeMessageSuffix * @see #setAfterMessagePrefix * @see #setAfterMessageSuffix - * @see javax.servlet.ServletContext#log(String) + * @see jakarta.servlet.ServletContext#log(String) */ public class ServletContextRequestLoggingFilter extends AbstractRequestLoggingFilter { diff --git a/spring-web/src/main/java/org/springframework/web/filter/ServletRequestPathFilter.java b/spring-web/src/main/java/org/springframework/web/filter/ServletRequestPathFilter.java index cc9e85015f47..eccdb82ae38b 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/ServletRequestPathFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/ServletRequestPathFilter.java @@ -17,12 +17,12 @@ import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.server.RequestPath; import org.springframework.web.util.ServletRequestPathUtils; diff --git a/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java b/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java index de2935bc6860..06e164297f8f 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java @@ -20,12 +20,12 @@ import java.io.InputStream; import java.io.PrintWriter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -37,7 +37,7 @@ import org.springframework.web.util.WebUtils; /** - * {@link javax.servlet.Filter} that generates an {@code ETag} value based on the + * {@link jakarta.servlet.Filter} that generates an {@code ETag} value based on the * content on the response. This ETag is compared to the {@code If-None-Match} * header of the request. If these headers are equal, the response content is * not sent, but rather a {@code 304 "Not Modified"} status instead. diff --git a/spring-web/src/main/java/org/springframework/web/jsf/DecoratingNavigationHandler.java b/spring-web/src/main/java/org/springframework/web/jsf/DecoratingNavigationHandler.java index 7d8f082586f6..98dd6cce8a61 100644 --- a/spring-web/src/main/java/org/springframework/web/jsf/DecoratingNavigationHandler.java +++ b/spring-web/src/main/java/org/springframework/web/jsf/DecoratingNavigationHandler.java @@ -16,8 +16,8 @@ package org.springframework.web.jsf; -import javax.faces.application.NavigationHandler; -import javax.faces.context.FacesContext; +import jakarta.faces.application.NavigationHandler; +import jakarta.faces.context.FacesContext; import org.springframework.lang.Nullable; @@ -34,7 +34,7 @@ * * @author Juergen Hoeller * @since 1.2.7 - * @see #handleNavigation(javax.faces.context.FacesContext, String, String, NavigationHandler) + * @see #handleNavigation(jakarta.faces.context.FacesContext, String, String, NavigationHandler) * @see DelegatingNavigationHandlerProxy */ public abstract class DecoratingNavigationHandler extends NavigationHandler { @@ -71,7 +71,7 @@ public final NavigationHandler getDecoratedNavigationHandler() { * This implementation of the standard JSF {@code handleNavigation} method * delegates to the overloaded variant, passing in constructor-injected * NavigationHandler as argument. - * @see #handleNavigation(javax.faces.context.FacesContext, String, String, javax.faces.application.NavigationHandler) + * @see #handleNavigation(jakarta.faces.context.FacesContext, String, String, jakarta.faces.application.NavigationHandler) */ @Override public final void handleNavigation(FacesContext facesContext, String fromAction, String outcome) { diff --git a/spring-web/src/main/java/org/springframework/web/jsf/DelegatingNavigationHandlerProxy.java b/spring-web/src/main/java/org/springframework/web/jsf/DelegatingNavigationHandlerProxy.java index a6eafaace42c..e1369563e9f8 100644 --- a/spring-web/src/main/java/org/springframework/web/jsf/DelegatingNavigationHandlerProxy.java +++ b/spring-web/src/main/java/org/springframework/web/jsf/DelegatingNavigationHandlerProxy.java @@ -16,8 +16,8 @@ package org.springframework.web.jsf; -import javax.faces.application.NavigationHandler; -import javax.faces.context.FacesContext; +import jakarta.faces.application.NavigationHandler; +import jakarta.faces.context.FacesContext; import org.springframework.beans.factory.BeanFactory; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/jsf/DelegatingPhaseListenerMulticaster.java b/spring-web/src/main/java/org/springframework/web/jsf/DelegatingPhaseListenerMulticaster.java index 261d9baac1b3..45b312738ceb 100644 --- a/spring-web/src/main/java/org/springframework/web/jsf/DelegatingPhaseListenerMulticaster.java +++ b/spring-web/src/main/java/org/springframework/web/jsf/DelegatingPhaseListenerMulticaster.java @@ -18,10 +18,10 @@ import java.util.Collection; -import javax.faces.context.FacesContext; -import javax.faces.event.PhaseEvent; -import javax.faces.event.PhaseId; -import javax.faces.event.PhaseListener; +import jakarta.faces.context.FacesContext; +import jakarta.faces.event.PhaseEvent; +import jakarta.faces.event.PhaseId; +import jakarta.faces.event.PhaseListener; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.ListableBeanFactory; diff --git a/spring-web/src/main/java/org/springframework/web/jsf/FacesContextUtils.java b/spring-web/src/main/java/org/springframework/web/jsf/FacesContextUtils.java index 144446031479..05c2addf4df2 100644 --- a/spring-web/src/main/java/org/springframework/web/jsf/FacesContextUtils.java +++ b/spring-web/src/main/java/org/springframework/web/jsf/FacesContextUtils.java @@ -16,8 +16,8 @@ package org.springframework.web.jsf; -import javax.faces.context.ExternalContext; -import javax.faces.context.FacesContext; +import jakarta.faces.context.ExternalContext; +import jakarta.faces.context.FacesContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-web/src/main/java/org/springframework/web/jsf/el/SpringBeanFacesELResolver.java b/spring-web/src/main/java/org/springframework/web/jsf/el/SpringBeanFacesELResolver.java index 922174d830d0..e30e7e7a7302 100644 --- a/spring-web/src/main/java/org/springframework/web/jsf/el/SpringBeanFacesELResolver.java +++ b/spring-web/src/main/java/org/springframework/web/jsf/el/SpringBeanFacesELResolver.java @@ -19,11 +19,11 @@ import java.beans.FeatureDescriptor; import java.util.Iterator; -import javax.el.ELContext; -import javax.el.ELException; -import javax.el.ELResolver; -import javax.el.PropertyNotWritableException; -import javax.faces.context.FacesContext; +import jakarta.el.ELContext; +import jakarta.el.ELException; +import jakarta.el.ELResolver; +import jakarta.el.PropertyNotWritableException; +import jakarta.faces.context.FacesContext; import org.springframework.lang.Nullable; import org.springframework.web.context.WebApplicationContext; diff --git a/spring-web/src/main/java/org/springframework/web/jsf/el/WebApplicationContextFacesELResolver.java b/spring-web/src/main/java/org/springframework/web/jsf/el/WebApplicationContextFacesELResolver.java index d729187464d3..6a072053fb15 100644 --- a/spring-web/src/main/java/org/springframework/web/jsf/el/WebApplicationContextFacesELResolver.java +++ b/spring-web/src/main/java/org/springframework/web/jsf/el/WebApplicationContextFacesELResolver.java @@ -19,11 +19,10 @@ import java.beans.FeatureDescriptor; import java.util.Iterator; -import javax.el.ELContext; -import javax.el.ELException; -import javax.el.ELResolver; -import javax.faces.context.FacesContext; - +import jakarta.el.ELContext; +import jakarta.el.ELException; +import jakarta.el.ELResolver; +import jakarta.faces.context.FacesContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/AbstractNamedValueMethodArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/method/annotation/AbstractNamedValueMethodArgumentResolver.java index 4e0c8095c608..703362d31e88 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/AbstractNamedValueMethodArgumentResolver.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/AbstractNamedValueMethodArgumentResolver.java @@ -19,7 +19,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; import org.springframework.beans.ConversionNotSupportedException; import org.springframework.beans.TypeMismatchException; diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/ExpressionValueMethodArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/method/annotation/ExpressionValueMethodArgumentResolver.java index 18c60dee2b75..70f2a06e6140 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/ExpressionValueMethodArgumentResolver.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/ExpressionValueMethodArgumentResolver.java @@ -16,7 +16,7 @@ package org.springframework.web.method.annotation; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.ConfigurableBeanFactory; diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java b/spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java index 94933860ce82..77489f0a9c3d 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java @@ -28,9 +28,8 @@ import java.util.Optional; import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.Part; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.Part; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -70,7 +69,7 @@ *

    Model attributes are obtained from the model or created with a default * constructor (and then added to the model). Once created the attribute is * populated via data binding to Servlet request parameters. Validation may be - * applied if the argument is annotated with {@code @javax.validation.Valid}. + * applied if the argument is annotated with {@code @jakarta.validation.Valid}. * or Spring's own {@code @org.springframework.validation.annotation.Validated}. * *

    When this handler is created with {@code annotationNotRequired=true} @@ -367,7 +366,7 @@ else if (StringUtils.startsWithIgnoreCase( /** * Validate the model attribute if applicable. - *

    The default implementation checks for {@code @javax.validation.Valid}, + *

    The default implementation checks for {@code @jakarta.validation.Valid}, * Spring's {@link org.springframework.validation.annotation.Validated}, * and custom annotations whose name starts with "Valid". * @param binder the DataBinder to be used @@ -387,7 +386,7 @@ protected void validateIfApplicable(WebDataBinder binder, MethodParameter parame /** * Validate the specified candidate value if applicable. - *

    The default implementation checks for {@code @javax.validation.Valid}, + *

    The default implementation checks for {@code @jakarta.validation.Valid}, * Spring's {@link org.springframework.validation.annotation.Validated}, * and custom annotations whose name starts with "Valid". * @param binder the DataBinder to be used diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolver.java index 221743e71541..7c71280f4fd4 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolver.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolver.java @@ -20,8 +20,8 @@ import java.util.LinkedHashMap; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.Part; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.Part; import org.springframework.core.MethodParameter; import org.springframework.core.ResolvableType; diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java index e1d373ca5b81..ec1aeb1149d6 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java @@ -22,8 +22,8 @@ import java.util.Map; import java.util.Optional; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.Part; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.Part; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -52,7 +52,7 @@ /** * Resolves method arguments annotated with @{@link RequestParam}, arguments of * type {@link MultipartFile} in conjunction with Spring's {@link MultipartResolver} - * abstraction, and arguments of type {@code javax.servlet.http.Part} in conjunction + * abstraction, and arguments of type {@code jakarta.servlet.http.Part} in conjunction * with Servlet 3.0 multipart requests. This resolver can also be created in default * resolution mode in which simple types (int, long, etc.) not annotated with * {@link RequestParam @RequestParam} are also treated as request parameters with diff --git a/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java b/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java index e92a6c47fe68..725bbfc0dc80 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java @@ -134,7 +134,7 @@ default Resource getResource() { * @throws IllegalStateException if the file has already been moved * in the filesystem and is not available anymore for another transfer * @see org.apache.commons.fileupload.FileItem#write(File) - * @see javax.servlet.http.Part#write(String) + * @see jakarta.servlet.http.Part#write(String) */ void transferTo(File dest) throws IOException, IllegalStateException; diff --git a/spring-web/src/main/java/org/springframework/web/multipart/MultipartHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/MultipartHttpServletRequest.java index 7788b1e70457..692dd710d22a 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/MultipartHttpServletRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/MultipartHttpServletRequest.java @@ -16,7 +16,7 @@ package org.springframework.web.multipart; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -26,7 +26,7 @@ * Provides additional methods for dealing with multipart content within a * servlet request, allowing to access uploaded files. * Implementations also need to override the standard - * {@link javax.servlet.ServletRequest} methods for parameter access, making + * {@link jakarta.servlet.ServletRequest} methods for parameter access, making * multipart parameters available. * *

    A concrete implementation is @@ -40,9 +40,9 @@ * @since 29.09.2003 * @see MultipartResolver * @see MultipartFile - * @see javax.servlet.http.HttpServletRequest#getParameter - * @see javax.servlet.http.HttpServletRequest#getParameterNames - * @see javax.servlet.http.HttpServletRequest#getParameterMap + * @see jakarta.servlet.http.HttpServletRequest#getParameter + * @see jakarta.servlet.http.HttpServletRequest#getParameterNames + * @see jakarta.servlet.http.HttpServletRequest#getParameterMap * @see org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest * @see org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest */ diff --git a/spring-web/src/main/java/org/springframework/web/multipart/MultipartResolver.java b/spring-web/src/main/java/org/springframework/web/multipart/MultipartResolver.java index c8d7b6423911..cd18292d2606 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/MultipartResolver.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/MultipartResolver.java @@ -16,7 +16,7 @@ package org.springframework.web.multipart; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; /** * A strategy interface for multipart file upload resolution in accordance @@ -42,7 +42,7 @@ * *

    If a {@link org.springframework.web.servlet.DispatcherServlet} detects a * multipart request, it will resolve it via the configured {@link MultipartResolver} - * and pass on a wrapped {@link javax.servlet.http.HttpServletRequest}. Controllers + * and pass on a wrapped {@link jakarta.servlet.http.HttpServletRequest}. Controllers * can then cast their given request to the {@link MultipartHttpServletRequest} * interface, which allows for access to any {@link MultipartFile MultipartFiles}. * Note that this cast is only supported in case of an actual multipart request. @@ -106,9 +106,9 @@ public interface MultipartResolver { * @see MultipartHttpServletRequest#getFile * @see MultipartHttpServletRequest#getFileNames * @see MultipartHttpServletRequest#getFileMap - * @see javax.servlet.http.HttpServletRequest#getParameter - * @see javax.servlet.http.HttpServletRequest#getParameterNames - * @see javax.servlet.http.HttpServletRequest#getParameterMap + * @see jakarta.servlet.http.HttpServletRequest#getParameter + * @see jakarta.servlet.http.HttpServletRequest#getParameterNames + * @see jakarta.servlet.http.HttpServletRequest#getParameterMap */ MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException; diff --git a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java b/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java deleted file mode 100644 index 99fcee5f8c48..000000000000 --- a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.multipart.commons; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileItemFactory; -import org.apache.commons.fileupload.FileUpload; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.core.io.Resource; -import org.springframework.core.log.LogFormatUtils; -import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.util.StringUtils; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.util.WebUtils; - -/** - * Base class for multipart resolvers that use Apache Commons FileUpload - * 1.2 or above. - * - *

    Provides common configuration properties and parsing functionality - * for multipart requests, using a Map of Spring CommonsMultipartFile instances - * as representation of uploaded files and a String-based parameter Map as - * representation of uploaded form fields. - * - * @author Juergen Hoeller - * @since 2.0 - * @see CommonsMultipartFile - * @see CommonsMultipartResolver - */ -public abstract class CommonsFileUploadSupport { - - protected final Log logger = LogFactory.getLog(getClass()); - - private final DiskFileItemFactory fileItemFactory; - - private final FileUpload fileUpload; - - private boolean uploadTempDirSpecified = false; - - private boolean preserveFilename = false; - - - /** - * Instantiate a new CommonsFileUploadSupport with its - * corresponding FileItemFactory and FileUpload instances. - * @see #newFileItemFactory - * @see #newFileUpload - */ - public CommonsFileUploadSupport() { - this.fileItemFactory = newFileItemFactory(); - this.fileUpload = newFileUpload(getFileItemFactory()); - } - - - /** - * Return the underlying {@code org.apache.commons.fileupload.disk.DiskFileItemFactory} - * instance. There is hardly any need to access this. - * @return the underlying DiskFileItemFactory instance - */ - public DiskFileItemFactory getFileItemFactory() { - return this.fileItemFactory; - } - - /** - * Return the underlying {@code org.apache.commons.fileupload.FileUpload} - * instance. There is hardly any need to access this. - * @return the underlying FileUpload instance - */ - public FileUpload getFileUpload() { - return this.fileUpload; - } - - /** - * Set the maximum allowed size (in bytes) before an upload gets rejected. - * -1 indicates no limit (the default). - * @param maxUploadSize the maximum upload size allowed - * @see org.apache.commons.fileupload.FileUploadBase#setSizeMax - */ - public void setMaxUploadSize(long maxUploadSize) { - this.fileUpload.setSizeMax(maxUploadSize); - } - - /** - * Set the maximum allowed size (in bytes) for each individual file before - * an upload gets rejected. -1 indicates no limit (the default). - * @param maxUploadSizePerFile the maximum upload size per file - * @since 4.2 - * @see org.apache.commons.fileupload.FileUploadBase#setFileSizeMax - */ - public void setMaxUploadSizePerFile(long maxUploadSizePerFile) { - this.fileUpload.setFileSizeMax(maxUploadSizePerFile); - } - - /** - * Set the maximum allowed size (in bytes) before uploads are written to disk. - * Uploaded files will still be received past this amount, but they will not be - * stored in memory. Default is 10240, according to Commons FileUpload. - * @param maxInMemorySize the maximum in memory size allowed - * @see org.apache.commons.fileupload.disk.DiskFileItemFactory#setSizeThreshold - */ - public void setMaxInMemorySize(int maxInMemorySize) { - this.fileItemFactory.setSizeThreshold(maxInMemorySize); - } - - /** - * Set the default character encoding to use for parsing requests, - * to be applied to headers of individual parts and to form fields. - * Default is ISO-8859-1, according to the Servlet spec. - *

    If the request specifies a character encoding itself, the request - * encoding will override this setting. This also allows for generically - * overriding the character encoding in a filter that invokes the - * {@code ServletRequest.setCharacterEncoding} method. - * @param defaultEncoding the character encoding to use - * @see javax.servlet.ServletRequest#getCharacterEncoding - * @see javax.servlet.ServletRequest#setCharacterEncoding - * @see WebUtils#DEFAULT_CHARACTER_ENCODING - * @see org.apache.commons.fileupload.FileUploadBase#setHeaderEncoding - */ - public void setDefaultEncoding(String defaultEncoding) { - this.fileUpload.setHeaderEncoding(defaultEncoding); - } - - /** - * Determine the default encoding to use for parsing requests. - * @see #setDefaultEncoding - */ - protected String getDefaultEncoding() { - String encoding = getFileUpload().getHeaderEncoding(); - if (encoding == null) { - encoding = WebUtils.DEFAULT_CHARACTER_ENCODING; - } - return encoding; - } - - /** - * Set the temporary directory where uploaded files get stored. - * Default is the servlet container's temporary directory for the web application. - * @see org.springframework.web.util.WebUtils#TEMP_DIR_CONTEXT_ATTRIBUTE - */ - public void setUploadTempDir(Resource uploadTempDir) throws IOException { - if (!uploadTempDir.exists() && !uploadTempDir.getFile().mkdirs()) { - throw new IllegalArgumentException("Given uploadTempDir [" + uploadTempDir + "] could not be created"); - } - this.fileItemFactory.setRepository(uploadTempDir.getFile()); - this.uploadTempDirSpecified = true; - } - - /** - * Return the temporary directory where uploaded files get stored. - * @see #setUploadTempDir - */ - protected boolean isUploadTempDirSpecified() { - return this.uploadTempDirSpecified; - } - - /** - * Set whether to preserve the filename as sent by the client, not stripping off - * path information in {@link CommonsMultipartFile#getOriginalFilename()}. - *

    Default is "false", stripping off path information that may prefix the - * actual filename e.g. from Opera. Switch this to "true" for preserving the - * client-specified filename as-is, including potential path separators. - * @since 4.3.5 - * @see MultipartFile#getOriginalFilename() - * @see CommonsMultipartFile#setPreserveFilename(boolean) - */ - public void setPreserveFilename(boolean preserveFilename) { - this.preserveFilename = preserveFilename; - } - - - /** - * Factory method for a Commons DiskFileItemFactory instance. - *

    Default implementation returns a standard DiskFileItemFactory. - * Can be overridden to use a custom subclass, e.g. for testing purposes. - * @return the new DiskFileItemFactory instance - */ - protected DiskFileItemFactory newFileItemFactory() { - return new DiskFileItemFactory(); - } - - /** - * Factory method for a Commons FileUpload instance. - *

    To be implemented by subclasses. - * @param fileItemFactory the Commons FileItemFactory to build upon - * @return the Commons FileUpload instance - */ - protected abstract FileUpload newFileUpload(FileItemFactory fileItemFactory); - - - /** - * Determine an appropriate FileUpload instance for the given encoding. - *

    Default implementation returns the shared FileUpload instance - * if the encoding matches, else creates a new FileUpload instance - * with the same configuration other than the desired encoding. - * @param encoding the character encoding to use - * @return an appropriate FileUpload instance. - */ - protected FileUpload prepareFileUpload(@Nullable String encoding) { - FileUpload fileUpload = getFileUpload(); - FileUpload actualFileUpload = fileUpload; - - // Use new temporary FileUpload instance if the request specifies - // its own encoding that does not match the default encoding. - if (encoding != null && !encoding.equals(fileUpload.getHeaderEncoding())) { - actualFileUpload = newFileUpload(getFileItemFactory()); - actualFileUpload.setSizeMax(fileUpload.getSizeMax()); - actualFileUpload.setFileSizeMax(fileUpload.getFileSizeMax()); - actualFileUpload.setHeaderEncoding(encoding); - } - - return actualFileUpload; - } - - /** - * Parse the given List of Commons FileItems into a Spring MultipartParsingResult, - * containing Spring MultipartFile instances and a Map of multipart parameter. - * @param fileItems the Commons FileItems to parse - * @param encoding the encoding to use for form fields - * @return the Spring MultipartParsingResult - * @see CommonsMultipartFile#CommonsMultipartFile(org.apache.commons.fileupload.FileItem) - */ - protected MultipartParsingResult parseFileItems(List fileItems, String encoding) { - MultiValueMap multipartFiles = new LinkedMultiValueMap<>(); - Map multipartParameters = new HashMap<>(); - Map multipartParameterContentTypes = new HashMap<>(); - - // Extract multipart files and multipart parameters. - for (FileItem fileItem : fileItems) { - if (fileItem.isFormField()) { - String value; - String partEncoding = determineEncoding(fileItem.getContentType(), encoding); - try { - value = fileItem.getString(partEncoding); - } - catch (UnsupportedEncodingException ex) { - if (logger.isWarnEnabled()) { - logger.warn("Could not decode multipart item '" + fileItem.getFieldName() + - "' with encoding '" + partEncoding + "': using platform default"); - } - value = fileItem.getString(); - } - String[] curParam = multipartParameters.get(fileItem.getFieldName()); - if (curParam == null) { - // simple form field - multipartParameters.put(fileItem.getFieldName(), new String[] {value}); - } - else { - // array of simple form fields - String[] newParam = StringUtils.addStringToArray(curParam, value); - multipartParameters.put(fileItem.getFieldName(), newParam); - } - multipartParameterContentTypes.put(fileItem.getFieldName(), fileItem.getContentType()); - } - else { - // multipart file field - CommonsMultipartFile file = createMultipartFile(fileItem); - multipartFiles.add(file.getName(), file); - LogFormatUtils.traceDebug(logger, traceOn -> - "Part '" + file.getName() + "', size " + file.getSize() + - " bytes, filename='" + file.getOriginalFilename() + "'" + - (traceOn ? ", storage=" + file.getStorageDescription() : "") - ); - } - } - return new MultipartParsingResult(multipartFiles, multipartParameters, multipartParameterContentTypes); - } - - /** - * Create a {@link CommonsMultipartFile} wrapper for the given Commons {@link FileItem}. - * @param fileItem the Commons FileItem to wrap - * @return the corresponding CommonsMultipartFile (potentially a custom subclass) - * @since 4.3.5 - * @see #setPreserveFilename(boolean) - * @see CommonsMultipartFile#setPreserveFilename(boolean) - */ - protected CommonsMultipartFile createMultipartFile(FileItem fileItem) { - CommonsMultipartFile multipartFile = new CommonsMultipartFile(fileItem); - multipartFile.setPreserveFilename(this.preserveFilename); - return multipartFile; - } - - /** - * Cleanup the Spring MultipartFiles created during multipart parsing, - * potentially holding temporary data on disk. - *

    Deletes the underlying Commons FileItem instances. - * @param multipartFiles a Collection of MultipartFile instances - * @see org.apache.commons.fileupload.FileItem#delete() - */ - protected void cleanupFileItems(MultiValueMap multipartFiles) { - for (List files : multipartFiles.values()) { - for (MultipartFile file : files) { - if (file instanceof CommonsMultipartFile) { - CommonsMultipartFile cmf = (CommonsMultipartFile) file; - cmf.getFileItem().delete(); - LogFormatUtils.traceDebug(logger, traceOn -> - "Cleaning up part '" + cmf.getName() + - "', filename '" + cmf.getOriginalFilename() + "'" + - (traceOn ? ", stored " + cmf.getStorageDescription() : "")); - } - } - } - } - - private String determineEncoding(String contentTypeHeader, String defaultEncoding) { - if (!StringUtils.hasText(contentTypeHeader)) { - return defaultEncoding; - } - MediaType contentType = MediaType.parseMediaType(contentTypeHeader); - Charset charset = contentType.getCharset(); - return (charset != null ? charset.name() : defaultEncoding); - } - - - /** - * Holder for a Map of Spring MultipartFiles and a Map of - * multipart parameters. - */ - protected static class MultipartParsingResult { - - private final MultiValueMap multipartFiles; - - private final Map multipartParameters; - - private final Map multipartParameterContentTypes; - - public MultipartParsingResult(MultiValueMap mpFiles, - Map mpParams, Map mpParamContentTypes) { - - this.multipartFiles = mpFiles; - this.multipartParameters = mpParams; - this.multipartParameterContentTypes = mpParamContentTypes; - } - - public MultiValueMap getMultipartFiles() { - return this.multipartFiles; - } - - public Map getMultipartParameters() { - return this.multipartParameters; - } - - public Map getMultipartParameterContentTypes() { - return this.multipartParameterContentTypes; - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartFile.java b/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartFile.java deleted file mode 100644 index 691b52519e23..000000000000 --- a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartFile.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.multipart.commons; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.nio.file.Files; -import java.nio.file.Path; - -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileUploadException; -import org.apache.commons.fileupload.disk.DiskFileItem; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.core.log.LogFormatUtils; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.StreamUtils; -import org.springframework.web.multipart.MultipartFile; - -/** - * {@link MultipartFile} implementation for Apache Commons FileUpload. - * - * @author Trevor D. Cook - * @author Juergen Hoeller - * @since 29.09.2003 - * @see CommonsMultipartResolver - */ -@SuppressWarnings("serial") -public class CommonsMultipartFile implements MultipartFile, Serializable { - - protected static final Log logger = LogFactory.getLog(CommonsMultipartFile.class); - - private final FileItem fileItem; - - private final long size; - - private boolean preserveFilename = false; - - - /** - * Create an instance wrapping the given FileItem. - * @param fileItem the FileItem to wrap - */ - public CommonsMultipartFile(FileItem fileItem) { - this.fileItem = fileItem; - this.size = this.fileItem.getSize(); - } - - - /** - * Return the underlying {@code org.apache.commons.fileupload.FileItem} - * instance. There is hardly any need to access this. - */ - public final FileItem getFileItem() { - return this.fileItem; - } - - /** - * Set whether to preserve the filename as sent by the client, not stripping off - * path information in {@link CommonsMultipartFile#getOriginalFilename()}. - *

    Default is "false", stripping off path information that may prefix the - * actual filename e.g. from Opera. Switch this to "true" for preserving the - * client-specified filename as-is, including potential path separators. - * @since 4.3.5 - * @see #getOriginalFilename() - * @see CommonsMultipartResolver#setPreserveFilename(boolean) - */ - public void setPreserveFilename(boolean preserveFilename) { - this.preserveFilename = preserveFilename; - } - - - @Override - public String getName() { - return this.fileItem.getFieldName(); - } - - @Override - public String getOriginalFilename() { - String filename = this.fileItem.getName(); - if (filename == null) { - // Should never happen. - return ""; - } - if (this.preserveFilename) { - // Do not try to strip off a path... - return filename; - } - - // Check for Unix-style path - int unixSep = filename.lastIndexOf('/'); - // Check for Windows-style path - int winSep = filename.lastIndexOf('\\'); - // Cut off at latest possible point - int pos = Math.max(winSep, unixSep); - if (pos != -1) { - // Any sort of path separator found... - return filename.substring(pos + 1); - } - else { - // A plain name - return filename; - } - } - - @Override - public String getContentType() { - return this.fileItem.getContentType(); - } - - @Override - public boolean isEmpty() { - return (this.size == 0); - } - - @Override - public long getSize() { - return this.size; - } - - @Override - public byte[] getBytes() { - if (!isAvailable()) { - throw new IllegalStateException("File has been moved - cannot be read again"); - } - byte[] bytes = this.fileItem.get(); - return (bytes != null ? bytes : new byte[0]); - } - - @Override - public InputStream getInputStream() throws IOException { - if (!isAvailable()) { - throw new IllegalStateException("File has been moved - cannot be read again"); - } - InputStream inputStream = this.fileItem.getInputStream(); - return (inputStream != null ? inputStream : StreamUtils.emptyInput()); - } - - @Override - public void transferTo(File dest) throws IOException, IllegalStateException { - if (!isAvailable()) { - throw new IllegalStateException("File has already been moved - cannot be transferred again"); - } - - if (dest.exists() && !dest.delete()) { - throw new IOException( - "Destination file [" + dest.getAbsolutePath() + "] already exists and could not be deleted"); - } - - try { - this.fileItem.write(dest); - LogFormatUtils.traceDebug(logger, traceOn -> { - String action = "transferred"; - if (!this.fileItem.isInMemory()) { - action = (isAvailable() ? "copied" : "moved"); - } - return "Part '" + getName() + "', filename '" + getOriginalFilename() + "'" + - (traceOn ? ", stored " + getStorageDescription() : "") + - ": " + action + " to [" + dest.getAbsolutePath() + "]"; - }); - } - catch (FileUploadException ex) { - throw new IllegalStateException(ex.getMessage(), ex); - } - catch (IllegalStateException | IOException ex) { - // Pass through IllegalStateException when coming from FileItem directly, - // or propagate an exception from I/O operations within FileItem.write - throw ex; - } - catch (Exception ex) { - throw new IOException("File transfer failed", ex); - } - } - - @Override - public void transferTo(Path dest) throws IOException, IllegalStateException { - if (!isAvailable()) { - throw new IllegalStateException("File has already been moved - cannot be transferred again"); - } - - FileCopyUtils.copy(this.fileItem.getInputStream(), Files.newOutputStream(dest)); - } - - /** - * Determine whether the multipart content is still available. - * If a temporary file has been moved, the content is no longer available. - */ - protected boolean isAvailable() { - // If in memory, it's available. - if (this.fileItem.isInMemory()) { - return true; - } - // Check actual existence of temporary file. - if (this.fileItem instanceof DiskFileItem) { - return ((DiskFileItem) this.fileItem).getStoreLocation().exists(); - } - // Check whether current file size is different than original one. - return (this.fileItem.getSize() == this.size); - } - - /** - * Return a description for the storage location of the multipart content. - * Tries to be as specific as possible: mentions the file location in case - * of a temporary file. - */ - public String getStorageDescription() { - if (this.fileItem.isInMemory()) { - return "in memory"; - } - else if (this.fileItem instanceof DiskFileItem) { - return "at [" + ((DiskFileItem) this.fileItem).getStoreLocation().getAbsolutePath() + "]"; - } - else { - return "on disk"; - } - } - - @Override - public String toString() { - return "MultipartFile[field=\"" + this.fileItem.getFieldName() + "\"" + - (this.fileItem.getName() != null ? ", filename=" + this.fileItem.getName() : "" ) + - (this.fileItem.getContentType() != null ? ", contentType=" + this.fileItem.getContentType() : "") + - ", size=" + this.fileItem.getSize() + "]"; - } -} diff --git a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartResolver.java b/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartResolver.java deleted file mode 100644 index b6911fe9813d..000000000000 --- a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartResolver.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.multipart.commons; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileItemFactory; -import org.apache.commons.fileupload.FileUpload; -import org.apache.commons.fileupload.FileUploadBase; -import org.apache.commons.fileupload.FileUploadException; -import org.apache.commons.fileupload.servlet.ServletFileUpload; -import org.apache.commons.fileupload.servlet.ServletRequestContext; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.web.context.ServletContextAware; -import org.springframework.web.multipart.MaxUploadSizeExceededException; -import org.springframework.web.multipart.MultipartException; -import org.springframework.web.multipart.MultipartHttpServletRequest; -import org.springframework.web.multipart.MultipartResolver; -import org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest; -import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest; -import org.springframework.web.util.WebUtils; - -/** - * Servlet-based {@link MultipartResolver} implementation for - * Apache Commons FileUpload - * 1.2 or above. This resolver variant delegates to a local FileUpload library - * within the application, providing maximum portability across Servlet containers. - * - *

    Commons FileUpload traditionally parses POST requests with any "multipart/" type. - * Supported HTTP methods may be customized through {@link #setSupportedMethods}. - * - *

    Provides "maxUploadSize", "maxInMemorySize" and "defaultEncoding" settings as - * bean properties (inherited from {@link CommonsFileUploadSupport}). See corresponding - * ServletFileUpload / DiskFileItemFactory properties ("sizeMax", "sizeThreshold", - * "headerEncoding") for details in terms of defaults and accepted values. - * - *

    Saves temporary files to the servlet container's temporary directory. - * Needs to be initialized either by an application context or - * via the constructor that takes a ServletContext (for standalone usage). - * - *

    Note: The common alternative is - * {@link org.springframework.web.multipart.support.StandardServletMultipartResolver}, - * delegating to the Servlet container's own multipart parser, with configuration to - * happen at the container level and potentially with container-specific limitations. - * - * @author Trevor D. Cook - * @author Juergen Hoeller - * @since 29.09.2003 - * @see #CommonsMultipartResolver(ServletContext) - * @see #setResolveLazily - * @see #setSupportedMethods - * @see org.apache.commons.fileupload.servlet.ServletFileUpload - * @see org.apache.commons.fileupload.disk.DiskFileItemFactory - * @see org.springframework.web.multipart.support.StandardServletMultipartResolver - */ -public class CommonsMultipartResolver extends CommonsFileUploadSupport - implements MultipartResolver, ServletContextAware { - - private boolean resolveLazily = false; - - @Nullable - private Set supportedMethods; - - - /** - * Constructor for use as bean. Determines the servlet container's - * temporary directory via the ServletContext passed in as through the - * ServletContextAware interface (typically by a WebApplicationContext). - * @see #setServletContext - * @see org.springframework.web.context.ServletContextAware - * @see org.springframework.web.context.WebApplicationContext - */ - public CommonsMultipartResolver() { - super(); - } - - /** - * Constructor for standalone usage. Determines the servlet container's - * temporary directory via the given ServletContext. - * @param servletContext the ServletContext to use - */ - public CommonsMultipartResolver(ServletContext servletContext) { - this(); - setServletContext(servletContext); - } - - - /** - * Set whether to resolve the multipart request lazily at the time of - * file or parameter access. - *

    Default is "false", resolving the multipart elements immediately, throwing - * corresponding exceptions at the time of the {@link #resolveMultipart} call. - * Switch this to "true" for lazy multipart parsing, throwing parse exceptions - * once the application attempts to obtain multipart files or parameters. - */ - public void setResolveLazily(boolean resolveLazily) { - this.resolveLazily = resolveLazily; - } - - /** - * Specify supported methods as an array of HTTP method names. - * The traditional Commons FileUpload default is "POST" only. - *

    When configured as a Spring property value, - * this can be a comma-separated String: e.g. "POST,PUT". - * @since 5.3.9 - */ - public void setSupportedMethods(String... supportedMethods) { - this.supportedMethods = new HashSet<>(Arrays.asList(supportedMethods)); - } - - /** - * Initialize the underlying {@code org.apache.commons.fileupload.servlet.ServletFileUpload} - * instance. Can be overridden to use a custom subclass, e.g. for testing purposes. - * @param fileItemFactory the Commons FileItemFactory to use - * @return the new ServletFileUpload instance - */ - @Override - protected FileUpload newFileUpload(FileItemFactory fileItemFactory) { - return new ServletFileUpload(fileItemFactory); - } - - @Override - public void setServletContext(ServletContext servletContext) { - if (!isUploadTempDirSpecified()) { - getFileItemFactory().setRepository(WebUtils.getTempDir(servletContext)); - } - } - - - @Override - public boolean isMultipart(HttpServletRequest request) { - return (this.supportedMethods != null ? - this.supportedMethods.contains(request.getMethod()) && - FileUploadBase.isMultipartContent(new ServletRequestContext(request)) : - ServletFileUpload.isMultipartContent(request)); - } - - @Override - public MultipartHttpServletRequest resolveMultipart(final HttpServletRequest request) throws MultipartException { - Assert.notNull(request, "Request must not be null"); - if (this.resolveLazily) { - return new DefaultMultipartHttpServletRequest(request) { - @Override - protected void initializeMultipart() { - MultipartParsingResult parsingResult = parseRequest(request); - setMultipartFiles(parsingResult.getMultipartFiles()); - setMultipartParameters(parsingResult.getMultipartParameters()); - setMultipartParameterContentTypes(parsingResult.getMultipartParameterContentTypes()); - } - }; - } - else { - MultipartParsingResult parsingResult = parseRequest(request); - return new DefaultMultipartHttpServletRequest(request, parsingResult.getMultipartFiles(), - parsingResult.getMultipartParameters(), parsingResult.getMultipartParameterContentTypes()); - } - } - - /** - * Parse the given servlet request, resolving its multipart elements. - * @param request the request to parse - * @return the parsing result - * @throws MultipartException if multipart resolution failed. - */ - protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException { - String encoding = determineEncoding(request); - FileUpload fileUpload = prepareFileUpload(encoding); - try { - List fileItems = ((ServletFileUpload) fileUpload).parseRequest(request); - return parseFileItems(fileItems, encoding); - } - catch (FileUploadBase.SizeLimitExceededException ex) { - throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex); - } - catch (FileUploadBase.FileSizeLimitExceededException ex) { - throw new MaxUploadSizeExceededException(fileUpload.getFileSizeMax(), ex); - } - catch (FileUploadException ex) { - throw new MultipartException("Failed to parse multipart servlet request", ex); - } - } - - /** - * Determine the encoding for the given request. - * Can be overridden in subclasses. - *

    The default implementation checks the request encoding, - * falling back to the default encoding specified for this resolver. - * @param request current HTTP request - * @return the encoding for the request (never {@code null}) - * @see javax.servlet.ServletRequest#getCharacterEncoding - * @see #setDefaultEncoding - */ - protected String determineEncoding(HttpServletRequest request) { - String encoding = request.getCharacterEncoding(); - if (encoding == null) { - encoding = getDefaultEncoding(); - } - return encoding; - } - - @Override - public void cleanupMultipart(MultipartHttpServletRequest request) { - if (!(request instanceof AbstractMultipartHttpServletRequest) || - ((AbstractMultipartHttpServletRequest) request).isResolved()) { - try { - cleanupFileItems(request.getMultiFileMap()); - } - catch (Throwable ex) { - logger.warn("Failed to perform multipart cleanup for servlet request", ex); - } - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/multipart/commons/package-info.java b/spring-web/src/main/java/org/springframework/web/multipart/commons/package-info.java deleted file mode 100644 index 03b636815d45..000000000000 --- a/spring-web/src/main/java/org/springframework/web/multipart/commons/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * MultipartResolver implementation for - * Apache Commons FileUpload. - */ -@NonNullApi -@NonNullFields -package org.springframework.web.multipart.commons; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/AbstractMultipartHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/AbstractMultipartHttpServletRequest.java index 3c2a8834c563..8504b96816c9 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/AbstractMultipartHttpServletRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/AbstractMultipartHttpServletRequest.java @@ -22,8 +22,8 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java index d882620af27b..3a7859e56159 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.Set; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/MissingServletRequestPartException.java b/spring-web/src/main/java/org/springframework/web/multipart/support/MissingServletRequestPartException.java index 414405d8038f..f19d587f5e2f 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/MissingServletRequestPartException.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/MissingServletRequestPartException.java @@ -16,7 +16,7 @@ package org.springframework.web.multipart.support; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; import org.springframework.web.multipart.MultipartResolver; diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java b/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java index 1cd8fb2c3cec..276c5a05e201 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java @@ -18,10 +18,10 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartResolutionDelegate.java b/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartResolutionDelegate.java index 7d554e9052d7..6d480e858147 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartResolutionDelegate.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartResolutionDelegate.java @@ -20,8 +20,8 @@ import java.util.Collection; import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.Part; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.Part; import org.springframework.core.MethodParameter; import org.springframework.core.ResolvableType; diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java index e390f90f733f..aa1bfca3c3fc 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java @@ -21,8 +21,8 @@ import java.io.InputStream; import java.nio.charset.Charset; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.Part; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.Part; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java index 6970c8e12ea7..7f21e5e2775b 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java @@ -32,9 +32,9 @@ import java.util.Map; import java.util.Set; -import javax.mail.internet.MimeUtility; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.Part; +import jakarta.mail.internet.MimeUtility; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.Part; import org.springframework.http.ContentDisposition; import org.springframework.http.HttpHeaders; diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java index dc06f0768bee..3a29473a4afb 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java @@ -16,9 +16,8 @@ package org.springframework.web.multipart.support; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.Part; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.Part; import org.apache.commons.logging.LogFactory; import org.springframework.http.MediaType; @@ -29,7 +28,7 @@ /** * Standard implementation of the {@link MultipartResolver} interface, - * based on the Servlet 3.0 {@link javax.servlet.http.Part} API. + * based on the Servlet 3.0 {@link jakarta.servlet.http.Part} API. * To be added as "multipartResolver" bean to a Spring DispatcherServlet context, * without any extra configuration at the bean level (see below). * @@ -44,9 +43,9 @@ * *

    Note: In order to use Servlet 3.0 based multipart parsing, * you need to mark the affected servlet with a "multipart-config" section in - * {@code web.xml}, or with a {@link javax.servlet.MultipartConfigElement} + * {@code web.xml}, or with a {@link jakarta.servlet.MultipartConfigElement} * in programmatic servlet registration, or (in case of a custom servlet class) - * possibly with a {@link javax.servlet.annotation.MultipartConfig} annotation + * possibly with a {@link jakarta.servlet.annotation.MultipartConfig} annotation * on your servlet class. Configuration settings such as maximum sizes or * storage locations need to be applied at that servlet registration level; * Servlet 3.0 does not allow for them to be set at the MultipartResolver level. diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletPartUtils.java b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletPartUtils.java index 6a9da0981c5f..5b5b18f13231 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletPartUtils.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletPartUtils.java @@ -19,8 +19,8 @@ import java.util.ArrayList; import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.Part; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.Part; import org.springframework.beans.MutablePropertyValues; import org.springframework.util.LinkedMultiValueMap; diff --git a/spring-web/src/main/java/org/springframework/web/server/adapter/AbstractReactiveWebInitializer.java b/spring-web/src/main/java/org/springframework/web/server/adapter/AbstractReactiveWebInitializer.java index afafa743394f..93db78699c2c 100644 --- a/spring-web/src/main/java/org/springframework/web/server/adapter/AbstractReactiveWebInitializer.java +++ b/spring-web/src/main/java/org/springframework/web/server/adapter/AbstractReactiveWebInitializer.java @@ -16,11 +16,11 @@ package org.springframework.web.server.adapter; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRegistration; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; diff --git a/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java b/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java index faa0ccbf6431..64df59fb2738 100644 --- a/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java +++ b/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java @@ -27,16 +27,16 @@ import java.util.List; import java.util.Map; -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; import org.springframework.http.HttpMethod; import org.springframework.lang.Nullable; /** - * {@link javax.servlet.http.HttpServletRequest} wrapper that caches all content read from + * {@link jakarta.servlet.http.HttpServletRequest} wrapper that caches all content read from * the {@linkplain #getInputStream() input stream} and {@linkplain #getReader() reader}, * and allows this content to be retrieved via a {@link #getContentAsByteArray() byte array}. * diff --git a/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java b/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java index 1b8d3337d801..d1de91db742d 100644 --- a/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java +++ b/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java @@ -22,17 +22,17 @@ import java.io.PrintWriter; import java.io.UnsupportedEncodingException; -import javax.servlet.ServletOutputStream; -import javax.servlet.WriteListener; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.WriteListener; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; import org.springframework.util.FastByteArrayOutputStream; /** - * {@link javax.servlet.http.HttpServletResponse} wrapper that caches all content written to + * {@link jakarta.servlet.http.HttpServletResponse} wrapper that caches all content written to * the {@linkplain #getOutputStream() output stream} and {@linkplain #getWriter() writer}, * and allows this content to be retrieved via a {@link #getContentAsByteArray() byte array}. * diff --git a/spring-web/src/main/java/org/springframework/web/util/CookieGenerator.java b/spring-web/src/main/java/org/springframework/web/util/CookieGenerator.java index 2324274e816c..82cc13d9eac6 100644 --- a/spring-web/src/main/java/org/springframework/web/util/CookieGenerator.java +++ b/spring-web/src/main/java/org/springframework/web/util/CookieGenerator.java @@ -16,9 +16,8 @@ package org.springframework.web.util; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -68,7 +67,7 @@ public class CookieGenerator { /** * Use the given name for cookies created by this generator. - * @see javax.servlet.http.Cookie#getName() + * @see jakarta.servlet.http.Cookie#getName() */ public void setCookieName(@Nullable String cookieName) { this.cookieName = cookieName; @@ -85,7 +84,7 @@ public String getCookieName() { /** * Use the given domain for cookies created by this generator. * The cookie is only visible to servers in this domain. - * @see javax.servlet.http.Cookie#setDomain + * @see jakarta.servlet.http.Cookie#setDomain */ public void setCookieDomain(@Nullable String cookieDomain) { this.cookieDomain = cookieDomain; @@ -102,7 +101,7 @@ public String getCookieDomain() { /** * Use the given path for cookies created by this generator. * The cookie is only visible to URLs in this path and below. - * @see javax.servlet.http.Cookie#setPath + * @see jakarta.servlet.http.Cookie#setPath */ public void setCookiePath(String cookiePath) { this.cookiePath = cookiePath; @@ -120,7 +119,7 @@ public String getCookiePath() { * Useful special value: -1 ... not persistent, deleted when client shuts down. *

    Default is no specific maximum age at all, using the Servlet container's * default. - * @see javax.servlet.http.Cookie#setMaxAge + * @see jakarta.servlet.http.Cookie#setMaxAge */ public void setCookieMaxAge(@Nullable Integer cookieMaxAge) { this.cookieMaxAge = cookieMaxAge; @@ -139,7 +138,7 @@ public Integer getCookieMaxAge() { * such as HTTPS (SSL). This is an indication to the receiving browser, * not processed by the HTTP server itself. *

    Default is "false". - * @see javax.servlet.http.Cookie#setSecure + * @see jakarta.servlet.http.Cookie#setSecure */ public void setCookieSecure(boolean cookieSecure) { this.cookieSecure = cookieSecure; @@ -156,7 +155,7 @@ public boolean isCookieSecure() { /** * Set whether the cookie is supposed to be marked with the "HttpOnly" attribute. *

    Default is "false". - * @see javax.servlet.http.Cookie#setHttpOnly + * @see jakarta.servlet.http.Cookie#setHttpOnly */ public void setCookieHttpOnly(boolean cookieHttpOnly) { this.cookieHttpOnly = cookieHttpOnly; diff --git a/spring-web/src/main/java/org/springframework/web/util/HttpSessionMutexListener.java b/spring-web/src/main/java/org/springframework/web/util/HttpSessionMutexListener.java index 369904116fe2..348375146963 100644 --- a/spring-web/src/main/java/org/springframework/web/util/HttpSessionMutexListener.java +++ b/spring-web/src/main/java/org/springframework/web/util/HttpSessionMutexListener.java @@ -18,8 +18,8 @@ import java.io.Serializable; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; +import jakarta.servlet.http.HttpSessionEvent; +import jakarta.servlet.http.HttpSessionListener; /** * Servlet HttpSessionListener that automatically exposes the session mutex @@ -39,7 +39,7 @@ * @author Juergen Hoeller * @since 1.2.7 * @see WebUtils#SESSION_MUTEX_ATTRIBUTE - * @see WebUtils#getSessionMutex(javax.servlet.http.HttpSession) + * @see WebUtils#getSessionMutex(jakarta.servlet.http.HttpSession) * @see org.springframework.web.servlet.mvc.AbstractController#setSynchronizeOnSession */ public class HttpSessionMutexListener implements HttpSessionListener { diff --git a/spring-web/src/main/java/org/springframework/web/util/IntrospectorCleanupListener.java b/spring-web/src/main/java/org/springframework/web/util/IntrospectorCleanupListener.java index d3afef75f980..cdf38031364a 100644 --- a/spring-web/src/main/java/org/springframework/web/util/IntrospectorCleanupListener.java +++ b/spring-web/src/main/java/org/springframework/web/util/IntrospectorCleanupListener.java @@ -18,8 +18,8 @@ import java.beans.Introspector; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; import org.springframework.beans.CachedIntrospectionResults; diff --git a/spring-web/src/main/java/org/springframework/web/util/NestedServletException.java b/spring-web/src/main/java/org/springframework/web/util/NestedServletException.java index 1f8db8376beb..08fc49bbeacf 100644 --- a/spring-web/src/main/java/org/springframework/web/util/NestedServletException.java +++ b/spring-web/src/main/java/org/springframework/web/util/NestedServletException.java @@ -16,7 +16,7 @@ package org.springframework.web.util; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; import org.springframework.core.NestedExceptionUtils; import org.springframework.lang.Nullable; diff --git a/spring-web/src/main/java/org/springframework/web/util/ServletContextPropertyUtils.java b/spring-web/src/main/java/org/springframework/web/util/ServletContextPropertyUtils.java index ffaefa75b4be..d0c07c9222a3 100644 --- a/spring-web/src/main/java/org/springframework/web/util/ServletContextPropertyUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/ServletContextPropertyUtils.java @@ -16,7 +16,7 @@ package org.springframework.web.util; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.lang.Nullable; import org.springframework.util.PropertyPlaceholderHelper; diff --git a/spring-web/src/main/java/org/springframework/web/util/ServletRequestPathUtils.java b/spring-web/src/main/java/org/springframework/web/util/ServletRequestPathUtils.java index b757f3e59f81..19c2c7742c85 100644 --- a/spring-web/src/main/java/org/springframework/web/util/ServletRequestPathUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/ServletRequestPathUtils.java @@ -18,11 +18,11 @@ import java.nio.charset.StandardCharsets; import java.util.List; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletMapping; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.MappingMatch; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletMapping; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.MappingMatch; import org.springframework.http.server.PathContainer; import org.springframework.http.server.RequestPath; diff --git a/spring-web/src/main/java/org/springframework/web/util/TagUtils.java b/spring-web/src/main/java/org/springframework/web/util/TagUtils.java index f1e206547b2a..d299c11de569 100644 --- a/spring-web/src/main/java/org/springframework/web/util/TagUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/TagUtils.java @@ -16,8 +16,8 @@ package org.springframework.web.util; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.Tag; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.Tag; import org.springframework.util.Assert; @@ -28,13 +28,13 @@ *

    *

      *
    • {@code page} will be transformed to - * {@link javax.servlet.jsp.PageContext#PAGE_SCOPE PageContext.PAGE_SCOPE} + * {@link jakarta.servlet.jsp.PageContext#PAGE_SCOPE PageContext.PAGE_SCOPE} *
    • {@code request} will be transformed to - * {@link javax.servlet.jsp.PageContext#REQUEST_SCOPE PageContext.REQUEST_SCOPE} + * {@link jakarta.servlet.jsp.PageContext#REQUEST_SCOPE PageContext.REQUEST_SCOPE} *
    • {@code session} will be transformed to - * {@link javax.servlet.jsp.PageContext#SESSION_SCOPE PageContext.SESSION_SCOPE} + * {@link jakarta.servlet.jsp.PageContext#SESSION_SCOPE PageContext.SESSION_SCOPE} *
    • {@code application} will be transformed to - * {@link javax.servlet.jsp.PageContext#APPLICATION_SCOPE PageContext.APPLICATION_SCOPE} + * {@link jakarta.servlet.jsp.PageContext#APPLICATION_SCOPE PageContext.APPLICATION_SCOPE} *
    * * @author Alef Arendsen @@ -123,7 +123,7 @@ public static boolean hasAncestorOfType(Tag tag, Class ancestorTagClass) { * or in the case of the {@link String}-typed arguments, is composed wholly * of whitespace; or if the supplied {@code ancestorTagClass} is not * type-assignable to the {@link Tag} class - * @see #hasAncestorOfType(javax.servlet.jsp.tagext.Tag, Class) + * @see #hasAncestorOfType(jakarta.servlet.jsp.tagext.Tag, Class) */ public static void assertHasAncestorOfType(Tag tag, Class ancestorTagClass, String tagName, String ancestorTagName) { diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java index 663dbb7566c4..a17335391a36 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java +++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java @@ -21,12 +21,11 @@ import java.util.Map; import java.util.Properties; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletMapping; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.MappingMatch; - +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletMapping; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.MappingMatch; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -51,7 +50,7 @@ * @author Rossen Stoyanchev * @since 14.01.2004 * @see #getLookupPathForRequest - * @see javax.servlet.RequestDispatcher + * @see jakarta.servlet.RequestDispatcher */ public class UrlPathHelper { @@ -92,7 +91,7 @@ public class UrlPathHelper { /** * Whether URL lookups should always use the full path within the current * web application context, i.e. within - * {@link javax.servlet.ServletContext#getContextPath()}. + * {@link jakarta.servlet.ServletContext#getContextPath()}. *

    If set to {@literal false} the path within the current servlet mapping * is used instead if applicable (i.e. in the case of a prefix based Servlet * mapping such as "/myServlet/*"). @@ -118,7 +117,7 @@ public void setAlwaysUseFullPath(boolean alwaysUseFullPath) { * @see #getContextPath * @see #getRequestUri * @see WebUtils#DEFAULT_CHARACTER_ENCODING - * @see javax.servlet.ServletRequest#getCharacterEncoding() + * @see jakarta.servlet.ServletRequest#getCharacterEncoding() * @see java.net.URLDecoder#decode(String, String) */ public void setUrlDecode(boolean urlDecode) { @@ -159,8 +158,8 @@ public boolean shouldRemoveSemicolonContent() { * {@code ServletRequest.setCharacterEncoding} method. * @param defaultEncoding the character encoding to use * @see #determineEncoding - * @see javax.servlet.ServletRequest#getCharacterEncoding() - * @see javax.servlet.ServletRequest#setCharacterEncoding(String) + * @see jakarta.servlet.ServletRequest#getCharacterEncoding() + * @see jakarta.servlet.ServletRequest#setCharacterEncoding(String) * @see WebUtils#DEFAULT_CHARACTER_ENCODING */ public void setDefaultEncoding(String defaultEncoding) { @@ -558,7 +557,7 @@ private String decodeAndCleanUriString(HttpServletRequest request, String uri) { * @param source the String to decode * @return the decoded String * @see WebUtils#DEFAULT_CHARACTER_ENCODING - * @see javax.servlet.ServletRequest#getCharacterEncoding + * @see jakarta.servlet.ServletRequest#getCharacterEncoding * @see java.net.URLDecoder#decode(String, String) * @see java.net.URLDecoder#decode(String) */ @@ -591,7 +590,7 @@ private String decodeInternal(HttpServletRequest request, String source) { * falling back to the default encoding specified for this resolver. * @param request current HTTP request * @return the encoding for the request (never {@code null}) - * @see javax.servlet.ServletRequest#getCharacterEncoding() + * @see jakarta.servlet.ServletRequest#getCharacterEncoding() * @see #setDefaultEncoding */ protected String determineEncoding(HttpServletRequest request) { diff --git a/spring-web/src/main/java/org/springframework/web/util/WebAppRootListener.java b/spring-web/src/main/java/org/springframework/web/util/WebAppRootListener.java index bd340eea48ba..d96231b501c2 100644 --- a/spring-web/src/main/java/org/springframework/web/util/WebAppRootListener.java +++ b/spring-web/src/main/java/org/springframework/web/util/WebAppRootListener.java @@ -16,8 +16,8 @@ package org.springframework.web.util; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; /** * Listener that sets a system property to the web application root directory. diff --git a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java index 8a0e76127ae8..7b4c471371ac 100644 --- a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java @@ -25,15 +25,15 @@ import java.util.StringTokenizer; import java.util.TreeMap; -import javax.servlet.ServletContext; -import javax.servlet.ServletRequest; -import javax.servlet.ServletRequestWrapper; -import javax.servlet.ServletResponse; -import javax.servlet.ServletResponseWrapper; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletRequestWrapper; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.ServletResponseWrapper; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpRequest; @@ -61,70 +61,70 @@ public abstract class WebUtils { *

    If included via a {@code RequestDispatcher}, the current resource will see the * originating request. Its own request URI is exposed as a request attribute. */ - public static final String INCLUDE_REQUEST_URI_ATTRIBUTE = "javax.servlet.include.request_uri"; + public static final String INCLUDE_REQUEST_URI_ATTRIBUTE = "jakarta.servlet.include.request_uri"; /** * Standard Servlet 2.3+ spec request attribute for include context path. *

    If included via a {@code RequestDispatcher}, the current resource will see the * originating context path. Its own context path is exposed as a request attribute. */ - public static final String INCLUDE_CONTEXT_PATH_ATTRIBUTE = "javax.servlet.include.context_path"; + public static final String INCLUDE_CONTEXT_PATH_ATTRIBUTE = "jakarta.servlet.include.context_path"; /** * Standard Servlet 2.3+ spec request attribute for include servlet path. *

    If included via a {@code RequestDispatcher}, the current resource will see the * originating servlet path. Its own servlet path is exposed as a request attribute. */ - public static final String INCLUDE_SERVLET_PATH_ATTRIBUTE = "javax.servlet.include.servlet_path"; + public static final String INCLUDE_SERVLET_PATH_ATTRIBUTE = "jakarta.servlet.include.servlet_path"; /** * Standard Servlet 2.3+ spec request attribute for include path info. *

    If included via a {@code RequestDispatcher}, the current resource will see the * originating path info. Its own path info is exposed as a request attribute. */ - public static final String INCLUDE_PATH_INFO_ATTRIBUTE = "javax.servlet.include.path_info"; + public static final String INCLUDE_PATH_INFO_ATTRIBUTE = "jakarta.servlet.include.path_info"; /** * Standard Servlet 2.3+ spec request attribute for include query string. *

    If included via a {@code RequestDispatcher}, the current resource will see the * originating query string. Its own query string is exposed as a request attribute. */ - public static final String INCLUDE_QUERY_STRING_ATTRIBUTE = "javax.servlet.include.query_string"; + public static final String INCLUDE_QUERY_STRING_ATTRIBUTE = "jakarta.servlet.include.query_string"; /** * Standard Servlet 2.4+ spec request attribute for forward request URI. *

    If forwarded to via a RequestDispatcher, the current resource will see its * own request URI. The originating request URI is exposed as a request attribute. */ - public static final String FORWARD_REQUEST_URI_ATTRIBUTE = "javax.servlet.forward.request_uri"; + public static final String FORWARD_REQUEST_URI_ATTRIBUTE = "jakarta.servlet.forward.request_uri"; /** * Standard Servlet 2.4+ spec request attribute for forward context path. *

    If forwarded to via a RequestDispatcher, the current resource will see its * own context path. The originating context path is exposed as a request attribute. */ - public static final String FORWARD_CONTEXT_PATH_ATTRIBUTE = "javax.servlet.forward.context_path"; + public static final String FORWARD_CONTEXT_PATH_ATTRIBUTE = "jakarta.servlet.forward.context_path"; /** * Standard Servlet 2.4+ spec request attribute for forward servlet path. *

    If forwarded to via a RequestDispatcher, the current resource will see its * own servlet path. The originating servlet path is exposed as a request attribute. */ - public static final String FORWARD_SERVLET_PATH_ATTRIBUTE = "javax.servlet.forward.servlet_path"; + public static final String FORWARD_SERVLET_PATH_ATTRIBUTE = "jakarta.servlet.forward.servlet_path"; /** * Standard Servlet 2.4+ spec request attribute for forward path info. *

    If forwarded to via a RequestDispatcher, the current resource will see its * own path ingo. The originating path info is exposed as a request attribute. */ - public static final String FORWARD_PATH_INFO_ATTRIBUTE = "javax.servlet.forward.path_info"; + public static final String FORWARD_PATH_INFO_ATTRIBUTE = "jakarta.servlet.forward.path_info"; /** * Standard Servlet 2.4+ spec request attribute for forward query string. *

    If forwarded to via a RequestDispatcher, the current resource will see its * own query string. The originating query string is exposed as a request attribute. */ - public static final String FORWARD_QUERY_STRING_ATTRIBUTE = "javax.servlet.forward.query_string"; + public static final String FORWARD_QUERY_STRING_ATTRIBUTE = "jakarta.servlet.forward.query_string"; /** * Standard Servlet 2.3+ spec request attribute for error page status code. @@ -132,7 +132,7 @@ public abstract class WebUtils { * to them directly rather than through the servlet container's error page * resolution mechanism. */ - public static final String ERROR_STATUS_CODE_ATTRIBUTE = "javax.servlet.error.status_code"; + public static final String ERROR_STATUS_CODE_ATTRIBUTE = "jakarta.servlet.error.status_code"; /** * Standard Servlet 2.3+ spec request attribute for error page exception type. @@ -140,7 +140,7 @@ public abstract class WebUtils { * to them directly rather than through the servlet container's error page * resolution mechanism. */ - public static final String ERROR_EXCEPTION_TYPE_ATTRIBUTE = "javax.servlet.error.exception_type"; + public static final String ERROR_EXCEPTION_TYPE_ATTRIBUTE = "jakarta.servlet.error.exception_type"; /** * Standard Servlet 2.3+ spec request attribute for error page message. @@ -148,7 +148,7 @@ public abstract class WebUtils { * to them directly rather than through the servlet container's error page * resolution mechanism. */ - public static final String ERROR_MESSAGE_ATTRIBUTE = "javax.servlet.error.message"; + public static final String ERROR_MESSAGE_ATTRIBUTE = "jakarta.servlet.error.message"; /** * Standard Servlet 2.3+ spec request attribute for error page exception. @@ -156,7 +156,7 @@ public abstract class WebUtils { * to them directly rather than through the servlet container's error page * resolution mechanism. */ - public static final String ERROR_EXCEPTION_ATTRIBUTE = "javax.servlet.error.exception"; + public static final String ERROR_EXCEPTION_ATTRIBUTE = "jakarta.servlet.error.exception"; /** * Standard Servlet 2.3+ spec request attribute for error page request URI. @@ -164,7 +164,7 @@ public abstract class WebUtils { * to them directly rather than through the servlet container's error page * resolution mechanism. */ - public static final String ERROR_REQUEST_URI_ATTRIBUTE = "javax.servlet.error.request_uri"; + public static final String ERROR_REQUEST_URI_ATTRIBUTE = "jakarta.servlet.error.request_uri"; /** * Standard Servlet 2.3+ spec request attribute for error page servlet name. @@ -172,7 +172,7 @@ public abstract class WebUtils { * to them directly rather than through the servlet container's error page * resolution mechanism. */ - public static final String ERROR_SERVLET_NAME_ATTRIBUTE = "javax.servlet.error.servlet_name"; + public static final String ERROR_SERVLET_NAME_ATTRIBUTE = "jakarta.servlet.error.servlet_name"; /** * Prefix of the charset clause in a content type String: ";charset=". @@ -190,7 +190,7 @@ public abstract class WebUtils { * Standard Servlet spec context attribute that specifies a temporary * directory for the current web application, of type {@code java.io.File}. */ - public static final String TEMP_DIR_CONTEXT_ATTRIBUTE = "javax.servlet.context.tempdir"; + public static final String TEMP_DIR_CONTEXT_ATTRIBUTE = "jakarta.servlet.context.tempdir"; /** * HTML escape parameter at the servlet context level @@ -331,7 +331,7 @@ public static File getTempDir(ServletContext servletContext) { * @param path the path within the web application * @return the corresponding real path * @throws FileNotFoundException if the path cannot be resolved to a resource - * @see javax.servlet.ServletContext#getRealPath + * @see jakarta.servlet.ServletContext#getRealPath */ public static String getRealPath(ServletContext servletContext, String path) throws FileNotFoundException { Assert.notNull(servletContext, "ServletContext must not be null"); @@ -492,7 +492,7 @@ else if (response instanceof ServletResponseWrapper) { /** * Determine whether the given request is an include request, * that is, not a top-level HTTP request coming in from the outside. - *

    Checks the presence of the "javax.servlet.include.request_uri" + *

    Checks the presence of the "jakarta.servlet.include.request_uri" * request attribute. Could check any request attribute that is only * present in an include request. * @param request current servlet request @@ -503,18 +503,18 @@ public static boolean isIncludeRequest(ServletRequest request) { } /** - * Expose the Servlet spec's error attributes as {@link javax.servlet.http.HttpServletRequest} + * Expose the Servlet spec's error attributes as {@link jakarta.servlet.http.HttpServletRequest} * attributes under the keys defined in the Servlet 2.3 specification, for error pages that * are rendered directly rather than through the Servlet container's error page resolution: - * {@code javax.servlet.error.status_code}, - * {@code javax.servlet.error.exception_type}, - * {@code javax.servlet.error.message}, - * {@code javax.servlet.error.exception}, - * {@code javax.servlet.error.request_uri}, - * {@code javax.servlet.error.servlet_name}. + * {@code jakarta.servlet.error.status_code}, + * {@code jakarta.servlet.error.exception_type}, + * {@code jakarta.servlet.error.message}, + * {@code jakarta.servlet.error.exception}, + * {@code jakarta.servlet.error.request_uri}, + * {@code jakarta.servlet.error.servlet_name}. *

    Does not override values if already present, to respect attribute values * that have been exposed explicitly before. - *

    Exposes status code 200 by default. Set the "javax.servlet.error.status_code" + *

    Exposes status code 200 by default. Set the "jakarta.servlet.error.status_code" * attribute explicitly (before or after) in order to expose a different status code. * @param request current servlet request * @param ex the exception encountered @@ -546,14 +546,14 @@ private static void exposeRequestAttributeIfNotPresent(ServletRequest request, S } /** - * Clear the Servlet spec's error attributes as {@link javax.servlet.http.HttpServletRequest} + * Clear the Servlet spec's error attributes as {@link jakarta.servlet.http.HttpServletRequest} * attributes under the keys defined in the Servlet 2.3 specification: - * {@code javax.servlet.error.status_code}, - * {@code javax.servlet.error.exception_type}, - * {@code javax.servlet.error.message}, - * {@code javax.servlet.error.exception}, - * {@code javax.servlet.error.request_uri}, - * {@code javax.servlet.error.servlet_name}. + * {@code jakarta.servlet.error.status_code}, + * {@code jakarta.servlet.error.exception_type}, + * {@code jakarta.servlet.error.message}, + * {@code jakarta.servlet.error.exception}, + * {@code jakarta.servlet.error.request_uri}, + * {@code jakarta.servlet.error.servlet_name}. * @param request current servlet request */ public static void clearErrorRequestAttributes(HttpServletRequest request) { @@ -683,9 +683,9 @@ else if (value != null) { * (if this is null or the empty string, all parameters will match) * @return map containing request parameters without the prefix, * containing either a String or a String array as values - * @see javax.servlet.ServletRequest#getParameterNames - * @see javax.servlet.ServletRequest#getParameterValues - * @see javax.servlet.ServletRequest#getParameterMap + * @see jakarta.servlet.ServletRequest#getParameterNames + * @see jakarta.servlet.ServletRequest#getParameterValues + * @see jakarta.servlet.ServletRequest#getParameterMap */ public static Map getParametersStartingWith(ServletRequest request, @Nullable String prefix) { Assert.notNull(request, "Request must not be null"); diff --git a/spring-web/src/test/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriterTests.java b/spring-web/src/test/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriterTests.java index 17c057d6d6fb..a4b292f86af4 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriterTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriterTests.java @@ -180,9 +180,8 @@ public String getFilename() { assertThat(value).isEqualTo("AaBbCc"); } - @Test // gh-24582 + @Test // gh-24582 public void writeMultipartRelated() { - MediaType mediaType = MediaType.parseMediaType("multipart/related;type=foo"); MultipartBodyBuilder bodyBuilder = new MultipartBodyBuilder(); @@ -297,9 +296,9 @@ static MultiValueMap parse(MockServerHttpResponse response, Map parts = this.reader.readMono(PARTS_ELEMENT_TYPE, request, emptyMap()).block(); - - assertThat(parts).containsOnlyKeys("filePart", "textPart"); - - Part part = parts.getFirst("filePart"); - assertThat(part).isInstanceOf(FilePart.class); - assertThat(part.name()).isEqualTo("filePart"); - assertThat(((FilePart) part).filename()).isEqualTo("foo.txt"); - DataBuffer buffer = DataBufferUtils.join(part.content()).block(); - assertThat(buffer.toString(UTF_8)).isEqualTo("Lorem Ipsum."); - DataBufferUtils.release(buffer); - - part = parts.getFirst("textPart"); - assertThat(part).isInstanceOf(FormFieldPart.class); - assertThat(part.name()).isEqualTo("textPart"); - assertThat(((FormFieldPart) part).value()).isEqualTo("sample-text"); - } - - @Test // SPR-16545 - void transferTo() throws IOException { - ServerHttpRequest request = generateMultipartRequest(); - MultiValueMap parts = this.reader.readMono(PARTS_ELEMENT_TYPE, request, emptyMap()).block(); - - assertThat(parts).isNotNull(); - FilePart part = (FilePart) parts.getFirst("filePart"); - assertThat(part).isNotNull(); - - File dest = File.createTempFile(part.filename(), "multipart"); - part.transferTo(dest).block(Duration.ofSeconds(5)); - - assertThat(dest.exists()).isTrue(); - assertThat(dest.length()).isEqualTo(12); - assertThat(dest.delete()).isTrue(); - } - - @Test - void bodyError() { - ServerHttpRequest request = generateErrorMultipartRequest(); - StepVerifier.create(this.reader.readMono(PARTS_ELEMENT_TYPE, request, emptyMap())).verifyError(); - } - - @Test - void readPartsWithoutDemand() { - ServerHttpRequest request = generateMultipartRequest(); - Mono> parts = this.reader.readMono(PARTS_ELEMENT_TYPE, request, emptyMap()); - ZeroDemandSubscriber subscriber = new ZeroDemandSubscriber(); - parts.subscribe(subscriber); - subscriber.cancel(); - } - - @Test - void gh23768() throws IOException { - ReadableByteChannel channel = new ClassPathResource("invalid.multipart", getClass()).readableChannel(); - Flux body = DataBufferUtils.readByteChannel(() -> channel, this.bufferFactory, 1024); - - MediaType contentType = new MediaType("multipart", "form-data", - singletonMap("boundary", "NbjrKgjbsaMLdnMxMfDpD6myWomYc0qNX0w")); - ServerHttpRequest request = MockServerHttpRequest.post("/") - .contentType(contentType) - .body(body); - - Mono> parts = this.reader.readMono(PARTS_ELEMENT_TYPE, request, emptyMap()); - - StepVerifier.create(parts) - .assertNext(result -> assertThat(result).isEmpty()) - .verifyComplete(); - } - - @Test - void readTooManyParts() { - testMultipartExceptions(reader -> reader.setMaxParts(1), - ex -> assertThat(ex) - .isInstanceOf(DecodingException.class) - .hasMessageStartingWith("Failure while parsing part[2]") - .hasRootCauseMessage("Too many parts: Part[2] but maxParts=1") - ); - } - - @Test - void readFilePartTooBig() { - testMultipartExceptions(reader -> reader.setMaxDiskUsagePerPart(5), - ex -> assertThat(ex) - .isInstanceOf(DecodingException.class) - .hasMessageStartingWith("Failure while parsing part[1]") - .hasRootCauseMessage("Part[1] exceeded the disk usage limit of 5 bytes") - ); - } - - @Test - void readPartHeadersTooBig() { - testMultipartExceptions(reader -> reader.setMaxInMemorySize(1), - ex -> assertThat(ex) - .isInstanceOf(DecodingException.class) - .hasMessageStartingWith("Failure while parsing part[1]") - .hasRootCauseMessage("Part[1] exceeded the in-memory limit of 1 bytes") - ); - } - - private void testMultipartExceptions( - Consumer configurer, Consumer assertions) { - - SynchronossPartHttpMessageReader reader = new SynchronossPartHttpMessageReader(); - configurer.accept(reader); - MultipartHttpMessageReader multipartReader = new MultipartHttpMessageReader(reader); - StepVerifier.create(multipartReader.readMono(PARTS_ELEMENT_TYPE, generateMultipartRequest(), emptyMap())) - .consumeErrorWith(assertions) - .verify(); - } - - private ServerHttpRequest generateMultipartRequest() { - MultipartBodyBuilder partsBuilder = new MultipartBodyBuilder(); - partsBuilder.part("filePart", new ClassPathResource("org/springframework/http/codec/multipart/foo.txt")); - partsBuilder.part("textPart", "sample-text"); - - MockClientHttpRequest outputMessage = new MockClientHttpRequest(HttpMethod.POST, "/"); - new MultipartHttpMessageWriter() - .write(Mono.just(partsBuilder.build()), null, MediaType.MULTIPART_FORM_DATA, outputMessage, null) - .block(Duration.ofSeconds(5)); - Flux requestBody = outputMessage.getBody() - .map(buffer -> this.bufferFactory.wrap(buffer.asByteBuffer())); - return MockServerHttpRequest.post("/") - .contentType(outputMessage.getHeaders().getContentType()) - .body(requestBody); - } - - private ServerHttpRequest generateErrorMultipartRequest() { - return MockServerHttpRequest.post("/") - .header(CONTENT_TYPE, MULTIPART_FORM_DATA.toString()) - .body(Flux.just(this.bufferFactory.wrap("invalid content".getBytes()))); - } - - private static class ZeroDemandSubscriber extends BaseSubscriber> { - - @Override - protected void hookOnSubscribe(Subscription subscription) { - // Just subscribe without requesting - } - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlDecoderTests.java b/spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlDecoderTests.java index 0f01d8c47a9f..64acde269375 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlDecoderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlDecoderTests.java @@ -253,7 +253,7 @@ private Mono toDataBufferMono(String value) { } - @javax.xml.bind.annotation.XmlType(name = "pojo") + @jakarta.xml.bind.annotation.XmlType(name = "pojo") public static class TypePojo { private String foo; diff --git a/spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlEncoderTests.java b/spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlEncoderTests.java index a32a3f727ebf..ab0f2ad8d634 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlEncoderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlEncoderTests.java @@ -20,10 +20,9 @@ import java.util.List; import java.util.function.Consumer; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElements; -import javax.xml.bind.annotation.XmlRootElement; - +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElements; +import jakarta.xml.bind.annotation.XmlRootElement; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; diff --git a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlRootElement.java b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlRootElement.java index 7a2dae1aca4c..3d17b3416964 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlRootElement.java +++ b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlRootElement.java @@ -19,7 +19,7 @@ /** * @author Arjen Poutsma */ -@javax.xml.bind.annotation.XmlRootElement +@jakarta.xml.bind.annotation.XmlRootElement public class XmlRootElement { } diff --git a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlRootElementWithName.java b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlRootElementWithName.java index 88de86671ac3..5fd82ef986ec 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlRootElementWithName.java +++ b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlRootElementWithName.java @@ -16,7 +16,7 @@ package org.springframework.http.codec.xml.jaxb; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlRootElement; /** * @author Arjen Poutsma diff --git a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlRootElementWithNameAndNamespace.java b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlRootElementWithNameAndNamespace.java index dfb765bd0981..3a89dd3e696a 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlRootElementWithNameAndNamespace.java +++ b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlRootElementWithNameAndNamespace.java @@ -16,7 +16,7 @@ package org.springframework.http.codec.xml.jaxb; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlRootElement; /** * @author Arjen Poutsma diff --git a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlType.java b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlType.java index cff0d9f45091..749f4c22e234 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlType.java +++ b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlType.java @@ -19,7 +19,7 @@ /** * @author Arjen Poutsma */ -@javax.xml.bind.annotation.XmlType +@jakarta.xml.bind.annotation.XmlType public class XmlType { } diff --git a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlTypeWithName.java b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlTypeWithName.java index 60c42519a8db..744524da5949 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlTypeWithName.java +++ b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlTypeWithName.java @@ -16,7 +16,7 @@ package org.springframework.http.codec.xml.jaxb; -import javax.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlType; /** * @author Arjen Poutsma diff --git a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlTypeWithNameAndNamespace.java b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlTypeWithNameAndNamespace.java index f1ea796fbaa2..a299b84c4c77 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlTypeWithNameAndNamespace.java +++ b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/XmlTypeWithNameAndNamespace.java @@ -16,7 +16,7 @@ package org.springframework.http.codec.xml.jaxb; -import javax.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlType; /** * @author Arjen Poutsma diff --git a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/package-info.java b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/package-info.java index f3b3a59496b2..00c3767ca863 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/package-info.java +++ b/spring-web/src/test/java/org/springframework/http/codec/xml/jaxb/package-info.java @@ -1,2 +1,2 @@ -@javax.xml.bind.annotation.XmlSchema(namespace = "namespace") +@jakarta.xml.bind.annotation.XmlSchema(namespace = "namespace") package org.springframework.http.codec.xml.jaxb; 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 43bfe0552098..9f307b450353 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 @@ -29,11 +29,12 @@ import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileItemFactory; -import org.apache.commons.fileupload.FileUpload; -import org.apache.commons.fileupload.RequestContext; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.tomcat.util.http.fileupload.FileItem; +import org.apache.tomcat.util.http.fileupload.FileItemFactory; +import org.apache.tomcat.util.http.fileupload.FileUpload; +import org.apache.tomcat.util.http.fileupload.RequestContext; +import org.apache.tomcat.util.http.fileupload.UploadContext; +import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory; import org.junit.jupiter.api.Test; import org.springframework.core.io.ClassPathResource; @@ -327,16 +328,17 @@ private void assertCannotWrite(MediaType mediaType) { } - private static class MockHttpOutputMessageRequestContext implements RequestContext { + private static class MockHttpOutputMessageRequestContext implements UploadContext { private final MockHttpOutputMessage outputMessage; + private final byte[] body; private MockHttpOutputMessageRequestContext(MockHttpOutputMessage outputMessage) { this.outputMessage = outputMessage; + this.body = this.outputMessage.getBodyAsBytes(); } - @Override public String getCharacterEncoding() { MediaType type = this.outputMessage.getHeaders().getContentType(); @@ -350,17 +352,17 @@ public String getContentType() { } @Override - @Deprecated - public int getContentLength() { - return this.outputMessage.getBodyAsBytes().length; + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(body); } @Override - public InputStream getInputStream() throws IOException { - return new ByteArrayInputStream(this.outputMessage.getBodyAsBytes()); + public long contentLength() { + return body.length; } } + public static class MyBean { private String string; diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/JsonbHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/JsonbHttpMessageConverterTests.java index 7649e8415bd5..44e14ac57612 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/json/JsonbHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/json/JsonbHttpMessageConverterTests.java @@ -162,7 +162,7 @@ public void writeUTF16() throws IOException { MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); String body = "H\u00e9llo W\u00f6rld"; this.converter.write(body, contentType, outputMessage); - assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_16BE)).as("Invalid result").isEqualTo(body); + assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_16BE)).as("Invalid result").isEqualTo("\"" + body + "\""); assertThat(outputMessage.getHeaders().getContentType()).as("Invalid content-type").isEqualTo(contentType); } @@ -260,7 +260,7 @@ public void prefixJson() throws IOException { MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); this.converter.setPrefixJson(true); this.converter.writeInternal("foo", null, outputMessage); - assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEqualTo(")]}', foo"); + assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEqualTo(")]}', \"foo\""); } @Test @@ -268,7 +268,7 @@ public void prefixJsonCustom() throws IOException { MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); this.converter.setJsonPrefix(")))"); this.converter.writeInternal("foo", null, outputMessage); - assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEqualTo(")))foo"); + assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEqualTo(")))\"foo\""); } diff --git a/spring-web/src/test/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverterTests.java index 0b02ce6ae1f2..c3c176bea6ce 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverterTests.java @@ -21,12 +21,12 @@ import java.util.List; import java.util.Set; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; import javax.xml.stream.XMLInputFactory; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverterTests.java index cf5fa05d46cd..dc210e628d08 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverterTests.java @@ -18,15 +18,14 @@ import java.nio.charset.StandardCharsets; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.XmlAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.adapters.XmlAdapter; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.xmlunit.diff.DifferenceEvaluator; 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 44bbd00a296e..79d0158eae99 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,7 +70,7 @@ void handlingError(HttpServer httpServer) throws Exception { assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); } - @ParameterizedHttpServerTest // SPR-15560 + @ParameterizedHttpServerTest // SPR-15560 void emptyPathSegments(HttpServer httpServer) throws Exception { startServer(httpServer); diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/HeadersAdaptersTests.java b/spring-web/src/test/java/org/springframework/http/server/reactive/HeadersAdaptersTests.java index ce7e1b14fbdc..0a95cdfdacaf 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/HeadersAdaptersTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/HeadersAdaptersTests.java @@ -136,7 +136,7 @@ static Stream headers() { arguments("Netty", new NettyHeadersAdapter(new DefaultHttpHeaders())), arguments("Tomcat", new TomcatHeadersAdapter(new MimeHeaders())), arguments("Undertow", new UndertowHeadersAdapter(new HeaderMap())), - arguments("Jetty", new JettyHeadersAdapter(new HttpFields())) + arguments("Jetty", new JettyHeadersAdapter(HttpFields.build())) ); } diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpRequestTests.java b/spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpRequestTests.java index 7eca5ed6e14e..d88f32d41194 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpRequestTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpRequestTests.java @@ -21,11 +21,10 @@ import java.util.Arrays; import java.util.Collections; -import javax.servlet.AsyncContext; -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.AsyncContext; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.core.io.buffer.DefaultDataBufferFactory; diff --git a/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderIntegrationTests.java b/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderIntegrationTests.java index d54f09f09d52..f53a7eb494a3 100644 --- a/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderIntegrationTests.java @@ -18,12 +18,11 @@ import java.util.List; -import javax.servlet.MultipartConfigElement; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.Part; - +import jakarta.servlet.MultipartConfigElement; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.Part; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; diff --git a/spring-web/src/test/java/org/springframework/web/context/ContextLoaderInitializerTests.java b/spring-web/src/test/java/org/springframework/web/context/ContextLoaderInitializerTests.java index 4c252fffd347..5bd5599aa97f 100644 --- a/spring-web/src/test/java/org/springframework/web/context/ContextLoaderInitializerTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/ContextLoaderInitializerTests.java @@ -18,9 +18,8 @@ import java.util.EventListener; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/context/request/RequestAndSessionScopedBeanTests.java b/spring-web/src/test/java/org/springframework/web/context/request/RequestAndSessionScopedBeanTests.java index c413f2ca4103..23613401695f 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/RequestAndSessionScopedBeanTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/RequestAndSessionScopedBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,7 @@ package org.springframework.web.context.request; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanCreationException; @@ -38,7 +37,7 @@ public class RequestAndSessionScopedBeanTests { @Test @SuppressWarnings("resource") - public void testPutBeanInRequest() throws Exception { + public void testPutBeanInRequest() { String targetBeanName = "target"; StaticWebApplicationContext wac = new StaticWebApplicationContext(); @@ -73,7 +72,7 @@ public void testPutBeanInRequest() throws Exception { @Test @SuppressWarnings("resource") - public void testPutBeanInSession() throws Exception { + public void testPutBeanInSession() { String targetBeanName = "target"; HttpServletRequest request = new MockHttpServletRequest(); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); diff --git a/spring-web/src/test/java/org/springframework/web/context/request/RequestContextListenerTests.java b/spring-web/src/test/java/org/springframework/web/context/request/RequestContextListenerTests.java index 4e4bdedb134c..84487b927d41 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/RequestContextListenerTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/RequestContextListenerTests.java @@ -16,8 +16,7 @@ package org.springframework.web.context.request; -import javax.servlet.ServletRequestEvent; - +import jakarta.servlet.ServletRequestEvent; import org.junit.jupiter.api.Test; import org.springframework.core.task.MockRunnable; diff --git a/spring-web/src/test/java/org/springframework/web/context/request/ServletRequestAttributesTests.java b/spring-web/src/test/java/org/springframework/web/context/request/ServletRequestAttributesTests.java index d71be10683a0..373df295887a 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/ServletRequestAttributesTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/ServletRequestAttributesTests.java @@ -19,9 +19,8 @@ import java.io.Serializable; import java.math.BigInteger; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; import org.junit.jupiter.api.Test; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; diff --git a/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestTests.java b/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestTests.java index db295dc5a997..42ab49c58380 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestTests.java @@ -19,13 +19,12 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/context/request/WebApplicationContextScopeTests.java b/spring-web/src/test/java/org/springframework/web/context/request/WebApplicationContextScopeTests.java index 8315021b4b59..4f4a3a1d8f23 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/WebApplicationContextScopeTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/WebApplicationContextScopeTests.java @@ -16,8 +16,7 @@ package org.springframework.web.context.request; -import javax.servlet.ServletContextEvent; - +import jakarta.servlet.ServletContextEvent; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.support.GenericBeanDefinition; diff --git a/spring-web/src/test/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequestTests.java b/spring-web/src/test/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequestTests.java index 6a71cf98582f..1d0ddfbe1b07 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequestTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequestTests.java @@ -18,8 +18,7 @@ import java.util.function.Consumer; -import javax.servlet.AsyncEvent; - +import jakarta.servlet.AsyncEvent; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerErrorTests.java b/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerErrorTests.java index 6ecb5fd2fd54..c9ff621c4d62 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerErrorTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerErrorTests.java @@ -19,8 +19,7 @@ import java.util.concurrent.Callable; import java.util.function.Consumer; -import javax.servlet.AsyncEvent; - +import jakarta.servlet.AsyncEvent; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTests.java b/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTests.java index ccde83a39c4c..2a88cd9566b3 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTests.java @@ -19,8 +19,7 @@ import java.util.concurrent.Callable; import java.util.function.Consumer; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTimeoutTests.java b/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTimeoutTests.java index e07100c00450..d3293e41c669 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTimeoutTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTimeoutTests.java @@ -19,8 +19,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.Future; -import javax.servlet.AsyncEvent; - +import jakarta.servlet.AsyncEvent; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/context/support/Spr8510Tests.java b/spring-web/src/test/java/org/springframework/web/context/support/Spr8510Tests.java index c8036faac907..85b7e70f0957 100644 --- a/spring-web/src/test/java/org/springframework/web/context/support/Spr8510Tests.java +++ b/spring-web/src/test/java/org/springframework/web/context/support/Spr8510Tests.java @@ -16,8 +16,7 @@ package org.springframework.web.context.support; -import javax.servlet.ServletContextEvent; - +import jakarta.servlet.ServletContextEvent; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.ClassPathBeanDefinitionScanner; diff --git a/spring-web/src/test/java/org/springframework/web/cors/DefaultCorsProcessorTests.java b/spring-web/src/test/java/org/springframework/web/cors/DefaultCorsProcessorTests.java index c57aeffeadab..0212bada3e1c 100644 --- a/spring-web/src/test/java/org/springframework/web/cors/DefaultCorsProcessorTests.java +++ b/spring-web/src/test/java/org/springframework/web/cors/DefaultCorsProcessorTests.java @@ -18,8 +18,7 @@ import java.util.Arrays; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/cors/reactive/CorsWebFilterTests.java b/spring-web/src/test/java/org/springframework/web/cors/reactive/CorsWebFilterTests.java index 2a269ad5534b..9d1c940dc03b 100644 --- a/spring-web/src/test/java/org/springframework/web/cors/reactive/CorsWebFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/cors/reactive/CorsWebFilterTests.java @@ -19,8 +19,7 @@ import java.io.IOException; import java.util.Arrays; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; diff --git a/spring-web/src/test/java/org/springframework/web/filter/CharacterEncodingFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/CharacterEncodingFilterTests.java index 8ab956d66f43..41d3a4192eaa 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/CharacterEncodingFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/CharacterEncodingFilterTests.java @@ -16,11 +16,10 @@ package org.springframework.web.filter; -import javax.servlet.DispatcherType; -import javax.servlet.FilterChain; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.DispatcherType; +import jakarta.servlet.FilterChain; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.web.testfixture.servlet.MockFilterConfig; diff --git a/spring-web/src/test/java/org/springframework/web/filter/CompositeFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/CompositeFilterTests.java index fe9a21dd88a8..322a38997048 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/CompositeFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/CompositeFilterTests.java @@ -19,14 +19,13 @@ import java.io.IOException; import java.util.Arrays; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import org.junit.jupiter.api.Test; import org.springframework.web.testfixture.servlet.MockFilterConfig; diff --git a/spring-web/src/test/java/org/springframework/web/filter/ContentCachingResponseWrapperTests.java b/spring-web/src/test/java/org/springframework/web/filter/ContentCachingResponseWrapperTests.java index 576d0287d17b..c7f326ac5bbb 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/ContentCachingResponseWrapperTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/ContentCachingResponseWrapperTests.java @@ -17,8 +17,7 @@ import java.nio.charset.StandardCharsets; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; diff --git a/spring-web/src/test/java/org/springframework/web/filter/CorsFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/CorsFilterTests.java index 35a72e528cb4..f3e13468d002 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/CorsFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/CorsFilterTests.java @@ -19,9 +19,8 @@ import java.io.IOException; import java.util.Arrays; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; - +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/filter/DelegatingFilterProxyTests.java b/spring-web/src/test/java/org/springframework/web/filter/DelegatingFilterProxyTests.java index 3454a81d4eb4..875169ca2524 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/DelegatingFilterProxyTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/DelegatingFilterProxyTests.java @@ -18,14 +18,13 @@ import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import org.junit.jupiter.api.Test; import org.springframework.web.context.WebApplicationContext; diff --git a/spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java index 35fa6df4c4f7..a96aee17ccf0 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java @@ -19,14 +19,13 @@ import java.io.IOException; import java.util.Enumeration; -import javax.servlet.DispatcherType; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.DispatcherType; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/filter/HiddenHttpMethodFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/HiddenHttpMethodFilterTests.java index c35c86b60363..07a508247a31 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/HiddenHttpMethodFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/HiddenHttpMethodFilterTests.java @@ -18,12 +18,11 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; diff --git a/spring-web/src/test/java/org/springframework/web/filter/OncePerRequestFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/OncePerRequestFilterTests.java index 94024a67492e..f535af81640a 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/OncePerRequestFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/OncePerRequestFilterTests.java @@ -18,13 +18,12 @@ import java.io.IOException; -import javax.servlet.DispatcherType; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.DispatcherType; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/filter/RelativeRedirectFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/RelativeRedirectFilterTests.java index dd23fd6ac278..f8e67ea7b1d1 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/RelativeRedirectFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/RelativeRedirectFilterTests.java @@ -16,9 +16,8 @@ package org.springframework.web.filter; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.junit.jupiter.api.Test; import org.mockito.InOrder; import org.mockito.Mockito; diff --git a/spring-web/src/test/java/org/springframework/web/filter/RequestContextFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/RequestContextFilterTests.java index c88b2e36c951..fdfe302fbdf4 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/RequestContextFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/RequestContextFilterTests.java @@ -18,11 +18,10 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import org.junit.jupiter.api.Test; import org.springframework.web.context.request.RequestAttributes; 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 e3053bbb1b49..b7684a5a82fd 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 @@ -18,10 +18,9 @@ import java.nio.charset.StandardCharsets; -import javax.servlet.FilterChain; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.FilterChain; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.util.FileCopyUtils; diff --git a/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java index 1dccc8e02abc..445aa47e7bdc 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java @@ -18,9 +18,8 @@ import java.nio.charset.StandardCharsets; -import javax.servlet.FilterChain; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.FilterChain; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.util.FileCopyUtils; diff --git a/spring-web/src/test/java/org/springframework/web/jsf/DelegatingNavigationHandlerTests.java b/spring-web/src/test/java/org/springframework/web/jsf/DelegatingNavigationHandlerTests.java index 07a27a0cd62b..51904f646872 100644 --- a/spring-web/src/test/java/org/springframework/web/jsf/DelegatingNavigationHandlerTests.java +++ b/spring-web/src/test/java/org/springframework/web/jsf/DelegatingNavigationHandlerTests.java @@ -16,9 +16,8 @@ package org.springframework.web.jsf; -import javax.faces.application.NavigationHandler; -import javax.faces.context.FacesContext; - +import jakarta.faces.application.NavigationHandler; +import jakarta.faces.context.FacesContext; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanFactory; diff --git a/spring-web/src/test/java/org/springframework/web/jsf/DelegatingPhaseListenerTests.java b/spring-web/src/test/java/org/springframework/web/jsf/DelegatingPhaseListenerTests.java index f174615da966..733b51464e91 100644 --- a/spring-web/src/test/java/org/springframework/web/jsf/DelegatingPhaseListenerTests.java +++ b/spring-web/src/test/java/org/springframework/web/jsf/DelegatingPhaseListenerTests.java @@ -16,11 +16,10 @@ package org.springframework.web.jsf; -import javax.faces.context.FacesContext; -import javax.faces.event.PhaseEvent; -import javax.faces.event.PhaseId; -import javax.faces.event.PhaseListener; - +import jakarta.faces.context.FacesContext; +import jakarta.faces.event.PhaseEvent; +import jakarta.faces.event.PhaseId; +import jakarta.faces.event.PhaseListener; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.ListableBeanFactory; diff --git a/spring-web/src/test/java/org/springframework/web/jsf/MockFacesContext.java b/spring-web/src/test/java/org/springframework/web/jsf/MockFacesContext.java index 77ef2ad1e585..f72986433508 100644 --- a/spring-web/src/test/java/org/springframework/web/jsf/MockFacesContext.java +++ b/spring-web/src/test/java/org/springframework/web/jsf/MockFacesContext.java @@ -18,22 +18,22 @@ import java.util.Iterator; -import javax.faces.application.Application; -import javax.faces.application.FacesMessage; -import javax.faces.application.FacesMessage.Severity; -import javax.faces.component.UIViewRoot; -import javax.faces.context.ExternalContext; -import javax.faces.context.FacesContext; -import javax.faces.context.ResponseStream; -import javax.faces.context.ResponseWriter; -import javax.faces.render.RenderKit; +import jakarta.faces.application.Application; +import jakarta.faces.application.FacesMessage; +import jakarta.faces.application.FacesMessage.Severity; +import jakarta.faces.component.UIViewRoot; +import jakarta.faces.context.ExternalContext; +import jakarta.faces.context.FacesContext; +import jakarta.faces.context.ResponseStream; +import jakarta.faces.context.ResponseWriter; +import jakarta.faces.render.RenderKit; /** * Mock implementation of the {@code FacesContext} class to facilitate * standalone Action unit tests. * * @author Ulrik Sandberg - * @see javax.faces.context.FacesContext + * @see jakarta.faces.context.FacesContext */ public class MockFacesContext extends FacesContext { diff --git a/spring-web/src/test/java/org/springframework/web/jsf/MockLifecycle.java b/spring-web/src/test/java/org/springframework/web/jsf/MockLifecycle.java index 39685816ff55..41aaf64ca973 100644 --- a/spring-web/src/test/java/org/springframework/web/jsf/MockLifecycle.java +++ b/spring-web/src/test/java/org/springframework/web/jsf/MockLifecycle.java @@ -16,10 +16,10 @@ package org.springframework.web.jsf; -import javax.faces.FacesException; -import javax.faces.context.FacesContext; -import javax.faces.event.PhaseListener; -import javax.faces.lifecycle.Lifecycle; +import jakarta.faces.FacesException; +import jakarta.faces.context.FacesContext; +import jakarta.faces.event.PhaseListener; +import jakarta.faces.lifecycle.Lifecycle; /** * @author Juergen Hoeller diff --git a/spring-web/src/test/java/org/springframework/web/method/ControllerAdviceBeanTests.java b/spring-web/src/test/java/org/springframework/web/method/ControllerAdviceBeanTests.java index a75c220fdf22..78d24a16170f 100644 --- a/spring-web/src/test/java/org/springframework/web/method/ControllerAdviceBeanTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/ControllerAdviceBeanTests.java @@ -20,8 +20,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.List; -import javax.annotation.Priority; - +import jakarta.annotation.Priority; import org.junit.jupiter.api.Test; import org.springframework.beans.BeanUtils; diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/CookieValueMethodArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/CookieValueMethodArgumentResolverTests.java index 47b184f4881e..581e4fe2b129 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/CookieValueMethodArgumentResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/CookieValueMethodArgumentResolverTests.java @@ -18,8 +18,7 @@ import java.lang.reflect.Method; -import javax.servlet.http.Cookie; - +import jakarta.servlet.http.Cookie; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/ExceptionHandlerMethodResolverTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/ExceptionHandlerMethodResolverTests.java index 1a2ebcf81536..30fe752b58e6 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/ExceptionHandlerMethodResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/ExceptionHandlerMethodResolverTests.java @@ -21,9 +21,8 @@ import java.net.BindException; import java.net.SocketException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.stereotype.Controller; diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolverTests.java index 8bc0dcb26600..2c1693a6065d 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolverTests.java @@ -19,8 +19,7 @@ import java.util.Collections; import java.util.Map; -import javax.servlet.http.Part; - +import jakarta.servlet.http.Part; import org.junit.jupiter.api.Test; import org.springframework.core.MethodParameter; diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java index 5ad7e894bb11..684d3d76ca43 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java @@ -21,8 +21,7 @@ import java.util.Map; import java.util.Optional; -import javax.servlet.http.Part; - +import jakarta.servlet.http.Part; import org.junit.jupiter.api.Test; import org.springframework.beans.propertyeditors.StringTrimmerEditor; diff --git a/spring-web/src/test/java/org/springframework/web/multipart/commons/CommonsMultipartResolverTests.java b/spring-web/src/test/java/org/springframework/web/multipart/commons/CommonsMultipartResolverTests.java deleted file mode 100644 index e37bb54c025b..000000000000 --- a/spring-web/src/test/java/org/springframework/web/multipart/commons/CommonsMultipartResolverTests.java +++ /dev/null @@ -1,618 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.multipart.commons; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileItemFactory; -import org.apache.commons.fileupload.FileItemHeaders; -import org.apache.commons.fileupload.FileUpload; -import org.apache.commons.fileupload.servlet.ServletFileUpload; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.MutablePropertyValues; -import org.springframework.http.MediaType; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.ServletRequestDataBinder; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.StaticWebApplicationContext; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; -import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor; -import org.springframework.web.multipart.support.MultipartFilter; -import org.springframework.web.multipart.support.StringMultipartFileEditor; -import org.springframework.web.testfixture.servlet.MockFilterConfig; -import org.springframework.web.testfixture.servlet.MockHttpServletRequest; -import org.springframework.web.testfixture.servlet.MockHttpServletResponse; -import org.springframework.web.testfixture.servlet.MockServletContext; -import org.springframework.web.testfixture.servlet.PassThroughFilterChain; -import org.springframework.web.util.WebUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Juergen Hoeller - * @author Arjen Poutsma - * @since 08.10.2003 - */ -public class CommonsMultipartResolverTests { - - @Test - public void isMultipartWithDefaultSetting() { - CommonsMultipartResolver resolver = new CommonsMultipartResolver(); - - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - assertThat(resolver.isMultipart(request)).isFalse(); - - request.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE); - assertThat(resolver.isMultipart(request)).isTrue(); - - request.setContentType(MediaType.MULTIPART_MIXED_VALUE); - assertThat(resolver.isMultipart(request)).isTrue(); - - request.setContentType(MediaType.MULTIPART_RELATED_VALUE); - assertThat(resolver.isMultipart(request)).isTrue(); - - request = new MockHttpServletRequest("PUT", "/"); - assertThat(resolver.isMultipart(request)).isFalse(); - - request.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE); - assertThat(resolver.isMultipart(request)).isFalse(); - - request.setContentType(MediaType.MULTIPART_MIXED_VALUE); - assertThat(resolver.isMultipart(request)).isFalse(); - - request.setContentType(MediaType.MULTIPART_RELATED_VALUE); - assertThat(resolver.isMultipart(request)).isFalse(); - } - - @Test - public void isMultipartWithSupportedMethods() { - CommonsMultipartResolver resolver = new CommonsMultipartResolver(); - resolver.setSupportedMethods("POST", "PUT"); - - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - assertThat(resolver.isMultipart(request)).isFalse(); - - request.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE); - assertThat(resolver.isMultipart(request)).isTrue(); - - request.setContentType(MediaType.MULTIPART_MIXED_VALUE); - assertThat(resolver.isMultipart(request)).isTrue(); - - request.setContentType(MediaType.MULTIPART_RELATED_VALUE); - assertThat(resolver.isMultipart(request)).isTrue(); - - request = new MockHttpServletRequest("PUT", "/"); - assertThat(resolver.isMultipart(request)).isFalse(); - - request.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE); - assertThat(resolver.isMultipart(request)).isTrue(); - - request.setContentType(MediaType.MULTIPART_MIXED_VALUE); - assertThat(resolver.isMultipart(request)).isTrue(); - - request.setContentType(MediaType.MULTIPART_RELATED_VALUE); - assertThat(resolver.isMultipart(request)).isTrue(); - } - - @Test - public void withApplicationContext() throws Exception { - doTestWithApplicationContext(false); - } - - @Test - public void withApplicationContextAndLazyResolution() throws Exception { - doTestWithApplicationContext(true); - } - - private void doTestWithApplicationContext(boolean lazy) throws Exception { - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(new MockServletContext()); - wac.getServletContext().setAttribute(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File("mytemp")); - wac.refresh(); - MockCommonsMultipartResolver resolver = new MockCommonsMultipartResolver(); - resolver.setMaxUploadSize(1000); - resolver.setMaxInMemorySize(100); - resolver.setDefaultEncoding("enc"); - if (lazy) { - resolver.setResolveLazily(false); - } - resolver.setServletContext(wac.getServletContext()); - assertThat(resolver.getFileUpload().getSizeMax()).isEqualTo(1000); - assertThat(resolver.getFileItemFactory().getSizeThreshold()).isEqualTo(100); - assertThat(resolver.getFileUpload().getHeaderEncoding()).isEqualTo("enc"); - assertThat(resolver.getFileItemFactory().getRepository().getAbsolutePath().endsWith("mytemp")).isTrue(); - - MockHttpServletRequest originalRequest = new MockHttpServletRequest(); - originalRequest.setMethod("POST"); - originalRequest.setContentType("multipart/form-data"); - originalRequest.addHeader("Content-type", "multipart/form-data"); - originalRequest.addParameter("getField", "getValue"); - assertThat(resolver.isMultipart(originalRequest)).isTrue(); - MultipartHttpServletRequest request = resolver.resolveMultipart(originalRequest); - - doTestParameters(request); - - doTestFiles(request); - - doTestBinding(resolver, originalRequest, request); - - wac.close(); - } - - private void doTestParameters(MultipartHttpServletRequest request) { - Set parameterNames = new HashSet<>(); - Enumeration parameterEnum = request.getParameterNames(); - while (parameterEnum.hasMoreElements()) { - parameterNames.add(parameterEnum.nextElement()); - } - assertThat(parameterNames.size()).isEqualTo(3); - assertThat(parameterNames.contains("field3")).isTrue(); - assertThat(parameterNames.contains("field4")).isTrue(); - assertThat(parameterNames.contains("getField")).isTrue(); - assertThat(request.getParameter("field3")).isEqualTo("value3"); - List parameterValues = Arrays.asList(request.getParameterValues("field3")); - assertThat(parameterValues.size()).isEqualTo(1); - assertThat(parameterValues.contains("value3")).isTrue(); - assertThat(request.getParameter("field4")).isEqualTo("value4"); - parameterValues = Arrays.asList(request.getParameterValues("field4")); - assertThat(parameterValues.size()).isEqualTo(2); - assertThat(parameterValues.contains("value4")).isTrue(); - assertThat(parameterValues.contains("value5")).isTrue(); - assertThat(request.getParameter("field4")).isEqualTo("value4"); - assertThat(request.getParameter("getField")).isEqualTo("getValue"); - - List parameterMapKeys = new ArrayList<>(); - List parameterMapValues = new ArrayList<>(); - for (Object o : request.getParameterMap().keySet()) { - String key = (String) o; - parameterMapKeys.add(key); - parameterMapValues.add(request.getParameterMap().get(key)); - } - assertThat(parameterMapKeys.size()).isEqualTo(3); - assertThat(parameterMapValues.size()).isEqualTo(3); - int field3Index = parameterMapKeys.indexOf("field3"); - int field4Index = parameterMapKeys.indexOf("field4"); - int getFieldIndex = parameterMapKeys.indexOf("getField"); - assertThat(field3Index != -1).isTrue(); - assertThat(field4Index != -1).isTrue(); - assertThat(getFieldIndex != -1).isTrue(); - parameterValues = Arrays.asList((String[]) parameterMapValues.get(field3Index)); - assertThat(parameterValues.size()).isEqualTo(1); - assertThat(parameterValues.contains("value3")).isTrue(); - parameterValues = Arrays.asList((String[]) parameterMapValues.get(field4Index)); - assertThat(parameterValues.size()).isEqualTo(2); - assertThat(parameterValues.contains("value4")).isTrue(); - assertThat(parameterValues.contains("value5")).isTrue(); - parameterValues = Arrays.asList((String[]) parameterMapValues.get(getFieldIndex)); - assertThat(parameterValues.size()).isEqualTo(1); - assertThat(parameterValues.contains("getValue")).isTrue(); - } - - private void doTestFiles(MultipartHttpServletRequest request) throws IOException { - Set fileNames = new HashSet<>(); - Iterator fileIter = request.getFileNames(); - while (fileIter.hasNext()) { - fileNames.add(fileIter.next()); - } - assertThat(fileNames.size()).isEqualTo(3); - assertThat(fileNames.contains("field1")).isTrue(); - assertThat(fileNames.contains("field2")).isTrue(); - assertThat(fileNames.contains("field2x")).isTrue(); - CommonsMultipartFile file1 = (CommonsMultipartFile) request.getFile("field1"); - CommonsMultipartFile file2 = (CommonsMultipartFile) request.getFile("field2"); - CommonsMultipartFile file2x = (CommonsMultipartFile) request.getFile("field2x"); - - Map fileMap = request.getFileMap(); - assertThat(fileMap.size()).isEqualTo(3); - assertThat(fileMap.containsKey("field1")).isTrue(); - assertThat(fileMap.containsKey("field2")).isTrue(); - assertThat(fileMap.containsKey("field2x")).isTrue(); - assertThat(fileMap.get("field1")).isEqualTo(file1); - assertThat(fileMap.get("field2")).isEqualTo(file2); - assertThat(fileMap.get("field2x")).isEqualTo(file2x); - - MultiValueMap multiFileMap = request.getMultiFileMap(); - assertThat(multiFileMap.size()).isEqualTo(3); - assertThat(multiFileMap.containsKey("field1")).isTrue(); - assertThat(multiFileMap.containsKey("field2")).isTrue(); - assertThat(multiFileMap.containsKey("field2x")).isTrue(); - List field1Files = multiFileMap.get("field1"); - assertThat(field1Files.size()).isEqualTo(2); - assertThat(field1Files.contains(file1)).isTrue(); - assertThat(multiFileMap.getFirst("field1")).isEqualTo(file1); - assertThat(multiFileMap.getFirst("field2")).isEqualTo(file2); - assertThat(multiFileMap.getFirst("field2x")).isEqualTo(file2x); - - assertThat(file1.getContentType()).isEqualTo("type1"); - assertThat(file2.getContentType()).isEqualTo("type2"); - assertThat(file2x.getContentType()).isEqualTo("type2"); - assertThat(file1.getOriginalFilename()).isEqualTo("field1.txt"); - assertThat(file2.getOriginalFilename()).isEqualTo("field2.txt"); - assertThat(file2x.getOriginalFilename()).isEqualTo("field2x.txt"); - assertThat(new String(file1.getBytes())).isEqualTo("text1"); - assertThat(new String(file2.getBytes())).isEqualTo("text2"); - assertThat(file1.getSize()).isEqualTo(5); - assertThat(file2.getSize()).isEqualTo(5); - boolean condition1 = file1.getInputStream() instanceof ByteArrayInputStream; - assertThat(condition1).isTrue(); - boolean condition = file2.getInputStream() instanceof ByteArrayInputStream; - assertThat(condition).isTrue(); - File transfer1 = new File("C:/transfer1"); - file1.transferTo(transfer1); - File transfer2 = new File("C:/transfer2"); - file2.transferTo(transfer2); - assertThat(((MockFileItem) file1.getFileItem()).writtenFile).isEqualTo(transfer1); - assertThat(((MockFileItem) file2.getFileItem()).writtenFile).isEqualTo(transfer2); - - } - - private void doTestBinding(MockCommonsMultipartResolver resolver, MockHttpServletRequest originalRequest, - MultipartHttpServletRequest request) throws UnsupportedEncodingException { - - MultipartTestBean1 mtb1 = new MultipartTestBean1(); - assertThat(mtb1.getField1()).isEqualTo(null); - assertThat(mtb1.getField2()).isEqualTo(null); - ServletRequestDataBinder binder = new ServletRequestDataBinder(mtb1, "mybean"); - binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor()); - binder.bind(request); - List file1List = request.getFiles("field1"); - CommonsMultipartFile file1a = (CommonsMultipartFile) file1List.get(0); - CommonsMultipartFile file1b = (CommonsMultipartFile) file1List.get(1); - CommonsMultipartFile file2 = (CommonsMultipartFile) request.getFile("field2"); - assertThat(mtb1.getField1()[0]).isEqualTo(file1a); - assertThat(mtb1.getField1()[1]).isEqualTo(file1b); - assertThat(new String(mtb1.getField2())).isEqualTo(new String(file2.getBytes())); - - MultipartTestBean2 mtb2 = new MultipartTestBean2(); - assertThat(mtb2.getField1()).isEqualTo(null); - assertThat(mtb2.getField2()).isEqualTo(null); - binder = new ServletRequestDataBinder(mtb2, "mybean"); - binder.registerCustomEditor(String.class, "field1", new StringMultipartFileEditor()); - binder.registerCustomEditor(String.class, "field2", new StringMultipartFileEditor("UTF-16")); - binder.bind(request); - assertThat(mtb2.getField1()[0]).isEqualTo(new String(file1a.getBytes())); - assertThat(mtb2.getField1()[1]).isEqualTo(new String(file1b.getBytes())); - assertThat(mtb2.getField2()).isEqualTo(new String(file2.getBytes(), "UTF-16")); - - resolver.cleanupMultipart(request); - assertThat(((MockFileItem) file1a.getFileItem()).deleted).isTrue(); - assertThat(((MockFileItem) file1b.getFileItem()).deleted).isTrue(); - assertThat(((MockFileItem) file2.getFileItem()).deleted).isTrue(); - - resolver.setEmpty(true); - request = resolver.resolveMultipart(originalRequest); - binder.setBindEmptyMultipartFiles(false); - String firstBound = mtb2.getField2(); - binder.bind(request); - assertThat(mtb2.getField2().isEmpty()).isFalse(); - assertThat(mtb2.getField2()).isEqualTo(firstBound); - - request = resolver.resolveMultipart(originalRequest); - binder.setBindEmptyMultipartFiles(true); - binder.bind(request); - assertThat(mtb2.getField2().isEmpty()).isTrue(); - } - - @Test - public void withServletContextAndFilter() throws Exception { - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(new MockServletContext()); - wac.registerSingleton("filterMultipartResolver", MockCommonsMultipartResolver.class, new MutablePropertyValues()); - wac.getServletContext().setAttribute(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File("mytemp")); - wac.refresh(); - wac.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - CommonsMultipartResolver resolver = new CommonsMultipartResolver(wac.getServletContext()); - assertThat(resolver.getFileItemFactory().getRepository().getAbsolutePath().endsWith("mytemp")).isTrue(); - - MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); - filterConfig.addInitParameter("class", "notWritable"); - filterConfig.addInitParameter("unknownParam", "someValue"); - final MultipartFilter filter = new MultipartFilter(); - filter.init(filterConfig); - - final List files = new ArrayList<>(); - final FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { - MultipartHttpServletRequest request = (MultipartHttpServletRequest) servletRequest; - files.addAll(request.getFileMap().values()); - } - }; - - FilterChain filterChain2 = new PassThroughFilterChain(filter, filterChain); - - MockHttpServletRequest originalRequest = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - originalRequest.setMethod("POST"); - originalRequest.setContentType("multipart/form-data"); - originalRequest.addHeader("Content-type", "multipart/form-data"); - filter.doFilter(originalRequest, response, filterChain2); - - CommonsMultipartFile file1 = (CommonsMultipartFile) files.get(0); - CommonsMultipartFile file2 = (CommonsMultipartFile) files.get(1); - assertThat(((MockFileItem) file1.getFileItem()).deleted).isTrue(); - assertThat(((MockFileItem) file2.getFileItem()).deleted).isTrue(); - } - - @Test - public void withServletContextAndFilterWithCustomBeanName() throws Exception { - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(new MockServletContext()); - wac.refresh(); - wac.registerSingleton("myMultipartResolver", MockCommonsMultipartResolver.class, new MutablePropertyValues()); - wac.getServletContext().setAttribute(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File("mytemp")); - wac.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - CommonsMultipartResolver resolver = new CommonsMultipartResolver(wac.getServletContext()); - assertThat(resolver.getFileItemFactory().getRepository().getAbsolutePath().endsWith("mytemp")).isTrue(); - - MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); - filterConfig.addInitParameter("multipartResolverBeanName", "myMultipartResolver"); - - final List files = new ArrayList<>(); - FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest originalRequest, ServletResponse response) { - if (originalRequest instanceof MultipartHttpServletRequest) { - MultipartHttpServletRequest request = (MultipartHttpServletRequest) originalRequest; - files.addAll(request.getFileMap().values()); - } - } - }; - - MultipartFilter filter = new MultipartFilter() { - private boolean invoked = false; - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, - FilterChain filterChain) throws ServletException, IOException { - super.doFilterInternal(request, response, filterChain); - super.doFilterInternal(request, response, filterChain); - if (invoked) { - throw new ServletException("Should not have been invoked twice"); - } - invoked = true; - } - }; - filter.init(filterConfig); - - MockHttpServletRequest originalRequest = new MockHttpServletRequest(); - originalRequest.setMethod("POST"); - originalRequest.setContentType("multipart/form-data"); - originalRequest.addHeader("Content-type", "multipart/form-data"); - HttpServletResponse response = new MockHttpServletResponse(); - filter.doFilter(originalRequest, response, filterChain); - CommonsMultipartFile file1 = (CommonsMultipartFile) files.get(0); - CommonsMultipartFile file2 = (CommonsMultipartFile) files.get(1); - assertThat(((MockFileItem) file1.getFileItem()).deleted).isTrue(); - assertThat(((MockFileItem) file2.getFileItem()).deleted).isTrue(); - } - - - public static class MockCommonsMultipartResolver extends CommonsMultipartResolver { - - private boolean empty; - - protected void setEmpty(boolean empty) { - this.empty = empty; - } - - @Override - protected FileUpload newFileUpload(FileItemFactory fileItemFactory) { - return new ServletFileUpload() { - @Override - public List parseRequest(HttpServletRequest request) { - if (request instanceof MultipartHttpServletRequest) { - throw new IllegalStateException("Already a multipart request"); - } - List fileItems = new ArrayList<>(); - MockFileItem fileItem1 = new MockFileItem( - "field1", "type1", empty ? "" : "field1.txt", empty ? "" : "text1"); - MockFileItem fileItem1x = new MockFileItem( - "field1", "type1", empty ? "" : "field1.txt", empty ? "" : "text1"); - MockFileItem fileItem2 = new MockFileItem( - "field2", "type2", empty ? "" : "C:\\mypath/field2.txt", empty ? "" : "text2"); - MockFileItem fileItem2x = new MockFileItem( - "field2x", "type2", empty ? "" : "C:/mypath\\field2x.txt", empty ? "" : "text2"); - MockFileItem fileItem3 = new MockFileItem("field3", null, null, "value3"); - MockFileItem fileItem4 = new MockFileItem("field4", "text/html; charset=iso-8859-1", null, "value4"); - MockFileItem fileItem5 = new MockFileItem("field4", null, null, "value5"); - fileItems.add(fileItem1); - fileItems.add(fileItem1x); - fileItems.add(fileItem2); - fileItems.add(fileItem2x); - fileItems.add(fileItem3); - fileItems.add(fileItem4); - fileItems.add(fileItem5); - return fileItems; - } - }; - } - } - - - private static class MockFileItem implements FileItem { - - private String fieldName; - private String contentType; - private String name; - private String value; - - private File writtenFile; - private boolean deleted; - - public MockFileItem(String fieldName, String contentType, String name, String value) { - this.fieldName = fieldName; - this.contentType = contentType; - this.name = name; - this.value = value; - } - - @Override - public InputStream getInputStream() throws IOException { - return new ByteArrayInputStream(value.getBytes()); - } - - @Override - public String getContentType() { - return contentType; - } - - @Override - public String getName() { - return name; - } - - @Override - public boolean isInMemory() { - return true; - } - - @Override - public long getSize() { - return value.length(); - } - - @Override - public byte[] get() { - return value.getBytes(); - } - - @Override - public String getString(String encoding) throws UnsupportedEncodingException { - return new String(get(), encoding); - } - - @Override - public String getString() { - return value; - } - - @Override - public void write(File file) throws Exception { - this.writtenFile = file; - } - - @Override - public void delete() { - this.deleted = true; - } - - @Override - public String getFieldName() { - return fieldName; - } - - @Override - public void setFieldName(String s) { - this.fieldName = s; - } - - @Override - public boolean isFormField() { - return (this.name == null); - } - - @Override - public void setFormField(boolean b) { - throw new UnsupportedOperationException(); - } - - @Override - public OutputStream getOutputStream() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public FileItemHeaders getHeaders() { - throw new UnsupportedOperationException(); - } - - @Override - public void setHeaders(FileItemHeaders headers) { - throw new UnsupportedOperationException(); - } - } - - - public class MultipartTestBean1 { - - private MultipartFile[] field1; - private byte[] field2; - - public void setField1(MultipartFile[] field1) { - this.field1 = field1; - } - - public MultipartFile[] getField1() { - return field1; - } - - public void setField2(byte[] field2) { - this.field2 = field2; - } - - public byte[] getField2() { - return field2; - } - } - - - public class MultipartTestBean2 { - - private String[] field1; - private String field2; - - public void setField1(String[] field1) { - this.field1 = field1; - } - - public String[] getField1() { - return field1; - } - - public void setField2(String field2) { - this.field2 = field2; - } - - public String getField2() { - return field2; - } - } - -} diff --git a/spring-web/src/test/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequestTests.java b/spring-web/src/test/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequestTests.java index b9c0e2ee90a7..28aebfa7e82c 100644 --- a/spring-web/src/test/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequestTests.java +++ b/spring-web/src/test/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequestTests.java @@ -19,9 +19,8 @@ import java.net.URI; import java.nio.charset.StandardCharsets; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; diff --git a/spring-web/src/test/java/org/springframework/web/util/ServletRequestPathUtilsTests.java b/spring-web/src/test/java/org/springframework/web/util/ServletRequestPathUtilsTests.java index 6814bd55df70..b8ccbaaeeb91 100644 --- a/spring-web/src/test/java/org/springframework/web/util/ServletRequestPathUtilsTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/ServletRequestPathUtilsTests.java @@ -15,8 +15,7 @@ */ package org.springframework.web.util; -import javax.servlet.http.MappingMatch; - +import jakarta.servlet.http.MappingMatch; import org.junit.jupiter.api.Test; import org.springframework.http.server.RequestPath; diff --git a/spring-web/src/test/java/org/springframework/web/util/TagUtilsTests.java b/spring-web/src/test/java/org/springframework/web/util/TagUtilsTests.java index 2306cdca78cf..bfcc8214445e 100644 --- a/spring-web/src/test/java/org/springframework/web/util/TagUtilsTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/TagUtilsTests.java @@ -16,10 +16,9 @@ package org.springframework.web.util; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.Tag; -import javax.servlet.jsp.tagext.TagSupport; - +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.Tag; +import jakarta.servlet.jsp.tagext.TagSupport; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java b/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java index 998af1c9eb16..3f1864566280 100644 --- a/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java @@ -21,8 +21,7 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/DelegatingServletInputStream.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/DelegatingServletInputStream.java index 7be60d7318d3..03e4c18f5507 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/DelegatingServletInputStream.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/DelegatingServletInputStream.java @@ -19,13 +19,13 @@ import java.io.IOException; import java.io.InputStream; -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; import org.springframework.util.Assert; /** - * Delegating implementation of {@link javax.servlet.ServletInputStream}. + * Delegating implementation of {@link jakarta.servlet.ServletInputStream}. * *

    Used by {@link MockHttpServletRequest}; typically not directly * used for testing application controllers. diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/DelegatingServletOutputStream.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/DelegatingServletOutputStream.java index 774f4bf672c3..e35f81d30f5f 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/DelegatingServletOutputStream.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/DelegatingServletOutputStream.java @@ -19,13 +19,13 @@ import java.io.IOException; import java.io.OutputStream; -import javax.servlet.ServletOutputStream; -import javax.servlet.WriteListener; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.WriteListener; import org.springframework.util.Assert; /** - * Delegating implementation of {@link javax.servlet.ServletOutputStream}. + * Delegating implementation of {@link jakarta.servlet.ServletOutputStream}. * *

    Used by {@link MockHttpServletResponse}; typically not directly * used for testing application controllers. diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockAsyncContext.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockAsyncContext.java index 0391911be354..f01b2b7411e2 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockAsyncContext.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockAsyncContext.java @@ -20,15 +20,15 @@ import java.util.ArrayList; import java.util.List; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.AsyncContext; +import jakarta.servlet.AsyncEvent; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.BeanUtils; import org.springframework.lang.Nullable; diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockBodyContent.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockBodyContent.java index 1d6a50611f24..5992baa04d60 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockBodyContent.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockBodyContent.java @@ -21,14 +21,14 @@ import java.io.StringReader; import java.io.Writer; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.tagext.BodyContent; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.jsp.JspWriter; +import jakarta.servlet.jsp.tagext.BodyContent; import org.springframework.lang.Nullable; /** - * Mock implementation of the {@link javax.servlet.jsp.tagext.BodyContent} class. + * Mock implementation of the {@link jakarta.servlet.jsp.tagext.BodyContent} class. * Only necessary for testing applications when testing custom JSP tags. * * @author Juergen Hoeller diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockCookie.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockCookie.java index 8f2e5eaa9756..c0305df35af4 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockCookie.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockCookie.java @@ -20,7 +20,7 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; -import javax.servlet.http.Cookie; +import jakarta.servlet.http.Cookie; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockExpressionEvaluator.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockExpressionEvaluator.java deleted file mode 100644 index 3358798e7689..000000000000 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockExpressionEvaluator.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.testfixture.servlet; - -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; - -import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager; - -/** - * Mock implementation of the JSP 2.0 {@link javax.servlet.jsp.el.ExpressionEvaluator} - * interface, delegating to the Apache JSTL {@link ExpressionEvaluatorManager}. - * Only necessary for testing applications when testing custom JSP tags. - * - *

    Note that the Apache JSTL implementation (jstl.jar, standard.jar) has to be - * available on the classpath to use this expression evaluator. - * - * @author Juergen Hoeller - * @since 1.1.5 - * @see org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager - */ -@SuppressWarnings("deprecation") -public class MockExpressionEvaluator extends javax.servlet.jsp.el.ExpressionEvaluator { - - private final PageContext pageContext; - - - /** - * Create a new MockExpressionEvaluator for the given PageContext. - * @param pageContext the JSP PageContext to run in - */ - public MockExpressionEvaluator(PageContext pageContext) { - this.pageContext = pageContext; - } - - - @Override - @SuppressWarnings("rawtypes") - public javax.servlet.jsp.el.Expression parseExpression(final String expression, final Class expectedType, - final javax.servlet.jsp.el.FunctionMapper functionMapper) throws javax.servlet.jsp.el.ELException { - - return new javax.servlet.jsp.el.Expression() { - @Override - public Object evaluate(javax.servlet.jsp.el.VariableResolver variableResolver) throws javax.servlet.jsp.el.ELException { - return doEvaluate(expression, expectedType, functionMapper); - } - }; - } - - @Override - @SuppressWarnings("rawtypes") - public Object evaluate(String expression, Class expectedType, javax.servlet.jsp.el.VariableResolver variableResolver, - javax.servlet.jsp.el.FunctionMapper functionMapper) throws javax.servlet.jsp.el.ELException { - - return doEvaluate(expression, expectedType, functionMapper); - } - - @SuppressWarnings("rawtypes") - protected Object doEvaluate(String expression, Class expectedType, javax.servlet.jsp.el.FunctionMapper functionMapper) - throws javax.servlet.jsp.el.ELException { - - try { - return ExpressionEvaluatorManager.evaluate("JSP EL expression", expression, expectedType, this.pageContext); - } - catch (JspException ex) { - throw new javax.servlet.jsp.el.ELException("Parsing of JSP EL expression \"" + expression + "\" failed", ex); - } - } - -} diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockFilterChain.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockFilterChain.java index 259fecf306a3..ed7b3d93dda0 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockFilterChain.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockFilterChain.java @@ -22,20 +22,20 @@ import java.util.Iterator; import java.util.List; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** - * Mock implementation of the {@link javax.servlet.FilterChain} interface. + * Mock implementation of the {@link jakarta.servlet.FilterChain} interface. * *

    A {@link MockFilterChain} can be configured with one or more filters and a * Servlet to invoke. The first time the chain is called, it invokes all filters diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockFilterConfig.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockFilterConfig.java index 2cd954986c36..931f043df599 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockFilterConfig.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockFilterConfig.java @@ -21,17 +21,17 @@ import java.util.LinkedHashMap; import java.util.Map; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Mock implementation of the {@link javax.servlet.FilterConfig} interface. + * Mock implementation of the {@link jakarta.servlet.FilterConfig} interface. * *

    Used for testing the web framework; also useful for testing - * custom {@link javax.servlet.Filter} implementations. + * custom {@link jakarta.servlet.Filter} implementations. * * @author Juergen Hoeller * @since 1.0.2 diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletMapping.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletMapping.java index 4b2ce3087f15..b24ed628e590 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletMapping.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletMapping.java @@ -16,8 +16,8 @@ package org.springframework.web.testfixture.servlet; -import javax.servlet.http.HttpServletMapping; -import javax.servlet.http.MappingMatch; +import jakarta.servlet.http.HttpServletMapping; +import jakarta.servlet.http.MappingMatch; import org.springframework.lang.Nullable; diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletRequest.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletRequest.java index d9023c3ca1ed..bcf9172d8f9c 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletRequest.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletRequest.java @@ -43,21 +43,21 @@ import java.util.TimeZone; import java.util.stream.Collectors; -import javax.servlet.AsyncContext; -import javax.servlet.DispatcherType; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletMapping; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpUpgradeHandler; -import javax.servlet.http.Part; +import jakarta.servlet.AsyncContext; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletMapping; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.HttpUpgradeHandler; +import jakarta.servlet.http.Part; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -72,7 +72,7 @@ import org.springframework.util.StringUtils; /** - * Mock implementation of the {@link javax.servlet.http.HttpServletRequest} interface. + * Mock implementation of the {@link jakarta.servlet.http.HttpServletRequest} interface. * *

    The default, preferred {@link Locale} for the server mocked by this request * is {@link Locale#ENGLISH}. This value can be changed via {@link #addPreferredLocale} @@ -823,7 +823,7 @@ private void updateAcceptLanguageHeader() { *

    In contrast to the Servlet specification, this mock implementation * does not take into consideration any locales * specified via the {@code Accept-Language} header. - * @see javax.servlet.ServletRequest#getLocale() + * @see jakarta.servlet.ServletRequest#getLocale() * @see #addPreferredLocale(Locale) * @see #setPreferredLocales(List) */ @@ -841,7 +841,7 @@ public Locale getLocale() { *

    In contrast to the Servlet specification, this mock implementation * does not take into consideration any locales * specified via the {@code Accept-Language} header. - * @see javax.servlet.ServletRequest#getLocales() + * @see jakarta.servlet.ServletRequest#getLocales() * @see #addPreferredLocale(Locale) * @see #setPreferredLocales(List) */ @@ -864,7 +864,7 @@ public void setSecure(boolean secure) { /** * Return {@code true} if the {@link #setSecure secure} flag has been set * to {@code true} or if the {@link #getScheme scheme} is {@code https}. - * @see javax.servlet.ServletRequest#isSecure() + * @see jakarta.servlet.ServletRequest#isSecure() */ @Override public boolean isSecure() { diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java index 4a343c8344c7..00763fa97465 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java @@ -38,9 +38,9 @@ import java.util.Map; import java.util.TimeZone; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -51,7 +51,7 @@ import org.springframework.web.util.WebUtils; /** - * Mock implementation of the {@link javax.servlet.http.HttpServletResponse} interface. + * Mock implementation of the {@link jakarta.servlet.http.HttpServletResponse} interface. * *

    As of Spring Framework 5.0, this set of mocks is designed on a Servlet 4.0 baseline. * @@ -383,7 +383,7 @@ public void reset() { @Override public void setLocale(@Nullable Locale locale) { - // Although the Javadoc for javax.servlet.ServletResponse.setLocale(Locale) does not + // Although the Javadoc for jakarta.servlet.ServletResponse.setLocale(Locale) does not // state how a null value for the supplied Locale should be handled, both Tomcat and // Jetty simply ignore a null value. So we do the same here. if (locale == null) { diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpSession.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpSession.java index b8302c48c570..a33c7c9a2236 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpSession.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpSession.java @@ -25,17 +25,17 @@ import java.util.LinkedHashSet; import java.util.Map; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSessionBindingEvent; +import jakarta.servlet.http.HttpSessionBindingListener; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** - * Mock implementation of the {@link javax.servlet.http.HttpSession} interface. + * Mock implementation of the {@link jakarta.servlet.http.HttpSession} interface. * *

    As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline. * @@ -149,7 +149,7 @@ public int getMaxInactiveInterval() { } @Override - public javax.servlet.http.HttpSessionContext getSessionContext() { + public jakarta.servlet.http.HttpSessionContext getSessionContext() { throw new UnsupportedOperationException("getSessionContext"); } diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockJspWriter.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockJspWriter.java index 03997d1076bd..467a220a3f13 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockJspWriter.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockJspWriter.java @@ -20,13 +20,13 @@ import java.io.PrintWriter; import java.io.Writer; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.JspWriter; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.jsp.JspWriter; import org.springframework.lang.Nullable; /** - * Mock implementation of the {@link javax.servlet.jsp.JspWriter} class. + * Mock implementation of the {@link jakarta.servlet.jsp.JspWriter} class. * Only necessary for testing applications when testing custom JSP tags. * * @author Juergen Hoeller diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockMultipartHttpServletRequest.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockMultipartHttpServletRequest.java index c36eb3ac7bc0..88c51b9498db 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockMultipartHttpServletRequest.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockMultipartHttpServletRequest.java @@ -24,9 +24,9 @@ import java.util.List; import java.util.Map; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.Part; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Part; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPageContext.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPageContext.java index 7ffc2d626319..f45973ef9d03 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPageContext.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPageContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,24 +24,24 @@ import java.util.LinkedHashSet; import java.util.Map; -import javax.el.ELContext; -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.PageContext; +import jakarta.el.ELContext; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.jsp.JspWriter; +import jakarta.servlet.jsp.PageContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Mock implementation of the {@link javax.servlet.jsp.PageContext} interface. + * Mock implementation of the {@link jakarta.servlet.jsp.PageContext} interface. * Only necessary for testing applications when testing custom JSP tags. * *

    Note: Expects initialization via the constructor rather than via the @@ -293,8 +293,9 @@ public JspWriter getOut() { @Override @Deprecated - public javax.servlet.jsp.el.ExpressionEvaluator getExpressionEvaluator() { - return new MockExpressionEvaluator(this); + @Nullable + public jakarta.servlet.jsp.el.ExpressionEvaluator getExpressionEvaluator() { + return null; } @Override @@ -306,7 +307,7 @@ public ELContext getELContext() { @Override @Deprecated @Nullable - public javax.servlet.jsp.el.VariableResolver getVariableResolver() { + public jakarta.servlet.jsp.el.VariableResolver getVariableResolver() { return null; } diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPart.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPart.java index 4079fd69c724..ac1ce65d0ef0 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPart.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPart.java @@ -22,7 +22,7 @@ import java.util.Collection; import java.util.Collections; -import javax.servlet.http.Part; +import jakarta.servlet.http.Part; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -30,7 +30,7 @@ import org.springframework.util.Assert; /** - * Mock implementation of {@code javax.servlet.http.Part}. + * Mock implementation of {@code jakarta.servlet.http.Part}. * * @author Rossen Stoyanchev * @author Juergen Hoeller diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockRequestDispatcher.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockRequestDispatcher.java index 597f1730fff2..38379ac6ede6 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockRequestDispatcher.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockRequestDispatcher.java @@ -16,18 +16,17 @@ package org.springframework.web.testfixture.servlet; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.util.Assert; /** - * Mock implementation of the {@link javax.servlet.RequestDispatcher} interface. + * Mock implementation of the {@link jakarta.servlet.RequestDispatcher} interface. * * @author Rod Johnson * @author Juergen Hoeller diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockServletConfig.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockServletConfig.java index 81fcc2421dbb..17f4541a1384 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockServletConfig.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockServletConfig.java @@ -21,14 +21,14 @@ import java.util.LinkedHashMap; import java.util.Map; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Mock implementation of the {@link javax.servlet.ServletConfig} interface. + * Mock implementation of the {@link jakarta.servlet.ServletConfig} interface. * * @author Rod Johnson * @author Juergen Hoeller diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockServletContext.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockServletContext.java index 978bdf09b053..b44a3b13283f 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockServletContext.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockServletContext.java @@ -31,17 +31,16 @@ import java.util.Map; import java.util.Set; -import javax.servlet.Filter; -import javax.servlet.FilterRegistration; -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; -import javax.servlet.SessionCookieConfig; -import javax.servlet.SessionTrackingMode; -import javax.servlet.descriptor.JspConfigDescriptor; - +import jakarta.servlet.Filter; +import jakarta.servlet.FilterRegistration; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRegistration; +import jakarta.servlet.SessionCookieConfig; +import jakarta.servlet.SessionTrackingMode; +import jakarta.servlet.descriptor.JspConfigDescriptor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -59,7 +58,7 @@ import org.springframework.web.util.WebUtils; /** - * Mock implementation of the {@link javax.servlet.ServletContext} interface. + * Mock implementation of the {@link jakarta.servlet.ServletContext} interface. * *

    As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline. * @@ -663,7 +662,7 @@ public T createServlet(Class c) throws ServletException { /** * This method always returns {@code null}. - * @see javax.servlet.ServletContext#getServletRegistration(java.lang.String) + * @see jakarta.servlet.ServletContext#getServletRegistration(java.lang.String) */ @Override @Nullable @@ -673,7 +672,7 @@ public ServletRegistration getServletRegistration(String servletName) { /** * This method always returns an {@linkplain Collections#emptyMap empty map}. - * @see javax.servlet.ServletContext#getServletRegistrations() + * @see jakarta.servlet.ServletContext#getServletRegistrations() */ @Override public Map getServletRegistrations() { @@ -702,7 +701,7 @@ public T createFilter(Class c) throws ServletException { /** * This method always returns {@code null}. - * @see javax.servlet.ServletContext#getFilterRegistration(java.lang.String) + * @see jakarta.servlet.ServletContext#getFilterRegistration(java.lang.String) */ @Override @Nullable @@ -712,7 +711,7 @@ public FilterRegistration getFilterRegistration(String filterName) { /** * This method always returns an {@linkplain Collections#emptyMap empty map}. - * @see javax.servlet.ServletContext#getFilterRegistrations() + * @see jakarta.servlet.ServletContext#getFilterRegistrations() */ @Override public Map getFilterRegistrations() { diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockSessionCookieConfig.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockSessionCookieConfig.java index c7f834508745..04f4a8ceabc4 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockSessionCookieConfig.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockSessionCookieConfig.java @@ -16,16 +16,16 @@ package org.springframework.web.testfixture.servlet; -import javax.servlet.SessionCookieConfig; +import jakarta.servlet.SessionCookieConfig; import org.springframework.lang.Nullable; /** - * Mock implementation of the {@link javax.servlet.SessionCookieConfig} interface. + * Mock implementation of the {@link jakarta.servlet.SessionCookieConfig} interface. * * @author Juergen Hoeller * @since 4.0 - * @see javax.servlet.ServletContext#getSessionCookieConfig() + * @see jakarta.servlet.ServletContext#getSessionCookieConfig() */ public class MockSessionCookieConfig implements SessionCookieConfig { diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/PassThroughFilterChain.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/PassThroughFilterChain.java index e3537156ac53..2100b0421b93 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/PassThroughFilterChain.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/PassThroughFilterChain.java @@ -18,26 +18,26 @@ import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Implementation of the {@link javax.servlet.FilterConfig} interface which + * Implementation of the {@link jakarta.servlet.FilterConfig} interface which * simply passes the call through to a given Filter/FilterChain combination * (indicating the next Filter in the chain along with the FilterChain that it is * supposed to work on) or to a given Servlet (indicating the end of the chain). * * @author Juergen Hoeller * @since 2.0.3 - * @see javax.servlet.Filter - * @see javax.servlet.Servlet + * @see jakarta.servlet.Filter + * @see jakarta.servlet.Servlet * @see MockFilterChain */ public class PassThroughFilterChain implements FilterChain { diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/xml/Pojo.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/xml/Pojo.java index 59accabc9a29..87487adebc7c 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/xml/Pojo.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/xml/Pojo.java @@ -16,7 +16,7 @@ package org.springframework.web.testfixture.xml; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlRootElement; /** * @author Sebastien Deleuze diff --git a/spring-webflux/spring-webflux.gradle b/spring-webflux/spring-webflux.gradle index b762e09c5cb6..464f3f8902c0 100644 --- a/spring-webflux/spring-webflux.gradle +++ b/spring-webflux/spring-webflux.gradle @@ -9,18 +9,19 @@ dependencies { api("io.projectreactor:reactor-core") optional(project(":spring-context")) optional(project(":spring-context-support")) // for FreeMarker support - optional("javax.servlet:javax.servlet-api") - optional("javax.websocket:javax.websocket-api") + optional("jakarta.servlet:jakarta.servlet-api") + optional("jakarta.websocket:jakarta.websocket-api") optional("org.webjars:webjars-locator-core") optional("org.freemarker:freemarker") optional("com.fasterxml.jackson.core:jackson-databind") optional("com.fasterxml.jackson.dataformat:jackson-dataformat-smile") optional("io.projectreactor.netty:reactor-netty-http") optional("org.apache.tomcat:tomcat-websocket") - optional("org.eclipse.jetty.websocket:websocket-server") { - exclude group: "javax.servlet", module: "javax.servlet" + optional("org.eclipse.jetty.websocket:websocket-jetty-server") { + exclude group: "jakarta.servlet", module: "jakarta.servlet-api" } - optional("io.undertow:undertow-websockets-jsr") + optional("org.eclipse.jetty.websocket:websocket-jetty-client") + optional("io.undertow:undertow-websockets-jsr-jakartaee9") optional("org.apache.httpcomponents:httpclient") optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") @@ -29,10 +30,10 @@ dependencies { testImplementation(testFixtures(project(":spring-beans"))) testImplementation(testFixtures(project(":spring-core"))) testImplementation(testFixtures(project(":spring-web"))) - testImplementation("javax.xml.bind:jaxb-api") + testImplementation("jakarta.xml.bind:jakarta.xml.bind-api") testImplementation("com.fasterxml:aalto-xml") testImplementation("org.hibernate:hibernate-validator") - testImplementation("javax.validation:validation-api") + testImplementation("jakarta.validation:jakarta.validation-api") testImplementation("io.reactivex.rxjava3:rxjava") testImplementation("io.projectreactor:reactor-test") testImplementation("io.undertow:undertow-core") @@ -48,12 +49,11 @@ dependencies { testRuntimeOnly("org.jetbrains.kotlin:kotlin-scripting-jsr223") testRuntimeOnly("org.jruby:jruby") testRuntimeOnly("org.python:jython-standalone") - testRuntimeOnly("org.synchronoss.cloud:nio-multipart-parser") testRuntimeOnly("org.webjars:underscorejs") - testRuntimeOnly("org.glassfish:javax.el") + testRuntimeOnly("org.glassfish:jakarta.el") testRuntimeOnly("com.sun.xml.bind:jaxb-core") testRuntimeOnly("com.sun.xml.bind:jaxb-impl") - testRuntimeOnly("com.sun.activation:javax.activation") + testRuntimeOnly("com.sun.activation:jakarta.activation") } test { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java index 828ac8aa0889..1de7d9428e94 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java @@ -383,7 +383,7 @@ public ReactiveAdapterRegistry webFluxAdapterRegistry() { public Validator webFluxValidator() { Validator validator = getValidator(); if (validator == null) { - if (ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) { + if (ClassUtils.isPresent("jakarta.validation.Validator", getClass().getClassLoader())) { Class clazz; try { String name = "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean"; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java index 230ed80958aa..b1c37b591dd6 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java @@ -51,7 +51,7 @@ * constructor and then added to the model. Once created the attribute is * populated via data binding to the request (form data, query params). * Validation also may be applied if the argument is annotated with - * {@code @javax.validation.Valid} or Spring's own + * {@code @jakarta.validation.Valid} or Spring's own * {@code @org.springframework.validation.annotation.Validated}. * *

    When this handler is created with {@code useDefaultResolution=true} diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestBodyMethodArgumentResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestBodyMethodArgumentResolver.java index c1bce52df999..2ec18252b64d 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestBodyMethodArgumentResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestBodyMethodArgumentResolver.java @@ -34,7 +34,7 @@ * body of the request through a compatible {@code HttpMessageReader}. * *

    An {@code @RequestBody} method argument is also validated if it is - * annotated with {@code @javax.validation.Valid} or + * annotated with {@code @jakarta.validation.Valid} or * {@link org.springframework.validation.annotation.Validated}. Validation * failure results in an {@link ServerWebInputException}. * diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java index 4ec3f0ecec3c..6905132b8673 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java @@ -296,7 +296,7 @@ protected Mono sendRedirect(String targetUrl, ServerWebExchange exchange) /** * Whether the given targetUrl has a host that is a "foreign" system in which - * case {@link javax.servlet.http.HttpServletResponse#encodeRedirectURL} will not be applied. + * case {@link jakarta.servlet.http.HttpServletResponse#encodeRedirectURL} will not be applied. * This method returns {@code true} if the {@link #setHosts(String[])} * property is configured and the target URL has a host that does not match. * @param targetUrl the target redirect URL diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/Jetty10WebSocketHandlerAdapter.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/Jetty10WebSocketHandlerAdapter.java deleted file mode 100644 index 5b88fab79771..000000000000 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/Jetty10WebSocketHandlerAdapter.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.reactive.socket.adapter; - -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.function.Function; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; -import org.eclipse.jetty.websocket.api.extensions.Frame; - -import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.web.reactive.socket.CloseStatus; -import org.springframework.web.reactive.socket.WebSocketHandler; -import org.springframework.web.reactive.socket.WebSocketMessage; -import org.springframework.web.reactive.socket.WebSocketMessage.Type; -import org.springframework.web.reactive.socket.WebSocketSession; - -/** - * Identical to {@link JettyWebSocketHandlerAdapter}, only excluding the - * {@code onWebSocketFrame} method, since the {@link Frame} argument has moved - * to a different package in Jetty 10. - * - * @author Rossen Stoyanchev - * @since 5.3.4 - */ -@WebSocket -public class Jetty10WebSocketHandlerAdapter { - - private final WebSocketHandler delegateHandler; - - private final Function sessionFactory; - - @Nullable - private JettyWebSocketSession delegateSession; - - - public Jetty10WebSocketHandlerAdapter(WebSocketHandler handler, - Function sessionFactory) { - - Assert.notNull(handler, "WebSocketHandler is required"); - Assert.notNull(sessionFactory, "'sessionFactory' is required"); - this.delegateHandler = handler; - this.sessionFactory = sessionFactory; - } - - - @OnWebSocketConnect - public void onWebSocketConnect(Session session) { - this.delegateSession = this.sessionFactory.apply(session); - this.delegateHandler.handle(this.delegateSession) - .checkpoint(session.getUpgradeRequest().getRequestURI() + " [JettyWebSocketHandlerAdapter]") - .subscribe(this.delegateSession); - } - - @OnWebSocketMessage - public void onWebSocketText(String message) { - if (this.delegateSession != null) { - WebSocketMessage webSocketMessage = toMessage(Type.TEXT, message); - this.delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); - } - } - - @OnWebSocketMessage - public void onWebSocketBinary(byte[] message, int offset, int length) { - if (this.delegateSession != null) { - ByteBuffer buffer = ByteBuffer.wrap(message, offset, length); - WebSocketMessage webSocketMessage = toMessage(Type.BINARY, buffer); - this.delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); - } - } - -// TODO: onWebSocketFrame can't be declared without compiling against Jetty 10 -// Jetty 10: org.eclipse.jetty.websocket.api.Frame -// Jetty 9: org.eclipse.jetty.websocket.api.extensions.Frame -// -// private static final ByteBuffer EMPTY_PAYLOAD = ByteBuffer.wrap(new byte[0]); -// -// @OnWebSocketFrame -// public void onWebSocketFrame(Frame frame) { -// if (this.delegateSession != null) { -// if (OpCode.PONG == frame.getOpCode()) { -// ByteBuffer buffer = (frame.getPayload() != null ? frame.getPayload() : EMPTY_PAYLOAD); -// WebSocketMessage webSocketMessage = toMessage(Type.PONG, buffer); -// this.delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); -// } -// } -// } - - private WebSocketMessage toMessage(Type type, T message) { - WebSocketSession session = this.delegateSession; - Assert.state(session != null, "Cannot create message without a session"); - if (Type.TEXT.equals(type)) { - byte[] bytes = ((String) message).getBytes(StandardCharsets.UTF_8); - DataBuffer buffer = session.bufferFactory().wrap(bytes); - return new WebSocketMessage(Type.TEXT, buffer); - } - else if (Type.BINARY.equals(type)) { - DataBuffer buffer = session.bufferFactory().wrap((ByteBuffer) message); - return new WebSocketMessage(Type.BINARY, buffer); - } - else if (Type.PONG.equals(type)) { - DataBuffer buffer = session.bufferFactory().wrap((ByteBuffer) message); - return new WebSocketMessage(Type.PONG, buffer); - } - else { - throw new IllegalArgumentException("Unexpected message type: " + message); - } - } - - @OnWebSocketClose - public void onWebSocketClose(int statusCode, String reason) { - if (this.delegateSession != null) { - this.delegateSession.handleClose(CloseStatus.create(statusCode, reason)); - } - } - - @OnWebSocketError - public void onWebSocketError(Throwable cause) { - if (this.delegateSession != null) { - this.delegateSession.handleError(cause); - } - } - -} diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/JettyWebSocketHandlerAdapter.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/JettyWebSocketHandlerAdapter.java index baa8e14537e3..79f750abd72b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/JettyWebSocketHandlerAdapter.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/JettyWebSocketHandlerAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import java.nio.charset.StandardCharsets; import java.util.function.Function; +import org.eclipse.jetty.websocket.api.Frame; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; @@ -27,8 +28,7 @@ import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; -import org.eclipse.jetty.websocket.api.extensions.Frame; -import org.eclipse.jetty.websocket.common.OpCode; +import org.eclipse.jetty.websocket.core.OpCode; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.lang.Nullable; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/StandardWebSocketHandlerAdapter.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/StandardWebSocketHandlerAdapter.java index a503d9d76c5d..d4699ca32e0a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/StandardWebSocketHandlerAdapter.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/StandardWebSocketHandlerAdapter.java @@ -20,11 +20,11 @@ import java.nio.charset.StandardCharsets; import java.util.function.Function; -import javax.websocket.CloseReason; -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.PongMessage; -import javax.websocket.Session; +import jakarta.websocket.CloseReason; +import jakarta.websocket.Endpoint; +import jakarta.websocket.EndpointConfig; +import jakarta.websocket.PongMessage; +import jakarta.websocket.Session; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.lang.Nullable; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/StandardWebSocketSession.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/StandardWebSocketSession.java index 3679f36f0eb3..b08e4aca2cc5 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/StandardWebSocketSession.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/StandardWebSocketSession.java @@ -20,12 +20,11 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import javax.websocket.CloseReason; -import javax.websocket.CloseReason.CloseCodes; -import javax.websocket.SendHandler; -import javax.websocket.SendResult; -import javax.websocket.Session; - +import jakarta.websocket.CloseReason; +import jakarta.websocket.CloseReason.CloseCodes; +import jakarta.websocket.SendHandler; +import jakarta.websocket.SendResult; +import jakarta.websocket.Session; import reactor.core.publisher.Mono; import reactor.core.publisher.Sinks; @@ -38,7 +37,7 @@ /** * Spring {@link WebSocketSession} adapter for a standard Java (JSR 356) - * {@link javax.websocket.Session}. + * {@link jakarta.websocket.Session}. * * @author Violeta Georgieva * @author Rossen Stoyanchev diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/TomcatWebSocketSession.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/TomcatWebSocketSession.java index d06f87533ba8..f23bcd42d260 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/TomcatWebSocketSession.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/TomcatWebSocketSession.java @@ -18,8 +18,7 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import javax.websocket.Session; - +import jakarta.websocket.Session; import org.apache.tomcat.websocket.WsSession; import reactor.core.publisher.Sinks; @@ -29,7 +28,7 @@ /** * Spring {@link WebSocketSession} adapter for Tomcat's - * {@link javax.websocket.Session}. + * {@link jakarta.websocket.Session}. * * @author Violeta Georgieva * @since 5.0 diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/JettyWebSocketClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/JettyWebSocketClient.java index 9bbeb08f845b..4c98f03937e2 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/JettyWebSocketClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/JettyWebSocketClient.java @@ -17,29 +17,22 @@ package org.springframework.web.reactive.socket.client; import java.io.IOException; -import java.lang.reflect.Method; import java.net.URI; import java.util.function.Function; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.UpgradeRequest; -import org.eclipse.jetty.websocket.api.UpgradeResponse; import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; -import org.eclipse.jetty.websocket.client.io.UpgradeListener; import reactor.core.publisher.Mono; import reactor.core.publisher.Sinks; import org.springframework.context.Lifecycle; import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.http.HttpHeaders; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; import org.springframework.web.reactive.socket.HandshakeInfo; import org.springframework.web.reactive.socket.WebSocketHandler; import org.springframework.web.reactive.socket.adapter.ContextWebSocketHandler; -import org.springframework.web.reactive.socket.adapter.Jetty10WebSocketHandlerAdapter; import org.springframework.web.reactive.socket.adapter.JettyWebSocketHandlerAdapter; import org.springframework.web.reactive.socket.adapter.JettyWebSocketSession; @@ -54,37 +47,23 @@ * * @author Violeta Georgieva * @author Rossen Stoyanchev + * @author Juergen Hoeller * @since 5.0 */ public class JettyWebSocketClient implements WebSocketClient, Lifecycle { - private static ClassLoader loader = JettyWebSocketClient.class.getClassLoader(); - - private static final boolean jetty10Present; - - static { - jetty10Present = ClassUtils.isPresent( - "org.eclipse.jetty.websocket.client.JettyUpgradeListener", loader); - } - - private static final Log logger = LogFactory.getLog(JettyWebSocketClient.class); - private final org.eclipse.jetty.websocket.client.WebSocketClient jettyClient; private final boolean externallyManaged; - private final UpgradeHelper upgradeHelper = - (jetty10Present ? new Jetty10UpgradeHelper() : new Jetty9UpgradeHelper()); - /** * Default constructor that creates and manages an instance of a Jetty * {@link org.eclipse.jetty.websocket.client.WebSocketClient WebSocketClient}. * The instance can be obtained with {@link #getJettyClient()} for further * configuration. - * *

    Note: When this constructor is used {@link Lifecycle} * methods of this class are delegated to the Jetty {@code WebSocketClient}. */ @@ -96,7 +75,6 @@ public JettyWebSocketClient() { /** * Constructor that accepts an existing instance of a Jetty * {@link org.eclipse.jetty.websocket.client.WebSocketClient WebSocketClient}. - * *

    Note: Use of this constructor implies the Jetty * {@code WebSocketClient} is externally managed and hence {@link Lifecycle} * methods of this class are not delegated to it. @@ -165,8 +143,13 @@ private Mono executeInternal(URI url, HttpHeaders headers, WebSocketHandle url, ContextWebSocketHandler.decorate(handler, contextView), completionSink); ClientUpgradeRequest request = new ClientUpgradeRequest(); request.setSubProtocols(handler.getSubProtocols()); - return this.upgradeHelper.upgrade( - this.jettyClient, jettyHandler, url, request, headers, completionSink); + try { + this.jettyClient.connect(jettyHandler, url, request); + return completionSink.asMono(); + } + catch (IOException ex) { + return Mono.error(ex); + } }); } @@ -175,9 +158,7 @@ private Object createHandler(URI url, WebSocketHandler handler, Sinks.Empty upgrade(org.eclipse.jetty.websocket.client.WebSocketClient jettyClient, - Object jettyHandler, URI url, ClientUpgradeRequest request, HttpHeaders headers, - Sinks.Empty completionSink); - } - - - private static class Jetty9UpgradeHelper implements UpgradeHelper { - - @Override - public Mono upgrade(org.eclipse.jetty.websocket.client.WebSocketClient jettyClient, - Object jettyHandler, URI url, ClientUpgradeRequest request, HttpHeaders headers, - Sinks.Empty completionSink) { - - try { - jettyClient.connect(jettyHandler, url, request, new DefaultUpgradeListener(headers)); - return completionSink.asMono(); - } - catch (IOException ex) { - return Mono.error(ex); - } - } - } - - private static class DefaultUpgradeListener implements UpgradeListener { - - private final HttpHeaders headers; - - - public DefaultUpgradeListener(HttpHeaders headers) { - this.headers = headers; - } - - @Override - public void onHandshakeRequest(UpgradeRequest request) { - this.headers.forEach(request::setHeader); - } - - @Override - public void onHandshakeResponse(UpgradeResponse response) { - } - } - - private static class Jetty10UpgradeHelper implements UpgradeHelper { - - // On Jetty 9 returns Future, on Jetty 10 returns CompletableFuture - private static final Method connectMethod; - - static { - try { - Class type = loader.loadClass("org.eclipse.jetty.websocket.client.WebSocketClient"); - connectMethod = type.getMethod("connect", Object.class, URI.class, ClientUpgradeRequest.class); - } - catch (ClassNotFoundException | NoSuchMethodException ex) { - throw new IllegalStateException("No compatible Jetty version found", ex); - } - } - - @Override - public Mono upgrade(org.eclipse.jetty.websocket.client.WebSocketClient jettyClient, - Object jettyHandler, URI url, ClientUpgradeRequest request, HttpHeaders headers, - Sinks.Empty completionSink) { - - // TODO: pass JettyUpgradeListener argument to set headers from HttpHeaders (like we do for Jetty 9) - // which would require a JDK Proxy since it is new in Jetty 10 - - ReflectionUtils.invokeMethod(connectMethod, jettyClient, jettyHandler, url, request); - return completionSink.asMono(); - } - } - } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/StandardWebSocketClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/StandardWebSocketClient.java index 4bf98585a059..39b61505a191 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/StandardWebSocketClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/StandardWebSocketClient.java @@ -20,14 +20,13 @@ import java.util.List; import java.util.Map; -import javax.websocket.ClientEndpointConfig; -import javax.websocket.ClientEndpointConfig.Configurator; -import javax.websocket.ContainerProvider; -import javax.websocket.Endpoint; -import javax.websocket.HandshakeResponse; -import javax.websocket.Session; -import javax.websocket.WebSocketContainer; - +import jakarta.websocket.ClientEndpointConfig; +import jakarta.websocket.ClientEndpointConfig.Configurator; +import jakarta.websocket.ContainerProvider; +import jakarta.websocket.Endpoint; +import jakarta.websocket.HandshakeResponse; +import jakarta.websocket.Session; +import jakarta.websocket.WebSocketContainer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Mono; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/TomcatWebSocketClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/TomcatWebSocketClient.java index 8310268db4a6..72c44fc496b8 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/TomcatWebSocketClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/TomcatWebSocketClient.java @@ -16,9 +16,8 @@ package org.springframework.web.reactive.socket.client; -import javax.websocket.Session; -import javax.websocket.WebSocketContainer; - +import jakarta.websocket.Session; +import jakarta.websocket.WebSocketContainer; import org.apache.tomcat.websocket.WsWebSocketContainer; import reactor.core.publisher.Sinks; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/support/HandshakeWebSocketService.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/support/HandshakeWebSocketService.java index 9255dd6ea7f5..78d6bcb8b60f 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/support/HandshakeWebSocketService.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/support/HandshakeWebSocketService.java @@ -70,8 +70,6 @@ public class HandshakeWebSocketService implements WebSocketService, Lifecycle { private static final boolean jettyPresent; - private static final boolean jetty10Present; - private static final boolean undertowPresent; private static final boolean reactorNettyPresent; @@ -79,8 +77,7 @@ public class HandshakeWebSocketService implements WebSocketService, Lifecycle { static { ClassLoader loader = HandshakeWebSocketService.class.getClassLoader(); tomcatPresent = ClassUtils.isPresent("org.apache.tomcat.websocket.server.WsHttpUpgradeHandler", loader); - jettyPresent = ClassUtils.isPresent("org.eclipse.jetty.websocket.server.WebSocketServerFactory", loader); - jetty10Present = ClassUtils.isPresent("org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer", loader); + jettyPresent = ClassUtils.isPresent("org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer", loader); undertowPresent = ClassUtils.isPresent("io.undertow.websockets.WebSocketProtocolHandshakeHandler", loader); reactorNettyPresent = ClassUtils.isPresent("reactor.netty.http.server.HttpServerResponse", loader); } @@ -122,9 +119,6 @@ private static RequestUpgradeStrategy initUpgradeStrategy() { else if (jettyPresent) { className = "JettyRequestUpgradeStrategy"; } - else if (jetty10Present) { - className = "Jetty10RequestUpgradeStrategy"; - } else if (undertowPresent) { className = "UndertowRequestUpgradeStrategy"; } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/DefaultServerEndpointConfig.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/DefaultServerEndpointConfig.java index 421b16d9630d..913f65cf76a6 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/DefaultServerEndpointConfig.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/DefaultServerEndpointConfig.java @@ -21,16 +21,16 @@ import java.util.List; import java.util.Map; -import javax.websocket.Decoder; -import javax.websocket.Encoder; -import javax.websocket.Endpoint; -import javax.websocket.Extension; -import javax.websocket.server.ServerEndpointConfig; +import jakarta.websocket.Decoder; +import jakarta.websocket.Encoder; +import jakarta.websocket.Endpoint; +import jakarta.websocket.Extension; +import jakarta.websocket.server.ServerEndpointConfig; import org.springframework.util.Assert; /** - * Default implementation of {@link javax.websocket.server.ServerEndpointConfig} + * Default implementation of {@link jakarta.websocket.server.ServerEndpointConfig} * for use in {@code RequestUpgradeStrategy} implementations. * * @author Violeta Georgieva @@ -48,7 +48,7 @@ class DefaultServerEndpointConfig extends ServerEndpointConfig.Configurator /** - * Constructor with a path and an {@code javax.websocket.Endpoint}. + * Constructor with a path and an {@code jakarta.websocket.Endpoint}. * @param path the endpoint path * @param endpoint the endpoint instance */ diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/Jetty10RequestUpgradeStrategy.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/Jetty10RequestUpgradeStrategy.java deleted file mode 100644 index cf5ab945817c..000000000000 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/Jetty10RequestUpgradeStrategy.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.reactive.socket.server.upgrade; - -import java.lang.reflect.Method; -import java.util.function.Supplier; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; -import reactor.core.publisher.Mono; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.target.EmptyTargetSource; -import org.springframework.core.io.buffer.DataBufferFactory; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.http.server.reactive.ServerHttpRequestDecorator; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.http.server.reactive.ServerHttpResponseDecorator; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.reactive.socket.HandshakeInfo; -import org.springframework.web.reactive.socket.WebSocketHandler; -import org.springframework.web.reactive.socket.adapter.ContextWebSocketHandler; -import org.springframework.web.reactive.socket.adapter.Jetty10WebSocketHandlerAdapter; -import org.springframework.web.reactive.socket.adapter.JettyWebSocketSession; -import org.springframework.web.reactive.socket.server.RequestUpgradeStrategy; -import org.springframework.web.server.ServerWebExchange; - -/** - * A {@link RequestUpgradeStrategy} for use with Jetty 10. - * - * @author Rossen Stoyanchev - * @since 5.3.4 - */ -public class Jetty10RequestUpgradeStrategy implements RequestUpgradeStrategy { - - private static final Class webSocketCreatorClass; - - private static final Method getContainerMethod; - - private static final Method upgradeMethod; - - private static final Method setAcceptedSubProtocol; - - static { - ClassLoader loader = Jetty10RequestUpgradeStrategy.class.getClassLoader(); - try { - webSocketCreatorClass = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketCreator"); - - Class type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer"); - getContainerMethod = type.getMethod("getContainer", ServletContext.class); - Method upgrade = ReflectionUtils.findMethod(type, "upgrade", (Class[]) null); - Assert.state(upgrade != null, "Upgrade method not found"); - upgradeMethod = upgrade; - - type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse"); - setAcceptedSubProtocol = type.getMethod("setAcceptedSubProtocol", String.class); - } - catch (Exception ex) { - throw new IllegalStateException("No compatible Jetty version found", ex); - } - } - - - @Override - public Mono upgrade( - ServerWebExchange exchange, WebSocketHandler handler, - @Nullable String subProtocol, Supplier handshakeInfoFactory) { - - ServerHttpRequest request = exchange.getRequest(); - ServerHttpResponse response = exchange.getResponse(); - - HttpServletRequest servletRequest = ServerHttpRequestDecorator.getNativeRequest(request); - HttpServletResponse servletResponse = ServerHttpResponseDecorator.getNativeResponse(response); - ServletContext servletContext = servletRequest.getServletContext(); - - HandshakeInfo handshakeInfo = handshakeInfoFactory.get(); - DataBufferFactory factory = response.bufferFactory(); - - // Trigger WebFlux preCommit actions and upgrade - return exchange.getResponse().setComplete() - .then(Mono.deferContextual(contextView -> { - Jetty10WebSocketHandlerAdapter adapter = new Jetty10WebSocketHandlerAdapter( - ContextWebSocketHandler.decorate(handler, contextView), - session -> new JettyWebSocketSession(session, handshakeInfo, factory)); - - try { - Object creator = createJettyWebSocketCreator(adapter, subProtocol); - Object container = ReflectionUtils.invokeMethod(getContainerMethod, null, servletContext); - ReflectionUtils.invokeMethod(upgradeMethod, container, creator, servletRequest, servletResponse); - } - catch (Exception ex) { - return Mono.error(ex); - } - return Mono.empty(); - })); - } - - private static Object createJettyWebSocketCreator( - Jetty10WebSocketHandlerAdapter adapter, @Nullable String protocol) { - - ProxyFactory factory = new ProxyFactory(EmptyTargetSource.INSTANCE); - factory.addInterface(webSocketCreatorClass); - factory.addAdvice(new WebSocketCreatorInterceptor(adapter, protocol)); - return factory.getProxy(); - } - - - /** - * Proxy for a JettyWebSocketCreator to supply the WebSocket handler and set the sub-protocol. - */ - private static class WebSocketCreatorInterceptor implements MethodInterceptor { - - private final Jetty10WebSocketHandlerAdapter adapter; - - @Nullable - private final String protocol; - - - public WebSocketCreatorInterceptor( - Jetty10WebSocketHandlerAdapter adapter, @Nullable String protocol) { - - this.adapter = adapter; - this.protocol = protocol; - } - - @Nullable - @Override - public Object invoke(@NonNull MethodInvocation invocation) { - if (this.protocol != null) { - ReflectionUtils.invokeMethod( - setAcceptedSubProtocol, invocation.getArguments()[2], this.protocol); - } - return this.adapter; - } - } - -} diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java index cad57bd59119..b230bb587e98 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java @@ -16,26 +16,27 @@ package org.springframework.web.reactive.socket.server.upgrade; -import java.io.IOException; +import java.lang.reflect.Method; import java.util.function.Supplier; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.websocket.api.WebSocketPolicy; -import org.eclipse.jetty.websocket.server.WebSocketServerFactory; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; import reactor.core.publisher.Mono; -import org.springframework.context.Lifecycle; -import org.springframework.core.NamedThreadLocal; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.target.EmptyTargetSource; import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequestDecorator; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponseDecorator; +import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; import org.springframework.web.reactive.socket.HandshakeInfo; import org.springframework.web.reactive.socket.WebSocketHandler; import org.springframework.web.reactive.socket.adapter.ContextWebSocketHandler; @@ -45,102 +46,46 @@ import org.springframework.web.server.ServerWebExchange; /** - * A {@link RequestUpgradeStrategy} for use with Jetty. + * A {@link RequestUpgradeStrategy} for Jetty 11. * - * @author Violeta Georgieva * @author Rossen Stoyanchev - * @since 5.0 + * @since 5.3.4 */ -public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Lifecycle { - - private static final ThreadLocal adapterHolder = - new NamedThreadLocal<>("JettyWebSocketHandlerAdapter"); - - - @Nullable - private WebSocketPolicy webSocketPolicy; - - @Nullable - private WebSocketServerFactory factory; +public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy { - @Nullable - private volatile ServletContext servletContext; + private static final Class webSocketCreatorClass; - private volatile boolean running; + private static final Method getContainerMethod; - private final Object lifecycleMonitor = new Object(); + private static final Method upgradeMethod; + private static final Method setAcceptedSubProtocol; - /** - * Configure a {@link WebSocketPolicy} to use to initialize - * {@link WebSocketServerFactory}. - * @param webSocketPolicy the WebSocket settings - */ - public void setWebSocketPolicy(WebSocketPolicy webSocketPolicy) { - this.webSocketPolicy = webSocketPolicy; - } + static { + // TODO: can switch to non-reflective implementation now - /** - * Return the configured {@link WebSocketPolicy}, if any. - */ - @Nullable - public WebSocketPolicy getWebSocketPolicy() { - return this.webSocketPolicy; - } + ClassLoader loader = JettyRequestUpgradeStrategy.class.getClassLoader(); + try { + webSocketCreatorClass = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketCreator"); + Class type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer"); + getContainerMethod = type.getMethod("getContainer", ServletContext.class); + Method upgrade = ReflectionUtils.findMethod(type, "upgrade", (Class[]) null); + Assert.state(upgrade != null, "Upgrade method not found"); + upgradeMethod = upgrade; - @Override - public void start() { - synchronized (this.lifecycleMonitor) { - ServletContext servletContext = this.servletContext; - if (!isRunning() && servletContext != null) { - try { - this.factory = (this.webSocketPolicy != null ? - new WebSocketServerFactory(servletContext, this.webSocketPolicy) : - new WebSocketServerFactory(servletContext)); - this.factory.setCreator((request, response) -> { - WebSocketHandlerContainer container = adapterHolder.get(); - String protocol = container.getProtocol(); - if (protocol != null) { - response.setAcceptedSubProtocol(protocol); - } - return container.getAdapter(); - }); - this.factory.start(); - this.running = true; - } - catch (Throwable ex) { - throw new IllegalStateException("Unable to start WebSocketServerFactory", ex); - } - } + type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse"); + setAcceptedSubProtocol = type.getMethod("setAcceptedSubProtocol", String.class); } - } - - @Override - public void stop() { - synchronized (this.lifecycleMonitor) { - if (isRunning()) { - if (this.factory != null) { - try { - this.factory.stop(); - this.running = false; - } - catch (Throwable ex) { - throw new IllegalStateException("Failed to stop WebSocketServerFactory", ex); - } - } - } + catch (Exception ex) { + throw new IllegalStateException("No compatible Jetty version found", ex); } } - @Override - public boolean isRunning() { - return this.running; - } - @Override - public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, + public Mono upgrade( + ServerWebExchange exchange, WebSocketHandler handler, @Nullable String subProtocol, Supplier handshakeInfoFactory) { ServerHttpRequest request = exchange.getRequest(); @@ -148,16 +93,11 @@ public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, HttpServletRequest servletRequest = ServerHttpRequestDecorator.getNativeRequest(request); HttpServletResponse servletResponse = ServerHttpResponseDecorator.getNativeResponse(response); + ServletContext servletContext = servletRequest.getServletContext(); HandshakeInfo handshakeInfo = handshakeInfoFactory.get(); DataBufferFactory factory = response.bufferFactory(); - startLazily(servletRequest); - - Assert.state(this.factory != null, "No WebSocketServerFactory available"); - boolean isUpgrade = this.factory.isUpgradeRequest(servletRequest, servletResponse); - Assert.isTrue(isUpgrade, "Not a WebSocket handshake"); - // Trigger WebFlux preCommit actions and upgrade return exchange.getResponse().setComplete() .then(Mono.deferContextual(contextView -> { @@ -166,51 +106,53 @@ public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, session -> new JettyWebSocketSession(session, handshakeInfo, factory)); try { - adapterHolder.set(new WebSocketHandlerContainer(adapter, subProtocol)); - this.factory.acceptWebSocket(servletRequest, servletResponse); + Object creator = createJettyWebSocketCreator(adapter, subProtocol); + Object container = ReflectionUtils.invokeMethod(getContainerMethod, null, servletContext); + ReflectionUtils.invokeMethod(upgradeMethod, container, creator, servletRequest, servletResponse); } - catch (IOException ex) { + catch (Exception ex) { return Mono.error(ex); } - finally { - adapterHolder.remove(); - } return Mono.empty(); })); } - private void startLazily(HttpServletRequest request) { - if (isRunning()) { - return; - } - synchronized (this.lifecycleMonitor) { - if (!isRunning()) { - this.servletContext = request.getServletContext(); - start(); - } - } + private static Object createJettyWebSocketCreator( + JettyWebSocketHandlerAdapter adapter, @Nullable String protocol) { + + ProxyFactory factory = new ProxyFactory(EmptyTargetSource.INSTANCE); + factory.addInterface(webSocketCreatorClass); + factory.addAdvice(new WebSocketCreatorInterceptor(adapter, protocol)); + return factory.getProxy(); } - private static class WebSocketHandlerContainer { + /** + * Proxy for a JettyWebSocketCreator to supply the WebSocket handler and set the sub-protocol. + */ + private static class WebSocketCreatorInterceptor implements MethodInterceptor { private final JettyWebSocketHandlerAdapter adapter; @Nullable private final String protocol; - public WebSocketHandlerContainer(JettyWebSocketHandlerAdapter adapter, @Nullable String protocol) { + + public WebSocketCreatorInterceptor( + JettyWebSocketHandlerAdapter adapter, @Nullable String protocol) { + this.adapter = adapter; this.protocol = protocol; } - public JettyWebSocketHandlerAdapter getAdapter() { - return this.adapter; - } - @Nullable - public String getProtocol() { - return this.protocol; + @Override + public Object invoke(@NonNull MethodInvocation invocation) { + if (this.protocol != null) { + ReflectionUtils.invokeMethod( + setAcceptedSubProtocol, invocation.getArguments()[2], this.protocol); + } + return this.adapter; } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/TomcatRequestUpgradeStrategy.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/TomcatRequestUpgradeStrategy.java index f918410dd5ee..001f85cbca3a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/TomcatRequestUpgradeStrategy.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/TomcatRequestUpgradeStrategy.java @@ -19,11 +19,10 @@ import java.util.Collections; import java.util.function.Supplier; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.websocket.Endpoint; -import javax.websocket.server.ServerContainer; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.websocket.Endpoint; +import jakarta.websocket.server.ServerContainer; import org.apache.tomcat.websocket.server.WsServerContainer; import reactor.core.publisher.Mono; @@ -51,7 +50,7 @@ */ public class TomcatRequestUpgradeStrategy implements RequestUpgradeStrategy { - private static final String SERVER_CONTAINER_ATTR = "javax.websocket.server.ServerContainer"; + private static final String SERVER_CONTAINER_ATTR = "jakarta.websocket.server.ServerContainer"; @Nullable @@ -72,7 +71,7 @@ public class TomcatRequestUpgradeStrategy implements RequestUpgradeStrategy { /** * Exposes the underlying config option on - * {@link javax.websocket.server.ServerContainer#setAsyncSendTimeout(long)}. + * {@link jakarta.websocket.server.ServerContainer#setAsyncSendTimeout(long)}. */ public void setAsyncSendTimeout(Long timeoutInMillis) { this.asyncSendTimeout = timeoutInMillis; @@ -85,7 +84,7 @@ public Long getAsyncSendTimeout() { /** * Exposes the underlying config option on - * {@link javax.websocket.server.ServerContainer#setDefaultMaxSessionIdleTimeout(long)}. + * {@link jakarta.websocket.server.ServerContainer#setDefaultMaxSessionIdleTimeout(long)}. */ public void setMaxSessionIdleTimeout(Long timeoutInMillis) { this.maxSessionIdleTimeout = timeoutInMillis; @@ -98,7 +97,7 @@ public Long getMaxSessionIdleTimeout() { /** * Exposes the underlying config option on - * {@link javax.websocket.server.ServerContainer#setDefaultMaxTextMessageBufferSize(int)}. + * {@link jakarta.websocket.server.ServerContainer#setDefaultMaxTextMessageBufferSize(int)}. */ public void setMaxTextMessageBufferSize(Integer bufferSize) { this.maxTextMessageBufferSize = bufferSize; @@ -111,7 +110,7 @@ public Integer getMaxTextMessageBufferSize() { /** * Exposes the underlying config option on - * {@link javax.websocket.server.ServerContainer#setDefaultMaxBinaryMessageBufferSize(int)}. + * {@link jakarta.websocket.server.ServerContainer#setDefaultMaxBinaryMessageBufferSize(int)}. */ public void setMaxBinaryMessageBufferSize(Integer bufferSize) { this.maxBinaryMessageBufferSize = bufferSize; @@ -163,7 +162,7 @@ private WsServerContainer getContainer(HttpServletRequest request) { if (this.serverContainer == null) { Object container = request.getServletContext().getAttribute(SERVER_CONTAINER_ATTR); Assert.state(container instanceof WsServerContainer, - "ServletContext attribute 'javax.websocket.server.ServerContainer' not found."); + "ServletContext attribute 'jakarta.websocket.server.ServerContainer' not found."); this.serverContainer = (WsServerContainer) container; initServerContainer(this.serverContainer); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxConfigurationSupportTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxConfigurationSupportTests.java index 059b7779e740..57105eb973bb 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxConfigurationSupportTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxConfigurationSupportTests.java @@ -23,9 +23,8 @@ import java.util.List; import java.util.Map; -import javax.xml.bind.annotation.XmlRootElement; - import com.google.protobuf.Message; +import jakarta.xml.bind.annotation.XmlRootElement; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyExtractorsTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyExtractorsTests.java index bf1e58c2e5d5..63ab4782fe09 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyExtractorsTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyExtractorsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,11 +51,11 @@ import org.springframework.http.codec.FormHttpMessageReader; import org.springframework.http.codec.HttpMessageReader; import org.springframework.http.codec.json.Jackson2JsonDecoder; +import org.springframework.http.codec.multipart.DefaultPartHttpMessageReader; import org.springframework.http.codec.multipart.FilePart; import org.springframework.http.codec.multipart.FormFieldPart; import org.springframework.http.codec.multipart.MultipartHttpMessageReader; import org.springframework.http.codec.multipart.Part; -import org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader; import org.springframework.http.codec.xml.Jaxb2XmlDecoder; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; @@ -89,7 +89,7 @@ public void createContext() { messageReaders.add(new DecoderHttpMessageReader<>(new Jaxb2XmlDecoder())); messageReaders.add(new DecoderHttpMessageReader<>(new Jackson2JsonDecoder())); messageReaders.add(new FormHttpMessageReader()); - SynchronossPartHttpMessageReader partReader = new SynchronossPartHttpMessageReader(); + DefaultPartHttpMessageReader partReader = new DefaultPartHttpMessageReader(); messageReaders.add(partReader); messageReaders.add(new MultipartHttpMessageReader(partReader)); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageReaderArgumentResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageReaderArgumentResolverTests.java index 7d06e637b6b6..9a5f73021663 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageReaderArgumentResolverTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageReaderArgumentResolverTests.java @@ -27,12 +27,11 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; -import javax.xml.bind.annotation.XmlRootElement; - import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.core.Maybe; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Single; +import jakarta.xml.bind.annotation.XmlRootElement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolverTests.java index 514dd48d955f..0d6f7719426c 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolverTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolverTests.java @@ -21,9 +21,8 @@ import java.util.Map; import java.util.function.Function; -import javax.validation.constraints.NotEmpty; - import io.reactivex.rxjava3.core.Single; +import jakarta.validation.constraints.NotEmpty; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingMessageConversionIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingMessageConversionIntegrationTests.java index 5472eca8f6b5..e97d9b03b432 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingMessageConversionIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingMessageConversionIntegrationTests.java @@ -23,14 +23,13 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - import io.reactivex.rxjava3.core.Completable; import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.core.Maybe; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Single; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; diff --git a/spring-webmvc/spring-webmvc.gradle b/spring-webmvc/spring-webmvc.gradle index 99e70f68f622..cb8bd88e583f 100644 --- a/spring-webmvc/spring-webmvc.gradle +++ b/spring-webmvc/spring-webmvc.gradle @@ -9,14 +9,14 @@ dependencies { api(project(":spring-core")) api(project(":spring-expression")) api(project(":spring-web")) - compileOnly("javax.servlet:javax.servlet-api") + compileOnly("jakarta.servlet:jakarta.servlet-api") compileOnly("com.google.code.findbugs:findbugs") // for groovy-templates optional(project(":spring-context-support")) // for FreeMarker support optional(project(":spring-oxm")) - optional("javax.servlet.jsp:javax.servlet.jsp-api") - optional("javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api") - optional("javax.el:javax.el-api") - optional("javax.xml.bind:jaxb-api") + optional("jakarta.servlet.jsp:jakarta.servlet.jsp-api") + optional("jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api") + optional("jakarta.el:jakarta.el-api") + optional("jakarta.xml.bind:jakarta.xml.bind-api") optional("org.webjars:webjars-locator-core") optional("com.rometools:rome") optional("com.github.librepdf:openpdf") @@ -26,12 +26,6 @@ dependencies { optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml") optional("com.fasterxml.jackson.dataformat:jackson-dataformat-smile") optional("com.fasterxml.jackson.dataformat:jackson-dataformat-cbor") - optional("org.apache.tiles:tiles-api") - optional("org.apache.tiles:tiles-core") - optional("org.apache.tiles:tiles-servlet") - optional("org.apache.tiles:tiles-jsp") - optional("org.apache.tiles:tiles-el") - optional("org.apache.tiles:tiles-extras") optional("org.codehaus.groovy:groovy-templates") optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") @@ -41,24 +35,22 @@ dependencies { testImplementation(testFixtures(project(":spring-core"))) testImplementation(testFixtures(project(":spring-context"))) testImplementation(testFixtures(project(":spring-web"))) - testImplementation("javax.servlet:javax.servlet-api") + testImplementation("jakarta.servlet:jakarta.servlet-api") testImplementation("org.eclipse.jetty:jetty-servlet") { - exclude group: "javax.servlet", module: "javax.servlet" + exclude group: "jakarta.servlet", module: "jakarta.servlet-api" } testImplementation("org.eclipse.jetty:jetty-server") { - exclude group: "javax.servlet", module: "javax.servlet" + exclude group: "jakarta.servlet", module: "jakarta.servlet-api" } testImplementation("org.apache.httpcomponents:httpclient") - testImplementation("commons-fileupload:commons-fileupload") testImplementation("commons-io:commons-io") - testImplementation("joda-time:joda-time") testImplementation("org.mozilla:rhino") testImplementation("org.dom4j:dom4j") testImplementation("jaxen:jaxen") testImplementation("org.xmlunit:xmlunit-assertj") testImplementation("org.xmlunit:xmlunit-matchers") testImplementation("org.hibernate:hibernate-validator") - testImplementation("javax.validation:validation-api") + testImplementation("jakarta.validation:jakarta.validation-api") testImplementation("io.projectreactor:reactor-core") testImplementation("io.reactivex.rxjava3:rxjava") testImplementation("org.jetbrains.kotlin:kotlin-script-runtime") @@ -66,8 +58,8 @@ dependencies { testRuntimeOnly("org.jruby:jruby") testRuntimeOnly("org.python:jython-standalone") testRuntimeOnly("org.webjars:underscorejs") - testRuntimeOnly("org.glassfish:javax.el") + testRuntimeOnly("org.glassfish:jakarta.el") testRuntimeOnly("com.sun.xml.bind:jaxb-core") testRuntimeOnly("com.sun.xml.bind:jaxb-impl") - testRuntimeOnly("com.sun.activation:javax.activation") + testRuntimeOnly("com.sun.activation:jakarta.activation") } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/AsyncHandlerInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/AsyncHandlerInterceptor.java index c3e1828e9f19..054a727baf24 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/AsyncHandlerInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/AsyncHandlerInterceptor.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.method.HandlerMethod; @@ -38,7 +38,7 @@ * invokes {@code preHandle}, {@code postHandle}, and {@code afterCompletion}. * To distinguish between the initial request and the subsequent dispatch * after asynchronous handling completes, interceptors can check whether the - * {@code javax.servlet.DispatcherType} of {@link javax.servlet.ServletRequest} + * {@code jakarta.servlet.DispatcherType} of {@link jakarta.servlet.ServletRequest} * is {@code "REQUEST"} or {@code "ASYNC"}. * *

    Note that {@code HandlerInterceptor} implementations may need to do work diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java index 5be28f3e13e0..45ee3a9bc51c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java @@ -30,12 +30,11 @@ import java.util.Set; import java.util.stream.Collectors; -import javax.servlet.DispatcherType; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.DispatcherType; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -1220,7 +1219,7 @@ else if (hasMultipartException(request)) { } /** - * Check "javax.servlet.error.exception" attribute for a multipart exception. + * Check "jakarta.servlet.error.exception" attribute for a multipart exception. */ private boolean hasMultipartException(HttpServletRequest request) { Throwable error = (Throwable) request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/FlashMapManager.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/FlashMapManager.java index 2632d6710be3..921e1d8e7b00 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/FlashMapManager.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/FlashMapManager.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java index 40e1d1030e91..ea0f30431854 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java @@ -24,12 +24,12 @@ import java.util.concurrent.Callable; import java.util.stream.Collectors; -import javax.servlet.DispatcherType; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.springframework.beans.BeanUtils; import org.springframework.context.ApplicationContext; @@ -443,7 +443,7 @@ public void setThreadContextInheritable(boolean threadContextInheritable) { * Set whether this servlet should dispatch an HTTP OPTIONS request to * the {@link #doService} method. *

    Default in the {@code FrameworkServlet} is "false", applying - * {@link javax.servlet.http.HttpServlet}'s default behavior (i.e.enumerating + * {@link jakarta.servlet.http.HttpServlet}'s default behavior (i.e.enumerating * all standard HTTP request methods as a response to the OPTIONS request). * Note however that as of 4.3 the {@code DispatcherServlet} sets this * property to "true" by default due to its built-in support for OPTIONS. @@ -462,7 +462,7 @@ public void setDispatchOptionsRequest(boolean dispatchOptionsRequest) { /** * Set whether this servlet should dispatch an HTTP TRACE request to * the {@link #doService} method. - *

    Default is "false", applying {@link javax.servlet.http.HttpServlet}'s + *

    Default is "false", applying {@link jakarta.servlet.http.HttpServlet}'s * default behavior (i.e. reflecting the message received back to the client). *

    Turn this flag on if you prefer TRACE requests to go through the * regular dispatching chain, just like other HTTP requests. This usually @@ -1153,7 +1153,7 @@ private void publishRequestHandledEvent(HttpServletRequest request, HttpServletR * Can be overridden in subclasses. * @param request current HTTP request * @return the username, or {@code null} if none found - * @see javax.servlet.http.HttpServletRequest#getUserPrincipal() + * @see jakarta.servlet.http.HttpServletRequest#getUserPrincipal() */ @Nullable protected String getUsernameForRequest(HttpServletRequest request) { @@ -1172,8 +1172,8 @@ protected String getUsernameForRequest(HttpServletRequest request) { * @param request current HTTP request * @param response current HTTP response * @throws Exception in case of any kind of processing failure - * @see javax.servlet.http.HttpServlet#doGet - * @see javax.servlet.http.HttpServlet#doPost + * @see jakarta.servlet.http.HttpServlet#doGet + * @see jakarta.servlet.http.HttpServlet#doPost */ protected abstract void doService(HttpServletRequest request, HttpServletResponse response) throws Exception; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerAdapter.java index cd43bdce5b15..a29e8bf0a142 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerAdapter.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExceptionResolver.java index 3fef242dea13..e6f446bb7cdd 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExceptionResolver.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExecutionChain.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExecutionChain.java index be69a0bf9368..76f5cb357712 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExecutionChain.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExecutionChain.java @@ -21,9 +21,8 @@ import java.util.Collections; import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerInterceptor.java index 09f126c747ef..d904cb6d254f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerInterceptor.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.web.method.HandlerMethod; @@ -70,7 +70,7 @@ * @see org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor * @see org.springframework.web.servlet.i18n.LocaleChangeInterceptor * @see org.springframework.web.servlet.theme.ThemeChangeInterceptor - * @see javax.servlet.Filter + * @see jakarta.servlet.Filter */ public interface HandlerInterceptor { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerMapping.java index 105250893728..0a64002f0181 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerMapping.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/HttpServletBean.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/HttpServletBean.java index ccd87dba220a..1d4766cab344 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/HttpServletBean.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/HttpServletBean.java @@ -20,10 +20,9 @@ import java.util.HashSet; import java.util.Set; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; - +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -48,7 +47,7 @@ import org.springframework.web.context.support.StandardServletEnvironment; /** - * Simple extension of {@link javax.servlet.http.HttpServlet} which treats + * Simple extension of {@link jakarta.servlet.http.HttpServlet} which treats * its config parameters ({@code init-param} entries within the * {@code servlet} tag in {@code web.xml}) as bean properties. * diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleContextResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleContextResolver.java index a51e6f4255fd..0140cf192ba2 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleContextResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleContextResolver.java @@ -18,8 +18,8 @@ import java.util.Locale; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.i18n.LocaleContext; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleResolver.java index fd0c651f84a5..0a6e99c8ff99 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleResolver.java @@ -18,8 +18,8 @@ import java.util.Locale; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/ModelAndViewDefiningException.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/ModelAndViewDefiningException.java index 63e337c61c2c..73f4ee3a9c0a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/ModelAndViewDefiningException.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/ModelAndViewDefiningException.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/NoHandlerFoundException.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/NoHandlerFoundException.java index e33c262f2c62..64413cd40961 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/NoHandlerFoundException.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/NoHandlerFoundException.java @@ -16,9 +16,9 @@ package org.springframework.web.servlet; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpHeaders; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/RequestToViewNameTranslator.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/RequestToViewNameTranslator.java index 5206cc5c8cf7..df95379987ce 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/RequestToViewNameTranslator.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/RequestToViewNameTranslator.java @@ -16,13 +16,13 @@ package org.springframework.web.servlet; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; /** * Strategy interface for translating an incoming - * {@link javax.servlet.http.HttpServletRequest} into a + * {@link jakarta.servlet.http.HttpServletRequest} into a * logical view name when no view name is explicitly supplied. * * @author Rob Harrop diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/ThemeResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/ThemeResolver.java index 61bcfd83cdcf..f38dd8081ce3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/ThemeResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/ThemeResolver.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/View.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/View.java index f59cd054d369..3d8bb3c36973 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/View.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/View.java @@ -18,8 +18,8 @@ import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java index 21d15bd89530..2684d24e5ea7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java @@ -178,9 +178,9 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { static { ClassLoader classLoader = AnnotationDrivenBeanDefinitionParser.class.getClassLoader(); - javaxValidationPresent = ClassUtils.isPresent("javax.validation.Validator", classLoader); + javaxValidationPresent = ClassUtils.isPresent("jakarta.validation.Validator", classLoader); romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", classLoader); - jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader); + jaxb2Present = ClassUtils.isPresent("jakarta.xml.bind.Binder", classLoader); jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader); jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java index fd7660f58c7b..8f08e691c8bf 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,6 @@ public void init() { registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser()); registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser()); registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser()); - registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser()); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/TilesConfigurerBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/TilesConfigurerBeanDefinitionParser.java deleted file mode 100644 index 3c5aa27645b5..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/TilesConfigurerBeanDefinitionParser.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.config; - -import java.util.ArrayList; -import java.util.List; - -import org.w3c.dom.Element; - -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.StringUtils; -import org.springframework.util.xml.DomUtils; - -/** - * Parse the <mvc:tiles-configurer> MVC namespace element and register - * a corresponding {@code TilesConfigurer} bean. - * - * @author Rossen Stoyanchev - * @author Juergen Hoeller - * @since 4.1 - */ -public class TilesConfigurerBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { - - /** - * The bean name used for the {@code TilesConfigurer}. - */ - public static final String BEAN_NAME = "mvcTilesConfigurer"; - - - @Override - protected String getBeanClassName(Element element) { - return "org.springframework.web.servlet.view.tiles3.TilesConfigurer"; - } - - @Override - protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) { - return BEAN_NAME; - } - - @Override - protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - List childElements = DomUtils.getChildElementsByTagName(element, "definitions"); - if (!childElements.isEmpty()) { - List locations = new ArrayList<>(childElements.size()); - for (Element childElement : childElements) { - locations.add(childElement.getAttribute("location")); - } - builder.addPropertyValue("definitions", StringUtils.toStringArray(locations)); - } - if (element.hasAttribute("check-refresh")) { - builder.addPropertyValue("checkRefresh", element.getAttribute("check-refresh")); - } - if (element.hasAttribute("validate-definitions")) { - builder.addPropertyValue("validateDefinitions", element.getAttribute("validate-definitions")); - } - if (element.hasAttribute("definitions-factory")) { - builder.addPropertyValue("definitionsFactoryClass", element.getAttribute("definitions-factory")); - } - if (element.hasAttribute("preparer-factory")) { - builder.addPropertyValue("preparerFactoryClass", element.getAttribute("preparer-factory")); - } - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java index d9693b2f3e08..421d7c182c61 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,6 @@ import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver; import org.springframework.web.servlet.view.groovy.GroovyMarkupViewResolver; import org.springframework.web.servlet.view.script.ScriptTemplateViewResolver; -import org.springframework.web.servlet.view.tiles3.TilesViewResolver; /** * Parse the {@code view-resolvers} MVC namespace element and register @@ -92,10 +91,6 @@ public BeanDefinition parse(Element element, ParserContext context) { resolverBeanDef.getPropertyValues().add("suffix", ".jsp"); addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef); } - else if ("tiles".equals(name)) { - resolverBeanDef = new RootBeanDefinition(TilesViewResolver.class); - addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef); - } else if ("freemarker".equals(name)) { resolverBeanDef = new RootBeanDefinition(FreeMarkerViewResolver.class); resolverBeanDef.getPropertyValues().add("suffix", ".ftl"); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer.java index 6f5d1d3b3107..7e4d475aa8c1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.Map; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.http.MediaType; import org.springframework.http.MediaTypeFactory; @@ -102,7 +102,7 @@ public class ContentNegotiationConfigurer { /** - * Class constructor with {@link javax.servlet.ServletContext}. + * Class constructor with {@link jakarta.servlet.ServletContext}. */ public ContentNegotiationConfigurer(@Nullable ServletContext servletContext) { if (servletContext != null) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurer.java index fff78a82c71b..752febb40824 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurer.java @@ -18,7 +18,7 @@ import java.util.Collections; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.core.Ordered; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.java index ba710151595d..54ff13fc5627 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.Map; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.context.ApplicationContext; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolverRegistry.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolverRegistry.java index cf740c31690a..87c414d27792 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolverRegistry.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolverRegistry.java @@ -40,8 +40,6 @@ import org.springframework.web.servlet.view.groovy.GroovyMarkupViewResolver; import org.springframework.web.servlet.view.script.ScriptTemplateConfigurer; import org.springframework.web.servlet.view.script.ScriptTemplateViewResolver; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; -import org.springframework.web.servlet.view.tiles3.TilesViewResolver; /** * Assist with the configuration of a chain of @@ -165,22 +163,6 @@ public UrlBasedViewResolverRegistration jsp(String prefix, String suffix) { return new UrlBasedViewResolverRegistration(resolver); } - /** - * Register Tiles 3.x view resolver. - *

    Note that you must also configure Tiles by adding a - * {@link org.springframework.web.servlet.view.tiles3.TilesConfigurer} bean. - */ - public UrlBasedViewResolverRegistration tiles() { - if (!checkBeanOfType(TilesConfigurer.class)) { - throw new BeanInitializationException("In addition to a Tiles view resolver " + - "there must also be a single TilesConfigurer bean in this web application context " + - "(or its parent)."); - } - TilesRegistration registration = new TilesRegistration(); - this.viewResolvers.add(registration.getViewResolver()); - return registration; - } - /** * Register a FreeMarker view resolver with an empty default view name * prefix and a default suffix of ".ftl". @@ -292,13 +274,6 @@ protected List getViewResolvers() { } - private static class TilesRegistration extends UrlBasedViewResolverRegistration { - - public TilesRegistration() { - super(new TilesViewResolver()); - } - } - private static class FreeMarkerRegistration extends UrlBasedViewResolverRegistration { public FreeMarkerRegistration() { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java index e0e91bf8d323..7afe6a07a9b7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java @@ -23,7 +23,7 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.BeanFactoryUtils; @@ -218,14 +218,14 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv static { ClassLoader classLoader = WebMvcConfigurationSupport.class.getClassLoader(); romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", classLoader); - jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader); + jaxb2Present = ClassUtils.isPresent("jakarta.xml.bind.Binder", classLoader); jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader); jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader); jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader); jackson2CborPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory", classLoader); gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader); - jsonbPresent = ClassUtils.isPresent("javax.json.bind.Jsonb", classLoader); + jsonbPresent = ClassUtils.isPresent("jakarta.json.bind.Jsonb", classLoader); kotlinSerializationJsonPresent = ClassUtils.isPresent("kotlinx.serialization.json.Json", classLoader); } @@ -279,7 +279,7 @@ public final ApplicationContext getApplicationContext() { } /** - * Set the {@link javax.servlet.ServletContext}, e.g. for resource handling, + * Set the {@link jakarta.servlet.ServletContext}, e.g. for resource handling, * looking up file extensions, etc. */ @Override @@ -288,7 +288,7 @@ public void setServletContext(@Nullable ServletContext servletContext) { } /** - * Return the associated {@link javax.servlet.ServletContext}. + * Return the associated {@link jakarta.servlet.ServletContext}. * @since 4.2 */ @Nullable @@ -774,7 +774,7 @@ protected void addFormatters(FormatterRegistry registry) { public Validator mvcValidator() { Validator validator = getValidator(); if (validator == null) { - if (ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) { + if (ClassUtils.isPresent("jakarta.validation.Validator", getClass().getClassLoader())) { Class clazz; try { String className = "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean"; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/AbstractServerResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/AbstractServerResponse.java index d191c05c298a..a35571fdf222 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/AbstractServerResponse.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/AbstractServerResponse.java @@ -21,10 +21,10 @@ import java.util.EnumSet; import java.util.Set; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultAsyncServerResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultAsyncServerResponse.java index e720174b37ea..73e91e507ba9 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultAsyncServerResponse.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultAsyncServerResponse.java @@ -25,11 +25,10 @@ import java.util.concurrent.TimeoutException; import java.util.function.Function; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.reactivestreams.Publisher; import org.springframework.core.ReactiveAdapter; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultEntityResponseBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultEntityResponseBuilder.java index fedfe2d4a409..cf674214be4b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultEntityResponseBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultEntityResponseBuilder.java @@ -30,12 +30,11 @@ import java.util.function.Consumer; import java.util.stream.Collectors; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.reactivestreams.Publisher; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultRenderingResponseBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultRenderingResponseBuilder.java index 8b6a4faa140f..db34f733cf5a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultRenderingResponseBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultRenderingResponseBuilder.java @@ -23,9 +23,9 @@ import java.util.Map; import java.util.function.Consumer; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.core.Conventions; import org.springframework.http.HttpHeaders; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java index 26f76e7ca0ab..5d6b5ef0248f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java @@ -37,13 +37,13 @@ import java.util.Set; import java.util.stream.Collectors; -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.Part; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.Part; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequestBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequestBuilder.java index 9598c0180041..7dbca4417cbc 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequestBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequestBuilder.java @@ -33,13 +33,13 @@ import java.util.function.Consumer; import java.util.stream.Collectors; -import javax.servlet.ReadListener; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import javax.servlet.http.Part; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.Part; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerResponseBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerResponseBuilder.java index 8f9dbcde88cd..7cbb36ff99d3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerResponseBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerResponseBuilder.java @@ -26,9 +26,9 @@ import java.util.function.BiFunction; import java.util.function.Consumer; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.CacheControl; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/EntityResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/EntityResponse.java index e2bb1c543b24..56e033e747c7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/EntityResponse.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/EntityResponse.java @@ -22,7 +22,7 @@ import java.util.Set; import java.util.function.Consumer; -import javax.servlet.http.Cookie; +import jakarta.servlet.http.Cookie; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.CacheControl; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ErrorHandlingServerResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ErrorHandlingServerResponse.java index 9ae67ec10237..bce77dbe4c7e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ErrorHandlingServerResponse.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ErrorHandlingServerResponse.java @@ -22,10 +22,9 @@ import java.util.function.BiFunction; import java.util.function.Predicate; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RenderingResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RenderingResponse.java index 569ede13e66a..83e727067e1d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RenderingResponse.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RenderingResponse.java @@ -20,7 +20,7 @@ import java.util.Map; import java.util.function.Consumer; -import javax.servlet.http.Cookie; +import jakarta.servlet.http.Cookie; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java index 664d6a851dc1..b359806396bc 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java @@ -35,12 +35,11 @@ import java.util.function.Function; import java.util.function.Predicate; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import javax.servlet.http.Part; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.Part; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java index 6bbb3a43391e..ec006e193ada 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java @@ -29,11 +29,11 @@ import java.util.OptionalLong; import java.util.function.Consumer; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import javax.servlet.http.Part; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.Part; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.io.buffer.DataBuffer; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java index 11efe5b02232..7e9fb25c0bc0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java @@ -30,11 +30,10 @@ import java.util.function.BiFunction; import java.util.function.Consumer; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.reactivestreams.Publisher; import org.springframework.core.ParameterizedTypeReference; 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 e078a66d110a..a3965a0a1cf5 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 @@ -24,10 +24,10 @@ import java.util.List; import java.util.function.Consumer; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.CacheControl; import org.springframework.http.HttpHeaders; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/HandlerFunctionAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/HandlerFunctionAdapter.java index 67fac910b781..819c7e9e2104 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/HandlerFunctionAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/HandlerFunctionAdapter.java @@ -18,10 +18,9 @@ import java.util.List; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/RouterFunctionMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/RouterFunctionMapping.java index 7597f0af686d..d0b96a7fb03b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/RouterFunctionMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/RouterFunctionMapping.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.InitializingBean; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java index e5e2db0b6a16..6af3b3cb2d52 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java @@ -18,9 +18,8 @@ import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java index d3336710f0c4..f100a8ad33ae 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java @@ -22,10 +22,9 @@ import java.util.List; import java.util.Map; -import javax.servlet.DispatcherType; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.DispatcherType; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.springframework.beans.BeansException; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodExceptionResolver.java index 9f4ceb43a1f5..47acaf4bc526 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodExceptionResolver.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.handler; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.web.method.HandlerMethod; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java index 46f1707d1cfb..2073087a1508 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java @@ -32,8 +32,8 @@ import java.util.function.Function; import java.util.stream.Collectors; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.BeanFactoryUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java index 2f7be313ca98..f244dfdada25 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java @@ -23,8 +23,8 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/ConversionServiceExposingInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/ConversionServiceExposingInterceptor.java index a8e3b0ae3383..c5c25d694466 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/ConversionServiceExposingInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/ConversionServiceExposingInterceptor.java @@ -18,9 +18,9 @@ import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.core.convert.ConversionService; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/DispatcherServletWebRequest.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/DispatcherServletWebRequest.java index 6ea1536297dd..cace2a641517 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/DispatcherServletWebRequest.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/DispatcherServletWebRequest.java @@ -18,8 +18,8 @@ import java.util.Locale; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.servlet.support.RequestContextUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerExceptionResolverComposite.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerExceptionResolverComposite.java index 9732169bfd87..fbc49d5edbd8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerExceptionResolverComposite.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerExceptionResolverComposite.java @@ -19,8 +19,8 @@ import java.util.Collections; import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.core.Ordered; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java index 81d38fb3b8c7..76d90f320bb6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java @@ -27,8 +27,8 @@ import java.util.function.BiFunction; import java.util.stream.Collectors; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.InitializingBean; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/MappedInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/MappedInterceptor.java index 01e0961984e2..46977483ada3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/MappedInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/MappedInterceptor.java @@ -18,8 +18,8 @@ import java.util.Arrays; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.server.PathContainer; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/MatchableHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/MatchableHandlerMapping.java index 85ef3ec17da0..27ce57380c80 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/MatchableHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/MatchableHandlerMapping.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.handler; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; import org.springframework.web.servlet.HandlerMapping; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/PathPatternMatchableHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/PathPatternMatchableHandlerMapping.java index 4b7a906732bb..42028a912347 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/PathPatternMatchableHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/PathPatternMatchableHandlerMapping.java @@ -18,7 +18,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.server.PathContainer; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleMappingExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleMappingExceptionResolver.java index 99d8027638e2..61645c5c8de5 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleMappingExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleMappingExceptionResolver.java @@ -22,8 +22,8 @@ import java.util.Map; import java.util.Properties; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.web.servlet.ModelAndView; @@ -70,7 +70,7 @@ public class SimpleMappingExceptionResolver extends AbstractHandlerExceptionReso /** * Set the mappings between exception class names and error view names. * The exception class name can be a substring, with no wildcard support at present. - * A value of "ServletException" would match {@code javax.servlet.ServletException} + * A value of "ServletException" would match {@code jakarta.servlet.ServletException} * and subclasses, for example. *

    NB: Consider carefully how * specific the pattern is, and whether to include package information (which isn't mandatory). diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleServletHandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleServletHandlerAdapter.java index 7cc9fcf9f0d3..165688844429 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleServletHandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleServletHandlerAdapter.java @@ -16,9 +16,9 @@ package org.springframework.web.servlet.handler; -import javax.servlet.Servlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.Servlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.web.servlet.HandlerAdapter; @@ -47,8 +47,8 @@ * * @author Juergen Hoeller * @since 1.1.5 - * @see javax.servlet.Servlet - * @see javax.servlet.http.HttpServlet + * @see jakarta.servlet.Servlet + * @see jakarta.servlet.http.HttpServlet * @see SimpleServletPostProcessor * @see org.springframework.web.servlet.mvc.ServletWrappingController */ diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleServletPostProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleServletPostProcessor.java index 589d8cf5f31c..bfab08397d3f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleServletPostProcessor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleServletPostProcessor.java @@ -19,10 +19,10 @@ import java.util.Collections; import java.util.Enumeration; -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanInitializationException; @@ -34,7 +34,7 @@ /** * {@link org.springframework.beans.factory.config.BeanPostProcessor} * that applies initialization and destruction callbacks to beans that - * implement the {@link javax.servlet.Servlet} interface. + * implement the {@link jakarta.servlet.Servlet} interface. * *

    After initialization of the bean instance, the Servlet {@code init} * method will be called with a ServletConfig that contains the bean name @@ -61,8 +61,8 @@ * * @author Juergen Hoeller * @since 1.1.5 - * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) - * @see javax.servlet.Servlet#destroy() + * @see jakarta.servlet.Servlet#init(jakarta.servlet.ServletConfig) + * @see jakarta.servlet.Servlet#destroy() * @see SimpleServletHandlerAdapter */ public class SimpleServletPostProcessor implements diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/UserRoleAuthorizationInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/UserRoleAuthorizationInterceptor.java index a4a49ed09e52..90d1209c9ba4 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/UserRoleAuthorizationInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/UserRoleAuthorizationInterceptor.java @@ -18,9 +18,9 @@ import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.web.servlet.HandlerInterceptor; @@ -31,7 +31,7 @@ * * @author Juergen Hoeller * @since 20.06.2003 - * @see javax.servlet.http.HttpServletRequest#isUserInRole + * @see jakarta.servlet.http.HttpServletRequest#isUserInRole */ public class UserRoleAuthorizationInterceptor implements HandlerInterceptor { @@ -71,7 +71,7 @@ public final boolean preHandle(HttpServletRequest request, HttpServletResponse r * @param request current HTTP request * @param response current HTTP response * @param handler chosen handler to execute, for type and/or instance evaluation - * @throws javax.servlet.ServletException if there is an internal error + * @throws jakarta.servlet.ServletException if there is an internal error * @throws java.io.IOException in case of an I/O error when writing the response */ protected void handleNotAuthorized(HttpServletRequest request, HttpServletResponse response, Object handler) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/WebRequestHandlerInterceptorAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/WebRequestHandlerInterceptorAdapter.java index e669344f086a..a3028dcb27d7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/WebRequestHandlerInterceptorAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/WebRequestHandlerInterceptorAdapter.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.handler; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleContextResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleContextResolver.java index 786628f91ac9..98162f6fecbb 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleContextResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleContextResolver.java @@ -19,8 +19,8 @@ import java.util.Locale; import java.util.TimeZone; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.i18n.SimpleLocaleContext; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java index e5c027e96831..8df4c6c51df4 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java @@ -21,8 +21,8 @@ import java.util.List; import java.util.Locale; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; @@ -39,7 +39,7 @@ * @author Juergen Hoeller * @author Rossen Stoyanchev * @since 27.02.2003 - * @see javax.servlet.http.HttpServletRequest#getLocale() + * @see jakarta.servlet.http.HttpServletRequest#getLocale() */ public class AcceptHeaderLocaleResolver implements LocaleResolver { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java index 557bf7801e85..bf30ea4bc530 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java @@ -19,9 +19,9 @@ import java.util.Locale; import java.util.TimeZone; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.i18n.LocaleContext; import org.springframework.context.i18n.SimpleLocaleContext; @@ -333,7 +333,7 @@ protected String toLocaleValue(Locale locale) { * @param request the request to resolve the locale for * @return the default locale (never {@code null}) * @see #setDefaultLocale - * @see javax.servlet.http.HttpServletRequest#getLocale() + * @see jakarta.servlet.http.HttpServletRequest#getLocale() */ protected Locale determineDefaultLocale(HttpServletRequest request) { Locale defaultLocale = getDefaultLocale(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/FixedLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/FixedLocaleResolver.java index 60252cf4a047..ada77bdcd365 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/FixedLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/FixedLocaleResolver.java @@ -19,8 +19,8 @@ import java.util.Locale; import java.util.TimeZone; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.i18n.LocaleContext; import org.springframework.context.i18n.TimeZoneAwareLocaleContext; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java index 8e64ea6ed932..6f118374a275 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java @@ -18,10 +18,9 @@ import java.util.Locale; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/SessionLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/SessionLocaleResolver.java index 18572a08135d..7ae9042a09d0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/SessionLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/SessionLocaleResolver.java @@ -19,8 +19,8 @@ import java.util.Locale; import java.util.TimeZone; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.i18n.LocaleContext; import org.springframework.context.i18n.TimeZoneAwareLocaleContext; @@ -164,7 +164,7 @@ public void setLocaleContext(HttpServletRequest request, @Nullable HttpServletRe * @param request the request to resolve the locale for * @return the default locale (never {@code null}) * @see #setDefaultLocale - * @see javax.servlet.http.HttpServletRequest#getLocale() + * @see jakarta.servlet.http.HttpServletRequest#getLocale() */ protected Locale determineDefaultLocale(HttpServletRequest request) { Locale defaultLocale = getDefaultLocale(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/AbstractController.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/AbstractController.java index 8c40056b8eab..12a42a7a4918 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/AbstractController.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/AbstractController.java @@ -16,9 +16,9 @@ package org.springframework.web.servlet.mvc; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import org.springframework.http.HttpMethod; import org.springframework.lang.Nullable; @@ -135,7 +135,7 @@ public AbstractController(boolean restrictDefaultSupportedMethods) { * different servlet containers; the only 100% safe way is a session mutex. * @see AbstractController#handleRequestInternal * @see org.springframework.web.util.HttpSessionMutexListener - * @see org.springframework.web.util.WebUtils#getSessionMutex(javax.servlet.http.HttpSession) + * @see org.springframework.web.util.WebUtils#getSessionMutex(jakarta.servlet.http.HttpSession) */ public final void setSynchronizeOnSession(boolean synchronizeOnSession) { this.synchronizeOnSession = synchronizeOnSession; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/AbstractUrlViewController.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/AbstractUrlViewController.java index ef8c34989685..768b8ad3f7c6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/AbstractUrlViewController.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/AbstractUrlViewController.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.mvc; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.util.Assert; import org.springframework.web.servlet.ModelAndView; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/Controller.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/Controller.java index 4f59c52ca1b5..cc37288772d1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/Controller.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/Controller.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.mvc; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.web.servlet.ModelAndView; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/HttpRequestHandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/HttpRequestHandlerAdapter.java index 161750bc55dc..8fef024bce15 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/HttpRequestHandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/HttpRequestHandlerAdapter.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.mvc; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.web.HttpRequestHandler; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/LastModified.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/LastModified.java index a6cfdcf86a69..a35c825f2ebd 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/LastModified.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/LastModified.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.mvc; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; /** * Supports last-modified HTTP requests to facilitate content caching. @@ -39,7 +39,7 @@ * annotated controller method, returning a * {@link org.springframework.http.ResponseEntity} with an "ETag" and/or * "Last-Modified" headers set. - * @see javax.servlet.http.HttpServlet#getLastModified + * @see jakarta.servlet.http.HttpServlet#getLastModified * @see Controller * @see SimpleControllerHandlerAdapter * @see org.springframework.web.HttpRequestHandler @@ -58,7 +58,7 @@ public interface LastModified { * @return the time the underlying resource was last modified, or -1 * meaning that the content must always be regenerated * @see org.springframework.web.servlet.HandlerAdapter#getLastModified - * @see javax.servlet.http.HttpServlet#getLastModified + * @see jakarta.servlet.http.HttpServlet#getLastModified */ long getLastModified(HttpServletRequest request); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ParameterizableViewController.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ParameterizableViewController.java index c447a70c164a..6cf029898ce2 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ParameterizableViewController.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ParameterizableViewController.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.mvc; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ServletForwardingController.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ServletForwardingController.java index 8e4f3dccc131..fe1d2fb81d1d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ServletForwardingController.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ServletForwardingController.java @@ -16,11 +16,11 @@ package org.springframework.web.servlet.mvc; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.BeanNameAware; import org.springframework.lang.Nullable; @@ -157,9 +157,9 @@ protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpSer * @param request current HTTP request * @param response current HTTP response * @return {@code true} for include, {@code false} for forward - * @see javax.servlet.RequestDispatcher#forward - * @see javax.servlet.RequestDispatcher#include - * @see javax.servlet.ServletResponse#isCommitted + * @see jakarta.servlet.RequestDispatcher#forward + * @see jakarta.servlet.RequestDispatcher#include + * @see jakarta.servlet.ServletResponse#isCommitted * @see org.springframework.web.util.WebUtils#isIncludeRequest */ protected boolean useInclude(HttpServletRequest request, HttpServletResponse response) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ServletWrappingController.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ServletWrappingController.java index bcac67c11cbc..673c110da121 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ServletWrappingController.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ServletWrappingController.java @@ -19,11 +19,11 @@ import java.util.Enumeration; import java.util.Properties; -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; @@ -108,8 +108,8 @@ public ServletWrappingController() { /** * Set the class of the servlet to wrap. - * Needs to implement {@code javax.servlet.Servlet}. - * @see javax.servlet.Servlet + * Needs to implement {@code jakarta.servlet.Servlet}. + * @see jakarta.servlet.Servlet */ public void setServletClass(Class servletClass) { this.servletClass = servletClass; @@ -139,7 +139,7 @@ public void setBeanName(String name) { /** * Initialize the wrapped Servlet instance. - * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) + * @see jakarta.servlet.Servlet#init(jakarta.servlet.ServletConfig) */ @Override public void afterPropertiesSet() throws Exception { @@ -156,7 +156,7 @@ public void afterPropertiesSet() throws Exception { /** * Invoke the wrapped Servlet instance. - * @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) + * @see jakarta.servlet.Servlet#service(jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse) */ @Override protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) @@ -170,7 +170,7 @@ protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpSer /** * Destroy the wrapped Servlet instance. - * @see javax.servlet.Servlet#destroy() + * @see jakarta.servlet.Servlet#destroy() */ @Override public void destroy() { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/SimpleControllerHandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/SimpleControllerHandlerAdapter.java index 64372c665c60..a8acd760ec0f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/SimpleControllerHandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/SimpleControllerHandlerAdapter.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.mvc; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.web.servlet.HandlerAdapter; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/UrlFilenameViewController.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/UrlFilenameViewController.java index 4e2397d51d3d..fc026104af0a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/UrlFilenameViewController.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/UrlFilenameViewController.java @@ -19,7 +19,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/WebContentInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/WebContentInterceptor.java index 696be902b754..450ec25c9a81 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/WebContentInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/WebContentInterceptor.java @@ -21,10 +21,10 @@ import java.util.Map; import java.util.Properties; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.CacheControl; import org.springframework.http.server.PathContainer; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java index 6fd143c76d20..b2ae8bb1bf9c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java @@ -18,8 +18,8 @@ import java.io.IOException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractNameValueExpression.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractNameValueExpression.java index 5acc07c3dc44..91e5c16cb32d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractNameValueExpression.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractNameValueExpression.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.mvc.condition; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/CompositeRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/CompositeRequestCondition.java index 5857fdc5eb56..07b91753cffa 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/CompositeRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/CompositeRequestCondition.java @@ -21,7 +21,7 @@ import java.util.Collections; import java.util.List; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ConsumesRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ConsumesRequestCondition.java index 0efe0c849b3d..430fe9fbd4c2 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ConsumesRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ConsumesRequestCondition.java @@ -23,7 +23,7 @@ import java.util.List; import java.util.Set; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpHeaders; import org.springframework.http.InvalidMediaTypeException; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/HeadersRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/HeadersRequestCondition.java index e3f1773318ee..e2f78cac600c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/HeadersRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/HeadersRequestCondition.java @@ -21,7 +21,7 @@ import java.util.LinkedHashSet; import java.util.Set; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ParamsRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ParamsRequestCondition.java index f06f363aa2c3..074ce921978a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ParamsRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ParamsRequestCondition.java @@ -22,7 +22,7 @@ import java.util.LinkedHashSet; import java.util.Set; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PathPatternsRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PathPatternsRequestCondition.java index a89b4ed3cb6b..e7f4923065d8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PathPatternsRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PathPatternsRequestCondition.java @@ -25,7 +25,7 @@ import java.util.TreeSet; import java.util.stream.Collectors; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.server.PathContainer; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java index 9539415ae388..6bd5676e2b0f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java @@ -26,7 +26,7 @@ import java.util.List; import java.util.Set; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; import org.springframework.util.AntPathMatcher; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ProducesRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ProducesRequestCondition.java index 7a6af2272599..b7e3aa4fed66 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ProducesRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ProducesRequestCondition.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.Set; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.MediaType; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestCondition.java index d2eb27d2fa9c..cf399dcd1270 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestCondition.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.mvc.condition; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestConditionHolder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestConditionHolder.java index 5ea41adce503..ebed0908cb8e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestConditionHolder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestConditionHolder.java @@ -19,7 +19,7 @@ import java.util.Collection; import java.util.Collections; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestCondition.java index 4184239e4882..f00f2414a73f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestCondition.java @@ -23,8 +23,8 @@ import java.util.Map; import java.util.Set; -import javax.servlet.DispatcherType; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/AbstractHandlerMethodAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/AbstractHandlerMethodAdapter.java index 24ef3cb6573e..d12f14d02d82 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/AbstractHandlerMethodAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/AbstractHandlerMethodAdapter.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.mvc.method; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.core.Ordered; import org.springframework.lang.Nullable; @@ -111,7 +111,7 @@ public final long getLastModified(HttpServletRequest request, Object handler) { } /** - * Same contract as for {@link javax.servlet.http.HttpServlet#getLastModified(HttpServletRequest)}. + * Same contract as for {@link jakarta.servlet.http.HttpServlet#getLastModified(HttpServletRequest)}. * @param request current HTTP request * @param handlerMethod handler method to use * @return the lastModified value for the given handler diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java index 79622c386169..99cd5fe89d0c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java @@ -19,8 +19,8 @@ import java.util.List; import java.util.Set; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpMethod; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java index 8758e7cc76ac..d321a36ead1e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java @@ -26,8 +26,8 @@ import java.util.Map; import java.util.Set; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodArgumentResolver.java index 1dbc559e2ccf..b9bf4a176b19 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodArgumentResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodArgumentResolver.java @@ -29,8 +29,7 @@ import java.util.Optional; import java.util.Set; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -229,7 +228,7 @@ protected ServletServerHttpRequest createInputMessage(NativeWebRequest webReques /** * Validate the binding target if applicable. - *

    The default implementation checks for {@code @javax.validation.Valid}, + *

    The default implementation checks for {@code @jakarta.validation.Valid}, * Spring's {@link org.springframework.validation.annotation.Validated}, * and custom annotations whose name starts with "Valid". * @param binder the DataBinder to be used diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java index 158a33b9c918..bd18540925b9 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java @@ -26,9 +26,9 @@ import java.util.Locale; import java.util.Set; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.core.GenericTypeResolver; import org.springframework.core.MethodParameter; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java index 7be174e7a68b..83ae13af4eea 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java @@ -25,8 +25,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.InitializingBean; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinder.java index a0db1cac45a2..2708af1108fa 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinder.java @@ -18,7 +18,7 @@ import java.util.Map; -import javax.servlet.ServletRequest; +import jakarta.servlet.ServletRequest; import org.springframework.beans.MutablePropertyValues; import org.springframework.lang.Nullable; 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 6b9f0af70723..f498494a3a21 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 @@ -24,8 +24,8 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.core.MethodParameter; import org.springframework.core.ResolvableType; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpHeadersReturnValueHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpHeadersReturnValueHandler.java index 9678ac2fe781..224d3a17a01d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpHeadersReturnValueHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpHeadersReturnValueHandler.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.mvc.method.annotation; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.core.MethodParameter; import org.springframework.http.HttpHeaders; 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 7c60bee6675a..a78fb6011a17 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 @@ -23,8 +23,7 @@ import java.util.Map; import java.util.Set; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.aopalliance.intercept.MethodInterceptor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/PrincipalMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/PrincipalMethodArgumentResolver.java index dff70178eac6..23ebbd3f0d4c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/PrincipalMethodArgumentResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/PrincipalMethodArgumentResolver.java @@ -18,7 +18,7 @@ import java.security.Principal; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.MethodParameter; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestAttributeMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestAttributeMethodArgumentResolver.java index 5845ee5cdcb9..9156c86f7277 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestAttributeMethodArgumentResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestAttributeMethodArgumentResolver.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.mvc.method.annotation; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; import org.springframework.core.MethodParameter; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java index 6005b22e247b..59b056b47384 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java @@ -25,9 +25,9 @@ import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -528,7 +528,7 @@ public void setCacheSecondsForSessionAttributeHandlers(int cacheSecondsForSessio * same active logical session. However, this is not guaranteed across * different servlet containers; the only 100% safe way is a session mutex. * @see org.springframework.web.util.HttpSessionMutexListener - * @see org.springframework.web.util.WebUtils#getSessionMutex(javax.servlet.http.HttpSession) + * @see org.springframework.web.util.WebUtils#getSessionMutex(jakarta.servlet.http.HttpSession) */ public void setSynchronizeOnSession(boolean synchronizeOnSession) { this.synchronizeOnSession = synchronizeOnSession; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java index 1da7ca1ed8b3..a5061118a976 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java @@ -25,7 +25,7 @@ import java.util.Map; import java.util.function.Predicate; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.core.annotation.AnnotatedElementUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolver.java index e828239d7100..d32a396c4cfe 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolver.java @@ -18,7 +18,7 @@ import java.util.List; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.MethodParameter; import org.springframework.http.HttpInputMessage; @@ -46,7 +46,7 @@ *

      *
    • Annotated with @{@link RequestPart} *
    • Of type {@link MultipartFile} in conjunction with Spring's {@link MultipartResolver} abstraction - *
    • Of type {@code javax.servlet.http.Part} in conjunction with Servlet 3.0 multipart requests + *
    • Of type {@code jakarta.servlet.http.Part} in conjunction with Servlet 3.0 multipart requests *
    * *

    When a parameter is annotated with {@code @RequestPart}, the content of the part is @@ -96,7 +96,7 @@ public RequestPartMethodArgumentResolver(List> messageCo *

      *
    • annotated with {@code @RequestPart} *
    • of type {@link MultipartFile} unless annotated with {@code @RequestParam} - *
    • of type {@code javax.servlet.http.Part} unless annotated with + *
    • of type {@code jakarta.servlet.http.Part} unless annotated with * {@code @RequestParam} *
    */ diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java index 50e4fd56413b..0d8907f7c60a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java @@ -20,7 +20,7 @@ import java.lang.reflect.Type; import java.util.List; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.Conventions; import org.springframework.core.MethodParameter; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java index 6688fe5b5afa..f6550aed27c0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java @@ -22,8 +22,8 @@ import java.util.List; import java.util.function.Consumer; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.core.MethodParameter; import org.springframework.core.ReactiveAdapterRegistry; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java index f706afe2d4c6..2c96722b14ef 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java @@ -19,8 +19,7 @@ import java.util.List; import java.util.Set; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletCookieValueMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletCookieValueMethodArgumentResolver.java index 97c66a581a32..e41c49ce0bf8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletCookieValueMethodArgumentResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletCookieValueMethodArgumentResolver.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.mvc.method.annotation; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.core.MethodParameter; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java index ae3473873dee..db5d7556cc10 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java @@ -22,8 +22,8 @@ import java.lang.reflect.Type; import java.util.concurrent.Callable; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.MessageSource; import org.springframework.core.KotlinDetector; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletModelAttributeMethodProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletModelAttributeMethodProcessor.java index 38cf420e141f..b7e7418e7714 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletModelAttributeMethodProcessor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletModelAttributeMethodProcessor.java @@ -19,7 +19,7 @@ import java.util.Collections; import java.util.Map; -import javax.servlet.ServletRequest; +import jakarta.servlet.ServletRequest; import org.springframework.core.MethodParameter; import org.springframework.core.convert.ConversionService; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletRequestMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletRequestMethodArgumentResolver.java index 45ca54595efa..db80a70dfd13 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletRequestMethodArgumentResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletRequestMethodArgumentResolver.java @@ -24,10 +24,10 @@ import java.util.Locale; import java.util.TimeZone; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import javax.servlet.http.PushBuilder; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.PushBuilder; import org.springframework.core.MethodParameter; import org.springframework.http.HttpMethod; @@ -73,7 +73,7 @@ public class ServletRequestMethodArgumentResolver implements HandlerMethodArgume static { try { - pushBuilder = ClassUtils.forName("javax.servlet.http.PushBuilder", + pushBuilder = ClassUtils.forName("jakarta.servlet.http.PushBuilder", ServletRequestMethodArgumentResolver.class.getClassLoader()); } catch (ClassNotFoundException ex) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletResponseMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletResponseMethodArgumentResolver.java index 3ee6d5b0274b..45e71a9081b9 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletResponseMethodArgumentResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletResponseMethodArgumentResolver.java @@ -20,7 +20,7 @@ import java.io.OutputStream; import java.io.Writer; -import javax.servlet.ServletResponse; +import jakarta.servlet.ServletResponse; import org.springframework.core.MethodParameter; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SessionAttributeMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SessionAttributeMethodArgumentResolver.java index 3f68273d965f..c5cce648c07b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SessionAttributeMethodArgumentResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SessionAttributeMethodArgumentResolver.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.mvc.method.annotation; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; import org.springframework.core.MethodParameter; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/StreamingResponseBodyReturnValueHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/StreamingResponseBodyReturnValueHandler.java index 43472293e929..4cecd34e8af7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/StreamingResponseBodyReturnValueHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/StreamingResponseBodyReturnValueHandler.java @@ -19,8 +19,8 @@ import java.io.OutputStream; import java.util.concurrent.Callable; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.core.MethodParameter; import org.springframework.core.ResolvableType; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/UriComponentsBuilderMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/UriComponentsBuilderMethodArgumentResolver.java index 928af577e709..34fdfce6570c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/UriComponentsBuilderMethodArgumentResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/UriComponentsBuilderMethodArgumentResolver.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.mvc.method.annotation; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.MethodParameter; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java index 542f0ae8f87d..ce787c69cf4f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java @@ -19,9 +19,8 @@ import java.io.IOException; import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -463,7 +462,7 @@ protected ModelAndView handleMethodArgumentNotValidException(MethodArgumentNotVa /** * Handle the case where an {@linkplain RequestPart @RequestPart}, a {@link MultipartFile}, - * or a {@code javax.servlet.http.Part} argument is required but is missing. + * or a {@code jakarta.servlet.http.Part} argument is required but is missing. *

    By default, an HTTP 400 error is sent back to the client. * @param request current HTTP request * @param response current HTTP response @@ -544,12 +543,12 @@ protected ModelAndView handleAsyncRequestTimeoutException(AsyncRequestTimeoutExc /** * Invoked to send a server error. Sets the status to 500 and also sets the - * request attribute "javax.servlet.error.exception" to the Exception. + * request attribute "jakarta.servlet.error.exception" to the Exception. */ protected void sendServerError(Exception ex, HttpServletRequest request, HttpServletResponse response) throws IOException { - request.setAttribute("javax.servlet.error.exception", ex); + request.setAttribute("jakarta.servlet.error.exception", ex); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AbstractResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AbstractResourceResolver.java index 9f507232d19a..c4228ce0ed69 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AbstractResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AbstractResourceResolver.java @@ -18,8 +18,7 @@ import java.util.List; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AppCacheManifestTransformer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AppCacheManifestTransformer.java index 5f8facffd391..4c0d9b4d3bb4 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AppCacheManifestTransformer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AppCacheManifestTransformer.java @@ -26,8 +26,7 @@ import java.util.Collections; import java.util.Scanner; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CachingResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CachingResourceResolver.java index 762c84884150..882504fad0f5 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CachingResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CachingResourceResolver.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.stream.Collectors; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CachingResourceTransformer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CachingResourceTransformer.java index bea1c5fd9f21..2c220f04a8a9 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CachingResourceTransformer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CachingResourceTransformer.java @@ -18,8 +18,7 @@ import java.io.IOException; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java index a590d61f687e..e27e2ac1dab6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java @@ -25,8 +25,7 @@ import java.util.SortedSet; import java.util.TreeSet; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultResourceResolverChain.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultResourceResolverChain.java index e2aeb9b2512d..d01e9c334411 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultResourceResolverChain.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultResourceResolverChain.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.ListIterator; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.Resource; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultResourceTransformerChain.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultResourceTransformerChain.java index 6ea4c4aaf719..340fbc550ec8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultResourceTransformerChain.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultResourceTransformerChain.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.ListIterator; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.Resource; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultServletHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultServletHttpRequestHandler.java index f1b59d090763..ab68bbe6c53a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultServletHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultServletHttpRequestHandler.java @@ -18,11 +18,11 @@ import java.io.IOException; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/EncodedResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/EncodedResourceResolver.java index 846938eea344..4d0a6af7338e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/EncodedResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/EncodedResourceResolver.java @@ -28,7 +28,7 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.AbstractResource; import org.springframework.core.io.Resource; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/GzipResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/GzipResourceResolver.java index f7b8542befae..e38cea0bf29a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/GzipResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/GzipResourceResolver.java @@ -23,7 +23,7 @@ import java.net.URL; import java.util.List; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.AbstractResource; import org.springframework.core.io.Resource; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java index 2b97ac60895f..34c782c52990 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java @@ -28,7 +28,7 @@ import java.util.Map; import java.util.StringTokenizer; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index ed49cf3cd201..ace74e2dfb8d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -26,10 +26,9 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -303,7 +302,7 @@ public ContentNegotiationManager getContentNegotiationManager() { * response. *

    Use of this method is typically not necessary since mappings are * otherwise determined via - * {@link javax.servlet.ServletContext#getMimeType(String)} or via + * {@link jakarta.servlet.ServletContext#getMimeType(String)} or via * {@link MediaTypeFactory#getMediaType(Resource)}. * @param mediaTypes media type mappings * @since 5.2.4 @@ -728,7 +727,7 @@ protected boolean isInvalidPath(String path) { * the following lookups based on the resource filename and its path * extension: *

      - *
    1. {@link javax.servlet.ServletContext#getMimeType(String)} + *
    2. {@link jakarta.servlet.ServletContext#getMimeType(String)} *
    3. {@link #getMediaTypes()} *
    4. {@link MediaTypeFactory#getMediaType(String)} *
    diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceResolver.java index 4d75d61be73b..f4417b9287c0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceResolver.java @@ -18,7 +18,7 @@ import java.util.List; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.Resource; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceResolverChain.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceResolverChain.java index c7672a7d5eac..678164977e0c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceResolverChain.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceResolverChain.java @@ -18,7 +18,7 @@ import java.util.List; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.Resource; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceTransformer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceTransformer.java index 31059fef795c..7decb81b5283 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceTransformer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceTransformer.java @@ -18,7 +18,7 @@ import java.io.IOException; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.Resource; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceTransformerChain.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceTransformerChain.java index a1db04400230..a92e84260d90 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceTransformerChain.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceTransformerChain.java @@ -18,7 +18,7 @@ import java.io.IOException; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.Resource; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceTransformerSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceTransformerSupport.java index 3050727042a0..888cd74a08b1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceTransformerSupport.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceTransformerSupport.java @@ -18,7 +18,7 @@ import java.util.Collections; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.Resource; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java index c193ad5794b9..da2e86a879b8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java @@ -18,15 +18,14 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java index c1f926cd86d9..7a2a6e2a67c6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java @@ -22,8 +22,7 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -75,7 +74,7 @@ public void setApplicationContext(ApplicationContext applicationContext) throws /** * Configure a {@code UrlPathHelper} to use in - * {@link #getForRequestUrl(javax.servlet.http.HttpServletRequest, String)} + * {@link #getForRequestUrl(jakarta.servlet.http.HttpServletRequest, String)} * in order to derive the lookup path for a target request URL path. */ public void setUrlPathHelper(UrlPathHelper urlPathHelper) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProviderExposingInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProviderExposingInterceptor.java index c83be5a76eba..c0b1fb902aa0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProviderExposingInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProviderExposingInterceptor.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.resource; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.util.Assert; import org.springframework.web.bind.ServletRequestBindingException; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java index d2041e5b6569..f4800afc4d24 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java @@ -28,7 +28,7 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.AbstractResource; import org.springframework.core.io.Resource; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/WebJarsResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/WebJarsResourceResolver.java index 6e0fca296a04..d7dbb15cd16a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/WebJarsResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/WebJarsResourceResolver.java @@ -18,8 +18,7 @@ import java.util.List; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.webjars.WebJarAssetLocator; import org.springframework.core.io.Resource; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractDispatcherServletInitializer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractDispatcherServletInitializer.java index 2ea14a032568..353c9d4a5805 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractDispatcherServletInitializer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractDispatcherServletInitializer.java @@ -18,13 +18,13 @@ import java.util.EnumSet; -import javax.servlet.DispatcherType; -import javax.servlet.Filter; -import javax.servlet.FilterRegistration; -import javax.servlet.FilterRegistration.Dynamic; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterRegistration; +import jakarta.servlet.FilterRegistration.Dynamic; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRegistration; import org.springframework.context.ApplicationContextInitializer; import org.springframework.core.Conventions; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractFlashMapManager.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractFlashMapManager.java index d740a3c2cc65..10b46f1923ba 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractFlashMapManager.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractFlashMapManager.java @@ -22,9 +22,8 @@ import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/JspAwareRequestContext.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/JspAwareRequestContext.java index de381b70f48e..b02d169ea8d0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/JspAwareRequestContext.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/JspAwareRequestContext.java @@ -20,16 +20,16 @@ import java.util.Map; import java.util.TimeZone; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.jstl.core.Config; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.jstl.core.Config; import org.springframework.lang.Nullable; /** * JSP-aware (and JSTL-aware) subclass of RequestContext, allowing for - * population of the context from a {@code javax.servlet.jsp.PageContext}. + * population of the context from a {@code jakarta.servlet.jsp.PageContext}. * *

    This context will detect a JSTL locale attribute in page/request/session/application * scope, in addition to the fallback locale strategy provided by the base class. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/JstlUtils.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/JstlUtils.java index 6ad2612b0177..84c7d1a3d39f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/JstlUtils.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/JstlUtils.java @@ -20,11 +20,11 @@ import java.util.ResourceBundle; import java.util.TimeZone; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import javax.servlet.jsp.jstl.core.Config; -import javax.servlet.jsp.jstl.fmt.LocalizationContext; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.jsp.jstl.core.Config; +import jakarta.servlet.jsp.jstl.fmt.LocalizationContext; import org.springframework.context.MessageSource; import org.springframework.context.support.MessageSourceResourceBundle; @@ -41,7 +41,7 @@ public abstract class JstlUtils { /** - * Checks JSTL's "javax.servlet.jsp.jstl.fmt.localizationContext" + * Checks JSTL's "jakarta.servlet.jsp.jstl.fmt.localizationContext" * context-param and creates a corresponding child message source, * with the provided Spring-defined MessageSource as parent. * @param servletContext the ServletContext we're running in diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java index 9907bce5a8f8..db97efc2bae6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java @@ -22,11 +22,11 @@ import java.util.Map; import java.util.TimeZone; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.jsp.jstl.core.Config; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.jsp.jstl.core.Config; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceResolvable; @@ -93,7 +93,7 @@ public class RequestContext { protected static final boolean jstlPresent = ClassUtils.isPresent( - "javax.servlet.jsp.jstl.core.Config", RequestContext.class.getClassLoader()); + "jakarta.servlet.jsp.jstl.core.Config", RequestContext.class.getClassLoader()); private HttpServletRequest request; @@ -137,7 +137,7 @@ public class RequestContext { * Pass in a ServletContext to be able to fallback to the root WebApplicationContext. * @param request current HTTP request * @see org.springframework.web.servlet.DispatcherServlet - * @see #RequestContext(javax.servlet.http.HttpServletRequest, javax.servlet.ServletContext) + * @see #RequestContext(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.ServletContext) */ public RequestContext(HttpServletRequest request) { this(request, null, null, null); @@ -152,7 +152,7 @@ public RequestContext(HttpServletRequest request) { * @param request current HTTP request * @param response current HTTP response * @see org.springframework.web.servlet.DispatcherServlet - * @see #RequestContext(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.ServletContext, Map) + * @see #RequestContext(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse, jakarta.servlet.ServletContext, Map) */ public RequestContext(HttpServletRequest request, HttpServletResponse response) { this(request, response, null, null); @@ -183,7 +183,7 @@ public RequestContext(HttpServletRequest request, @Nullable ServletContext servl * @param model the model attributes for the current view (can be {@code null}, * using the request attributes for Errors retrieval) * @see org.springframework.web.servlet.DispatcherServlet - * @see #RequestContext(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.ServletContext, Map) + * @see #RequestContext(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse, jakarta.servlet.ServletContext, Map) */ public RequestContext(HttpServletRequest request, @Nullable Map model) { this(request, null, null, model); @@ -324,7 +324,7 @@ public TimeZone getTimeZone() { *

    The default implementation checks for a JSTL locale attribute in request, session * or application scope; if not found, returns the {@code HttpServletRequest.getLocale()}. * @return the fallback locale (never {@code null}) - * @see javax.servlet.http.HttpServletRequest#getLocale() + * @see jakarta.servlet.http.HttpServletRequest#getLocale() */ protected Locale getFallbackLocale() { if (jstlPresent) { @@ -533,7 +533,7 @@ public RequestDataValueProcessor getRequestDataValueProcessor() { * indicates the current web application. This is useful for building links * to other resources within the application. *

    Delegates to the UrlPathHelper for decoding. - * @see javax.servlet.http.HttpServletRequest#getContextPath + * @see jakarta.servlet.http.HttpServletRequest#getContextPath * @see #getUrlPathHelper */ public String getContextPath() { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContextUtils.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContextUtils.java index 05f3e78f2eea..8f7e97acb1e1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContextUtils.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContextUtils.java @@ -20,10 +20,10 @@ import java.util.Map; import java.util.TimeZone; -import javax.servlet.ServletContext; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.i18n.LocaleContext; import org.springframework.context.i18n.TimeZoneAwareLocaleContext; @@ -136,7 +136,7 @@ public static LocaleResolver getLocaleResolver(HttpServletRequest request) { * LocaleResolver bound to the request by the DispatcherServlet * (if available), falling back to the request's accept-header Locale. *

    This method serves as a straightforward alternative to the standard - * Servlet {@link javax.servlet.http.HttpServletRequest#getLocale()} method, + * Servlet {@link jakarta.servlet.http.HttpServletRequest#getLocale()} method, * falling back to the latter if no more specific locale has been found. *

    Consider using {@link org.springframework.context.i18n.LocaleContextHolder#getLocale()} * which will normally be populated with the same Locale. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestDataValueProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestDataValueProcessor.java index 654d5996fcfc..dba327445530 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestDataValueProcessor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestDataValueProcessor.java @@ -18,7 +18,7 @@ import java.util.Map; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java index 900e224f195f..3c04f0be2736 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.support; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/SessionFlashMapManager.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/SessionFlashMapManager.java index d201b25b6e02..faf981da8728 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/SessionFlashMapManager.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/SessionFlashMapManager.java @@ -18,9 +18,9 @@ import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import org.springframework.lang.Nullable; import org.springframework.web.servlet.FlashMap; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java index e6bb3a73a592..6da820e822e0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java @@ -24,9 +24,9 @@ import java.util.Set; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.CacheControl; import org.springframework.http.HttpHeaders; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/ArgumentAware.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/ArgumentAware.java index 1d4401556fe0..6e00296c1b2d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/ArgumentAware.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/ArgumentAware.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags; -import javax.servlet.jsp.JspTagException; +import jakarta.servlet.jsp.JspTagException; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/ArgumentTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/ArgumentTag.java index 682165916728..84ba71c1f7b8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/ArgumentTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/ArgumentTag.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.tags; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.BodyTagSupport; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.BodyTagSupport; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/BindErrorsTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/BindErrorsTag.java index 5cc8a7659129..75042ea5105f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/BindErrorsTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/BindErrorsTag.java @@ -16,9 +16,9 @@ package org.springframework.web.servlet.tags; -import javax.servlet.ServletException; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; import org.springframework.lang.Nullable; import org.springframework.validation.Errors; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/BindTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/BindTag.java index dafdbd52b9d6..5268a3a9ce09 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/BindTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/BindTag.java @@ -18,8 +18,8 @@ import java.beans.PropertyEditor; -import javax.servlet.jsp.JspTagException; -import javax.servlet.jsp.PageContext; +import jakarta.servlet.jsp.JspTagException; +import jakarta.servlet.jsp.PageContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EditorAwareTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EditorAwareTag.java index 499619e8d961..d6c9e2e773d1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EditorAwareTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EditorAwareTag.java @@ -18,7 +18,7 @@ import java.beans.PropertyEditor; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EscapeBodyTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EscapeBodyTag.java index 63daac01ffee..d759c7fcfa10 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EscapeBodyTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EscapeBodyTag.java @@ -18,9 +18,9 @@ import java.io.IOException; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.BodyContent; -import javax.servlet.jsp.tagext.BodyTag; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.BodyContent; +import jakarta.servlet.jsp.tagext.BodyTag; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EvalTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EvalTag.java index 165a9141f513..ea079a8be8ac 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EvalTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EvalTag.java @@ -18,8 +18,8 @@ import java.io.IOException; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; import org.springframework.context.expression.BeanFactoryResolver; import org.springframework.context.expression.EnvironmentAccessor; @@ -102,7 +102,7 @@ public class EvalTag extends HtmlEscapingAwareTag { /** - * {@link javax.servlet.jsp.PageContext} attribute for the + * {@link jakarta.servlet.jsp.PageContext} attribute for the * page-level {@link EvaluationContext} instance. */ private static final String EVALUATION_CONTEXT_PAGE_ATTRIBUTE = @@ -212,7 +212,7 @@ private static class JspPropertyAccessor implements PropertyAccessor { private final PageContext pageContext; @Nullable - private final javax.servlet.jsp.el.VariableResolver variableResolver; + private final jakarta.servlet.jsp.el.VariableResolver variableResolver; public JspPropertyAccessor(PageContext pageContext) { this.pageContext = pageContext; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/HtmlEscapeTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/HtmlEscapeTag.java index 04d080538be1..0d4ba42e51f3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/HtmlEscapeTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/HtmlEscapeTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; /** * The {@code } tag sets default HTML escape value for the current diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/HtmlEscapingAwareTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/HtmlEscapingAwareTag.java index 09612a03e7e5..65a5e7275c85 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/HtmlEscapingAwareTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/HtmlEscapingAwareTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.lang.Nullable; import org.springframework.web.util.HtmlUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/MessageTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/MessageTag.java index ed240284af10..3c794e0f93ac 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/MessageTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/MessageTag.java @@ -22,8 +22,8 @@ import java.util.Collections; import java.util.List; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.JspTagException; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspTagException; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceResolvable; @@ -227,7 +227,7 @@ public void setText(String text) { * Set PageContext attribute name under which to expose * a variable that contains the resolved message. * @see #setScope - * @see javax.servlet.jsp.PageContext#setAttribute + * @see jakarta.servlet.jsp.PageContext#setAttribute */ public void setVar(String var) { this.var = var; @@ -238,7 +238,7 @@ public void setVar(String var) { * Default is SCOPE_PAGE ("page"). * @see #setVar * @see org.springframework.web.util.TagUtils#SCOPE_PAGE - * @see javax.servlet.jsp.PageContext#setAttribute + * @see jakarta.servlet.jsp.PageContext#setAttribute */ public void setScope(String scope) { this.scope = scope; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/NestedPathTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/NestedPathTag.java index c010c7bb8c0e..c8fe794798d0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/NestedPathTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/NestedPathTag.java @@ -16,10 +16,10 @@ package org.springframework.web.servlet.tags; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.TagSupport; -import javax.servlet.jsp.tagext.TryCatchFinally; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.TagSupport; +import jakarta.servlet.jsp.tagext.TryCatchFinally; import org.springframework.beans.PropertyAccessor; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/ParamTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/ParamTag.java index b0ca15a947e7..513ea6bae21d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/ParamTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/ParamTag.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.tags; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.BodyTagSupport; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.BodyTagSupport; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/RequestContextAwareTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/RequestContextAwareTag.java index ee730b82bab4..af503346e07c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/RequestContextAwareTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/RequestContextAwareTag.java @@ -16,11 +16,10 @@ package org.springframework.web.servlet.tags; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.JspTagException; -import javax.servlet.jsp.tagext.TagSupport; -import javax.servlet.jsp.tagext.TryCatchFinally; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspTagException; +import jakarta.servlet.jsp.tagext.TagSupport; +import jakarta.servlet.jsp.tagext.TryCatchFinally; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -51,7 +50,7 @@ public abstract class RequestContextAwareTag extends TagSupport implements TryCatchFinally { /** - * {@link javax.servlet.jsp.PageContext} attribute for the + * {@link jakarta.servlet.jsp.PageContext} attribute for the * page-level {@link RequestContext} instance. */ public static final String REQUEST_CONTEXT_PAGE_ATTRIBUTE = @@ -105,7 +104,7 @@ protected final RequestContext getRequestContext() { * @return same as TagSupport.doStartTag * @throws Exception any exception, any checked one other than * a JspException gets wrapped in a JspException by doStartTag - * @see javax.servlet.jsp.tagext.TagSupport#doStartTag + * @see jakarta.servlet.jsp.tagext.TagSupport#doStartTag */ protected abstract int doStartTagInternal() throws Exception; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/TransformTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/TransformTag.java index 3957d3bfd3da..00083c879469 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/TransformTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/TransformTag.java @@ -19,8 +19,8 @@ import java.beans.PropertyEditor; import java.io.IOException; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.TagSupport; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.TagSupport; import org.springframework.lang.Nullable; import org.springframework.web.util.TagUtils; @@ -114,7 +114,7 @@ public void setValue(Object value) { * Set PageContext attribute name under which to expose * a variable that contains the result of the transformation. * @see #setScope - * @see javax.servlet.jsp.PageContext#setAttribute + * @see jakarta.servlet.jsp.PageContext#setAttribute */ public void setVar(String var) { this.var = var; @@ -125,7 +125,7 @@ public void setVar(String var) { * Default is SCOPE_PAGE ("page"). * @see #setVar * @see org.springframework.web.util.TagUtils#SCOPE_PAGE - * @see javax.servlet.jsp.PageContext#setAttribute + * @see jakarta.servlet.jsp.PageContext#setAttribute */ public void setScope(String scope) { this.scope = scope; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java index 079b3214846f..8e30154bb0f7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java @@ -24,11 +24,11 @@ import java.util.List; import java.util.Set; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractCheckedElementTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractCheckedElementTag.java index 5e40396a7c79..0c83f0d66252 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractCheckedElementTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractCheckedElementTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractDataBoundFormElementTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractDataBoundFormElementTag.java index bfcb2c3fba86..00dcf90a6109 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractDataBoundFormElementTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractDataBoundFormElementTag.java @@ -18,10 +18,10 @@ import java.beans.PropertyEditor; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; import org.springframework.beans.PropertyAccessor; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractFormTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractFormTag.java index fb48d00cac46..f766ccf54d16 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractFormTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractFormTag.java @@ -18,7 +18,7 @@ import java.beans.PropertyEditor; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; @@ -32,8 +32,8 @@ * actual tag rendering. * *

    Subclasses (or test classes) can override the {@link #createTagWriter()} method to - * redirect output to a {@link java.io.Writer} other than the {@link javax.servlet.jsp.JspWriter} - * associated with the current {@link javax.servlet.jsp.PageContext}. + * redirect output to a {@link java.io.Writer} other than the {@link jakarta.servlet.jsp.JspWriter} + * associated with the current {@link jakarta.servlet.jsp.PageContext}. * * @author Rob Harrop * @author Juergen Hoeller @@ -69,8 +69,8 @@ protected final void writeOptionalAttribute(TagWriter tagWriter, String attribut /** * Create the {@link TagWriter} which all output will be written to. By default, - * the {@link TagWriter} writes its output to the {@link javax.servlet.jsp.JspWriter} - * for the current {@link javax.servlet.jsp.PageContext}. Subclasses may choose to + * the {@link TagWriter} writes its output to the {@link jakarta.servlet.jsp.JspWriter} + * for the current {@link jakarta.servlet.jsp.PageContext}. Subclasses may choose to * change the {@link java.io.Writer} to which output is actually written. */ protected TagWriter createTagWriter() { @@ -117,7 +117,7 @@ protected boolean isDefaultHtmlEscape() { /** * Subclasses should implement this method to perform tag content rendering. - * @return valid tag render instruction as per {@link javax.servlet.jsp.tagext.Tag#doStartTag()}. + * @return valid tag render instruction as per {@link jakarta.servlet.jsp.tagext.Tag#doStartTag()}. */ protected abstract int writeTagContent(TagWriter tagWriter) throws JspException; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractHtmlElementBodyTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractHtmlElementBodyTag.java index 0212d7a1de97..92528dcabf43 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractHtmlElementBodyTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractHtmlElementBodyTag.java @@ -18,9 +18,9 @@ import java.io.IOException; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.BodyContent; -import javax.servlet.jsp.tagext.BodyTag; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.BodyContent; +import jakarta.servlet.jsp.tagext.BodyTag; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -62,7 +62,7 @@ protected int writeTagContent(TagWriter tagWriter) throws JspException { * If {@link #shouldRender rendering}, flush any buffered * {@link BodyContent} or, if no {@link BodyContent} is supplied, * {@link #renderDefaultContent render the default content}. - * @return a {@link javax.servlet.jsp.tagext.Tag#EVAL_PAGE} result + * @return a {@link jakarta.servlet.jsp.tagext.Tag#EVAL_PAGE} result */ @Override public int doEndTag() throws JspException { @@ -122,21 +122,21 @@ protected boolean shouldRender() throws JspException { /** * Called during {@link #writeTagContent} allowing subclasses to add any attributes to the - * {@link javax.servlet.jsp.PageContext} as needed. + * {@link jakarta.servlet.jsp.PageContext} as needed. */ protected void exposeAttributes() throws JspException { } /** * Called by {@link #doFinally} allowing subclasses to remove any attributes from the - * {@link javax.servlet.jsp.PageContext} as needed. + * {@link jakarta.servlet.jsp.PageContext} as needed. */ protected void removeAttributes() { } /** * The user customised the output of the error messages - flush the - * buffered content into the main {@link javax.servlet.jsp.JspWriter}. + * buffered content into the main {@link jakarta.servlet.jsp.JspWriter}. */ protected void flushBufferedBodyContent(BodyContent bodyContent) throws JspException { try { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractHtmlElementTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractHtmlElementTag.java index 1599694fd80e..11fd195246d2 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractHtmlElementTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractHtmlElementTag.java @@ -19,8 +19,8 @@ import java.util.HashMap; import java.util.Map; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.DynamicAttributes; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.DynamicAttributes; import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractHtmlInputElementTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractHtmlInputElementTag.java index 8549bea401ea..ce6a786bab1c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractHtmlInputElementTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractHtmlInputElementTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractMultiCheckedElementTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractMultiCheckedElementTag.java index 8a02ecacb64a..340fe962f852 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractMultiCheckedElementTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractMultiCheckedElementTag.java @@ -20,7 +20,7 @@ import java.util.Iterator; import java.util.Map; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.beans.BeanWrapper; import org.springframework.beans.PropertyAccessorFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractSingleCheckedElementTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractSingleCheckedElementTag.java index 84f2505bd83f..e0683cc64eb8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractSingleCheckedElementTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/AbstractSingleCheckedElementTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/ButtonTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/ButtonTag.java index 53ece7b3c71d..805adeefb16a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/ButtonTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/ButtonTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/CheckboxTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/CheckboxTag.java index f3b1d2a84854..7f5518a65788 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/CheckboxTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/CheckboxTag.java @@ -18,7 +18,7 @@ import java.util.Collection; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.web.bind.WebDataBinder; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/CheckboxesTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/CheckboxesTag.java index a9693fd6baf6..ab7207a73a7e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/CheckboxesTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/CheckboxesTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.web.bind.WebDataBinder; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/ErrorsTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/ErrorsTag.java index 106f359f9876..a1c1c978d66f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/ErrorsTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/ErrorsTag.java @@ -20,9 +20,9 @@ import java.util.Arrays; import java.util.List; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.BodyTag; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.BodyTag; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/FormTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/FormTag.java index 54d0c869f6f8..d4028073a188 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/FormTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/FormTag.java @@ -19,12 +19,12 @@ import java.nio.charset.UnsupportedCharsetException; import java.util.Map; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; import org.springframework.beans.PropertyAccessor; import org.springframework.core.Conventions; @@ -255,7 +255,7 @@ public class FormTag extends AbstractHtmlElementTag { private static final String MODEL_ATTRIBUTE = "modelAttribute"; /** - * The name of the {@link javax.servlet.jsp.PageContext} attribute under which the + * The name of the {@link jakarta.servlet.jsp.PageContext} attribute under which the * form object name is exposed. */ public static final String MODEL_ATTRIBUTE_VARIABLE_NAME = @@ -537,9 +537,9 @@ protected boolean isMethodBrowserSupported(String method) { /** * Writes the opening part of the block '{@code form}' tag and exposes - * the form object name in the {@link javax.servlet.jsp.PageContext}. + * the form object name in the {@link jakarta.servlet.jsp.PageContext}. * @param tagWriter the {@link TagWriter} to which the form content is to be written - * @return {@link javax.servlet.jsp.tagext.Tag#EVAL_BODY_INCLUDE} + * @return {@link jakarta.servlet.jsp.tagext.Tag#EVAL_BODY_INCLUDE} */ @Override protected int writeTagContent(TagWriter tagWriter) throws JspException { @@ -684,7 +684,7 @@ private String processAction(String action) { /** * Closes the '{@code form}' block tag and removes the form object name - * from the {@link javax.servlet.jsp.PageContext}. + * from the {@link jakarta.servlet.jsp.PageContext}. */ @Override public int doEndTag() throws JspException { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/HiddenInputTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/HiddenInputTag.java index 48704bff8530..9e1de82fb95e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/HiddenInputTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/HiddenInputTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; /** * The {@code } tag renders an HTML 'input' tag with type 'hidden' using diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/InputTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/InputTag.java index 0605bb10868d..91834aea14ec 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/InputTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/InputTag.java @@ -18,7 +18,7 @@ import java.util.Map; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/LabelTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/LabelTag.java index 6f8a91f1ec4c..018c098473bc 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/LabelTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/LabelTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -222,7 +222,7 @@ protected String getFor() { /** * Writes the opening '{@code label}' tag and forces a block tag so * that body content is written correctly. - * @return {@link javax.servlet.jsp.tagext.Tag#EVAL_BODY_INCLUDE} + * @return {@link jakarta.servlet.jsp.tagext.Tag#EVAL_BODY_INCLUDE} */ @Override protected int writeTagContent(TagWriter tagWriter) throws JspException { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/OptionTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/OptionTag.java index b9eaa89b6664..3197706bc13e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/OptionTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/OptionTag.java @@ -16,9 +16,9 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.BodyContent; -import javax.servlet.jsp.tagext.BodyTag; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.BodyContent; +import jakarta.servlet.jsp.tagext.BodyTag; import org.springframework.lang.Nullable; import org.springframework.web.servlet.support.BindStatus; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/OptionWriter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/OptionWriter.java index 3e75186c2e38..433ac220ede1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/OptionWriter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/OptionWriter.java @@ -20,7 +20,7 @@ import java.util.Collection; import java.util.Map; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.beans.BeanWrapper; import org.springframework.beans.PropertyAccessorFactory; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/OptionsTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/OptionsTag.java index 6e00a19d3985..6a8c8ca75600 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/OptionsTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/OptionsTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/PasswordInputTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/PasswordInputTag.java index 5eb69eedfae4..ff958a4d2ed2 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/PasswordInputTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/PasswordInputTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; /** * The {@code } tag renders an HTML 'input' tag with type 'password' diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/RadioButtonTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/RadioButtonTag.java index cb11d8dc0141..13f7b5dc4c3d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/RadioButtonTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/RadioButtonTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; /** * The {@code } tag renders an HTML 'input' tag with type 'radio'. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/SelectTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/SelectTag.java index 96bb041c46e3..8c7d92b5e503 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/SelectTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/SelectTag.java @@ -19,7 +19,7 @@ import java.util.Collection; import java.util.Map; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; @@ -243,7 +243,7 @@ public class SelectTag extends AbstractHtmlInputElementTag { /** - * The {@link javax.servlet.jsp.PageContext} attribute under + * The {@link jakarta.servlet.jsp.PageContext} attribute under * which the bound value is exposed to inner {@link OptionTag OptionTags}. */ public static final String LIST_VALUE_PAGE_ATTRIBUTE = diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/TagIdGenerator.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/TagIdGenerator.java index 24685e9826be..ff51344d1a1a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/TagIdGenerator.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/TagIdGenerator.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.PageContext; +import jakarta.servlet.jsp.PageContext; /** * Utility class for generating '{@code id}' attributes values for JSP tags. Given the diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/TagWriter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/TagWriter.java index 87cedb540223..5c147ea258da 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/TagWriter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/TagWriter.java @@ -21,8 +21,8 @@ import java.util.ArrayDeque; import java.util.Deque; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/TextareaTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/TextareaTag.java index ce6f700a7237..b8d5ae2501d3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/TextareaTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/TextareaTag.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/CookieThemeResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/CookieThemeResolver.java index a9ca3fc75fa4..19e5c26a89f3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/CookieThemeResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/CookieThemeResolver.java @@ -16,9 +16,9 @@ package org.springframework.web.servlet.theme; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/FixedThemeResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/FixedThemeResolver.java index 986d3972299a..02a588d9a062 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/FixedThemeResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/FixedThemeResolver.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.theme; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/SessionThemeResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/SessionThemeResolver.java index 8a8faa76a766..d6270d123306 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/SessionThemeResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/SessionThemeResolver.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.theme; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/ThemeChangeInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/ThemeChangeInterceptor.java index 152e9b19362e..81bb05a36987 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/ThemeChangeInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/theme/ThemeChangeInterceptor.java @@ -16,9 +16,9 @@ package org.springframework.web.servlet.theme; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ThemeResolver; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractCachingViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractCachingViewResolver.java index b7f0ebfbcc20..d7bf2fa33762 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractCachingViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractCachingViewResolver.java @@ -21,8 +21,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractTemplateView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractTemplateView.java index 7a1a24cd7568..3d028668df10 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractTemplateView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractTemplateView.java @@ -20,10 +20,10 @@ import java.util.LinkedHashMap; import java.util.Map; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import org.springframework.web.servlet.support.RequestContext; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractView.java index 5df004609b72..5f47cb303c6b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractView.java @@ -27,9 +27,9 @@ import java.util.Set; import java.util.StringTokenizer; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.BeanNameAware; import org.springframework.http.MediaType; @@ -388,7 +388,7 @@ protected void prepareResponse(HttpServletRequest request, HttpServletResponse r * generating download content that requires temporary caching on the * client side, typically via the response OutputStream. * @see #prepareResponse - * @see javax.servlet.http.HttpServletResponse#getOutputStream() + * @see jakarta.servlet.http.HttpServletResponse#getOutputStream() */ protected boolean generatesDownloadContent() { return false; @@ -432,7 +432,7 @@ protected abstract void renderMergedOutputModel( /** * Expose the model objects in the given map as request attributes. * Names will be taken from the model Map. - * This method is suitable for all resources reachable by {@link javax.servlet.RequestDispatcher}. + * This method is suitable for all resources reachable by {@link jakarta.servlet.RequestDispatcher}. * @param model a Map of model objects to expose * @param request current HTTP request */ diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java index 2d61e8a19105..3c1699a5abd4 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java @@ -25,9 +25,9 @@ import java.util.Map; import java.util.Set; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.InitializingBean; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.java index 9d9bc6811ccb..7f3bec996ecc 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.view; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/InternalResourceView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/InternalResourceView.java index 6deab1ca3b48..f1d050135a63 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/InternalResourceView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/InternalResourceView.java @@ -18,10 +18,10 @@ import java.util.Map; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -31,7 +31,7 @@ /** * Wrapper for a JSP or other resource within the same web application. * Exposes model objects as request attributes and forwards the request to - * the specified resource URL using a {@link javax.servlet.RequestDispatcher}. + * the specified resource URL using a {@link jakarta.servlet.RequestDispatcher}. * *

    A URL for this view is supposed to specify a resource within the web * application, suitable for RequestDispatcher's {@code forward} or @@ -57,9 +57,9 @@ * @author Rod Johnson * @author Juergen Hoeller * @author Rob Harrop - * @see javax.servlet.RequestDispatcher#forward - * @see javax.servlet.RequestDispatcher#include - * @see javax.servlet.ServletResponse#flushBuffer + * @see jakarta.servlet.RequestDispatcher#forward + * @see jakarta.servlet.RequestDispatcher#include + * @see jakarta.servlet.ServletResponse#flushBuffer * @see InternalResourceViewResolver * @see JstlView */ @@ -102,9 +102,9 @@ public InternalResourceView(String url, boolean alwaysInclude) { * Specify whether to always include the view rather than forward to it. *

    Default is "false". Switch this flag on to enforce the use of a * Servlet include, even if a forward would be possible. - * @see javax.servlet.RequestDispatcher#forward - * @see javax.servlet.RequestDispatcher#include - * @see #useInclude(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + * @see jakarta.servlet.RequestDispatcher#forward + * @see jakarta.servlet.RequestDispatcher#include + * @see #useInclude(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse) */ public void setAlwaysInclude(boolean alwaysInclude) { this.alwaysInclude = alwaysInclude; @@ -238,9 +238,9 @@ protected RequestDispatcher getRequestDispatcher(HttpServletRequest request, Str * @param request current HTTP request * @param response current HTTP response * @return {@code true} for include, {@code false} for forward - * @see javax.servlet.RequestDispatcher#forward - * @see javax.servlet.RequestDispatcher#include - * @see javax.servlet.ServletResponse#isCommitted + * @see jakarta.servlet.RequestDispatcher#forward + * @see jakarta.servlet.RequestDispatcher#include + * @see jakarta.servlet.ServletResponse#isCommitted * @see org.springframework.web.util.WebUtils#isIncludeRequest */ protected boolean useInclude(HttpServletRequest request, HttpServletResponse response) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/InternalResourceViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/InternalResourceViewResolver.java index e89ba2dcff77..4404be51854d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/InternalResourceViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/InternalResourceViewResolver.java @@ -49,7 +49,7 @@ public class InternalResourceViewResolver extends UrlBasedViewResolver { private static final boolean jstlPresent = ClassUtils.isPresent( - "javax.servlet.jsp.jstl.core.Config", InternalResourceViewResolver.class.getClassLoader()); + "jakarta.servlet.jsp.jstl.core.Config", InternalResourceViewResolver.class.getClassLoader()); @Nullable private Boolean alwaysInclude; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/JstlView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/JstlView.java index c11eb4e6c94d..780f6f2b923a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/JstlView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/JstlView.java @@ -16,8 +16,8 @@ package org.springframework.web.servlet.view; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.context.MessageSource; import org.springframework.lang.Nullable; @@ -101,7 +101,7 @@ public JstlView(String url) { * @param url the URL to forward to * @param messageSource the MessageSource to expose to JSTL tags * (will be wrapped with a JSTL-aware MessageSource that is aware of JSTL's - * {@code javax.servlet.jsp.jstl.fmt.localizationContext} context-param) + * {@code jakarta.servlet.jsp.jstl.fmt.localizationContext} context-param) * @see JstlUtils#getJstlAwareMessageSource */ public JstlView(String url, MessageSource messageSource) { @@ -112,7 +112,7 @@ public JstlView(String url, MessageSource messageSource) { /** * Wraps the MessageSource with a JSTL-aware MessageSource that is aware - * of JSTL's {@code javax.servlet.jsp.jstl.fmt.localizationContext} + * of JSTL's {@code jakarta.servlet.jsp.jstl.fmt.localizationContext} * context-param. * @see JstlUtils#getJstlAwareMessageSource */ diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java index 6ecaffcf9652..a88401e65a92 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java @@ -27,8 +27,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.BeanUtils; import org.springframework.http.HttpStatus; @@ -81,7 +81,7 @@ * @see #setContextRelative * @see #setHttp10Compatible * @see #setExposeModelAttributes - * @see javax.servlet.http.HttpServletResponse#sendRedirect + * @see jakarta.servlet.http.HttpServletResponse#sendRedirect */ public class RedirectView extends AbstractUrlBasedView implements SmartView { @@ -178,7 +178,7 @@ public RedirectView(String url, boolean contextRelative, boolean http10Compatibl *

    Default is "false": A URL that starts with a slash will be interpreted * as absolute, i.e. taken as-is. If "true", the context path will be * prepended to the URL in such a case. - * @see javax.servlet.http.HttpServletRequest#getContextPath + * @see jakarta.servlet.http.HttpServletRequest#getContextPath */ public void setContextRelative(boolean contextRelative) { this.contextRelative = contextRelative; @@ -193,7 +193,7 @@ public void setContextRelative(boolean contextRelative) { *

    Many HTTP 1.1 clients treat 302 just like 303, not making any * difference. However, some clients depend on 303 when redirecting * after a POST request; turn this flag off in such a scenario. - * @see javax.servlet.http.HttpServletResponse#sendRedirect + * @see jakarta.servlet.http.HttpServletResponse#sendRedirect */ public void setHttp10Compatible(boolean http10Compatible) { this.http10Compatible = http10Compatible; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/UrlBasedViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/UrlBasedViewResolver.java index d25f426d9e4e..d25a6ac05fa7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/UrlBasedViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/UrlBasedViewResolver.java @@ -21,7 +21,7 @@ import java.util.Map; import java.util.Properties; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.BeanUtils; import org.springframework.context.ApplicationContext; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ViewResolverComposite.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ViewResolverComposite.java index 7b2441564f1a..5421c4b90022 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ViewResolverComposite.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ViewResolverComposite.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.Locale; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractPdfStamperView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractPdfStamperView.java index c21e03560e8f..356af133ef12 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractPdfStamperView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractPdfStamperView.java @@ -20,11 +20,10 @@ import java.io.IOException; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStamper; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.util.Assert; import org.springframework.web.servlet.view.AbstractUrlBasedView; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractPdfView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractPdfView.java index 4a26d2ecdada..8cac515a6e48 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractPdfView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractPdfView.java @@ -20,13 +20,12 @@ import java.io.OutputStream; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.PageSize; import com.lowagie.text.pdf.PdfWriter; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.servlet.view.AbstractView; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractXlsView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractXlsView.java index ab9ba67be3c9..9727fd3a352c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractXlsView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractXlsView.java @@ -19,10 +19,9 @@ import java.io.IOException; import java.util.Map; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Workbook; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractXlsxStreamingView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractXlsxStreamingView.java index 1f6dccb1d5e3..9b120a1b6f1b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractXlsxStreamingView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractXlsxStreamingView.java @@ -19,9 +19,8 @@ import java.io.IOException; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractXlsxView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractXlsxView.java index 78d8360bbe92..888a00d1be1a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractXlsxView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/document/AbstractXlsxView.java @@ -18,8 +18,7 @@ import java.util.Map; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractAtomFeedView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractAtomFeedView.java index 58e0893cd272..95a54eb0b4a0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractAtomFeedView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractAtomFeedView.java @@ -19,11 +19,10 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import com.rometools.rome.feed.atom.Entry; import com.rometools.rome.feed.atom.Feed; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; /** * Abstract superclass for Atom Feed views, using the diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractFeedView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractFeedView.java index 6ea756645817..f976446a1b6f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractFeedView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractFeedView.java @@ -19,12 +19,11 @@ import java.io.OutputStreamWriter; import java.util.Map; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import com.rometools.rome.feed.WireFeed; import com.rometools.rome.io.WireFeedOutput; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.util.StringUtils; import org.springframework.web.servlet.view.AbstractView; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractRssFeedView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractRssFeedView.java index aef278f791ba..aa22a8768926 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractRssFeedView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractRssFeedView.java @@ -19,11 +19,10 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import com.rometools.rome.feed.rss.Channel; import com.rometools.rome.feed.rss.Item; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.MediaType; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfig.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfig.java index 42b04cfa84f3..22c43eaed914 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfig.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.web.servlet.view.freemarker; -import freemarker.ext.jsp.TaglibFactory; import freemarker.template.Configuration; /** @@ -41,10 +40,4 @@ public interface FreeMarkerConfig { */ Configuration getConfiguration(); - /** - * Return the {@link TaglibFactory} used to enable JSP tags to be - * accessed from FreeMarker templates. - */ - TaglibFactory getTaglibFactory(); - } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java index 0eb2e30f3bc7..9caac97a3398 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,8 @@ import java.io.IOException; import java.util.List; -import javax.servlet.ServletContext; - import freemarker.cache.ClassTemplateLoader; import freemarker.cache.TemplateLoader; -import freemarker.ext.jsp.TaglibFactory; import freemarker.template.Configuration; import freemarker.template.TemplateException; @@ -32,7 +29,6 @@ import org.springframework.lang.Nullable; import org.springframework.ui.freemarker.FreeMarkerConfigurationFactory; import org.springframework.util.Assert; -import org.springframework.web.context.ServletContextAware; /** * JavaBean to configure FreeMarker for web usage, via the "configLocation" @@ -78,14 +74,11 @@ * @see FreeMarkerView */ public class FreeMarkerConfigurer extends FreeMarkerConfigurationFactory - implements FreeMarkerConfig, InitializingBean, ResourceLoaderAware, ServletContextAware { + implements FreeMarkerConfig, InitializingBean, ResourceLoaderAware { @Nullable private Configuration configuration; - @Nullable - private TaglibFactory taglibFactory; - /** * Set a preconfigured Configuration to use for the FreeMarker web config, e.g. a @@ -98,14 +91,6 @@ public void setConfiguration(Configuration configuration) { this.configuration = configuration; } - /** - * Initialize the {@link TaglibFactory} for the given ServletContext. - */ - @Override - public void setServletContext(ServletContext servletContext) { - this.taglibFactory = new TaglibFactory(servletContext); - } - /** * Initialize FreeMarkerConfigurationFactory's Configuration @@ -140,13 +125,4 @@ public Configuration getConfiguration() { return this.configuration; } - /** - * Return the TaglibFactory object wrapped by this bean. - */ - @Override - public TaglibFactory getTaglibFactory() { - Assert.state(this.taglibFactory != null, "No TaglibFactory available"); - return this.taglibFactory; - } - } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerView.java index faa25110ea3e..7d22d659eaa7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerView.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,39 +18,22 @@ import java.io.FileNotFoundException; import java.io.IOException; -import java.util.Collections; -import java.util.Enumeration; import java.util.Locale; import java.util.Map; -import javax.servlet.GenericServlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - import freemarker.core.ParseException; -import freemarker.ext.jsp.TaglibFactory; -import freemarker.ext.servlet.AllHttpScopesHashModel; -import freemarker.ext.servlet.FreemarkerServlet; -import freemarker.ext.servlet.HttpRequestHashModel; -import freemarker.ext.servlet.HttpRequestParametersHashModel; -import freemarker.ext.servlet.HttpSessionHashModel; -import freemarker.ext.servlet.ServletContextHashModel; import freemarker.template.Configuration; import freemarker.template.DefaultObjectWrapperBuilder; import freemarker.template.ObjectWrapper; import freemarker.template.SimpleHash; import freemarker.template.Template; import freemarker.template.TemplateException; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.context.ApplicationContextException; import org.springframework.lang.Nullable; @@ -95,12 +78,6 @@ public class FreeMarkerView extends AbstractTemplateView { @Nullable private Configuration configuration; - @Nullable - private TaglibFactory taglibFactory; - - @Nullable - private ServletContextHashModel servletContextHashModel; - /** * Set the encoding of the FreeMarker template file. Default is determined @@ -124,10 +101,6 @@ protected String getEncoding() { * Set the FreeMarker Configuration to be used by this view. *

    If this is not set, the default lookup will occur: a single {@link FreeMarkerConfig} * is expected in the current web application context, with any bean name. - * Note: using this method will cause a new instance of {@link TaglibFactory} - * to created for every single {@link FreeMarkerView} instance. This can be quite expensive - * in terms of memory and initial CPU usage. In production it is recommended that you use - * a {@link FreeMarkerConfig} which exposes a single shared {@link TaglibFactory}. */ public void setConfiguration(@Nullable Configuration configuration) { this.configuration = configuration; @@ -164,23 +137,10 @@ protected Configuration obtainConfiguration() { */ @Override protected void initServletContext(ServletContext servletContext) throws BeansException { - if (getConfiguration() != null) { - this.taglibFactory = new TaglibFactory(servletContext); - } - else { + if (getConfiguration() == null) { FreeMarkerConfig config = autodetectConfiguration(); setConfiguration(config.getConfiguration()); - this.taglibFactory = config.getTaglibFactory(); - } - - GenericServlet servlet = new GenericServletAdapter(); - try { - servlet.init(new DelegatingServletConfig()); - } - catch (ServletException ex) { - throw new BeanInitializationException("Initialization of GenericServlet adapter failed", ex); } - this.servletContextHashModel = new ServletContextHashModel(servlet, getObjectWrapper()); } /** @@ -306,7 +266,7 @@ protected void doRender(Map model, HttpServletRequest request, /** * Build a FreeMarker template model for the given model Map. - *

    The default implementation builds a {@link AllHttpScopesHashModel}. + *

    The default implementation builds a {@link SimpleHash}. * @param model the model to use for rendering * @param request current HTTP request * @param response current servlet response @@ -315,33 +275,11 @@ protected void doRender(Map model, HttpServletRequest request, protected SimpleHash buildTemplateModel(Map model, HttpServletRequest request, HttpServletResponse response) { - AllHttpScopesHashModel fmModel = new AllHttpScopesHashModel(getObjectWrapper(), getServletContext(), request); - fmModel.put(FreemarkerServlet.KEY_JSP_TAGLIBS, this.taglibFactory); - fmModel.put(FreemarkerServlet.KEY_APPLICATION, this.servletContextHashModel); - fmModel.put(FreemarkerServlet.KEY_SESSION, buildSessionModel(request, response)); - fmModel.put(FreemarkerServlet.KEY_REQUEST, new HttpRequestHashModel(request, response, getObjectWrapper())); - fmModel.put(FreemarkerServlet.KEY_REQUEST_PARAMETERS, new HttpRequestParametersHashModel(request)); + SimpleHash fmModel = new SimpleHash(getObjectWrapper()); fmModel.putAll(model); return fmModel; } - /** - * Build a FreeMarker {@link HttpSessionHashModel} for the given request, - * detecting whether a session already exists and reacting accordingly. - * @param request current HTTP request - * @param response current servlet response - * @return the FreeMarker HttpSessionHashModel - */ - private HttpSessionHashModel buildSessionModel(HttpServletRequest request, HttpServletResponse response) { - HttpSession session = request.getSession(false); - if (session != null) { - return new HttpSessionHashModel(session, getObjectWrapper()); - } - else { - return new HttpSessionHashModel(null, request, response, getObjectWrapper()); - } - } - /** * Retrieve the FreeMarker template for the given locale, * to be rendering by this view. @@ -391,49 +329,4 @@ protected void processTemplate(Template template, SimpleHash model, HttpServletR template.process(model, response.getWriter()); } - - /** - * Simple adapter class that extends {@link GenericServlet}. - * Needed for JSP access in FreeMarker. - */ - @SuppressWarnings("serial") - private static class GenericServletAdapter extends GenericServlet { - - @Override - public void service(ServletRequest servletRequest, ServletResponse servletResponse) { - // no-op - } - } - - - /** - * Internal implementation of the {@link ServletConfig} interface, - * to be passed to the servlet adapter. - */ - private class DelegatingServletConfig implements ServletConfig { - - @Override - @Nullable - public String getServletName() { - return FreeMarkerView.this.getBeanName(); - } - - @Override - @Nullable - public ServletContext getServletContext() { - return FreeMarkerView.this.getServletContext(); - } - - @Override - @Nullable - public String getInitParameter(String paramName) { - return null; - } - - @Override - public Enumeration getInitParameterNames() { - return Collections.enumeration(Collections.emptySet()); - } - } - } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupView.java index 8db7d12d53d9..e91c0f822033 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupView.java @@ -21,11 +21,10 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import groovy.text.Template; import groovy.text.markup.MarkupTemplateEngine; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactoryUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/AbstractJackson2View.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/AbstractJackson2View.java index 9d116dc8ca07..e85cea4415e6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/AbstractJackson2View.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/AbstractJackson2View.java @@ -21,9 +21,6 @@ import java.io.OutputStream; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import com.fasterxml.jackson.annotation.JsonView; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonGenerator; @@ -31,6 +28,8 @@ import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.ser.FilterProvider; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.converter.json.MappingJacksonValue; import org.springframework.lang.Nullable; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateView.java index 1593a88ae410..57e627e89cb4 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateView.java @@ -32,9 +32,10 @@ import javax.script.ScriptEngineManager; import javax.script.ScriptException; import javax.script.SimpleBindings; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactoryUtils; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/AbstractSpringPreparerFactory.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/AbstractSpringPreparerFactory.java deleted file mode 100644 index f6fdb90aea64..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/AbstractSpringPreparerFactory.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.view.tiles3; - -import org.apache.tiles.TilesException; -import org.apache.tiles.preparer.ViewPreparer; -import org.apache.tiles.preparer.factory.PreparerFactory; -import org.apache.tiles.request.Request; - -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.servlet.DispatcherServlet; - -/** - * Abstract implementation of the Tiles {@link org.apache.tiles.preparer.factory.PreparerFactory} - * interface, obtaining the current Spring WebApplicationContext and delegating to - * {@link #getPreparer(String, org.springframework.web.context.WebApplicationContext)}. - * - * @author Juergen Hoeller - * @since 3.2 - * @see #getPreparer(String, org.springframework.web.context.WebApplicationContext) - * @see SimpleSpringPreparerFactory - * @see SpringBeanPreparerFactory - */ -public abstract class AbstractSpringPreparerFactory implements PreparerFactory { - - @Override - public ViewPreparer getPreparer(String name, Request context) { - WebApplicationContext webApplicationContext = (WebApplicationContext) context.getContext("request").get( - DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE); - if (webApplicationContext == null) { - webApplicationContext = (WebApplicationContext) context.getContext("application").get( - WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); - if (webApplicationContext == null) { - throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?"); - } - } - return getPreparer(name, webApplicationContext); - } - - /** - * Obtain a preparer instance for the given preparer name, - * based on the given Spring WebApplicationContext. - * @param name the name of the preparer - * @param context the current Spring WebApplicationContext - * @return the preparer instance - * @throws TilesException in case of failure - */ - protected abstract ViewPreparer getPreparer(String name, WebApplicationContext context) throws TilesException; - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SimpleSpringPreparerFactory.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SimpleSpringPreparerFactory.java deleted file mode 100644 index 0ef018d51252..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SimpleSpringPreparerFactory.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.view.tiles3; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.tiles.TilesException; -import org.apache.tiles.preparer.PreparerException; -import org.apache.tiles.preparer.ViewPreparer; -import org.apache.tiles.preparer.factory.NoSuchPreparerException; - -import org.springframework.util.ClassUtils; -import org.springframework.web.context.WebApplicationContext; - -/** - * Tiles {@link org.apache.tiles.preparer.factory.PreparerFactory} implementation - * that expects preparer class names and builds preparer instances for those, - * creating them through the Spring ApplicationContext in order to apply - * Spring container callbacks and configured Spring BeanPostProcessors. - * - * @author Juergen Hoeller - * @since 3.2 - * @see SpringBeanPreparerFactory - */ -public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory { - - /** Cache of shared ViewPreparer instances: bean name -> bean instance. */ - private final Map sharedPreparers = new ConcurrentHashMap<>(16); - - - @Override - protected ViewPreparer getPreparer(String name, WebApplicationContext context) throws TilesException { - // Quick check on the concurrent map first, with minimal locking. - ViewPreparer preparer = this.sharedPreparers.get(name); - if (preparer == null) { - synchronized (this.sharedPreparers) { - preparer = this.sharedPreparers.get(name); - if (preparer == null) { - try { - Class beanClass = ClassUtils.forName(name, context.getClassLoader()); - if (!ViewPreparer.class.isAssignableFrom(beanClass)) { - throw new PreparerException( - "Invalid preparer class [" + name + "]: does not implement ViewPreparer interface"); - } - preparer = (ViewPreparer) context.getAutowireCapableBeanFactory().createBean(beanClass); - this.sharedPreparers.put(name, preparer); - } - catch (ClassNotFoundException ex) { - throw new NoSuchPreparerException("Preparer class [" + name + "] not found", ex); - } - } - } - } - return preparer; - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SpringBeanPreparerFactory.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SpringBeanPreparerFactory.java deleted file mode 100644 index 19e6cfec1ffd..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SpringBeanPreparerFactory.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.view.tiles3; - -import org.apache.tiles.TilesException; -import org.apache.tiles.preparer.ViewPreparer; - -import org.springframework.web.context.WebApplicationContext; - -/** - * Tiles {@link org.apache.tiles.preparer.factory.PreparerFactory} implementation - * that expects preparer bean names and obtains preparer beans from the - * Spring ApplicationContext. The full bean creation process will be in - * the control of the Spring application context in this case, allowing - * for the use of scoped beans etc. - * - * @author Juergen Hoeller - * @since 3.2 - * @see SimpleSpringPreparerFactory - */ -public class SpringBeanPreparerFactory extends AbstractSpringPreparerFactory { - - @Override - protected ViewPreparer getPreparer(String name, WebApplicationContext context) throws TilesException { - return context.getBean(name, ViewPreparer.class); - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SpringLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SpringLocaleResolver.java deleted file mode 100644 index 038d1ac71d66..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SpringLocaleResolver.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.view.tiles3; - -import java.util.Locale; - -import javax.servlet.http.HttpServletRequest; - -import org.apache.tiles.locale.impl.DefaultLocaleResolver; -import org.apache.tiles.request.Request; -import org.apache.tiles.request.servlet.NotAServletEnvironmentException; -import org.apache.tiles.request.servlet.ServletUtil; - -import org.springframework.web.servlet.support.RequestContextUtils; - -/** - * Tiles LocaleResolver adapter that delegates to a Spring - * {@link org.springframework.web.servlet.LocaleResolver}, exposing the - * DispatcherServlet-managed locale. - * - *

    This adapter gets automatically registered by {@link TilesConfigurer}. - * - * @author Nicolas Le Bas - * @since 3.2 - * @see org.apache.tiles.definition.UrlDefinitionsFactory#LOCALE_RESOLVER_IMPL_PROPERTY - */ -public class SpringLocaleResolver extends DefaultLocaleResolver { - - @Override - public Locale resolveLocale(Request request) { - try { - HttpServletRequest servletRequest = ServletUtil.getServletRequest(request).getRequest(); - if (servletRequest != null) { - return RequestContextUtils.getLocale(servletRequest); - } - } - catch (NotAServletEnvironmentException ex) { - // ignore - } - return super.resolveLocale(request); - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SpringWildcardServletTilesApplicationContext.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SpringWildcardServletTilesApplicationContext.java deleted file mode 100644 index ee23c042cd6c..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/SpringWildcardServletTilesApplicationContext.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.view.tiles3; - -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Locale; - -import javax.servlet.ServletContext; - -import org.apache.tiles.request.ApplicationResource; -import org.apache.tiles.request.locale.URLApplicationResource; -import org.apache.tiles.request.servlet.ServletApplicationContext; - -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.lang.Nullable; -import org.springframework.util.CollectionUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.web.context.support.ServletContextResourcePatternResolver; - -/** - * Spring-specific subclass of the Tiles ServletApplicationContext. - * - * @author Rossen Stoyanchev - * @author Juergen Hoeller - * @since 3.2 - */ -public class SpringWildcardServletTilesApplicationContext extends ServletApplicationContext { - - private final ResourcePatternResolver resolver; - - - public SpringWildcardServletTilesApplicationContext(ServletContext servletContext) { - super(servletContext); - this.resolver = new ServletContextResourcePatternResolver(servletContext); - } - - - @Override - @Nullable - public ApplicationResource getResource(String localePath) { - Collection urlSet = getResources(localePath); - if (!CollectionUtils.isEmpty(urlSet)) { - return urlSet.iterator().next(); - } - return null; - } - - @Override - @Nullable - public ApplicationResource getResource(ApplicationResource base, Locale locale) { - Collection urlSet = getResources(base.getLocalePath(locale)); - if (!CollectionUtils.isEmpty(urlSet)) { - return urlSet.iterator().next(); - } - return null; - } - - @Override - public Collection getResources(String path) { - Resource[] resources; - try { - resources = this.resolver.getResources(path); - } - catch (IOException ex) { - ((ServletContext) getContext()).log("Resource retrieval failed for path: " + path, ex); - return Collections.emptyList(); - } - if (ObjectUtils.isEmpty(resources)) { - ((ServletContext) getContext()).log("No resources found for path pattern: " + path); - return Collections.emptyList(); - } - - Collection resourceList = new ArrayList<>(resources.length); - for (Resource resource : resources) { - try { - URL url = resource.getURL(); - resourceList.add(new URLApplicationResource(url.toExternalForm(), url)); - } - catch (IOException ex) { - // Shouldn't happen with the kind of resources we're using - throw new IllegalArgumentException("No URL for " + resource, ex); - } - } - return resourceList; - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesConfigurer.java deleted file mode 100644 index dbbdf0f22e91..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesConfigurer.java +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.view.tiles3; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import javax.el.ArrayELResolver; -import javax.el.BeanELResolver; -import javax.el.CompositeELResolver; -import javax.el.ListELResolver; -import javax.el.MapELResolver; -import javax.el.ResourceBundleELResolver; -import javax.servlet.ServletContext; -import javax.servlet.jsp.JspFactory; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.tiles.TilesContainer; -import org.apache.tiles.TilesException; -import org.apache.tiles.definition.DefinitionsFactory; -import org.apache.tiles.definition.DefinitionsReader; -import org.apache.tiles.definition.dao.BaseLocaleUrlDefinitionDAO; -import org.apache.tiles.definition.dao.CachingLocaleUrlDefinitionDAO; -import org.apache.tiles.definition.digester.DigesterDefinitionsReader; -import org.apache.tiles.el.ELAttributeEvaluator; -import org.apache.tiles.el.ScopeELResolver; -import org.apache.tiles.el.TilesContextBeanELResolver; -import org.apache.tiles.el.TilesContextELResolver; -import org.apache.tiles.evaluator.AttributeEvaluator; -import org.apache.tiles.evaluator.AttributeEvaluatorFactory; -import org.apache.tiles.evaluator.BasicAttributeEvaluatorFactory; -import org.apache.tiles.evaluator.impl.DirectAttributeEvaluator; -import org.apache.tiles.extras.complete.CompleteAutoloadTilesContainerFactory; -import org.apache.tiles.extras.complete.CompleteAutoloadTilesInitializer; -import org.apache.tiles.factory.AbstractTilesContainerFactory; -import org.apache.tiles.factory.BasicTilesContainerFactory; -import org.apache.tiles.impl.mgmt.CachingTilesContainer; -import org.apache.tiles.locale.LocaleResolver; -import org.apache.tiles.preparer.factory.PreparerFactory; -import org.apache.tiles.request.ApplicationContext; -import org.apache.tiles.request.ApplicationContextAware; -import org.apache.tiles.request.ApplicationResource; -import org.apache.tiles.startup.DefaultTilesInitializer; -import org.apache.tiles.startup.TilesInitializer; - -import org.springframework.beans.BeanUtils; -import org.springframework.beans.BeanWrapper; -import org.springframework.beans.PropertyAccessorFactory; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.web.context.ServletContextAware; - -/** - * Helper class to configure Tiles 3.x for the Spring Framework. See - * https://tiles.apache.org - * for more information about Tiles, which basically is a templating mechanism - * for web applications using JSPs and other template engines. - * - *

    The TilesConfigurer simply configures a TilesContainer using a set of files - * containing definitions, to be accessed by {@link TilesView} instances. This is a - * Spring-based alternative (for usage in Spring configuration) to the Tiles-provided - * {@code ServletContextListener} - * (e.g. {@link org.apache.tiles.extras.complete.CompleteAutoloadTilesListener} - * for usage in {@code web.xml}. - * - *

    TilesViews can be managed by any {@link org.springframework.web.servlet.ViewResolver}. - * For simple convention-based view resolution, consider using {@link TilesViewResolver}. - * - *

    A typical TilesConfigurer bean definition looks as follows: - * - *

    - * <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
    - *   <property name="definitions">
    - *     <list>
    - *       <value>/WEB-INF/defs/general.xml</value>
    - *       <value>/WEB-INF/defs/widgets.xml</value>
    - *       <value>/WEB-INF/defs/administrator.xml</value>
    - *       <value>/WEB-INF/defs/customer.xml</value>
    - *       <value>/WEB-INF/defs/templates.xml</value>
    - *     </list>
    - *   </property>
    - * </bean>
    - * 
    - * - * The values in the list are the actual Tiles XML files containing the definitions. - * If the list is not specified, the default is {@code "/WEB-INF/tiles.xml"}. - * - *

    Note that in Tiles 3 an underscore in the name of a file containing Tiles - * definitions is used to indicate locale information, for example: - * - *

    - * <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
    - *   <property name="definitions">
    - *     <list>
    - *       <value>/WEB-INF/defs/tiles.xml</value>
    - *       <value>/WEB-INF/defs/tiles_fr_FR.xml</value>
    - *     </list>
    - *   </property>
    - * </bean>
    - * 
    - * - * @author mick semb wever - * @author Rossen Stoyanchev - * @author Juergen Hoeller - * @since 3.2 - * @see TilesView - * @see TilesViewResolver - */ -public class TilesConfigurer implements ServletContextAware, InitializingBean, DisposableBean { - - private static final boolean tilesElPresent = - ClassUtils.isPresent("org.apache.tiles.el.ELAttributeEvaluator", TilesConfigurer.class.getClassLoader()); - - - protected final Log logger = LogFactory.getLog(getClass()); - - @Nullable - private TilesInitializer tilesInitializer; - - @Nullable - private String[] definitions; - - private boolean checkRefresh = false; - - private boolean validateDefinitions = true; - - @Nullable - private Class definitionsFactoryClass; - - @Nullable - private Class preparerFactoryClass; - - private boolean useMutableTilesContainer = false; - - @Nullable - private ServletContext servletContext; - - - /** - * Configure Tiles using a custom TilesInitializer, typically specified as an inner bean. - *

    Default is a variant of {@link org.apache.tiles.startup.DefaultTilesInitializer}, - * respecting the "definitions", "preparerFactoryClass" etc properties on this configurer. - *

    NOTE: Specifying a custom TilesInitializer effectively disables all other bean - * properties on this configurer. The entire initialization procedure is then left - * to the TilesInitializer as specified. - */ - public void setTilesInitializer(TilesInitializer tilesInitializer) { - this.tilesInitializer = tilesInitializer; - } - - /** - * Specify whether to apply Tiles 3.0's "complete-autoload" configuration. - *

    See {@link org.apache.tiles.extras.complete.CompleteAutoloadTilesContainerFactory} - * for details on the complete-autoload mode. - *

    NOTE: Specifying the complete-autoload mode effectively disables all other bean - * properties on this configurer. The entire initialization procedure is then left - * to {@link org.apache.tiles.extras.complete.CompleteAutoloadTilesInitializer}. - * @see org.apache.tiles.extras.complete.CompleteAutoloadTilesContainerFactory - * @see org.apache.tiles.extras.complete.CompleteAutoloadTilesInitializer - */ - public void setCompleteAutoload(boolean completeAutoload) { - if (completeAutoload) { - try { - this.tilesInitializer = new SpringCompleteAutoloadTilesInitializer(); - } - catch (Throwable ex) { - throw new IllegalStateException("Tiles-Extras 3.0 not available", ex); - } - } - else { - this.tilesInitializer = null; - } - } - - /** - * Set the Tiles definitions, i.e. the list of files containing the definitions. - * Default is "/WEB-INF/tiles.xml". - */ - public void setDefinitions(String... definitions) { - this.definitions = definitions; - } - - /** - * Set whether to check Tiles definition files for a refresh at runtime. - * Default is "false". - */ - public void setCheckRefresh(boolean checkRefresh) { - this.checkRefresh = checkRefresh; - } - - /** - * Set whether to validate the Tiles XML definitions. Default is "true". - */ - public void setValidateDefinitions(boolean validateDefinitions) { - this.validateDefinitions = validateDefinitions; - } - - /** - * Set the {@link org.apache.tiles.definition.DefinitionsFactory} implementation to use. - * Default is {@link org.apache.tiles.definition.UnresolvingLocaleDefinitionsFactory}, - * operating on definition resource URLs. - *

    Specify a custom DefinitionsFactory, e.g. a UrlDefinitionsFactory subclass, - * to customize the creation of Tiles Definition objects. Note that such a - * DefinitionsFactory has to be able to handle {@link java.net.URL} source objects, - * unless you configure a different TilesContainerFactory. - */ - public void setDefinitionsFactoryClass(Class definitionsFactoryClass) { - this.definitionsFactoryClass = definitionsFactoryClass; - } - - /** - * Set the {@link org.apache.tiles.preparer.factory.PreparerFactory} implementation to use. - * Default is {@link org.apache.tiles.preparer.factory.BasicPreparerFactory}, creating - * shared instances for specified preparer classes. - *

    Specify {@link SimpleSpringPreparerFactory} to autowire - * {@link org.apache.tiles.preparer.ViewPreparer} instances based on specified - * preparer classes, applying Spring's container callbacks as well as applying - * configured Spring BeanPostProcessors. If Spring's context-wide annotation-config - * has been activated, annotations in ViewPreparer classes will be automatically - * detected and applied. - *

    Specify {@link SpringBeanPreparerFactory} to operate on specified preparer - * names instead of classes, obtaining the corresponding Spring bean from - * the DispatcherServlet's application context. The full bean creation process - * will be in the control of the Spring application context in this case, - * allowing for the use of scoped beans etc. Note that you need to define one - * Spring bean definition per preparer name (as used in your Tiles definitions). - * @see SimpleSpringPreparerFactory - * @see SpringBeanPreparerFactory - */ - public void setPreparerFactoryClass(Class preparerFactoryClass) { - this.preparerFactoryClass = preparerFactoryClass; - } - - /** - * Set whether to use a MutableTilesContainer (typically the CachingTilesContainer - * implementation) for this application. Default is "false". - * @see org.apache.tiles.mgmt.MutableTilesContainer - * @see org.apache.tiles.impl.mgmt.CachingTilesContainer - */ - public void setUseMutableTilesContainer(boolean useMutableTilesContainer) { - this.useMutableTilesContainer = useMutableTilesContainer; - } - - @Override - public void setServletContext(ServletContext servletContext) { - this.servletContext = servletContext; - } - - /** - * Creates and exposes a TilesContainer for this web application, - * delegating to the TilesInitializer. - * @throws TilesException in case of setup failure - */ - @Override - public void afterPropertiesSet() throws TilesException { - Assert.state(this.servletContext != null, "No ServletContext available"); - ApplicationContext preliminaryContext = new SpringWildcardServletTilesApplicationContext(this.servletContext); - if (this.tilesInitializer == null) { - this.tilesInitializer = new SpringTilesInitializer(); - } - this.tilesInitializer.initialize(preliminaryContext); - } - - /** - * Removes the TilesContainer from this web application. - * @throws TilesException in case of cleanup failure - */ - @Override - public void destroy() throws TilesException { - if (this.tilesInitializer != null) { - this.tilesInitializer.destroy(); - } - } - - - private class SpringTilesInitializer extends DefaultTilesInitializer { - - @Override - protected AbstractTilesContainerFactory createContainerFactory(ApplicationContext context) { - return new SpringTilesContainerFactory(); - } - } - - - private class SpringTilesContainerFactory extends BasicTilesContainerFactory { - - @Override - protected TilesContainer createDecoratedContainer(TilesContainer originalContainer, ApplicationContext context) { - return (useMutableTilesContainer ? new CachingTilesContainer(originalContainer) : originalContainer); - } - - @Override - protected List getSources(ApplicationContext applicationContext) { - if (definitions != null) { - List result = new ArrayList<>(); - for (String definition : definitions) { - Collection resources = applicationContext.getResources(definition); - if (resources != null) { - result.addAll(resources); - } - } - return result; - } - else { - return super.getSources(applicationContext); - } - } - - @Override - protected BaseLocaleUrlDefinitionDAO instantiateLocaleDefinitionDao(ApplicationContext applicationContext, - LocaleResolver resolver) { - BaseLocaleUrlDefinitionDAO dao = super.instantiateLocaleDefinitionDao(applicationContext, resolver); - if (checkRefresh && dao instanceof CachingLocaleUrlDefinitionDAO) { - ((CachingLocaleUrlDefinitionDAO) dao).setCheckRefresh(true); - } - return dao; - } - - @Override - protected DefinitionsReader createDefinitionsReader(ApplicationContext context) { - DigesterDefinitionsReader reader = (DigesterDefinitionsReader) super.createDefinitionsReader(context); - reader.setValidating(validateDefinitions); - return reader; - } - - @Override - protected DefinitionsFactory createDefinitionsFactory(ApplicationContext applicationContext, - LocaleResolver resolver) { - - if (definitionsFactoryClass != null) { - DefinitionsFactory factory = BeanUtils.instantiateClass(definitionsFactoryClass); - if (factory instanceof ApplicationContextAware) { - ((ApplicationContextAware) factory).setApplicationContext(applicationContext); - } - BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(factory); - if (bw.isWritableProperty("localeResolver")) { - bw.setPropertyValue("localeResolver", resolver); - } - if (bw.isWritableProperty("definitionDAO")) { - bw.setPropertyValue("definitionDAO", createLocaleDefinitionDao(applicationContext, resolver)); - } - return factory; - } - else { - return super.createDefinitionsFactory(applicationContext, resolver); - } - } - - @Override - protected PreparerFactory createPreparerFactory(ApplicationContext context) { - if (preparerFactoryClass != null) { - return BeanUtils.instantiateClass(preparerFactoryClass); - } - else { - return super.createPreparerFactory(context); - } - } - - @Override - protected LocaleResolver createLocaleResolver(ApplicationContext context) { - return new SpringLocaleResolver(); - } - - @Override - protected AttributeEvaluatorFactory createAttributeEvaluatorFactory(ApplicationContext context, - LocaleResolver resolver) { - AttributeEvaluator evaluator; - if (tilesElPresent && JspFactory.getDefaultFactory() != null) { - evaluator = new TilesElActivator().createEvaluator(); - } - else { - evaluator = new DirectAttributeEvaluator(); - } - return new BasicAttributeEvaluatorFactory(evaluator); - } - } - - - private static class SpringCompleteAutoloadTilesInitializer extends CompleteAutoloadTilesInitializer { - - @Override - protected AbstractTilesContainerFactory createContainerFactory(ApplicationContext context) { - return new SpringCompleteAutoloadTilesContainerFactory(); - } - } - - - private static class SpringCompleteAutoloadTilesContainerFactory extends CompleteAutoloadTilesContainerFactory { - - @Override - protected LocaleResolver createLocaleResolver(ApplicationContext applicationContext) { - return new SpringLocaleResolver(); - } - } - - - private class TilesElActivator { - - public AttributeEvaluator createEvaluator() { - ELAttributeEvaluator evaluator = new ELAttributeEvaluator(); - evaluator.setExpressionFactory( - JspFactory.getDefaultFactory().getJspApplicationContext(servletContext).getExpressionFactory()); - evaluator.setResolver(new CompositeELResolverImpl()); - return evaluator; - } - } - - - private static class CompositeELResolverImpl extends CompositeELResolver { - - public CompositeELResolverImpl() { - add(new ScopeELResolver()); - add(new TilesContextELResolver(new TilesContextBeanELResolver())); - add(new TilesContextBeanELResolver()); - add(new ArrayELResolver(false)); - add(new ListELResolver(false)); - add(new MapELResolver(false)); - add(new ResourceBundleELResolver()); - add(new BeanELResolver(false)); - } - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesView.java deleted file mode 100644 index 93238075da6f..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesView.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.view.tiles3; - -import java.util.Locale; -import java.util.Map; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.tiles.TilesContainer; -import org.apache.tiles.access.TilesAccess; -import org.apache.tiles.renderer.DefinitionRenderer; -import org.apache.tiles.request.AbstractRequest; -import org.apache.tiles.request.ApplicationContext; -import org.apache.tiles.request.Request; -import org.apache.tiles.request.render.Renderer; -import org.apache.tiles.request.servlet.ServletRequest; -import org.apache.tiles.request.servlet.ServletUtil; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.web.context.request.RequestAttributes; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; -import org.springframework.web.servlet.support.JstlUtils; -import org.springframework.web.servlet.support.RequestContext; -import org.springframework.web.servlet.support.RequestContextUtils; -import org.springframework.web.servlet.view.AbstractUrlBasedView; - -/** - * {@link org.springframework.web.servlet.View} implementation that renders - * through the Tiles Request API. The "url" property is interpreted as name of a - * Tiles definition. - * - * @author Nicolas Le Bas - * @author mick semb wever - * @author Rossen Stoyanchev - * @author Sebastien Deleuze - * @since 3.2 - */ -public class TilesView extends AbstractUrlBasedView { - - @Nullable - private Renderer renderer; - - private boolean exposeJstlAttributes = true; - - private boolean alwaysInclude = false; - - @Nullable - private ApplicationContext applicationContext; - - - /** - * Set the {@link Renderer} to use. - * If not set, by default {@link DefinitionRenderer} is used. - */ - public void setRenderer(Renderer renderer) { - this.renderer = renderer; - } - - /** - * Whether to expose JSTL attributes. By default set to {@code true}. - * @see JstlUtils#exposeLocalizationContext(RequestContext) - */ - protected void setExposeJstlAttributes(boolean exposeJstlAttributes) { - this.exposeJstlAttributes = exposeJstlAttributes; - } - - /** - * Specify whether to always include the view rather than forward to it. - *

    Default is "false". Switch this flag on to enforce the use of a - * Servlet include, even if a forward would be possible. - * @since 4.1.2 - * @see TilesViewResolver#setAlwaysInclude - */ - public void setAlwaysInclude(boolean alwaysInclude) { - this.alwaysInclude = alwaysInclude; - } - - @Override - public void afterPropertiesSet() throws Exception { - super.afterPropertiesSet(); - - ServletContext servletContext = getServletContext(); - Assert.state(servletContext != null, "No ServletContext"); - this.applicationContext = ServletUtil.getApplicationContext(servletContext); - - if (this.renderer == null) { - TilesContainer container = TilesAccess.getContainer(this.applicationContext); - this.renderer = new DefinitionRenderer(container); - } - } - - - @Override - public boolean checkResource(final Locale locale) throws Exception { - Assert.state(this.renderer != null, "No Renderer set"); - - HttpServletRequest servletRequest = null; - RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); - if (requestAttributes instanceof ServletRequestAttributes) { - servletRequest = ((ServletRequestAttributes) requestAttributes).getRequest(); - } - - Request request = new ServletRequest(this.applicationContext, servletRequest, null) { - @Override - public Locale getRequestLocale() { - return locale; - } - }; - - return this.renderer.isRenderable(getUrl(), request); - } - - @Override - protected void renderMergedOutputModel(Map model, HttpServletRequest request, - HttpServletResponse response) throws Exception { - - Assert.state(this.renderer != null, "No Renderer set"); - - exposeModelAsRequestAttributes(model, request); - if (this.exposeJstlAttributes) { - JstlUtils.exposeLocalizationContext(new RequestContext(request, getServletContext())); - } - if (this.alwaysInclude) { - request.setAttribute(AbstractRequest.FORCE_INCLUDE_ATTRIBUTE_NAME, true); - } - - Request tilesRequest = createTilesRequest(request, response); - this.renderer.render(getUrl(), tilesRequest); - } - - /** - * Create a Tiles {@link Request}. - *

    This implementation creates a {@link ServletRequest}. - * @param request the current request - * @param response the current response - * @return the Tiles request - */ - protected Request createTilesRequest(final HttpServletRequest request, HttpServletResponse response) { - return new ServletRequest(this.applicationContext, request, response) { - @Override - public Locale getRequestLocale() { - return RequestContextUtils.getLocale(request); - } - }; - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesViewResolver.java deleted file mode 100644 index 33ba0451417a..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesViewResolver.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.view.tiles3; - -import org.apache.tiles.request.render.Renderer; - -import org.springframework.lang.Nullable; -import org.springframework.web.servlet.view.AbstractUrlBasedView; -import org.springframework.web.servlet.view.UrlBasedViewResolver; - -/** - * Convenience subclass of {@link UrlBasedViewResolver} that supports - * {@link TilesView} (i.e. Tiles definitions) and custom subclasses of it. - * - * @author Nicolas Le Bas - * @author Rossen Stoyanchev - * @author Juergen Hoeller - * @author Sebastien Deleuze - * @since 3.2 - */ -public class TilesViewResolver extends UrlBasedViewResolver { - - @Nullable - private Renderer renderer; - - @Nullable - private Boolean alwaysInclude; - - - /** - * This resolver requires {@link TilesView}. - */ - public TilesViewResolver() { - setViewClass(requiredViewClass()); - } - - - /** - * Set the {@link Renderer} to use. If not specified, a default - * {@link org.apache.tiles.renderer.DefinitionRenderer} will be used. - * @see TilesView#setRenderer(Renderer) - */ - public void setRenderer(Renderer renderer) { - this.renderer = renderer; - } - - /** - * Specify whether to always include the view rather than forward to it. - *

    Default is "false". Switch this flag on to enforce the use of a - * Servlet include, even if a forward would be possible. - * @since 4.1.2 - * @see TilesView#setAlwaysInclude - */ - public void setAlwaysInclude(Boolean alwaysInclude) { - this.alwaysInclude = alwaysInclude; - } - - - @Override - protected Class requiredViewClass() { - return TilesView.class; - } - - @Override - protected AbstractUrlBasedView instantiateView() { - return (getViewClass() == TilesView.class ? new TilesView() : super.instantiateView()); - } - - @Override - protected TilesView buildView(String viewName) throws Exception { - TilesView view = (TilesView) super.buildView(viewName); - if (this.renderer != null) { - view.setRenderer(this.renderer); - } - if (this.alwaysInclude != null) { - view.setAlwaysInclude(this.alwaysInclude); - } - return view; - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/package-info.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/package-info.java deleted file mode 100644 index ca03c5e3c470..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/package-info.java +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Support classes for the integration of - * Tiles 3 - * (the standalone version of Tiles) as Spring web view technology. - * Contains a View implementation for Tiles definitions. - */ -@NonNullApi -@NonNullFields -package org.springframework.web.servlet.view.tiles3; - -import org.springframework.lang.NonNullApi; -import org.springframework.lang.NonNullFields; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xml/MarshallingView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xml/MarshallingView.java index bf0e0641ca6c..36b7f04cbdf2 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xml/MarshallingView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xml/MarshallingView.java @@ -19,11 +19,12 @@ import java.io.ByteArrayOutputStream; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.xml.bind.JAXBElement; import javax.xml.transform.stream.StreamResult; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.xml.bind.JAXBElement; + import org.springframework.lang.Nullable; import org.springframework.oxm.Marshaller; import org.springframework.util.Assert; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xslt/XsltView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xslt/XsltView.java index e0383c5e3227..1d3c29b9395e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xslt/XsltView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xslt/XsltView.java @@ -23,8 +23,6 @@ import java.util.Map; import java.util.Properties; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import javax.xml.transform.ErrorListener; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; @@ -39,6 +37,8 @@ import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.w3c.dom.Document; import org.w3c.dom.Node; diff --git a/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc.xsd b/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc.xsd index c0364d28c12f..49bac9fb9ffc 100644 --- a/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc.xsd +++ b/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc.xsd @@ -251,7 +251,7 @@ As of 5.0 this executor is also used when a controller returns a reactive type that does streaming (e.g. "text/event-stream" or "application/x-ndjson") for the blocking writes to the - "javax.servlet.ServletOutputStream". + "jakarta.servlet.ServletOutputStream". ]]> @@ -1041,15 +1041,6 @@ ]]> - - - element - or declare a TilesConfigurer bean. - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - resolvers = compositeResolver.getViewResolvers(); @@ -800,9 +794,7 @@ public void testViewResolution() throws Exception { DirectFieldAccessor accessor = new DirectFieldAccessor(resolver); assertThat(accessor.getPropertyValue("viewClass")).isEqualTo(InternalResourceView.class); - assertThat(resolvers.get(2).getClass()).isEqualTo(TilesViewResolver.class); - - resolver = resolvers.get(3); + resolver = resolvers.get(2); assertThat(resolver).isInstanceOf(FreeMarkerViewResolver.class); accessor = new DirectFieldAccessor(resolver); assertThat(accessor.getPropertyValue("prefix")).isEqualTo("freemarker-"); @@ -810,34 +802,22 @@ public void testViewResolution() throws Exception { assertThat((String[]) accessor.getPropertyValue("viewNames")).isEqualTo(new String[] {"my*", "*Report"}); assertThat(accessor.getPropertyValue("cacheLimit")).isEqualTo(1024); - resolver = resolvers.get(4); + resolver = resolvers.get(3); assertThat(resolver).isInstanceOf(GroovyMarkupViewResolver.class); accessor = new DirectFieldAccessor(resolver); assertThat(accessor.getPropertyValue("prefix")).isEqualTo(""); assertThat(accessor.getPropertyValue("suffix")).isEqualTo(".tpl"); assertThat(accessor.getPropertyValue("cacheLimit")).isEqualTo(1024); - resolver = resolvers.get(5); + resolver = resolvers.get(4); assertThat(resolver).isInstanceOf(ScriptTemplateViewResolver.class); accessor = new DirectFieldAccessor(resolver); assertThat(accessor.getPropertyValue("prefix")).isEqualTo(""); assertThat(accessor.getPropertyValue("suffix")).isEqualTo(""); assertThat(accessor.getPropertyValue("cacheLimit")).isEqualTo(1024); + assertThat(resolvers.get(5).getClass()).isEqualTo(InternalResourceViewResolver.class); assertThat(resolvers.get(6).getClass()).isEqualTo(InternalResourceViewResolver.class); - assertThat(resolvers.get(7).getClass()).isEqualTo(InternalResourceViewResolver.class); - - TilesConfigurer tilesConfigurer = appContext.getBean(TilesConfigurer.class); - assertThat(tilesConfigurer).isNotNull(); - String[] definitions = { - "/org/springframework/web/servlet/resource/tiles/tiles1.xml", - "/org/springframework/web/servlet/resource/tiles/tiles2.xml" - }; - accessor = new DirectFieldAccessor(tilesConfigurer); - assertThat((String[]) accessor.getPropertyValue("definitions")).isEqualTo(definitions); - assertThat((boolean) accessor.getPropertyValue("checkRefresh")).isTrue(); - assertThat(accessor.getPropertyValue("definitionsFactoryClass")).isEqualTo(UnresolvingLocaleDefinitionsFactory.class); - assertThat(accessor.getPropertyValue("preparerFactoryClass")).isEqualTo(SpringBeanPreparerFactory.class); FreeMarkerConfigurer freeMarkerConfigurer = appContext.getBean(FreeMarkerConfigurer.class); assertThat(freeMarkerConfigurer).isNotNull(); @@ -874,7 +854,7 @@ public void testViewResolutionWithContentNegotiation() throws Exception { List resolvers = compositeResolver.getViewResolvers(); assertThat(resolvers.get(0).getClass()).isEqualTo(ContentNegotiatingViewResolver.class); ContentNegotiatingViewResolver cnvr = (ContentNegotiatingViewResolver) resolvers.get(0); - assertThat(cnvr.getViewResolvers().size()).isEqualTo(6); + assertThat(cnvr.getViewResolvers().size()).isEqualTo(5); assertThat(cnvr.getDefaultViews().size()).isEqualTo(1); assertThat(cnvr.isUseNotAcceptableStatusCode()).isTrue(); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurerTests.java index 1566076324e1..169ca70a4f50 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurerTests.java @@ -16,8 +16,7 @@ package org.springframework.web.servlet.config.annotation; -import javax.servlet.RequestDispatcher; - +import jakarta.servlet.RequestDispatcher; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java index e87be4ebe254..bdae7e1b78d6 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,8 +18,7 @@ import java.io.IOException; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletException; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Bean; @@ -33,7 +32,6 @@ import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver; import org.springframework.web.servlet.view.groovy.GroovyMarkupConfigurer; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; import org.springframework.web.testfixture.servlet.MockHttpServletResponse; import org.springframework.web.testfixture.servlet.MockServletConfig; @@ -56,12 +54,6 @@ public void freemarker() throws Exception { assertThat(response.getContentAsString()).isEqualTo("Hello World!"); } - @Test - public void tiles() throws Exception { - MockHttpServletResponse response = runTest(TilesWebConfig.class); - assertThat(response.getForwardedUrl()).isEqualTo("/WEB-INF/index.jsp"); - } - @Test public void groovyMarkup() throws Exception { MockHttpServletResponse response = runTest(GroovyMarkupWebConfig.class); @@ -75,13 +67,6 @@ public void freemarkerInvalidConfig() throws Exception { .withMessageContaining("In addition to a FreeMarker view resolver "); } - @Test - public void tilesInvalidConfig() throws Exception { - assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> - runTest(InvalidTilesWebConfig.class)) - .withMessageContaining("In addition to a Tiles view resolver "); - } - @Test public void groovyMarkupInvalidConfig() throws Exception { assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> @@ -151,22 +136,6 @@ public FreeMarkerConfigurer freeMarkerConfigurer() { } } - @Configuration - static class TilesWebConfig extends AbstractWebConfig { - - @Override - public void configureViewResolvers(ViewResolverRegistry registry) { - registry.tiles(); - } - - @Bean - public TilesConfigurer tilesConfigurer() { - TilesConfigurer configurer = new TilesConfigurer(); - configurer.setDefinitions("/WEB-INF/tiles.xml"); - return configurer; - } - } - @Configuration static class GroovyMarkupWebConfig extends AbstractWebConfig { @@ -192,15 +161,6 @@ public void configureViewResolvers(ViewResolverRegistry registry) { } } - @Configuration - static class InvalidTilesWebConfig extends WebMvcConfigurationSupport { - - @Override - public void configureViewResolvers(ViewResolverRegistry registry) { - registry.tiles(); - } - } - @Configuration static class InvalidGroovyMarkupWebConfig extends WebMvcConfigurationSupport { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolverRegistryTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolverRegistryTests.java index e3373b829232..4986338605cd 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolverRegistryTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolverRegistryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,8 +36,6 @@ import org.springframework.web.servlet.view.json.MappingJackson2JsonView; import org.springframework.web.servlet.view.script.ScriptTemplateConfigurer; import org.springframework.web.servlet.view.script.ScriptTemplateViewResolver; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; -import org.springframework.web.servlet.view.tiles3.TilesViewResolver; import org.springframework.web.servlet.view.xml.MarshallingView; import static org.assertj.core.api.Assertions.assertThat; @@ -57,7 +55,6 @@ public class ViewResolverRegistryTests { public void setup() { StaticWebApplicationContext context = new StaticWebApplicationContext(); context.registerSingleton("freeMarkerConfigurer", FreeMarkerConfigurer.class); - context.registerSingleton("tilesConfigurer", TilesConfigurer.class); context.registerSingleton("groovyMarkupConfigurer", GroovyMarkupConfigurer.class); context.registerSingleton("scriptTemplateConfigurer", ScriptTemplateConfigurer.class); @@ -131,12 +128,6 @@ public void jspMultipleResolvers() { assertThat(this.registry.getViewResolvers().get(1).getClass()).isEqualTo(InternalResourceViewResolver.class); } - @Test - public void tiles() { - this.registry.tiles(); - checkAndGetResolver(TilesViewResolver.class); - } - @Test public void freeMarker() { this.registry.freeMarker().prefix("/").suffix(".fmt").cache(false); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java index dad6504f9a1c..c53cc812bf4f 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,15 +16,14 @@ package org.springframework.web.servlet.config.annotation; +import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map; -import javax.servlet.http.HttpServletRequest; - import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; -import org.joda.time.DateTime; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.beans.DirectFieldAccessor; @@ -437,7 +436,7 @@ public void handle() { @RequestMapping("/foo/{id}/bar/{date}") public HttpEntity methodWithTwoPathVariables(@PathVariable Integer id, - @DateTimeFormat(iso = ISO.DATE) @PathVariable DateTime date) { + @DateTimeFormat(iso = ISO.DATE) @PathVariable Date date) { return null; } } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultEntityResponseBuilderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultEntityResponseBuilderTests.java index 0d7553bb80d1..00969fbb85c1 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultEntityResponseBuilderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultEntityResponseBuilderTests.java @@ -25,9 +25,8 @@ import java.util.List; import java.util.Set; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; import org.junit.jupiter.api.Test; import org.springframework.core.ParameterizedTypeReference; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultRenderingResponseTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultRenderingResponseTests.java index 56fec0a442b5..6ffb5da58a8f 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultRenderingResponseTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultRenderingResponseTests.java @@ -23,8 +23,7 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.Cookie; - +import jakarta.servlet.http.Cookie; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerRequestBuilderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerRequestBuilderTests.java index 254f84c67ab3..e1de828a5327 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerRequestBuilderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerRequestBuilderTests.java @@ -21,9 +21,8 @@ import java.util.Collections; import java.util.List; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; import org.junit.jupiter.api.Test; import org.springframework.http.HttpMethod; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerRequestTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerRequestTests.java index 07233b27ecec..4a5a19d276fa 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerRequestTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerRequestTests.java @@ -32,9 +32,8 @@ import java.util.Optional; import java.util.OptionalLong; -import javax.servlet.http.Cookie; -import javax.servlet.http.Part; - +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.Part; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerResponseBuilderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerResponseBuilderTests.java index 23621b73197c..d70ffb3a8e81 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerResponseBuilderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerResponseBuilderTests.java @@ -27,8 +27,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; -import javax.servlet.http.Cookie; - +import jakarta.servlet.http.Cookie; import org.junit.jupiter.api.Test; import org.reactivestreams.Publisher; import reactor.core.publisher.Mono; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/ResourceHandlerFunctionTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/ResourceHandlerFunctionTests.java index ccefb80b4519..a5cfa327b7d8 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/ResourceHandlerFunctionTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/ResourceHandlerFunctionTests.java @@ -23,8 +23,7 @@ import java.util.Collections; import java.util.EnumSet; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/BeanNameUrlHandlerMappingTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/BeanNameUrlHandlerMappingTests.java index 650790d502a4..5e166b87f35f 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/BeanNameUrlHandlerMappingTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/BeanNameUrlHandlerMappingTests.java @@ -16,8 +16,7 @@ package org.springframework.web.servlet.handler; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/CorsAbstractHandlerMappingTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/CorsAbstractHandlerMappingTests.java index 68e6dc066e02..3c4fa750f4f4 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/CorsAbstractHandlerMappingTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/CorsAbstractHandlerMappingTests.java @@ -19,8 +19,8 @@ import java.util.Collections; import java.util.stream.Stream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMappingIntrospectorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMappingIntrospectorTests.java index 745d642b5ad4..d020753e799e 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMappingIntrospectorTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMappingIntrospectorTests.java @@ -21,8 +21,7 @@ import java.util.Collections; import java.util.List; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMappingTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMappingTests.java index 7273780514ec..62b3a895d3a0 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMappingTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMappingTests.java @@ -21,8 +21,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.provider.Arguments; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java index d610c30215cf..ccda745f7935 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java @@ -23,8 +23,7 @@ import java.util.List; import java.util.Set; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/MappedInterceptorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/MappedInterceptorTests.java index d404c32346ab..5bff705f31fe 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/MappedInterceptorTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/MappedInterceptorTests.java @@ -20,9 +20,8 @@ import java.util.function.Function; import java.util.stream.Stream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.util.PathMatcher; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleMappingExceptionResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleMappingExceptionResolverTests.java index 0b284c947346..7f8d8e8f5d20 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleMappingExceptionResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleMappingExceptionResolverTests.java @@ -19,8 +19,7 @@ import java.util.Collections; import java.util.Properties; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolverTests.java index c7bd35954a47..90374faf6e14 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolverTests.java @@ -20,8 +20,7 @@ import java.util.Collections; import java.util.Locale; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/CookieLocaleResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/CookieLocaleResolverTests.java index 185ca9d3f695..bb2846759d41 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/CookieLocaleResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/CookieLocaleResolverTests.java @@ -19,9 +19,8 @@ import java.util.Locale; import java.util.TimeZone; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; import org.junit.jupiter.api.Test; import org.springframework.context.i18n.LocaleContext; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/SessionLocaleResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/SessionLocaleResolverTests.java index d9f1cc612385..cd702850ea1d 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/SessionLocaleResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/SessionLocaleResolverTests.java @@ -18,8 +18,7 @@ import java.util.Locale; -import javax.servlet.http.HttpSession; - +import jakarta.servlet.http.HttpSession; import org.junit.jupiter.api.Test; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/ControllerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/ControllerTests.java index a5983b9e5579..7da7119b54bd 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/ControllerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/ControllerTests.java @@ -18,15 +18,14 @@ import java.util.Properties; -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.web.context.support.StaticWebApplicationContext; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/annotation/CglibProxyControllerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/annotation/CglibProxyControllerTests.java index d2718fc76900..3fbdadb0533f 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/annotation/CglibProxyControllerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/annotation/CglibProxyControllerTests.java @@ -19,8 +19,7 @@ import java.io.IOException; import java.io.Writer; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletException; import org.junit.jupiter.api.Test; import org.springframework.aop.Pointcut; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/annotation/JdkProxyControllerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/annotation/JdkProxyControllerTests.java index a7ab53498d51..a1de84fb2c83 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/annotation/JdkProxyControllerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/annotation/JdkProxyControllerTests.java @@ -19,8 +19,7 @@ import java.io.IOException; import java.io.Writer; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletException; import org.junit.jupiter.api.Test; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/CompositeRequestConditionTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/CompositeRequestConditionTests.java index fbc5b58b5c85..9258f9cb9e96 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/CompositeRequestConditionTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/CompositeRequestConditionTests.java @@ -16,8 +16,7 @@ package org.springframework.web.servlet.mvc.condition; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/PathPatternsRequestConditionTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/PathPatternsRequestConditionTests.java index 52071bd97aae..089664828569 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/PathPatternsRequestConditionTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/PathPatternsRequestConditionTests.java @@ -16,8 +16,7 @@ package org.springframework.web.servlet.mvc.condition; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/PatternsRequestConditionTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/PatternsRequestConditionTests.java index 5150c0325bb1..41cda092523c 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/PatternsRequestConditionTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/PatternsRequestConditionTests.java @@ -18,8 +18,7 @@ import java.util.Collections; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/ProducesRequestConditionTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/ProducesRequestConditionTests.java index fc1d77166acb..15244e1baa25 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/ProducesRequestConditionTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/ProducesRequestConditionTests.java @@ -20,8 +20,7 @@ import java.util.Collection; import java.util.Collections; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/RequestConditionHolderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/RequestConditionHolderTests.java index 786df9c16a0a..6aa86cbfa907 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/RequestConditionHolderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/RequestConditionHolderTests.java @@ -16,8 +16,7 @@ package org.springframework.web.servlet.mvc.condition; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.web.bind.annotation.RequestMethod; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestConditionTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestConditionTests.java index c0dbd0a62422..7cb38ac95a1b 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestConditionTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestConditionTests.java @@ -18,9 +18,8 @@ import java.util.Collections; -import javax.servlet.DispatcherType; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.DispatcherType; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java index 32277c53bee5..fb36283ffa6b 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java @@ -25,8 +25,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoTests.java index 11a435d25d9c..4df25abdf9d9 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoTests.java @@ -21,8 +21,7 @@ import java.util.List; import java.util.stream.Stream; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/AbstractRequestAttributesArgumentResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/AbstractRequestAttributesArgumentResolverTests.java index 7ec195b1e3d5..a3f3082b9d7a 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/AbstractRequestAttributesArgumentResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/AbstractRequestAttributesArgumentResolverTests.java @@ -19,9 +19,8 @@ import java.lang.reflect.Method; import java.util.Optional; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/AbstractServletHandlerMethodTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/AbstractServletHandlerMethodTests.java index c9cfaf7ec417..3d99f5a4f1a8 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/AbstractServletHandlerMethodTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/AbstractServletHandlerMethodTests.java @@ -16,8 +16,7 @@ package org.springframework.web.servlet.mvc.method.annotation; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletException; import org.junit.jupiter.api.AfterEach; import org.springframework.beans.factory.config.BeanDefinition; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/CrossOriginTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/CrossOriginTests.java index f4fa67d7ce8a..8a4fbb7f93b5 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/CrossOriginTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/CrossOriginTests.java @@ -25,8 +25,7 @@ import java.util.Properties; import java.util.stream.Stream; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.DirectFieldAccessor; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java index a46de7c7b80a..5351a27e3cf9 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java @@ -30,8 +30,7 @@ import java.util.Date; import java.util.Set; -import javax.servlet.FilterChain; - +import jakarta.servlet.FilterChain; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorTests.java index f870aca3ca01..ebcbc87f7cdb 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorTests.java @@ -22,12 +22,11 @@ import java.util.Collections; import java.util.List; -import javax.servlet.FilterChain; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; +import jakarta.servlet.FilterChain; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java index 99abb24debdf..bce9d4f1a6be 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,13 +22,11 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.Arrays; +import java.util.Date; import java.util.List; import java.util.Optional; -import javax.servlet.http.HttpServletRequest; - -import org.joda.time.DateTime; -import org.joda.time.format.ISODateTimeFormat; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -202,11 +200,10 @@ public void fromMethodNameTypeLevelPathVariable() { @Test public void fromMethodNameTwoPathVariables() { - DateTime now = DateTime.now(); UriComponents uriComponents = fromMethodName( - ControllerWithMethods.class, "methodWithTwoPathVariables", 1, now).build(); + ControllerWithMethods.class, "methodWithTwoPathVariables", 1, "2009-10-31").build(); - assertThat(uriComponents.getPath()).isEqualTo("/something/1/foo/" + ISODateTimeFormat.date().print(now)); + assertThat(uriComponents.getPath()).isEqualTo("/something/1/foo/2009-10-31"); } @Test @@ -549,7 +546,7 @@ HttpEntity methodWithPathVariable(@PathVariable String id) { @RequestMapping("/{id}/foo/{date}") HttpEntity methodWithTwoPathVariables( - @PathVariable Integer id, @DateTimeFormat(iso = ISO.DATE) @PathVariable DateTime date) { + @PathVariable Integer id, @DateTimeFormat(iso = ISO.DATE) @PathVariable Date date) { return null; } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/PrincipalMethodArgumentResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/PrincipalMethodArgumentResolverTests.java index c32813c40cc2..cb32bf088bf5 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/PrincipalMethodArgumentResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/PrincipalMethodArgumentResolverTests.java @@ -23,8 +23,7 @@ import java.lang.reflect.Method; import java.security.Principal; -import javax.servlet.ServletRequest; - +import jakarta.servlet.ServletRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterIntegrationTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterIntegrationTests.java index 29a75dcdbe93..9d3a147ac32b 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterIntegrationTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterIntegrationTests.java @@ -35,11 +35,10 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.validation.Valid; - +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartIntegrationTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartIntegrationTests.java index 8e69fc631faa..4370f9a471e5 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartIntegrationTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,8 +24,7 @@ import java.util.Map; import java.util.Optional; -import javax.servlet.MultipartConfigElement; - +import jakarta.servlet.MultipartConfigElement; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; @@ -61,7 +60,6 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartResolver; -import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.multipart.support.StandardServletMultipartResolver; import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @@ -93,16 +91,8 @@ public static void startServer() throws Exception { ServletContextHandler handler = new ServletContextHandler(); handler.setContextPath("/"); - - Class config = CommonsMultipartResolverTestConfig.class; - ServletHolder commonsResolverServlet = new ServletHolder(DispatcherServlet.class); - commonsResolverServlet.setInitParameter("contextConfigLocation", config.getName()); - commonsResolverServlet.setInitParameter("contextClass", AnnotationConfigWebApplicationContext.class.getName()); - handler.addServlet(commonsResolverServlet, "/commons-resolver/*"); - - config = StandardMultipartResolverTestConfig.class; ServletHolder standardResolverServlet = new ServletHolder(DispatcherServlet.class); - standardResolverServlet.setInitParameter("contextConfigLocation", config.getName()); + standardResolverServlet.setInitParameter("contextConfigLocation", StandardMultipartResolverTestConfig.class.getName()); standardResolverServlet.setInitParameter("contextClass", AnnotationConfigWebApplicationContext.class.getName()); standardResolverServlet.getRegistration().setMultipartConfig(new MultipartConfigElement("")); handler.addServlet(standardResolverServlet, "/standard-resolver/*"); @@ -141,12 +131,6 @@ public void setup() { } - @Test - public void commonsMultipartResolver() throws Exception { - testCreate(baseUrl + "/commons-resolver/test", "Jason"); - testCreate(baseUrl + "/commons-resolver/test", "Arjen"); - } - @Test public void standardMultipartResolver() throws Exception { testCreate(baseUrl + "/standard-resolver/test", "Jason"); @@ -207,17 +191,6 @@ public RequestPartTestController controller() { } - @Configuration - @SuppressWarnings("unused") - static class CommonsMultipartResolverTestConfig extends RequestPartTestConfig { - - @Bean - public MultipartResolver multipartResolver() { - return new CommonsMultipartResolver(); - } - } - - @Configuration @SuppressWarnings("unused") static class StandardMultipartResolverTestConfig extends RequestPartTestConfig { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolverTests.java index 9cf34618a62e..e97e807c058b 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolverTests.java @@ -23,10 +23,9 @@ import java.util.List; import java.util.Optional; -import javax.servlet.http.Part; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; - +import jakarta.servlet.http.Part; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorMockTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorMockTests.java index b805e00a499d..e4cae1627c44 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorMockTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorMockTests.java @@ -23,9 +23,8 @@ import java.util.List; import java.util.Optional; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; - +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; 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 e5fa5c684733..dfc40e2807c0 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 @@ -21,8 +21,7 @@ import java.util.EnumSet; import java.util.List; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletException; import org.junit.jupiter.api.Test; import org.springframework.beans.ConversionNotSupportedException; @@ -287,7 +286,7 @@ private ResponseEntity testException(Exception ex) { // SPR-9653 if (HttpStatus.INTERNAL_SERVER_ERROR.equals(responseEntity.getStatusCode())) { - assertThat(this.servletRequest.getAttribute("javax.servlet.error.exception")).isSameAs(ex); + assertThat(this.servletRequest.getAttribute("jakarta.servlet.error.exception")).isSameAs(ex); } this.defaultExceptionResolver.resolveException(this.servletRequest, this.servletResponse, null, ex); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java index 6957bdfc828e..8f07c7071f8e 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java @@ -49,18 +49,17 @@ import java.util.UUID; import java.util.stream.Stream; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.Part; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; -import javax.xml.bind.annotation.XmlRootElement; - +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.Part; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.xml.bind.annotation.XmlRootElement; import org.junit.jupiter.api.Test; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletCookieValueMethodArgumentResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletCookieValueMethodArgumentResolverTests.java index 8b34cccd5a2a..80507cad758b 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletCookieValueMethodArgumentResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletCookieValueMethodArgumentResolverTests.java @@ -18,8 +18,7 @@ import java.lang.reflect.Method; -import javax.servlet.http.Cookie; - +import jakarta.servlet.http.Cookie; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethodTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethodTests.java index d26e4cc0c1fe..ba386fce36b8 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethodTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethodTests.java @@ -24,9 +24,8 @@ import java.util.List; import java.util.Locale; -import javax.servlet.FilterChain; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.FilterChain; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletRequestMethodArgumentResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletRequestMethodArgumentResolverTests.java index aacbd3e00820..b6f8dc0027ca 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletRequestMethodArgumentResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletRequestMethodArgumentResolverTests.java @@ -28,10 +28,9 @@ import java.util.Locale; import java.util.TimeZone; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpSession; -import javax.servlet.http.PushBuilder; - +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.PushBuilder; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletResponseMethodArgumentResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletResponseMethodArgumentResolverTests.java index e467caa94d88..b0ed4c8b9879 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletResponseMethodArgumentResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletResponseMethodArgumentResolverTests.java @@ -20,8 +20,7 @@ import java.io.Writer; import java.lang.reflect.Method; -import javax.servlet.ServletResponse; - +import jakarta.servlet.ServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletAnnotationControllerHandlerMethodTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletAnnotationControllerHandlerMethodTests.java index 9944159df7f6..464fad986b34 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletAnnotationControllerHandlerMethodTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletAnnotationControllerHandlerMethodTests.java @@ -27,8 +27,8 @@ import java.util.Map; import java.util.stream.Stream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.propertyeditors.CustomDateEditor; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.java index e2574d4224c2..ed98ab46efa9 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.java @@ -216,7 +216,7 @@ public void handleConversionNotSupportedException() throws Exception { assertThat(response.getStatus()).as("Invalid status code").isEqualTo(500); // SPR-9653 - assertThat(request.getAttribute("javax.servlet.error.exception")).isSameAs(ex); + assertThat(request.getAttribute("jakarta.servlet.error.exception")).isSameAs(ex); } @Test // SPR-14669 diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java index 4b12502b8e58..8d7057058d9c 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java @@ -20,8 +20,7 @@ import java.util.Collections; import java.util.List; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerIntegrationTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerIntegrationTests.java index a55bd6f8434e..85a8644bb11d 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerIntegrationTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerIntegrationTests.java @@ -21,8 +21,7 @@ import java.nio.charset.StandardCharsets; import java.util.stream.Stream; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index 6ced3a30d33e..e7f87759cdbf 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -22,8 +22,7 @@ import java.util.Collections; import java.util.List; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceTransformerSupportTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceTransformerSupportTests.java index 0e6da211e4ec..77af33758411 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceTransformerSupportTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceTransformerSupportTests.java @@ -19,8 +19,7 @@ import java.util.Collections; import java.util.List; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java index 0e7ba7745869..941edbadb9df 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java @@ -20,11 +20,10 @@ import java.util.Collections; import java.util.List; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderJavaConfigTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderJavaConfigTests.java index 18c6b229d919..82e8e6f18fe6 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderJavaConfigTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderJavaConfigTests.java @@ -16,10 +16,9 @@ package org.springframework.web.servlet.resource; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/WebJarsResourceResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/WebJarsResourceResolverTests.java index 1a9fbae7f41c..0c65d74038ef 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/WebJarsResourceResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/WebJarsResourceResolverTests.java @@ -19,8 +19,7 @@ import java.util.Collections; import java.util.List; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/AnnotationConfigDispatcherServletInitializerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/AnnotationConfigDispatcherServletInitializerTests.java index aded6595300c..9339486bd374 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/AnnotationConfigDispatcherServletInitializerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/AnnotationConfigDispatcherServletInitializerTests.java @@ -22,15 +22,14 @@ import java.util.LinkedHashMap; import java.util.Map; -import javax.servlet.DispatcherType; -import javax.servlet.Filter; -import javax.servlet.FilterRegistration.Dynamic; -import javax.servlet.Servlet; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; - +import jakarta.servlet.DispatcherType; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterRegistration.Dynamic; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRegistration; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/DispatcherServletInitializerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/DispatcherServletInitializerTests.java index 1035e5720253..15bf12019e83 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/DispatcherServletInitializerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/DispatcherServletInitializerTests.java @@ -20,10 +20,9 @@ import java.util.LinkedHashMap; import java.util.Map; -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; - +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRegistration; import org.junit.jupiter.api.Test; import org.springframework.web.context.WebApplicationContext; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/FlashMapManagerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/FlashMapManagerTests.java index 2867d42ce4ee..46be451297ef 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/FlashMapManagerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/FlashMapManagerTests.java @@ -23,9 +23,8 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.assertj.core.api.ObjectAssert; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/MockFilterRegistration.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/MockFilterRegistration.java index 59443780c583..49502b0ad9bb 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/MockFilterRegistration.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/MockFilterRegistration.java @@ -21,8 +21,8 @@ import java.util.Map; import java.util.Set; -import javax.servlet.DispatcherType; -import javax.servlet.FilterRegistration.Dynamic; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.FilterRegistration.Dynamic; class MockFilterRegistration implements Dynamic { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/MockServletRegistration.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/MockServletRegistration.java index e696ae945e74..46be1eab5a4c 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/MockServletRegistration.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/MockServletRegistration.java @@ -22,9 +22,9 @@ import java.util.Map; import java.util.Set; -import javax.servlet.MultipartConfigElement; -import javax.servlet.ServletRegistration; -import javax.servlet.ServletSecurityElement; +import jakarta.servlet.MultipartConfigElement; +import jakarta.servlet.ServletRegistration; +import jakarta.servlet.ServletSecurityElement; class MockServletRegistration implements ServletRegistration.Dynamic { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/RequestDataValueProcessorWrapper.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/RequestDataValueProcessorWrapper.java index e64f832e4bc4..fec70f740893 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/RequestDataValueProcessorWrapper.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/RequestDataValueProcessorWrapper.java @@ -18,7 +18,7 @@ import java.util.Map; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; public class RequestDataValueProcessorWrapper implements RequestDataValueProcessor { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/ServletUriComponentsBuilderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/ServletUriComponentsBuilderTests.java index fa0c94566242..66b518a2e8e1 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/ServletUriComponentsBuilderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/ServletUriComponentsBuilderTests.java @@ -16,8 +16,7 @@ package org.springframework.web.servlet.support; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/ArgumentTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/ArgumentTagTests.java index af2c4795d5b4..35b5bd152f52 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/ArgumentTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/ArgumentTagTests.java @@ -16,11 +16,10 @@ package org.springframework.web.servlet.tags; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.Tag; -import javax.servlet.jsp.tagext.TagSupport; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.Tag; +import jakarta.servlet.jsp.tagext.TagSupport; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/BindTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/BindTagTests.java index 24a9942e3499..932c2dac82db 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/BindTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/BindTagTests.java @@ -23,10 +23,9 @@ import java.util.Date; import java.util.Set; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.propertyeditors.CustomDateEditor; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/EvalTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/EvalTagTests.java index e1657060bfd9..6af1562e568c 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/EvalTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/EvalTagTests.java @@ -21,8 +21,7 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/HtmlEscapeTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/HtmlEscapeTagTests.java index 7f8f57aa5f82..36ed82289bf4 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/HtmlEscapeTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/HtmlEscapeTagTests.java @@ -16,11 +16,10 @@ package org.springframework.web.servlet.tags; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.BodyTag; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.BodyTag; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.web.testfixture.servlet.MockServletContext; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/MessageTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/MessageTagTests.java index 03698a7c57fb..10feee616127 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/MessageTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/MessageTagTests.java @@ -19,12 +19,11 @@ import java.util.Arrays; import java.util.List; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.context.MessageSourceResolvable; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/ParamTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/ParamTagTests.java index 8ff108a6fb17..ea6f4e20cf6c 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/ParamTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/ParamTagTests.java @@ -16,11 +16,10 @@ package org.springframework.web.servlet.tags; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.Tag; -import javax.servlet.jsp.tagext.TagSupport; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.Tag; +import jakarta.servlet.jsp.tagext.TagSupport; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/ThemeTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/ThemeTagTests.java index 2704a5582716..f7311c4c17e6 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/ThemeTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/ThemeTagTests.java @@ -19,12 +19,11 @@ import java.util.Arrays; import java.util.List; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.context.MessageSourceResolvable; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/UrlTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/UrlTagTests.java index 1b84cd220408..faabcbc0857e 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/UrlTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/UrlTagTests.java @@ -21,10 +21,9 @@ import java.util.List; import java.util.Set; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/AbstractFormTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/AbstractFormTagTests.java index 50f254a42fba..75c418270bf2 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/AbstractFormTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/AbstractFormTagTests.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspException; import org.springframework.beans.testfixture.beans.TestBean; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/AbstractHtmlElementTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/AbstractHtmlElementTagTests.java index ee6f02fa693c..63cc5683921e 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/AbstractHtmlElementTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/AbstractHtmlElementTagTests.java @@ -21,9 +21,8 @@ import java.util.Collections; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.jsp.JspException; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.jsp.JspException; import org.junit.jupiter.api.BeforeEach; import org.springframework.validation.BindingResult; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/ButtonTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/ButtonTagTests.java index 02a4fe580040..98ca668dfa01 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/ButtonTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/ButtonTagTests.java @@ -18,8 +18,7 @@ import java.io.Writer; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.testfixture.beans.TestBean; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/CheckboxTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/CheckboxTagTests.java index 39e1bb710b9a..9b38741aa2e6 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/CheckboxTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/CheckboxTagTests.java @@ -25,9 +25,8 @@ import java.util.List; import java.util.Map; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.Tag; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/CheckboxesTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/CheckboxesTagTests.java index c7455c7f859d..170d1cf36e40 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/CheckboxesTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/CheckboxesTagTests.java @@ -29,9 +29,8 @@ import java.util.Map; import java.util.Set; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.Tag; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/ErrorsTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/ErrorsTagTests.java index e6c72fccce73..0ae564baf1ff 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/ErrorsTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/ErrorsTagTests.java @@ -20,12 +20,11 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.BodyTag; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.BodyTag; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.testfixture.beans.TestBean; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/FormTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/FormTagTests.java index 11fc024163cc..46c84f5d4b30 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/FormTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/FormTagTests.java @@ -18,9 +18,8 @@ import java.util.Collections; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.web.servlet.support.RequestDataValueProcessor; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/HiddenInputTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/HiddenInputTagTests.java index e323aff62bba..39a6cf13eeb9 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/HiddenInputTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/HiddenInputTagTests.java @@ -16,9 +16,8 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.testfixture.beans.TestBean; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/InputTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/InputTagTests.java index 59def204ee51..39da1b05c3f9 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/InputTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/InputTagTests.java @@ -18,9 +18,8 @@ import java.io.Writer; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.testfixture.beans.TestBean; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/LabelTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/LabelTagTests.java index 5f4ee4c83e0b..4f7c25d891b4 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/LabelTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/LabelTagTests.java @@ -16,9 +16,8 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.testfixture.beans.TestBean; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/OptionTagEnumTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/OptionTagEnumTests.java index d3783cf3e1fd..1b3fe831d7ae 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/OptionTagEnumTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/OptionTagEnumTests.java @@ -16,9 +16,8 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.tagext.BodyTag; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.tagext.BodyTag; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.testfixture.beans.CustomEnum; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/OptionTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/OptionTagTests.java index a94bee41a7d7..608a62595e10 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/OptionTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/OptionTagTests.java @@ -22,9 +22,8 @@ import java.util.ArrayList; import java.util.List; -import javax.servlet.jsp.tagext.BodyTag; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.tagext.BodyTag; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.propertyeditors.StringArrayPropertyEditor; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/OptionsTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/OptionsTagTests.java index 48479f6bebf9..a8e87811b901 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/OptionsTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/OptionsTagTests.java @@ -24,10 +24,9 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.jsp.tagext.BodyTag; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.jsp.tagext.BodyTag; +import jakarta.servlet.jsp.tagext.Tag; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/PasswordInputTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/PasswordInputTagTests.java index 2c2858648d5a..64c1484371c1 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/PasswordInputTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/PasswordInputTagTests.java @@ -18,9 +18,8 @@ import java.io.Writer; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/RadioButtonTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/RadioButtonTagTests.java index ac40da641332..d856021dfa53 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/RadioButtonTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/RadioButtonTagTests.java @@ -20,9 +20,8 @@ import java.io.StringReader; import java.util.Collections; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.Tag; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/RadioButtonsTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/RadioButtonsTagTests.java index 50bbf2c2ec63..49d2daf22297 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/RadioButtonsTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/RadioButtonsTagTests.java @@ -27,9 +27,8 @@ import java.util.Map; import java.util.Set; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.Tag; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/SelectTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/SelectTagTests.java index bade64bf142e..9fb65efea400 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/SelectTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/SelectTagTests.java @@ -29,9 +29,8 @@ import java.util.Map; import java.util.TreeMap; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.tagext.Tag; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/TagIdGeneratorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/TagIdGeneratorTests.java index 153b9df5760e..1f8b8037cd97 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/TagIdGeneratorTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/TagIdGeneratorTests.java @@ -18,8 +18,7 @@ import java.util.stream.IntStream; -import javax.servlet.jsp.PageContext; - +import jakarta.servlet.jsp.PageContext; import org.junit.jupiter.api.Test; import org.springframework.web.testfixture.servlet.MockPageContext; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/TextareaTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/TextareaTagTests.java index f5f06f49a0d7..cb08134dd721 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/TextareaTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/TextareaTagTests.java @@ -16,8 +16,7 @@ package org.springframework.web.servlet.tags.form; -import javax.servlet.jsp.tagext.Tag; - +import jakarta.servlet.jsp.tagext.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.testfixture.beans.TestBean; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/BaseViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/BaseViewTests.java index b7a8bec1336c..29c69d17568a 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/BaseViewTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/BaseViewTests.java @@ -21,10 +21,9 @@ import java.util.Map; import java.util.Properties; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContextException; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/DummyMacroRequestContext.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/DummyMacroRequestContext.java index cd2bc87d09f5..6f0c1cf8cdb9 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/DummyMacroRequestContext.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/DummyMacroRequestContext.java @@ -19,7 +19,7 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.web.servlet.support.BindStatus; import org.springframework.web.servlet.support.RequestContext; 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 d731b51c4df7..b1f492d0b08c 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 @@ -20,8 +20,7 @@ import java.util.HashMap; import java.util.Map; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.web.servlet.View; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ResourceBundleViewResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ResourceBundleViewResolverTests.java index 3e6efbb07e4d..8fc296bf057d 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ResourceBundleViewResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ResourceBundleViewResolverTests.java @@ -20,9 +20,8 @@ import java.util.Map; import java.util.MissingResourceException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ViewResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ViewResolverTests.java index 25c5a590c82c..4e5c93087a71 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ViewResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ViewResolverTests.java @@ -22,14 +22,13 @@ import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.jstl.core.Config; -import javax.servlet.jsp.jstl.fmt.LocalizationContext; - +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.jsp.jstl.core.Config; +import jakarta.servlet.jsp.jstl.fmt.LocalizationContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/document/XlsViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/document/XlsViewTests.java index 4f9d0aee5295..a7febf995d04 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/document/XlsViewTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/document/XlsViewTests.java @@ -20,9 +20,8 @@ import java.util.HashMap; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/feed/AtomFeedViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/feed/AtomFeedViewTests.java index 842d7e449de1..f6725f99f8b4 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/feed/AtomFeedViewTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/feed/AtomFeedViewTests.java @@ -21,12 +21,11 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import com.rometools.rome.feed.atom.Content; import com.rometools.rome.feed.atom.Entry; import com.rometools.rome.feed.atom.Feed; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.core.testfixture.xml.XmlContent; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/feed/RssFeedViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/feed/RssFeedViewTests.java index 5ab862e01717..7389774ccb28 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/feed/RssFeedViewTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/feed/RssFeedViewTests.java @@ -21,12 +21,11 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import com.rometools.rome.feed.rss.Channel; import com.rometools.rome.feed.rss.Description; import com.rometools.rome.feed.rss.Item; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.core.testfixture.xml.XmlContent; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/freemarker/FreeMarkerMacroTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/freemarker/FreeMarkerMacroTests.java index 6db737d433a4..e04675deb9ec 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/freemarker/FreeMarkerMacroTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/freemarker/FreeMarkerMacroTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,14 +21,13 @@ import java.util.HashMap; import java.util.Map; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; - import freemarker.template.Configuration; import freemarker.template.SimpleHash; import freemarker.template.Template; import freemarker.template.TemplateException; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -71,7 +70,7 @@ public class FreeMarkerMacroTests { @BeforeEach - public void setUp() throws Exception { + public void setup() throws Exception { ServletContext sc = new MockServletContext(); wac = new StaticWebApplicationContext(); wac.setServletContext(sc); @@ -79,7 +78,6 @@ public void setUp() throws Exception { // final Template expectedTemplate = new Template(); fc = new FreeMarkerConfigurer(); fc.setTemplateLoaderPaths("classpath:/", "file://" + System.getProperty("java.io.tmpdir")); - fc.setServletContext(sc); fc.afterPropertiesSet(); wac.getDefaultListableBeanFactory().registerSingleton("freeMarkerConfigurer", fc); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/freemarker/FreeMarkerViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/freemarker/FreeMarkerViewTests.java index d9fd65dce96b..779ae6c0c0e9 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/freemarker/FreeMarkerViewTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/freemarker/FreeMarkerViewTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,12 +24,11 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.http.HttpServletResponse; - -import freemarker.ext.servlet.AllHttpScopesHashModel; import freemarker.template.Configuration; +import freemarker.template.SimpleHash; import freemarker.template.Template; import freemarker.template.TemplateException; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContextException; @@ -92,7 +91,6 @@ public void validTemplateName() throws Exception { Map configs = new HashMap<>(); FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setConfiguration(new TestConfiguration()); - configurer.setServletContext(sc); configs.put("configurer", configurer); given(wac.getBeansOfType(FreeMarkerConfig.class, true, false)).willReturn(configs); given(wac.getServletContext()).willReturn(sc); @@ -123,7 +121,6 @@ public void keepExistingContentType() throws Exception { Map configs = new HashMap<>(); FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setConfiguration(new TestConfiguration()); - configurer.setServletContext(sc); configs.put("configurer", configurer); given(wac.getBeansOfType(FreeMarkerConfig.class, true, false)).willReturn(configs); given(wac.getServletContext()).willReturn(sc); @@ -151,7 +148,6 @@ public void freeMarkerViewResolver() throws Exception { FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setConfiguration(new TestConfiguration()); - configurer.setServletContext(sc); StaticWebApplicationContext wac = new StaticWebApplicationContext(); wac.setServletContext(sc); @@ -191,9 +187,8 @@ public Template getTemplate(String name, final Locale locale) throws IOException @Override public void process(Object model, Writer writer) throws TemplateException, IOException { assertThat(locale).isEqualTo(Locale.US); - boolean condition = model instanceof AllHttpScopesHashModel; - assertThat(condition).isTrue(); - AllHttpScopesHashModel fmModel = (AllHttpScopesHashModel) model; + assertThat(model instanceof SimpleHash).isTrue(); + SimpleHash fmModel = (SimpleHash) model; assertThat(fmModel.get("myattr").toString()).isEqualTo("myvalue"); } }; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/groovy/GroovyMarkupViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/groovy/GroovyMarkupViewTests.java index 95df6be1a9d4..4e588a5de037 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/groovy/GroovyMarkupViewTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/groovy/GroovyMarkupViewTests.java @@ -21,12 +21,11 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.ServletContext; - import groovy.text.Template; import groovy.text.TemplateEngine; import groovy.text.markup.MarkupTemplateEngine; import groovy.text.markup.TemplateConfiguration; +import jakarta.servlet.ServletContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/JRubyScriptTemplateTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/JRubyScriptTemplateTests.java index 0ff0cede97f7..46854fde9958 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/JRubyScriptTemplateTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/JRubyScriptTemplateTests.java @@ -19,8 +19,7 @@ import java.util.HashMap; import java.util.Map; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/JythonScriptTemplateTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/JythonScriptTemplateTests.java index 28777a89de90..468a5e66d6fb 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/JythonScriptTemplateTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/JythonScriptTemplateTests.java @@ -19,8 +19,7 @@ import java.util.HashMap; import java.util.Map; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/KotlinScriptTemplateTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/KotlinScriptTemplateTests.java index f6ef3ac7c21f..a977f0ef8b43 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/KotlinScriptTemplateTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/KotlinScriptTemplateTests.java @@ -20,8 +20,7 @@ import java.util.Locale; import java.util.Map; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/NashornScriptTemplateTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/NashornScriptTemplateTests.java index 72f56d47a902..e0ddf1813978 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/NashornScriptTemplateTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/NashornScriptTemplateTests.java @@ -19,8 +19,7 @@ import java.util.HashMap; import java.util.Map; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledForJreRange; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesConfigurerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesConfigurerTests.java deleted file mode 100644 index 68296951f8ae..000000000000 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesConfigurerTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.view.tiles3; - -import org.apache.tiles.access.TilesAccess; -import org.apache.tiles.impl.BasicTilesContainer; -import org.apache.tiles.request.ApplicationContext; -import org.apache.tiles.request.Request; -import org.apache.tiles.request.servlet.ServletRequest; -import org.apache.tiles.request.servlet.ServletUtil; -import org.junit.jupiter.api.Test; - -import org.springframework.context.annotation.Configuration; -import org.springframework.web.testfixture.servlet.MockHttpServletRequest; -import org.springframework.web.testfixture.servlet.MockHttpServletResponse; -import org.springframework.web.testfixture.servlet.MockServletContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Test fixture for {@link TilesConfigurer}. - * - * @author Nicolas Le Bas - */ -public class TilesConfigurerTests { - - @Test - public void simpleBootstrap() { - MockServletContext servletContext = new MockServletContext(); - - TilesConfigurer tc = new TilesConfigurer(); - tc.setDefinitions("/org/springframework/web/servlet/view/tiles3/tiles-definitions.xml"); - tc.setCheckRefresh(true); - tc.setServletContext(servletContext); - tc.afterPropertiesSet(); - - ApplicationContext tilesContext = ServletUtil.getApplicationContext(servletContext); - - BasicTilesContainer container = (BasicTilesContainer) TilesAccess.getContainer(tilesContext); - Request requestContext = new ServletRequest(container.getApplicationContext(), - new MockHttpServletRequest(), new MockHttpServletResponse()); - assertThat(container.getDefinitionsFactory().getDefinition("test", requestContext)).isNotNull(); - - tc.destroy(); - } - - - @Configuration - public static class AppConfig { - } - -} diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewResolverTests.java deleted file mode 100644 index 11515bc2215d..000000000000 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewResolverTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.web.servlet.view.tiles3; - -import java.util.Locale; - -import org.apache.tiles.request.Request; -import org.apache.tiles.request.render.Renderer; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.web.context.support.StaticWebApplicationContext; -import org.springframework.web.testfixture.servlet.MockServletContext; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * Test fixture for {@link TilesViewResolver}. - * - * @author mick semb wever - */ -public class TilesViewResolverTests { - - private TilesViewResolver viewResolver; - - private Renderer renderer; - - - @BeforeEach - public void setUp() { - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(new MockServletContext()); - wac.refresh(); - - this.renderer = mock(Renderer.class); - - this.viewResolver = new TilesViewResolver(); - this.viewResolver.setRenderer(this.renderer); - this.viewResolver.setApplicationContext(wac); - } - - @Test - public void testResolve() throws Exception { - given(this.renderer.isRenderable(eq("/template.test"), isA(Request.class))).willReturn(true); - given(this.renderer.isRenderable(eq("/nonexistent.test"), isA(Request.class))).willReturn(false); - - boolean condition = this.viewResolver.resolveViewName("/template.test", Locale.ITALY) instanceof TilesView; - assertThat(condition).isTrue(); - assertThat(this.viewResolver.resolveViewName("/nonexistent.test", Locale.ITALY)).isNull(); - - verify(this.renderer).isRenderable(eq("/template.test"), isA(Request.class)); - verify(this.renderer).isRenderable(eq("/nonexistent.test"), isA(Request.class)); - } -} diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewTests.java deleted file mode 100644 index 90cb4d6171d7..000000000000 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.web.servlet.view.tiles3; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.tiles.request.AbstractRequest; -import org.apache.tiles.request.Request; -import org.apache.tiles.request.render.Renderer; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.web.context.support.StaticWebApplicationContext; -import org.springframework.web.servlet.DispatcherServlet; -import org.springframework.web.testfixture.servlet.MockHttpServletRequest; -import org.springframework.web.testfixture.servlet.MockHttpServletResponse; -import org.springframework.web.testfixture.servlet.MockServletContext; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * Test fixture for {@link TilesView}. - * - * @author mick semb wever - * @author Sebastien Deleuze - */ -public class TilesViewTests { - - private static final String VIEW_PATH = "template.test"; - - private TilesView view; - - private Renderer renderer; - - private MockHttpServletRequest request; - - private MockHttpServletResponse response; - - - @BeforeEach - public void setUp() throws Exception { - MockServletContext servletContext = new MockServletContext(); - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(servletContext); - wac.refresh(); - - request = new MockHttpServletRequest(); - request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - - response = new MockHttpServletResponse(); - - renderer = mock(Renderer.class); - - view = new TilesView(); - view.setServletContext(servletContext); - view.setRenderer(renderer); - view.setUrl(VIEW_PATH); - view.afterPropertiesSet(); - } - - @Test - public void render() throws Exception { - Map model = new HashMap<>(); - model.put("modelAttribute", "modelValue"); - view.render(model, request, response); - assertThat(request.getAttribute("modelAttribute")).isEqualTo("modelValue"); - verify(renderer).render(eq(VIEW_PATH), isA(Request.class)); - } - - @Test - public void alwaysIncludeDefaults() throws Exception { - view.render(new HashMap<>(), request, response); - assertThat(request.getAttribute(AbstractRequest.FORCE_INCLUDE_ATTRIBUTE_NAME)).isNull(); - } - - @Test - public void alwaysIncludeEnabled() throws Exception { - view.setAlwaysInclude(true); - view.render(new HashMap<>(), request, response); - assertThat((boolean) (Boolean) request.getAttribute(AbstractRequest.FORCE_INCLUDE_ATTRIBUTE_NAME)).isTrue(); - } - -} diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/xml/MarshallingViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/xml/MarshallingViewTests.java index 8a03c1028ca7..ae596f28875d 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/xml/MarshallingViewTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/xml/MarshallingViewTests.java @@ -20,10 +20,10 @@ import java.util.LinkedHashMap; import java.util.Map; -import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import javax.xml.transform.stream.StreamResult; +import jakarta.xml.bind.JAXBElement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/test/resources/org/springframework/web/context/WEB-INF/empty-servlet.xml b/spring-webmvc/src/test/resources/org/springframework/web/context/WEB-INF/empty-servlet.xml index f431f55292b2..45380a25d34c 100644 --- a/spring-webmvc/src/test/resources/org/springframework/web/context/WEB-INF/empty-servlet.xml +++ b/spring-webmvc/src/test/resources/org/springframework/web/context/WEB-INF/empty-servlet.xml @@ -3,7 +3,7 @@ - + diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution-content-negotiation.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution-content-negotiation.xml index 7f8d0f86d32a..b633c802fb66 100644 --- a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution-content-negotiation.xml +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution-content-negotiation.xml @@ -21,16 +21,11 @@ - - - - - diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution.xml index 0bb48e815799..32f0c092a1c9 100644 --- a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution.xml +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution.xml @@ -8,7 +8,6 @@ - @@ -18,13 +17,6 @@ - - - - - diff --git a/spring-websocket/spring-websocket.gradle b/spring-websocket/spring-websocket.gradle index 4ffe0ef667bd..fe4f65250fff 100644 --- a/spring-websocket/spring-websocket.gradle +++ b/spring-websocket/spring-websocket.gradle @@ -6,20 +6,20 @@ dependencies { api(project(":spring-web")) optional(project(":spring-messaging")) optional(project(":spring-webmvc")) - optional("javax.servlet:javax.servlet-api") - optional("javax.websocket:javax.websocket-api") + optional("jakarta.servlet:jakarta.servlet-api") + optional("jakarta.websocket:jakarta.websocket-api") optional("org.apache.tomcat:tomcat-websocket") optional("org.glassfish.tyrus:tyrus-container-servlet") optional("org.eclipse.jetty:jetty-webapp") { - exclude group: "javax.servlet", module: "javax.servlet" + exclude group: "jakarta.servlet", module: "jakarta.servlet-api" } - optional("org.eclipse.jetty.websocket:websocket-server") { - exclude group: "javax.servlet", module: "javax.servlet" + optional("org.eclipse.jetty.websocket:websocket-jetty-server") { + exclude group: "jakarta.servlet", module: "jakarta.servlet-api" } - optional("org.eclipse.jetty.websocket:websocket-client") + optional("org.eclipse.jetty.websocket:websocket-jetty-client") optional("org.eclipse.jetty:jetty-client") - optional("io.undertow:undertow-servlet") - optional("io.undertow:undertow-websockets-jsr") + optional("io.undertow:undertow-servlet-jakartaee9") + optional("io.undertow:undertow-websockets-jsr-jakartaee9") optional("com.fasterxml.jackson.core:jackson-databind") testImplementation(testFixtures(project(":spring-core"))) testImplementation(testFixtures(project(":spring-web"))) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/Jetty10WebSocketHandlerAdapter.java b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/Jetty10WebSocketHandlerAdapter.java deleted file mode 100644 index c6a4c9f19cda..000000000000 --- a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/Jetty10WebSocketHandlerAdapter.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.socket.adapter.jetty; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; -import org.eclipse.jetty.websocket.api.extensions.Frame; - -import org.springframework.util.Assert; -import org.springframework.web.socket.BinaryMessage; -import org.springframework.web.socket.CloseStatus; -import org.springframework.web.socket.TextMessage; -import org.springframework.web.socket.WebSocketHandler; -import org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator; - -/** - * Identical to {@link JettyWebSocketHandlerAdapter}, only excluding the - * {@code onWebSocketFrame} method, since the {@link Frame} argument has moved - * to a different package in Jetty 10. - * - * @author Rossen Stoyanchev - * @since 5.3.4 - */ -@WebSocket -public class Jetty10WebSocketHandlerAdapter { - - private static final Log logger = LogFactory.getLog(Jetty10WebSocketHandlerAdapter.class); - - - private final WebSocketHandler webSocketHandler; - - private final JettyWebSocketSession wsSession; - - - public Jetty10WebSocketHandlerAdapter(WebSocketHandler webSocketHandler, JettyWebSocketSession wsSession) { - Assert.notNull(webSocketHandler, "WebSocketHandler must not be null"); - Assert.notNull(wsSession, "WebSocketSession must not be null"); - this.webSocketHandler = webSocketHandler; - this.wsSession = wsSession; - } - - - @OnWebSocketConnect - public void onWebSocketConnect(Session session) { - try { - this.wsSession.initializeNativeSession(session); - this.webSocketHandler.afterConnectionEstablished(this.wsSession); - } - catch (Exception ex) { - ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger); - } - } - - @OnWebSocketMessage - public void onWebSocketText(String payload) { - TextMessage message = new TextMessage(payload); - try { - this.webSocketHandler.handleMessage(this.wsSession, message); - } - catch (Exception ex) { - ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger); - } - } - - @OnWebSocketMessage - public void onWebSocketBinary(byte[] payload, int offset, int length) { - BinaryMessage message = new BinaryMessage(payload, offset, length, true); - try { - this.webSocketHandler.handleMessage(this.wsSession, message); - } - catch (Exception ex) { - ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger); - } - } - -// TODO: onWebSocketFrame can't be declared without compiling against Jetty 10 -// Jetty 10: org.eclipse.jetty.websocket.api.Frame -// Jetty 9: org.eclipse.jetty.websocket.api.extensions.Frame - -// @OnWebSocketFrame -// public void onWebSocketFrame(Frame frame) { -// if (OpCode.PONG == frame.getOpCode()) { -// ByteBuffer payload = frame.getPayload() != null ? frame.getPayload() : EMPTY_PAYLOAD; -// PongMessage message = new PongMessage(payload); -// try { -// this.webSocketHandler.handleMessage(this.wsSession, message); -// } -// catch (Exception ex) { -// ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger); -// } -// } -// } - - @OnWebSocketClose - public void onWebSocketClose(int statusCode, String reason) { - CloseStatus closeStatus = new CloseStatus(statusCode, reason); - try { - this.webSocketHandler.afterConnectionClosed(this.wsSession, closeStatus); - } - catch (Exception ex) { - if (logger.isWarnEnabled()) { - logger.warn("Unhandled exception after connection closed for " + this, ex); - } - } - } - - @OnWebSocketError - public void onWebSocketError(Throwable cause) { - try { - this.webSocketHandler.handleTransportError(this.wsSession, cause); - } - catch (Exception ex) { - ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger); - } - } - -} diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketHandlerAdapter.java b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketHandlerAdapter.java index 0c414a6b11eb..47b821cd53b2 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketHandlerAdapter.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketHandlerAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.eclipse.jetty.websocket.api.Frame; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; @@ -27,8 +28,7 @@ import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; -import org.eclipse.jetty.websocket.api.extensions.Frame; -import org.eclipse.jetty.websocket.common.OpCode; +import org.eclipse.jetty.websocket.core.OpCode; import org.springframework.util.Assert; import org.springframework.web.socket.BinaryMessage; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketSession.java b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketSession.java index 48b87417bbff..37a22a36eaa2 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketSession.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketSession.java @@ -17,9 +17,7 @@ package org.springframework.web.socket.adapter.jetty; import java.io.IOException; -import java.lang.reflect.Method; import java.net.InetSocketAddress; -import java.net.SocketAddress; import java.net.URI; import java.security.Principal; import java.util.ArrayList; @@ -27,16 +25,14 @@ import java.util.List; import java.util.Map; +import org.eclipse.jetty.websocket.api.ExtensionConfig; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; -import org.springframework.util.ReflectionUtils; import org.springframework.web.socket.BinaryMessage; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.PingMessage; @@ -57,12 +53,6 @@ */ public class JettyWebSocketSession extends AbstractWebSocketSession { - private static final ClassLoader loader = JettyWebSocketSession.class.getClassLoader(); - - private static final boolean jetty10Present = ClassUtils.isPresent( - "org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer", loader); - - private final String id; @Nullable @@ -80,8 +70,6 @@ public class JettyWebSocketSession extends AbstractWebSocketSession { @Nullable private Principal user; - private final SessionHelper sessionHelper; - /** * Create a new {@link JettyWebSocketSession} instance. @@ -102,7 +90,6 @@ public JettyWebSocketSession(Map attributes, @Nullable Principal super(attributes); this.id = idGenerator.generateId().toString(); this.user = user; - this.sessionHelper = (jetty10Present ? new Jetty10SessionHelper() : new Jetty9SessionHelper()); } @@ -144,13 +131,13 @@ public Principal getPrincipal() { @Override public InetSocketAddress getLocalAddress() { checkNativeSessionInitialized(); - return this.sessionHelper.getLocalAddress(getNativeSession()); + return (InetSocketAddress) getNativeSession().getLocalAddress(); } @Override public InetSocketAddress getRemoteAddress() { checkNativeSessionInitialized(); - return this.sessionHelper.getRemoteAddress(getNativeSession()); + return (InetSocketAddress) getNativeSession().getRemoteAddress(); } /** @@ -164,7 +151,7 @@ public void setTextMessageSizeLimit(int messageSizeLimit) { @Override public int getTextMessageSizeLimit() { checkNativeSessionInitialized(); - return this.sessionHelper.getTextMessageSizeLimit(getNativeSession()); + return (int) getNativeSession().getMaxTextMessageSize(); } /** @@ -178,7 +165,7 @@ public void setBinaryMessageSizeLimit(int messageSizeLimit) { @Override public int getBinaryMessageSizeLimit() { checkNativeSessionInitialized(); - return this.sessionHelper.getBinaryMessageSizeLimit(getNativeSession()); + return (int) getNativeSession().getMaxBinaryMessageSize(); } @Override @@ -201,13 +188,25 @@ public void initializeNativeSession(Session session) { this.headers = HttpHeaders.readOnlyHttpHeaders(headers); this.acceptedProtocol = session.getUpgradeResponse().getAcceptedSubProtocol(); - this.extensions = this.sessionHelper.getExtensions(session); + this.extensions = getExtensions(session); if (this.user == null) { this.user = session.getUpgradeRequest().getUserPrincipal(); } } + private List getExtensions(Session session) { + List configs = session.getUpgradeResponse().getExtensions(); + if (!CollectionUtils.isEmpty(configs)) { + List result = new ArrayList<>(configs.size()); + for (ExtensionConfig config : configs) { + result.add(new WebSocketExtension(config.getName(), config.getParameters())); + } + return Collections.unmodifiableList(result); + } + return Collections.emptyList(); + } + @Override protected void sendTextMessage(TextMessage message) throws IOException { @@ -238,127 +237,4 @@ protected void closeInternal(CloseStatus status) throws IOException { getNativeSession().close(status.getCode(), status.getReason()); } - - /** - * Encapsulate incompatible changes between Jetty 9.4 and 10. - */ - private interface SessionHelper { - - List getExtensions(Session session); - - int getTextMessageSizeLimit(Session session); - - int getBinaryMessageSizeLimit(Session session); - - InetSocketAddress getRemoteAddress(Session session); - - InetSocketAddress getLocalAddress(Session session); - - } - - - private static class Jetty9SessionHelper implements SessionHelper { - - @Override - public List getExtensions(Session session) { - List configs = session.getUpgradeResponse().getExtensions(); - if (!CollectionUtils.isEmpty(configs)) { - List result = new ArrayList<>(configs.size()); - for (ExtensionConfig config : configs) { - result.add(new WebSocketExtension(config.getName(), config.getParameters())); - } - return Collections.unmodifiableList(result); - } - return Collections.emptyList(); - } - - @Override - public int getTextMessageSizeLimit(Session session) { - return session.getPolicy().getMaxTextMessageSize(); - } - - @Override - public int getBinaryMessageSizeLimit(Session session) { - return session.getPolicy().getMaxBinaryMessageSize(); - } - - @Override - public InetSocketAddress getRemoteAddress(Session session) { - return session.getRemoteAddress(); - } - - @Override - public InetSocketAddress getLocalAddress(Session session) { - return session.getLocalAddress(); - } - } - - - private static class Jetty10SessionHelper implements SessionHelper { - - private static final Method getTextMessageSizeLimitMethod; - - private static final Method getBinaryMessageSizeLimitMethod; - - private static final Method getRemoteAddressMethod; - - private static final Method getLocalAddressMethod; - - static { - try { - Class type = loader.loadClass("org.eclipse.jetty.websocket.api.Session"); - getTextMessageSizeLimitMethod = type.getMethod("getMaxTextMessageSize"); - getBinaryMessageSizeLimitMethod = type.getMethod("getMaxBinaryMessageSize"); - getRemoteAddressMethod = type.getMethod("getRemoteAddress"); - getLocalAddressMethod = type.getMethod("getLocalAddress"); - } - catch (ClassNotFoundException | NoSuchMethodException ex) { - throw new IllegalStateException("No compatible Jetty version found", ex); - } - } - - // TODO: Extension info can't be accessed without compiling against Jetty 10 - // Jetty 10: org.eclipse.jetty.websocket.api.ExtensionConfig - // Jetty 9: org.eclipse.jetty.websocket.api.extensions.ExtensionConfig - - @Override - public List getExtensions(Session session) { - return Collections.emptyList(); - } - - // TODO: WebSocketPolicy can't be accessed without compiling against Jetty 10 (class -> interface) - - @Override - @SuppressWarnings("ConstantConditions") - public int getTextMessageSizeLimit(Session session) { - long result = (long) ReflectionUtils.invokeMethod(getTextMessageSizeLimitMethod, session.getPolicy()); - Assert.state(result <= Integer.MAX_VALUE, "textMessageSizeLimit is larger than Integer.MAX_VALUE"); - return (int) result; - } - - @Override - @SuppressWarnings("ConstantConditions") - public int getBinaryMessageSizeLimit(Session session) { - long result = (long) ReflectionUtils.invokeMethod(getBinaryMessageSizeLimitMethod, session.getPolicy()); - Assert.state(result <= Integer.MAX_VALUE, "binaryMessageSizeLimit is larger than Integer.MAX_VALUE"); - return (int) result; - } - - @Override - @SuppressWarnings("ConstantConditions") - public InetSocketAddress getRemoteAddress(Session session) { - SocketAddress address = (SocketAddress) ReflectionUtils.invokeMethod(getRemoteAddressMethod, session); - Assert.isInstanceOf(InetSocketAddress.class, address); - return (InetSocketAddress) address; - } - - @Override - @SuppressWarnings("ConstantConditions") - public InetSocketAddress getLocalAddress(Session session) { - SocketAddress address = (SocketAddress) ReflectionUtils.invokeMethod(getLocalAddressMethod, session); - Assert.isInstanceOf(InetSocketAddress.class, address); - return (InetSocketAddress) address; - } - } - } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/WebSocketToJettyExtensionConfigAdapter.java b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/WebSocketToJettyExtensionConfigAdapter.java index 1adc61cc4d6c..b941c267122f 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/WebSocketToJettyExtensionConfigAdapter.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/WebSocketToJettyExtensionConfigAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,8 @@ package org.springframework.web.socket.adapter.jetty; -import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; +import org.eclipse.jetty.websocket.api.ExtensionConfig; +import org.eclipse.jetty.websocket.common.JettyExtensionConfig; import org.springframework.web.socket.WebSocketExtension; @@ -27,7 +28,7 @@ * @author Rossen Stoyanchev * @since 4.0 */ -public class WebSocketToJettyExtensionConfigAdapter extends ExtensionConfig { +public class WebSocketToJettyExtensionConfigAdapter extends JettyExtensionConfig { public WebSocketToJettyExtensionConfigAdapter(WebSocketExtension extension) { super(extension.getName()); diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/ConvertingEncoderDecoderSupport.java b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/ConvertingEncoderDecoderSupport.java index 05e1a4b75c0d..489891d11a5f 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/ConvertingEncoderDecoderSupport.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/ConvertingEncoderDecoderSupport.java @@ -18,11 +18,11 @@ import java.nio.ByteBuffer; -import javax.websocket.DecodeException; -import javax.websocket.Decoder; -import javax.websocket.EncodeException; -import javax.websocket.Encoder; -import javax.websocket.EndpointConfig; +import jakarta.websocket.DecodeException; +import jakarta.websocket.Decoder; +import jakarta.websocket.EncodeException; +import jakarta.websocket.Encoder; +import jakarta.websocket.EndpointConfig; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; @@ -38,8 +38,8 @@ import org.springframework.web.context.ContextLoader; /** - * Base class that can be used to implement a standard {@link javax.websocket.Encoder} - * and/or {@link javax.websocket.Decoder}. It provides encode and decode method + * Base class that can be used to implement a standard {@link jakarta.websocket.Encoder} + * and/or {@link jakarta.websocket.Decoder}. It provides encode and decode method * implementations that delegate to a Spring {@link ConversionService}. * *

    By default, this class looks up a {@link ConversionService} registered in the @@ -50,7 +50,7 @@ * {@link #getConversionService()} method to provide an alternative lookup strategy. * *

    Subclasses can extend this class and should also implement one or - * both of {@link javax.websocket.Encoder} and {@link javax.websocket.Decoder}. + * both of {@link jakarta.websocket.Encoder} and {@link jakarta.websocket.Decoder}. * For convenience {@link ConvertingEncoderDecoderSupport.BinaryEncoder}, * {@link ConvertingEncoderDecoderSupport.BinaryDecoder}, * {@link ConvertingEncoderDecoderSupport.TextEncoder} and @@ -80,8 +80,8 @@ public abstract class ConvertingEncoderDecoderSupport { /** * Called to initialize the encoder/decoder. - * @see javax.websocket.Encoder#init(EndpointConfig) - * @see javax.websocket.Decoder#init(EndpointConfig) + * @see jakarta.websocket.Encoder#init(EndpointConfig) + * @see jakarta.websocket.Decoder#init(EndpointConfig) */ public void init(EndpointConfig config) { ApplicationContext applicationContext = getApplicationContext(); @@ -94,8 +94,8 @@ public void init(EndpointConfig config) { /** * Called to destroy the encoder/decoder. - * @see javax.websocket.Encoder#destroy() - * @see javax.websocket.Decoder#destroy() + * @see jakarta.websocket.Encoder#destroy() + * @see jakarta.websocket.Decoder#destroy() */ public void destroy() { } @@ -158,8 +158,8 @@ private Class[] resolveTypeArguments() { /** * Encode an object to a message. - * @see javax.websocket.Encoder.Text#encode(Object) - * @see javax.websocket.Encoder.Binary#encode(Object) + * @see jakarta.websocket.Encoder.Text#encode(Object) + * @see jakarta.websocket.Encoder.Binary#encode(Object) */ @SuppressWarnings("unchecked") @Nullable @@ -175,8 +175,8 @@ public M encode(T object) throws EncodeException { /** * Determine if a given message can be decoded. * @see #decode(Object) - * @see javax.websocket.Decoder.Text#willDecode(String) - * @see javax.websocket.Decoder.Binary#willDecode(ByteBuffer) + * @see jakarta.websocket.Decoder.Text#willDecode(String) + * @see jakarta.websocket.Decoder.Binary#willDecode(ByteBuffer) */ public boolean willDecode(M bytes) { return getConversionService().canConvert(getType(), getMessageType()); @@ -184,8 +184,8 @@ public boolean willDecode(M bytes) { /** * Decode the message into an object. - * @see javax.websocket.Decoder.Text#decode(String) - * @see javax.websocket.Decoder.Binary#decode(ByteBuffer) + * @see jakarta.websocket.Decoder.Text#decode(String) + * @see jakarta.websocket.Decoder.Binary#decode(ByteBuffer) */ @SuppressWarnings("unchecked") @Nullable @@ -208,7 +208,7 @@ public T decode(M message) throws DecodeException { /** - * A binary {@link javax.websocket.Encoder.Binary javax.websocket.Encoder} that delegates + * A binary {@link jakarta.websocket.Encoder.Binary jakarta.websocket.Encoder} that delegates * to Spring's conversion service. See {@link ConvertingEncoderDecoderSupport} for details. * @param the type that this Encoder can convert to */ @@ -218,7 +218,7 @@ public abstract static class BinaryEncoder extends ConvertingEncoderDecoderSu /** - * A binary {@link javax.websocket.Encoder.Binary javax.websocket.Encoder} that delegates + * A binary {@link jakarta.websocket.Encoder.Binary jakarta.websocket.Encoder} that delegates * to Spring's conversion service. See {@link ConvertingEncoderDecoderSupport} for details. * @param the type that this Decoder can convert from */ @@ -228,7 +228,7 @@ public abstract static class BinaryDecoder extends ConvertingEncoderDecoderSu /** - * A text {@link javax.websocket.Encoder.Text javax.websocket.Encoder} that delegates + * A text {@link jakarta.websocket.Encoder.Text jakarta.websocket.Encoder} that delegates * to Spring's conversion service. See {@link ConvertingEncoderDecoderSupport} for * details. * @param the type that this Encoder can convert to @@ -239,7 +239,7 @@ public abstract static class TextEncoder extends ConvertingEncoderDecoderSupp /** - * A Text {@link javax.websocket.Encoder.Text javax.websocket.Encoder} that delegates + * A Text {@link jakarta.websocket.Encoder.Text jakarta.websocket.Encoder} that delegates * to Spring's conversion service. See {@link ConvertingEncoderDecoderSupport} for details. * @param the type that this Decoder can convert from */ diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardToWebSocketExtensionAdapter.java b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardToWebSocketExtensionAdapter.java index d2908e6aff87..8f81d48bd680 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardToWebSocketExtensionAdapter.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardToWebSocketExtensionAdapter.java @@ -20,14 +20,14 @@ import java.util.Locale; import java.util.Map; -import javax.websocket.Extension; +import jakarta.websocket.Extension; import org.springframework.util.LinkedCaseInsensitiveMap; import org.springframework.web.socket.WebSocketExtension; /** * A sub-class of {@link org.springframework.web.socket.WebSocketExtension} that - * can be constructed from an {@link javax.websocket.Extension}. + * can be constructed from an {@link jakarta.websocket.Extension}. * * @author Rossen Stoyanchev * @since 4.0 diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketHandlerAdapter.java b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketHandlerAdapter.java index 2cdea2d1a041..27a794caa886 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketHandlerAdapter.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketHandlerAdapter.java @@ -18,11 +18,10 @@ import java.nio.ByteBuffer; -import javax.websocket.CloseReason; -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.MessageHandler; - +import jakarta.websocket.CloseReason; +import jakarta.websocket.Endpoint; +import jakarta.websocket.EndpointConfig; +import jakarta.websocket.MessageHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -58,7 +57,7 @@ public StandardWebSocketHandlerAdapter(WebSocketHandler handler, StandardWebSock @Override - public void onOpen(final javax.websocket.Session session, EndpointConfig config) { + public void onOpen(final jakarta.websocket.Session session, EndpointConfig config) { this.wsSession.initializeNativeSession(session); // The following inner classes need to remain since lambdas would not retain their @@ -93,9 +92,9 @@ public void onMessage(ByteBuffer message) { }); } - session.addMessageHandler(new MessageHandler.Whole() { + session.addMessageHandler(new MessageHandler.Whole() { @Override - public void onMessage(javax.websocket.PongMessage message) { + public void onMessage(jakarta.websocket.PongMessage message) { handlePongMessage(session, message.getApplicationData()); } }); @@ -108,7 +107,7 @@ public void onMessage(javax.websocket.PongMessage message) { } } - private void handleTextMessage(javax.websocket.Session session, String payload, boolean isLast) { + private void handleTextMessage(jakarta.websocket.Session session, String payload, boolean isLast) { TextMessage textMessage = new TextMessage(payload, isLast); try { this.handler.handleMessage(this.wsSession, textMessage); @@ -118,7 +117,7 @@ private void handleTextMessage(javax.websocket.Session session, String payload, } } - private void handleBinaryMessage(javax.websocket.Session session, ByteBuffer payload, boolean isLast) { + private void handleBinaryMessage(jakarta.websocket.Session session, ByteBuffer payload, boolean isLast) { BinaryMessage binaryMessage = new BinaryMessage(payload, isLast); try { this.handler.handleMessage(this.wsSession, binaryMessage); @@ -128,7 +127,7 @@ private void handleBinaryMessage(javax.websocket.Session session, ByteBuffer pay } } - private void handlePongMessage(javax.websocket.Session session, ByteBuffer payload) { + private void handlePongMessage(jakarta.websocket.Session session, ByteBuffer payload) { PongMessage pongMessage = new PongMessage(payload); try { this.handler.handleMessage(this.wsSession, pongMessage); @@ -139,7 +138,7 @@ private void handlePongMessage(javax.websocket.Session session, ByteBuffer paylo } @Override - public void onClose(javax.websocket.Session session, CloseReason reason) { + public void onClose(jakarta.websocket.Session session, CloseReason reason) { CloseStatus closeStatus = new CloseStatus(reason.getCloseCode().getCode(), reason.getReasonPhrase()); try { this.handler.afterConnectionClosed(this.wsSession, closeStatus); @@ -152,7 +151,7 @@ public void onClose(javax.websocket.Session session, CloseReason reason) { } @Override - public void onError(javax.websocket.Session session, Throwable exception) { + public void onError(jakarta.websocket.Session session, Throwable exception) { try { this.handler.handleTransportError(this.wsSession, exception); } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketSession.java b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketSession.java index d1a0672b956f..0252927f45ed 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketSession.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketSession.java @@ -25,10 +25,10 @@ import java.util.List; import java.util.Map; -import javax.websocket.CloseReason; -import javax.websocket.CloseReason.CloseCodes; -import javax.websocket.Extension; -import javax.websocket.Session; +import jakarta.websocket.CloseReason; +import jakarta.websocket.CloseReason.CloseCodes; +import jakarta.websocket.Extension; +import jakarta.websocket.Session; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/WebSocketToStandardExtensionAdapter.java b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/WebSocketToStandardExtensionAdapter.java index d9d78897c601..c3bc04b974bd 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/WebSocketToStandardExtensionAdapter.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/WebSocketToStandardExtensionAdapter.java @@ -19,13 +19,13 @@ import java.util.ArrayList; import java.util.List; -import javax.websocket.Extension; +import jakarta.websocket.Extension; import org.springframework.web.socket.WebSocketExtension; /** * Adapt an instance of {@link org.springframework.web.socket.WebSocketExtension} to - * the {@link javax.websocket.Extension} interface. + * the {@link jakarta.websocket.Extension} interface. * * @author Rossen Stoyanchev * @since 4.0 diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/client/jetty/JettyWebSocketClient.java b/spring-websocket/src/main/java/org/springframework/web/socket/client/jetty/JettyWebSocketClient.java index 982bbfa61e44..b70b3f22afba 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/client/jetty/JettyWebSocketClient.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/client/jetty/JettyWebSocketClient.java @@ -16,8 +16,6 @@ package org.springframework.web.socket.client.jetty; -import java.io.IOException; -import java.lang.reflect.Method; import java.net.URI; import java.security.Principal; import java.util.List; @@ -36,14 +34,11 @@ import org.springframework.core.task.TaskExecutor; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFutureTask; import org.springframework.web.socket.WebSocketExtension; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketSession; -import org.springframework.web.socket.adapter.jetty.Jetty10WebSocketHandlerAdapter; import org.springframework.web.socket.adapter.jetty.JettyWebSocketHandlerAdapter; import org.springframework.web.socket.adapter.jetty.JettyWebSocketSession; import org.springframework.web.socket.adapter.jetty.WebSocketToJettyExtensionConfigAdapter; @@ -61,36 +56,16 @@ * WebSocketConnectionManager} instead to auto-start a WebSocket connection. * * @author Rossen Stoyanchev + * @author Juergen Hoeller * @since 4.0 */ public class JettyWebSocketClient extends AbstractWebSocketClient implements Lifecycle { - private static ClassLoader loader = JettyWebSocketClient.class.getClassLoader(); - - private static final boolean jetty10Present; - - private static final Method setHeadersMethod; - - static { - jetty10Present = ClassUtils.isPresent( - "org.eclipse.jetty.websocket.client.JettyUpgradeListener", loader); - try { - setHeadersMethod = ClientUpgradeRequest.class.getMethod("setHeaders", Map.class); - } - catch (NoSuchMethodException ex) { - throw new IllegalStateException("No compatible Jetty version found", ex); - } - } - - private final org.eclipse.jetty.websocket.client.WebSocketClient client; @Nullable private AsyncListenableTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(); - private final UpgradeHelper upgradeHelper = - (jetty10Present ? new Jetty10UpgradeHelper() : new Jetty9UpgradeHelper()); - /** * Default constructor that creates an instance of @@ -170,19 +145,18 @@ public ListenableFuture doHandshakeInternal(WebSocketHandler w final ClientUpgradeRequest request = new ClientUpgradeRequest(); request.setSubProtocols(protocols); - for (WebSocketExtension e : extensions) { - request.addExtensions(new WebSocketToJettyExtensionConfigAdapter(e)); + for (WebSocketExtension extension : extensions) { + request.addExtensions(new WebSocketToJettyExtensionConfigAdapter(extension)); } - // Jetty 9: setHeaders declared in UpgradeRequestAdapter base class - // Jetty 10: setHeaders declared in ClientUpgradeRequest - ReflectionUtils.invokeMethod(setHeadersMethod, request, headers); + request.setHeaders(headers); Principal user = getUser(); JettyWebSocketSession wsSession = new JettyWebSocketSession(attributes, user); Callable connectTask = () -> { - Future future = this.upgradeHelper.connect(this.client, uri, request, wsHandler, wsSession); + JettyWebSocketHandlerAdapter adapter = new JettyWebSocketHandlerAdapter(wsHandler, wsSession); + Future future = this.client.connect(adapter, uri, request); future.get(this.client.getConnectTimeout() + 2000, TimeUnit.MILLISECONDS); return wsSession; }; @@ -206,55 +180,4 @@ protected Principal getUser() { return null; } - - /** - * Encapsulate incompatible changes between Jetty 9.4 and 10. - */ - private interface UpgradeHelper { - - Future connect(WebSocketClient client, URI url, ClientUpgradeRequest request, - WebSocketHandler handler, JettyWebSocketSession session) throws IOException; - } - - - private static class Jetty9UpgradeHelper implements UpgradeHelper { - - @Override - public Future connect(WebSocketClient client, URI url, ClientUpgradeRequest request, - WebSocketHandler handler, JettyWebSocketSession session) throws IOException { - - JettyWebSocketHandlerAdapter adapter = new JettyWebSocketHandlerAdapter(handler, session); - return client.connect(adapter, url, request); - } - } - - - private static class Jetty10UpgradeHelper implements UpgradeHelper { - - // On Jetty 9 returns Future, on Jetty 10 returns CompletableFuture - private static final Method connectMethod; - - static { - try { - Class type = loader.loadClass("org.eclipse.jetty.websocket.client.WebSocketClient"); - connectMethod = type.getMethod("connect", Object.class, URI.class, ClientUpgradeRequest.class); - } - catch (ClassNotFoundException | NoSuchMethodException ex) { - throw new IllegalStateException("No compatible Jetty version found", ex); - } - } - - @Override - @SuppressWarnings({"ConstantConditions", "unchecked"}) - public Future connect(WebSocketClient client, URI url, ClientUpgradeRequest request, - WebSocketHandler handler, JettyWebSocketSession session) { - - Jetty10WebSocketHandlerAdapter adapter = new Jetty10WebSocketHandlerAdapter(handler, session); - - // TODO: pass JettyUpgradeListener argument to set headers from HttpHeaders (like we do for Jetty 9) - // which would require a JDK Proxy since it is new in Jetty 10 - return (Future) ReflectionUtils.invokeMethod(connectMethod, client, adapter, url, request); - } - } - } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/AnnotatedEndpointConnectionManager.java b/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/AnnotatedEndpointConnectionManager.java index fcb568e49040..7347791e1ade 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/AnnotatedEndpointConnectionManager.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/AnnotatedEndpointConnectionManager.java @@ -16,9 +16,9 @@ package org.springframework.web.socket.client.standard; -import javax.websocket.ContainerProvider; -import javax.websocket.Session; -import javax.websocket.WebSocketContainer; +import jakarta.websocket.ContainerProvider; +import jakarta.websocket.Session; +import jakarta.websocket.WebSocketContainer; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; @@ -32,7 +32,7 @@ /** * A WebSocket connection manager that is given a URI, a - * {@link javax.websocket.ClientEndpoint}-annotated endpoint, connects to a + * {@link jakarta.websocket.ClientEndpoint}-annotated endpoint, connects to a * WebSocket server through the {@link #start()} and {@link #stop()} methods. * If {@link #setAutoStartup(boolean)} is set to {@code true} this will be * done automatically when the Spring ApplicationContext is refreshed. diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/EndpointConnectionManager.java b/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/EndpointConnectionManager.java index 1fa1ed777c42..c58fb951e971 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/EndpointConnectionManager.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/EndpointConnectionManager.java @@ -19,15 +19,15 @@ import java.util.Arrays; import java.util.List; -import javax.websocket.ClientEndpointConfig; -import javax.websocket.ClientEndpointConfig.Configurator; -import javax.websocket.ContainerProvider; -import javax.websocket.Decoder; -import javax.websocket.Encoder; -import javax.websocket.Endpoint; -import javax.websocket.Extension; -import javax.websocket.Session; -import javax.websocket.WebSocketContainer; +import jakarta.websocket.ClientEndpointConfig; +import jakarta.websocket.ClientEndpointConfig.Configurator; +import jakarta.websocket.ContainerProvider; +import jakarta.websocket.Decoder; +import jakarta.websocket.Encoder; +import jakarta.websocket.Endpoint; +import jakarta.websocket.Extension; +import jakarta.websocket.Session; +import jakarta.websocket.WebSocketContainer; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/StandardWebSocketClient.java b/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/StandardWebSocketClient.java index e942cb839240..3661300815f3 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/StandardWebSocketClient.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/StandardWebSocketClient.java @@ -27,13 +27,13 @@ import java.util.Map; import java.util.concurrent.Callable; -import javax.websocket.ClientEndpointConfig; -import javax.websocket.ClientEndpointConfig.Configurator; -import javax.websocket.ContainerProvider; -import javax.websocket.Endpoint; -import javax.websocket.Extension; -import javax.websocket.HandshakeResponse; -import javax.websocket.WebSocketContainer; +import jakarta.websocket.ClientEndpointConfig; +import jakarta.websocket.ClientEndpointConfig.Configurator; +import jakarta.websocket.ContainerProvider; +import jakarta.websocket.Endpoint; +import jakarta.websocket.Extension; +import jakarta.websocket.HandshakeResponse; +import jakarta.websocket.WebSocketContainer; import org.springframework.core.task.AsyncListenableTaskExecutor; import org.springframework.core.task.SimpleAsyncTaskExecutor; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/WebSocketContainerFactoryBean.java b/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/WebSocketContainerFactoryBean.java index 8c8591b2e0d8..66bb8ade6315 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/WebSocketContainerFactoryBean.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/WebSocketContainerFactoryBean.java @@ -16,13 +16,13 @@ package org.springframework.web.socket.client.standard; -import javax.websocket.ContainerProvider; -import javax.websocket.WebSocketContainer; +import jakarta.websocket.ContainerProvider; +import jakarta.websocket.WebSocketContainer; import org.springframework.beans.factory.FactoryBean; /** - * A FactoryBean for creating and configuring a {@link javax.websocket.WebSocketContainer} + * A FactoryBean for creating and configuring a {@link jakarta.websocket.WebSocketContainer} * through Spring XML configuration. In Java configuration, ignore this class and use * {@code ContainerProvider.getWebSocketContainer()} instead. * diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java index a0828f3f37bc..1c9fd553eef3 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java @@ -127,8 +127,8 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader); gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader); - jsonbPresent = ClassUtils.isPresent("javax.json.bind.Jsonb", classLoader); - javaxValidationPresent = ClassUtils.isPresent("javax.validation.Validator", classLoader); + jsonbPresent = ClassUtils.isPresent("jakarta.json.bind.Jsonb", classLoader); + javaxValidationPresent = ClassUtils.isPresent("jakarta.validation.Validator", classLoader); } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/Jetty10RequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/Jetty10RequestUpgradeStrategy.java deleted file mode 100644 index 1ba175654779..000000000000 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/Jetty10RequestUpgradeStrategy.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.socket.server.jetty; - -import java.lang.reflect.Method; -import java.lang.reflect.UndeclaredThrowableException; -import java.security.Principal; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.target.EmptyTargetSource; -import org.springframework.http.server.ServerHttpRequest; -import org.springframework.http.server.ServerHttpResponse; -import org.springframework.http.server.ServletServerHttpRequest; -import org.springframework.http.server.ServletServerHttpResponse; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.socket.WebSocketExtension; -import org.springframework.web.socket.WebSocketHandler; -import org.springframework.web.socket.adapter.jetty.Jetty10WebSocketHandlerAdapter; -import org.springframework.web.socket.adapter.jetty.JettyWebSocketSession; -import org.springframework.web.socket.server.HandshakeFailureException; -import org.springframework.web.socket.server.RequestUpgradeStrategy; - -/** - * A {@link RequestUpgradeStrategy} for Jetty 10. - * - * @author Rossen Stoyanchev - * @since 5.3.4 - */ -public class Jetty10RequestUpgradeStrategy implements RequestUpgradeStrategy { - - private static final String[] SUPPORTED_VERSIONS = new String[] { String.valueOf(13) }; - - private static final Class webSocketCreatorClass; - - private static final Method getContainerMethod; - - private static final Method upgradeMethod; - - private static final Method setAcceptedSubProtocol; - - static { - ClassLoader loader = Jetty10RequestUpgradeStrategy.class.getClassLoader(); - try { - webSocketCreatorClass = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketCreator"); - - Class type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer"); - getContainerMethod = type.getMethod("getContainer", ServletContext.class); - Method upgrade = ReflectionUtils.findMethod(type, "upgrade", (Class[]) null); - Assert.state(upgrade != null, "Upgrade method not found"); - upgradeMethod = upgrade; - - type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse"); - setAcceptedSubProtocol = type.getMethod("setAcceptedSubProtocol", String.class); - } - catch (Exception ex) { - throw new IllegalStateException("No compatible Jetty version found", ex); - } - } - - - @Override - public String[] getSupportedVersions() { - return SUPPORTED_VERSIONS; - } - - @Override - public List getSupportedExtensions(ServerHttpRequest request) { - return Collections.emptyList(); - } - - - @Override - public void upgrade(ServerHttpRequest request, ServerHttpResponse response, - @Nullable String selectedProtocol, List selectedExtensions, - @Nullable Principal user, WebSocketHandler handler, Map attributes) - throws HandshakeFailureException { - - Assert.isInstanceOf(ServletServerHttpRequest.class, request, "ServletServerHttpRequest required"); - HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest(); - ServletContext servletContext = servletRequest.getServletContext(); - - Assert.isInstanceOf(ServletServerHttpResponse.class, response, "ServletServerHttpResponse required"); - HttpServletResponse servletResponse = ((ServletServerHttpResponse) response).getServletResponse(); - - JettyWebSocketSession session = new JettyWebSocketSession(attributes, user); - Jetty10WebSocketHandlerAdapter handlerAdapter = new Jetty10WebSocketHandlerAdapter(handler, session); - - try { - Object creator = createJettyWebSocketCreator(handlerAdapter, selectedProtocol); - Object container = ReflectionUtils.invokeMethod(getContainerMethod, null, servletContext); - ReflectionUtils.invokeMethod(upgradeMethod, container, creator, servletRequest, servletResponse); - } - catch (UndeclaredThrowableException ex) { - throw new HandshakeFailureException("Failed to upgrade", ex.getUndeclaredThrowable()); - } - catch (Exception ex) { - throw new HandshakeFailureException("Failed to upgrade", ex); - } - } - - private static Object createJettyWebSocketCreator( - Jetty10WebSocketHandlerAdapter adapter, @Nullable String protocol) { - - ProxyFactory factory = new ProxyFactory(EmptyTargetSource.INSTANCE); - factory.addInterface(webSocketCreatorClass); - factory.addAdvice(new WebSocketCreatorInterceptor(adapter, protocol)); - return factory.getProxy(); - } - - - /** - * Proxy for a JettyWebSocketCreator to supply the WebSocket handler and set the sub-protocol. - */ - private static class WebSocketCreatorInterceptor implements MethodInterceptor { - - private final Jetty10WebSocketHandlerAdapter adapter; - - @Nullable - private final String protocol; - - - public WebSocketCreatorInterceptor( - Jetty10WebSocketHandlerAdapter adapter, @Nullable String protocol) { - - this.adapter = adapter; - this.protocol = protocol; - } - - @Nullable - @Override - public Object invoke(@NonNull MethodInvocation invocation) { - if (this.protocol != null) { - ReflectionUtils.invokeMethod( - setAcceptedSubProtocol, invocation.getArguments()[2], this.protocol); - } - return this.adapter; - } - } - -} diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java index b733141f39a5..946f061af37d 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java @@ -16,268 +16,149 @@ package org.springframework.web.socket.server.jetty; -import java.io.IOException; import java.lang.reflect.Method; +import java.lang.reflect.UndeclaredThrowableException; import java.security.Principal; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Set; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; -import org.eclipse.jetty.websocket.api.WebSocketPolicy; -import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; -import org.eclipse.jetty.websocket.server.WebSocketServerFactory; - -import org.springframework.context.Lifecycle; -import org.springframework.core.NamedThreadLocal; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.target.EmptyTargetSource; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.http.server.ServletServerHttpResponse; +import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.CollectionUtils; import org.springframework.util.ReflectionUtils; -import org.springframework.web.context.ServletContextAware; import org.springframework.web.socket.WebSocketExtension; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.adapter.jetty.JettyWebSocketHandlerAdapter; import org.springframework.web.socket.adapter.jetty.JettyWebSocketSession; -import org.springframework.web.socket.adapter.jetty.WebSocketToJettyExtensionConfigAdapter; import org.springframework.web.socket.server.HandshakeFailureException; import org.springframework.web.socket.server.RequestUpgradeStrategy; /** - * A {@link RequestUpgradeStrategy} for use with Jetty 9.4. Based on Jetty's - * internal {@code org.eclipse.jetty.websocket.server.WebSocketHandler} class. + * A {@link RequestUpgradeStrategy} for Jetty 11. * - * @author Phillip Webb * @author Rossen Stoyanchev - * @author Brian Clozel - * @author Juergen Hoeller - * @since 4.0 + * @since 5.3.4 */ -public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, ServletContextAware, Lifecycle { - - private static final ThreadLocal containerHolder = - new NamedThreadLocal<>("WebSocketHandlerContainer"); +public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy { - @Nullable - private WebSocketPolicy policy; + private static final String[] SUPPORTED_VERSIONS = new String[] { String.valueOf(13) }; - @Nullable - private volatile WebSocketServerFactory factory; + private static final Class webSocketCreatorClass; - @Nullable - private ServletContext servletContext; + private static final Method getContainerMethod; - private volatile boolean running; + private static final Method upgradeMethod; - @Nullable - private volatile List supportedExtensions; + private static final Method setAcceptedSubProtocol; + static { + // TODO: can switch to non-reflective implementation now - /** - * Default constructor that creates {@link WebSocketServerFactory} through - * its default constructor thus using a default {@link WebSocketPolicy}. - */ - public JettyRequestUpgradeStrategy() { - this.policy = WebSocketPolicy.newServerPolicy(); - } - - /** - * A constructor accepting a {@link WebSocketPolicy} to be used when - * creating the {@link WebSocketServerFactory} instance. - * @param policy the policy to use - * @since 4.3.5 - */ - public JettyRequestUpgradeStrategy(WebSocketPolicy policy) { - Assert.notNull(policy, "WebSocketPolicy must not be null"); - this.policy = policy; - } - - /** - * A constructor accepting a {@link WebSocketServerFactory}. - * @param factory the pre-configured factory to use - */ - public JettyRequestUpgradeStrategy(WebSocketServerFactory factory) { - Assert.notNull(factory, "WebSocketServerFactory must not be null"); - this.factory = factory; - } - + ClassLoader loader = JettyRequestUpgradeStrategy.class.getClassLoader(); + try { + webSocketCreatorClass = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketCreator"); - @Override - public void setServletContext(ServletContext servletContext) { - this.servletContext = servletContext; - } + Class type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer"); + getContainerMethod = type.getMethod("getContainer", ServletContext.class); + Method upgrade = ReflectionUtils.findMethod(type, "upgrade", (Class[]) null); + Assert.state(upgrade != null, "Upgrade method not found"); + upgradeMethod = upgrade; - @Override - public void start() { - if (!isRunning()) { - this.running = true; - try { - WebSocketServerFactory factory = this.factory; - if (factory == null) { - Assert.state(this.servletContext != null, "No ServletContext set"); - factory = new WebSocketServerFactory(this.servletContext, this.policy); - this.factory = factory; - } - factory.setCreator((request, response) -> { - WebSocketHandlerContainer container = containerHolder.get(); - Assert.state(container != null, "Expected WebSocketHandlerContainer"); - response.setAcceptedSubProtocol(container.getSelectedProtocol()); - response.setExtensions(container.getExtensionConfigs()); - return container.getHandler(); - }); - factory.start(); - } - catch (Throwable ex) { - throw new IllegalStateException("Unable to start Jetty WebSocketServerFactory", ex); - } + type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse"); + setAcceptedSubProtocol = type.getMethod("setAcceptedSubProtocol", String.class); } - } - - @Override - public void stop() { - if (isRunning()) { - this.running = false; - WebSocketServerFactory factory = this.factory; - if (factory != null) { - try { - factory.stop(); - } - catch (Throwable ex) { - throw new IllegalStateException("Unable to stop Jetty WebSocketServerFactory", ex); - } - } + catch (Exception ex) { + throw new IllegalStateException("No compatible Jetty version found", ex); } } - @Override - public boolean isRunning() { - return this.running; - } - @Override public String[] getSupportedVersions() { - return new String[] { String.valueOf(13) }; + return SUPPORTED_VERSIONS; } @Override public List getSupportedExtensions(ServerHttpRequest request) { - List extensions = this.supportedExtensions; - if (extensions == null) { - extensions = buildWebSocketExtensions(); - this.supportedExtensions = extensions; - } - return extensions; - } - - private List buildWebSocketExtensions() { - Set names = getExtensionNames(); - List result = new ArrayList<>(names.size()); - for (String name : names) { - result.add(new WebSocketExtension(name)); - } - return result; + return Collections.emptyList(); } - @SuppressWarnings({"unchecked", "deprecation"}) - private Set getExtensionNames() { - WebSocketServerFactory factory = this.factory; - Assert.state(factory != null, "No WebSocketServerFactory available"); - try { - return factory.getAvailableExtensionNames(); - } - catch (IncompatibleClassChangeError ex) { - // Fallback for versions prior to 9.4.21: - // 9.4.20.v20190813: ExtensionFactory (abstract class -> interface) - // 9.4.21.v20190926: ExtensionFactory (interface -> abstract class) + deprecated - Class clazz = org.eclipse.jetty.websocket.api.extensions.ExtensionFactory.class; - Method method = ClassUtils.getMethod(clazz, "getExtensionNames"); - Set result = (Set) ReflectionUtils.invokeMethod(method, factory.getExtensionFactory()); - return (result != null ? result : Collections.emptySet()); - } - } @Override public void upgrade(ServerHttpRequest request, ServerHttpResponse response, - @Nullable String selectedProtocol, List selectedExtensions, @Nullable Principal user, - WebSocketHandler wsHandler, Map attributes) throws HandshakeFailureException { + @Nullable String selectedProtocol, List selectedExtensions, + @Nullable Principal user, WebSocketHandler handler, Map attributes) + throws HandshakeFailureException { Assert.isInstanceOf(ServletServerHttpRequest.class, request, "ServletServerHttpRequest required"); HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest(); + ServletContext servletContext = servletRequest.getServletContext(); Assert.isInstanceOf(ServletServerHttpResponse.class, response, "ServletServerHttpResponse required"); HttpServletResponse servletResponse = ((ServletServerHttpResponse) response).getServletResponse(); - WebSocketServerFactory factory = this.factory; - Assert.state(factory != null, "No WebSocketServerFactory available"); - Assert.isTrue(factory.isUpgradeRequest(servletRequest, servletResponse), "Not a WebSocket handshake"); - JettyWebSocketSession session = new JettyWebSocketSession(attributes, user); - JettyWebSocketHandlerAdapter handlerAdapter = new JettyWebSocketHandlerAdapter(wsHandler, session); - - WebSocketHandlerContainer container = - new WebSocketHandlerContainer(handlerAdapter, selectedProtocol, selectedExtensions); + JettyWebSocketHandlerAdapter handlerAdapter = new JettyWebSocketHandlerAdapter(handler, session); try { - containerHolder.set(container); - factory.acceptWebSocket(servletRequest, servletResponse); + Object creator = createJettyWebSocketCreator(handlerAdapter, selectedProtocol); + Object container = ReflectionUtils.invokeMethod(getContainerMethod, null, servletContext); + ReflectionUtils.invokeMethod(upgradeMethod, container, creator, servletRequest, servletResponse); } - catch (IOException ex) { - throw new HandshakeFailureException( - "Response update failed during upgrade to WebSocket: " + request.getURI(), ex); + catch (UndeclaredThrowableException ex) { + throw new HandshakeFailureException("Failed to upgrade", ex.getUndeclaredThrowable()); } - finally { - containerHolder.remove(); + catch (Exception ex) { + throw new HandshakeFailureException("Failed to upgrade", ex); } } + private static Object createJettyWebSocketCreator( + JettyWebSocketHandlerAdapter adapter, @Nullable String protocol) { - private static class WebSocketHandlerContainer { - - private final JettyWebSocketHandlerAdapter handler; + ProxyFactory factory = new ProxyFactory(EmptyTargetSource.INSTANCE); + factory.addInterface(webSocketCreatorClass); + factory.addAdvice(new WebSocketCreatorInterceptor(adapter, protocol)); + return factory.getProxy(); + } - @Nullable - private final String selectedProtocol; - private final List extensionConfigs; + /** + * Proxy for a JettyWebSocketCreator to supply the WebSocket handler and set the sub-protocol. + */ + private static class WebSocketCreatorInterceptor implements MethodInterceptor { - public WebSocketHandlerContainer(JettyWebSocketHandlerAdapter handler, - @Nullable String protocol, List extensions) { + private final JettyWebSocketHandlerAdapter adapter; - this.handler = handler; - this.selectedProtocol = protocol; - if (CollectionUtils.isEmpty(extensions)) { - this.extensionConfigs = new ArrayList<>(0); - } - else { - this.extensionConfigs = new ArrayList<>(extensions.size()); - for (WebSocketExtension extension : extensions) { - this.extensionConfigs.add(new WebSocketToJettyExtensionConfigAdapter(extension)); - } - } - } + @Nullable + private final String protocol; - public JettyWebSocketHandlerAdapter getHandler() { - return this.handler; + public WebSocketCreatorInterceptor(JettyWebSocketHandlerAdapter adapter, @Nullable String protocol) { + this.adapter = adapter; + this.protocol = protocol; } @Nullable - public String getSelectedProtocol() { - return this.selectedProtocol; - } - - public List getExtensionConfigs() { - return this.extensionConfigs; + @Override + public Object invoke(@NonNull MethodInvocation invocation) { + if (this.protocol != null) { + ReflectionUtils.invokeMethod( + setAcceptedSubProtocol, invocation.getArguments()[2], this.protocol); + } + return this.adapter; } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractStandardUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractStandardUpgradeStrategy.java index 0528da269e1e..e19318ad2967 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractStandardUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractStandardUpgradeStrategy.java @@ -22,14 +22,13 @@ import java.util.List; import java.util.Map; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.websocket.Endpoint; -import javax.websocket.Extension; -import javax.websocket.WebSocketContainer; -import javax.websocket.server.ServerContainer; - +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.websocket.Endpoint; +import jakarta.websocket.Extension; +import jakarta.websocket.WebSocketContainer; +import jakarta.websocket.server.ServerContainer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -66,9 +65,9 @@ public abstract class AbstractStandardUpgradeStrategy implements RequestUpgradeS protected ServerContainer getContainer(HttpServletRequest request) { ServletContext servletContext = request.getServletContext(); - String attrName = "javax.websocket.server.ServerContainer"; + String attrName = "jakarta.websocket.server.ServerContainer"; ServerContainer container = (ServerContainer) servletContext.getAttribute(attrName); - Assert.notNull(container, "No 'javax.websocket.server.ServerContainer' ServletContext attribute. " + + Assert.notNull(container, "No 'jakarta.websocket.server.ServerContainer' ServletContext attribute. " + "Are you running in a Servlet container that supports JSR-356?"); return container; } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractTyrusRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractTyrusRequestUpgradeStrategy.java index b6406ac82b44..3a9f7b0561f5 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractTyrusRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractTyrusRequestUpgradeStrategy.java @@ -25,15 +25,14 @@ import java.util.List; import java.util.Random; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.websocket.DeploymentException; -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.Extension; -import javax.websocket.WebSocketContainer; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.websocket.DeploymentException; +import jakarta.websocket.Endpoint; +import jakarta.websocket.EndpointConfig; +import jakarta.websocket.Extension; +import jakarta.websocket.WebSocketContainer; import org.glassfish.tyrus.core.ComponentProviderService; import org.glassfish.tyrus.core.RequestContext; import org.glassfish.tyrus.core.TyrusEndpointWrapper; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/GlassFishRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/GlassFishRequestUpgradeStrategy.java index 8fc03354f9e7..07ca46500e1b 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/GlassFishRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/GlassFishRequestUpgradeStrategy.java @@ -19,10 +19,9 @@ import java.io.IOException; import java.lang.reflect.Constructor; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.glassfish.tyrus.core.TyrusUpgradeResponse; import org.glassfish.tyrus.core.Utils; import org.glassfish.tyrus.servlet.TyrusHttpUpgradeHandler; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServerEndpointExporter.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServerEndpointExporter.java index acbce32b8d30..efd7c756f84f 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServerEndpointExporter.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServerEndpointExporter.java @@ -22,11 +22,11 @@ import java.util.Map; import java.util.Set; -import javax.servlet.ServletContext; -import javax.websocket.DeploymentException; -import javax.websocket.server.ServerContainer; -import javax.websocket.server.ServerEndpoint; -import javax.websocket.server.ServerEndpointConfig; +import jakarta.servlet.ServletContext; +import jakarta.websocket.DeploymentException; +import jakarta.websocket.server.ServerContainer; +import jakarta.websocket.server.ServerEndpoint; +import jakarta.websocket.server.ServerEndpointConfig; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.SmartInitializingSingleton; @@ -36,7 +36,7 @@ import org.springframework.web.context.support.WebApplicationObjectSupport; /** - * Detects beans of type {@link javax.websocket.server.ServerEndpointConfig} and registers + * Detects beans of type {@link jakarta.websocket.server.ServerEndpointConfig} and registers * with the standard Java WebSocket runtime. Also detects beans annotated with * {@link ServerEndpoint} and registers them as well. Although not required, it is likely * annotated endpoints should have their {@code configurator} property set to @@ -93,7 +93,7 @@ protected ServerContainer getServerContainer() { protected void initServletContext(ServletContext servletContext) { if (this.serverContainer == null) { this.serverContainer = - (ServerContainer) servletContext.getAttribute("javax.websocket.server.ServerContainer"); + (ServerContainer) servletContext.getAttribute("jakarta.websocket.server.ServerContainer"); } } @@ -104,7 +104,7 @@ protected boolean isContextRequired() { @Override public void afterPropertiesSet() { - Assert.state(getServerContainer() != null, "javax.websocket.server.ServerContainer not available"); + Assert.state(getServerContainer() != null, "jakarta.websocket.server.ServerContainer not available"); } @Override diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServerEndpointRegistration.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServerEndpointRegistration.java index 78b138ff5097..bc42f3dc883d 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServerEndpointRegistration.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServerEndpointRegistration.java @@ -21,13 +21,13 @@ import java.util.List; import java.util.Map; -import javax.websocket.Decoder; -import javax.websocket.Encoder; -import javax.websocket.Endpoint; -import javax.websocket.Extension; -import javax.websocket.HandshakeResponse; -import javax.websocket.server.HandshakeRequest; -import javax.websocket.server.ServerEndpointConfig; +import jakarta.websocket.Decoder; +import jakarta.websocket.Encoder; +import jakarta.websocket.Endpoint; +import jakarta.websocket.Extension; +import jakarta.websocket.HandshakeResponse; +import jakarta.websocket.server.HandshakeRequest; +import jakarta.websocket.server.ServerEndpointConfig; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -36,17 +36,17 @@ import org.springframework.web.socket.handler.BeanCreatingHandlerProvider; /** - * An implementation of {@link javax.websocket.server.ServerEndpointConfig} for use in + * An implementation of {@link jakarta.websocket.server.ServerEndpointConfig} for use in * Spring-based applications. A {@link ServerEndpointRegistration} bean is detected by * {@link ServerEndpointExporter} and registered with a Java WebSocket runtime at startup. * - *

    Class constructors accept a singleton {@link javax.websocket.Endpoint} instance + *

    Class constructors accept a singleton {@link jakarta.websocket.Endpoint} instance * or an Endpoint specified by type {@link Class}. When specified by type, the endpoint * will be instantiated and initialized through the Spring ApplicationContext before * each client WebSocket connection. * *

    This class also extends - * {@link javax.websocket.server.ServerEndpointConfig.Configurator} to make it easier + * {@link jakarta.websocket.server.ServerEndpointConfig.Configurator} to make it easier * to override methods for customizing the handshake process. * * @author Rossen Stoyanchev @@ -78,7 +78,7 @@ public class ServerEndpointRegistration extends ServerEndpointConfig.Configurato /** * Create a new {@link ServerEndpointRegistration} instance from an - * {@code javax.websocket.Endpoint} instance. + * {@code jakarta.websocket.Endpoint} instance. * @param path the endpoint path * @param endpoint the endpoint instance */ @@ -92,7 +92,7 @@ public ServerEndpointRegistration(String path, Endpoint endpoint) { /** * Create a new {@link ServerEndpointRegistration} instance from an - * {@code javax.websocket.Endpoint} class. + * {@code jakarta.websocket.Endpoint} class. * @param path the endpoint path * @param endpointClass the endpoint class */ diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServletServerContainerFactoryBean.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServletServerContainerFactoryBean.java index 122402714371..7831250fb678 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServletServerContainerFactoryBean.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServletServerContainerFactoryBean.java @@ -16,9 +16,9 @@ package org.springframework.web.socket.server.standard; -import javax.servlet.ServletContext; -import javax.websocket.WebSocketContainer; -import javax.websocket.server.ServerContainer; +import jakarta.servlet.ServletContext; +import jakarta.websocket.WebSocketContainer; +import jakarta.websocket.server.ServerContainer; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; @@ -27,9 +27,9 @@ import org.springframework.web.context.ServletContextAware; /** - * A {@link FactoryBean} for configuring {@link javax.websocket.server.ServerContainer}. + * A {@link FactoryBean} for configuring {@link jakarta.websocket.server.ServerContainer}. * Since there is usually only one {@code ServerContainer} instance accessible under a - * well-known {@code javax.servlet.ServletContext} attribute, simply declaring this + * well-known {@code jakarta.servlet.ServletContext} attribute, simply declaring this * FactoryBean and using its setters allows for configuring the {@code ServerContainer} * through Spring configuration. * @@ -111,11 +111,11 @@ public void setServletContext(ServletContext servletContext) { @Override public void afterPropertiesSet() { Assert.state(this.servletContext != null, - "A ServletContext is required to access the javax.websocket.server.ServerContainer instance"); + "A ServletContext is required to access the jakarta.websocket.server.ServerContainer instance"); this.serverContainer = (ServerContainer) this.servletContext.getAttribute( - "javax.websocket.server.ServerContainer"); + "jakarta.websocket.server.ServerContainer"); Assert.state(this.serverContainer != null, - "Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext"); + "Attribute 'jakarta.websocket.server.ServerContainer' not found in ServletContext"); if (this.asyncSendTimeout != null) { this.serverContainer.setAsyncSendTimeout(this.asyncSendTimeout); diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/SpringConfigurator.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/SpringConfigurator.java index 712b978b09d3..a27654b86504 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/SpringConfigurator.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/SpringConfigurator.java @@ -20,9 +20,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.websocket.server.ServerEndpoint; -import javax.websocket.server.ServerEndpointConfig.Configurator; - +import jakarta.websocket.server.ServerEndpoint; +import jakarta.websocket.server.ServerEndpointConfig.Configurator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -35,7 +34,7 @@ import org.springframework.web.context.WebApplicationContext; /** - * A {@link javax.websocket.server.ServerEndpointConfig.Configurator} for initializing + * A {@link jakarta.websocket.server.ServerEndpointConfig.Configurator} for initializing * {@link ServerEndpoint}-annotated classes through Spring. * *

    diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/TomcatRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/TomcatRequestUpgradeStrategy.java index c3c6a191609d..37c194dfb410 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/TomcatRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/TomcatRequestUpgradeStrategy.java @@ -21,12 +21,11 @@ import java.util.List; import java.util.Map; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.websocket.Endpoint; -import javax.websocket.Extension; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.websocket.Endpoint; +import jakarta.websocket.Extension; import org.apache.tomcat.websocket.server.WsServerContainer; import org.springframework.http.server.ServerHttpRequest; @@ -38,10 +37,10 @@ * A WebSocket {@code RequestUpgradeStrategy} for Apache Tomcat. Compatible with * all versions of Tomcat that support JSR-356, i.e. Tomcat 7.0.47+ and higher. * - *

    To modify properties of the underlying {@link javax.websocket.server.ServerContainer} + *

    To modify properties of the underlying {@link jakarta.websocket.server.ServerContainer} * you can use {@link ServletServerContainerFactoryBean} in XML configuration or, * when using Java configuration, access the container instance through the - * "javax.websocket.server.ServerContainer" ServletContext attribute. + * "jakarta.websocket.server.ServerContainer" ServletContext attribute. * * @author Rossen Stoyanchev * @since 4.0 diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/UndertowRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/UndertowRequestUpgradeStrategy.java index 96ac372042f9..4ee43f18e509 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/UndertowRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/UndertowRequestUpgradeStrategy.java @@ -21,14 +21,13 @@ import java.util.List; import java.util.Map; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.websocket.Endpoint; -import javax.websocket.Extension; - import io.undertow.websockets.core.WebSocketVersion; import io.undertow.websockets.jsr.ServerWebSocketContainer; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.websocket.Endpoint; +import jakarta.websocket.Extension; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebLogicRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebLogicRequestUpgradeStrategy.java index cf04f519c9d2..8174297a5c46 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebLogicRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebLogicRequestUpgradeStrategy.java @@ -20,14 +20,13 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; -import javax.servlet.AsyncContext; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletRequestWrapper; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.AsyncContext; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletRequestWrapper; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.glassfish.tyrus.core.TyrusUpgradeResponse; import org.glassfish.tyrus.core.Utils; import org.glassfish.tyrus.spi.Connection; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebSphereRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebSphereRequestUpgradeStrategy.java index 62990dfe6820..6a69ec0769f2 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebSphereRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebSphereRequestUpgradeStrategy.java @@ -21,12 +21,12 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.websocket.Endpoint; -import javax.websocket.Extension; -import javax.websocket.server.ServerContainer; -import javax.websocket.server.ServerEndpointConfig; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.websocket.Endpoint; +import jakarta.websocket.Extension; +import jakarta.websocket.server.ServerContainer; +import jakarta.websocket.server.ServerEndpointConfig; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/AbstractHandshakeHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/AbstractHandshakeHandler.java index 8ca56429a4e8..efc771a7ed8f 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/AbstractHandshakeHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/AbstractHandshakeHandler.java @@ -67,7 +67,6 @@ * @see org.springframework.web.socket.server.standard.TomcatRequestUpgradeStrategy * @see org.springframework.web.socket.server.standard.UndertowRequestUpgradeStrategy * @see org.springframework.web.socket.server.standard.GlassFishRequestUpgradeStrategy - * @see org.springframework.web.socket.server.standard.WebLogicRequestUpgradeStrategy */ public abstract class AbstractHandshakeHandler implements HandshakeHandler, Lifecycle { @@ -75,8 +74,6 @@ public abstract class AbstractHandshakeHandler implements HandshakeHandler, Life private static final boolean jettyWsPresent; - private static final boolean jetty10WsPresent; - private static final boolean undertowWsPresent; private static final boolean glassfishWsPresent; @@ -89,10 +86,8 @@ public abstract class AbstractHandshakeHandler implements HandshakeHandler, Life ClassLoader classLoader = AbstractHandshakeHandler.class.getClassLoader(); tomcatWsPresent = ClassUtils.isPresent( "org.apache.tomcat.websocket.server.WsHttpUpgradeHandler", classLoader); - jetty10WsPresent = ClassUtils.isPresent( - "org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer", classLoader); jettyWsPresent = ClassUtils.isPresent( - "org.eclipse.jetty.websocket.server.WebSocketServerFactory", classLoader); + "org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer", classLoader); undertowWsPresent = ClassUtils.isPresent( "io.undertow.websockets.jsr.ServerWebSocketContainer", classLoader); glassfishWsPresent = ClassUtils.isPresent( @@ -140,9 +135,6 @@ private static RequestUpgradeStrategy initRequestUpgradeStrategy() { else if (jettyWsPresent) { className = "org.springframework.web.socket.server.jetty.JettyRequestUpgradeStrategy"; } - else if (jetty10WsPresent) { - className = "org.springframework.web.socket.server.jetty.Jetty10RequestUpgradeStrategy"; - } else if (undertowWsPresent) { className = "org.springframework.web.socket.server.standard.UndertowRequestUpgradeStrategy"; } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/DefaultHandshakeHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/DefaultHandshakeHandler.java index 7cd06ac757a3..a3701fc09974 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/DefaultHandshakeHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/DefaultHandshakeHandler.java @@ -16,7 +16,7 @@ package org.springframework.web.socket.server.support; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.web.context.ServletContextAware; import org.springframework.web.socket.server.RequestUpgradeStrategy; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java index 1f18ff4b9046..ba020c32fe82 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java @@ -21,7 +21,7 @@ import java.util.Enumeration; import java.util.Map; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSession; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; @@ -128,7 +128,7 @@ public boolean isCopyHttpSessionId() { /** * Whether to allow the HTTP session to be created while accessing it. *

    By default set to {@code false}. - * @see javax.servlet.http.HttpServletRequest#getSession(boolean) + * @see jakarta.servlet.http.HttpServletRequest#getSession(boolean) */ public void setCreateSession(boolean createSession) { this.createSession = createSession; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHandlerMapping.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHandlerMapping.java index 47a66b62999d..a6d5bfb7f915 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHandlerMapping.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHandlerMapping.java @@ -16,8 +16,8 @@ package org.springframework.web.socket.server.support; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.context.Lifecycle; import org.springframework.context.SmartLifecycle; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandler.java index 15c2a9ef3e30..997c547b4470 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandler.java @@ -22,11 +22,10 @@ import java.util.List; import java.util.Map; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/JettyXhrTransport.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/JettyXhrTransport.java index 772e6c0295de..df046d197e63 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/JettyXhrTransport.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/JettyXhrTransport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; -import org.eclipse.jetty.client.util.StringContentProvider; +import org.eclipse.jetty.client.util.StringRequestContent; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpMethod; @@ -142,7 +142,7 @@ protected ResponseEntity executeRequest(URI url, HttpMethod method, Request httpRequest = this.httpClient.newRequest(url).method(method); addHttpHeaders(httpRequest, headers); if (body != null) { - httpRequest.content(new StringContentProvider(body)); + httpRequest.body(new StringRequestContent(body)); } ContentResponse response; try { @@ -160,10 +160,12 @@ protected ResponseEntity executeRequest(URI url, HttpMethod method, private static void addHttpHeaders(Request request, HttpHeaders headers) { - headers.forEach((key, values) -> { - for (String value : values) { - request.header(key, value); - } + request.headers(fields -> { + headers.forEach((key, values) -> { + for (String value : values) { + fields.add(key, value); + } + }); }); } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java index e3a941937107..e1c6ba116fee 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java @@ -27,8 +27,7 @@ import java.util.Random; import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; - +import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/SockJsHttpRequestHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/SockJsHttpRequestHandler.java index 67f1da304a7b..555f8f8903e7 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/SockJsHttpRequestHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/SockJsHttpRequestHandler.java @@ -18,10 +18,10 @@ import java.io.IOException; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.Lifecycle; import org.springframework.http.server.ServerHttpRequest; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsService.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsService.java index 3409eb15dafe..8a33978475ed 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsService.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsService.java @@ -21,8 +21,7 @@ import java.util.LinkedHashSet; import java.util.Set; -import javax.servlet.ServletContext; - +import jakarta.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/WebSocketTransportHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/WebSocketTransportHandler.java index 77e7bbe2f0c9..8f58315f80af 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/WebSocketTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/WebSocketTransportHandler.java @@ -18,7 +18,7 @@ import java.util.Map; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.springframework.context.Lifecycle; import org.springframework.http.server.ServerHttpRequest; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java index a3d492ecf564..ce9786bc7585 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java @@ -26,7 +26,7 @@ import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; -import javax.servlet.ServletRequest; +import jakarta.servlet.ServletRequest; import org.springframework.http.HttpHeaders; import org.springframework.http.server.ServerHttpAsyncRequestControl; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/AbstractWebSocketIntegrationTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/AbstractWebSocketIntegrationTests.java index ec9f90bfccaf..588608f10d77 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/AbstractWebSocketIntegrationTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/AbstractWebSocketIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/JettyWebSocketTestServer.java b/spring-websocket/src/test/java/org/springframework/web/socket/JettyWebSocketTestServer.java index bec8dda74440..abe8c4d09591 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/JettyWebSocketTestServer.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/JettyWebSocketTestServer.java @@ -18,10 +18,9 @@ import java.util.EnumSet; -import javax.servlet.DispatcherType; -import javax.servlet.Filter; -import javax.servlet.ServletContext; - +import jakarta.servlet.DispatcherType; +import jakarta.servlet.Filter; +import jakarta.servlet.ServletContext; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/TomcatWebSocketTestServer.java b/spring-websocket/src/test/java/org/springframework/web/socket/TomcatWebSocketTestServer.java index 78ca7714ac40..12e5b54fa484 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/TomcatWebSocketTestServer.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/TomcatWebSocketTestServer.java @@ -19,9 +19,8 @@ import java.io.File; import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.ServletContext; - +import jakarta.servlet.Filter; +import jakarta.servlet.ServletContext; import org.apache.catalina.Context; import org.apache.catalina.connector.Connector; import org.apache.catalina.startup.Tomcat; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/UndertowTestServer.java b/spring-websocket/src/test/java/org/springframework/web/socket/UndertowTestServer.java index 589282256552..914450bec2e2 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/UndertowTestServer.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/UndertowTestServer.java @@ -19,12 +19,6 @@ import java.io.IOException; import java.net.InetSocketAddress; -import javax.servlet.DispatcherType; -import javax.servlet.Filter; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - import io.undertow.Undertow; import io.undertow.server.HttpHandler; import io.undertow.servlet.api.DeploymentInfo; @@ -34,6 +28,11 @@ import io.undertow.servlet.api.InstanceHandle; import io.undertow.servlet.api.ServletInfo; import io.undertow.websockets.jsr.WebSocketDeploymentInfo; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.Filter; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; import org.xnio.OptionMap; import org.xnio.Xnio; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/WebSocketTestServer.java b/spring-websocket/src/test/java/org/springframework/web/socket/WebSocketTestServer.java index 6b131e5573cb..92c4c3f3d8c2 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/WebSocketTestServer.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/WebSocketTestServer.java @@ -16,8 +16,8 @@ package org.springframework.web.socket; -import javax.servlet.Filter; -import javax.servlet.ServletContext; +import jakarta.servlet.Filter; +import jakarta.servlet.ServletContext; import org.springframework.web.context.WebApplicationContext; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/adapter/standard/ConvertingEncoderDecoderSupportTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/adapter/standard/ConvertingEncoderDecoderSupportTests.java index 440dd412d216..486cb4a07c6f 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/adapter/standard/ConvertingEncoderDecoderSupportTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/adapter/standard/ConvertingEncoderDecoderSupportTests.java @@ -18,11 +18,10 @@ import java.nio.ByteBuffer; -import javax.websocket.DecodeException; -import javax.websocket.Decoder; -import javax.websocket.EncodeException; -import javax.websocket.Encoder; - +import jakarta.websocket.DecodeException; +import jakarta.websocket.Decoder; +import jakarta.websocket.EncodeException; +import jakarta.websocket.Encoder; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/adapter/standard/StandardWebSocketHandlerAdapterTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/adapter/standard/StandardWebSocketHandlerAdapterTests.java index 03a817c1cbfd..a2f3501d122f 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/adapter/standard/StandardWebSocketHandlerAdapterTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/adapter/standard/StandardWebSocketHandlerAdapterTests.java @@ -18,11 +18,10 @@ import java.net.URI; -import javax.websocket.CloseReason; -import javax.websocket.CloseReason.CloseCodes; -import javax.websocket.MessageHandler; -import javax.websocket.Session; - +import jakarta.websocket.CloseReason; +import jakarta.websocket.CloseReason.CloseCodes; +import jakarta.websocket.MessageHandler; +import jakarta.websocket.Session; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/adapter/standard/StandardWebSocketSessionTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/adapter/standard/StandardWebSocketSessionTests.java index a16948cb4b1c..100c6b2e654d 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/adapter/standard/StandardWebSocketSessionTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/adapter/standard/StandardWebSocketSessionTests.java @@ -19,8 +19,7 @@ import java.util.HashMap; import java.util.Map; -import javax.websocket.Session; - +import jakarta.websocket.Session; import org.junit.jupiter.api.Test; import org.mockito.Mockito; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/client/jetty/JettyWebSocketClientTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/client/jetty/JettyWebSocketClientTests.java index 212b92ae8916..2a4faef0aa09 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/client/jetty/JettyWebSocketClientTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/client/jetty/JettyWebSocketClientTests.java @@ -16,36 +16,14 @@ package org.springframework.web.socket.client.jetty; -import java.net.URI; -import java.util.Arrays; - -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; -import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; -import org.eclipse.jetty.websocket.servlet.WebSocketCreator; -import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.util.CollectionUtils; -import org.springframework.web.socket.WebSocketHandler; -import org.springframework.web.socket.WebSocketHttpHeaders; -import org.springframework.web.socket.WebSocketSession; -import org.springframework.web.socket.adapter.jetty.JettyWebSocketHandlerAdapter; -import org.springframework.web.socket.adapter.jetty.JettyWebSocketSession; -import org.springframework.web.socket.handler.TextWebSocketHandler; - -import static org.assertj.core.api.Assertions.assertThat; - /** * Tests for {@link JettyWebSocketClient}. + * * @author Rossen Stoyanchev */ public class JettyWebSocketClientTests { + /* TODO: complete upgrade to Jetty 11 private JettyWebSocketClient client; private TestJettyWebSocketServer server; @@ -113,12 +91,12 @@ public TestJettyWebSocketServer(final WebSocketHandler webSocketHandler) { connector.setPort(0); this.server.addConnector(connector); - this.server.setHandler(new org.eclipse.jetty.websocket.server.WebSocketHandler() { + this.server.setHandler(new WebSocketUpgradeHandler() { @Override - public void configure(WebSocketServletFactory factory) { - factory.setCreator(new WebSocketCreator() { + public void configure(JettyWebSocketServletFactory factory) { + factory.setCreator(new JettyWebSocketCreator() { @Override - public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp) { + public Object createWebSocket(JettyServerUpgradeRequest req, JettyServerUpgradeResponse resp) { if (!CollectionUtils.isEmpty(req.getSubProtocols())) { resp.setAcceptedSubProtocol(req.getSubProtocols().get(0)); } @@ -142,5 +120,6 @@ public int getPort() { return ((ServerConnector) this.server.getConnectors()[0]).getLocalPort(); } } + */ } diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/client/standard/StandardWebSocketClientTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/client/standard/StandardWebSocketClientTests.java index 99c34eec0e7a..6246a681e825 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/client/standard/StandardWebSocketClientTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/client/standard/StandardWebSocketClientTests.java @@ -22,10 +22,9 @@ import java.util.List; import java.util.Map; -import javax.websocket.ClientEndpointConfig; -import javax.websocket.Endpoint; -import javax.websocket.WebSocketContainer; - +import jakarta.websocket.ClientEndpointConfig; +import jakarta.websocket.Endpoint; +import jakarta.websocket.WebSocketContainer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/server/standard/ServerEndpointExporterTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/server/standard/ServerEndpointExporterTests.java index 13cc9f4e6cad..f170340f693f 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/server/standard/ServerEndpointExporterTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/server/standard/ServerEndpointExporterTests.java @@ -16,13 +16,12 @@ package org.springframework.web.socket.server.standard; -import javax.servlet.ServletContext; -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.Session; -import javax.websocket.server.ServerContainer; -import javax.websocket.server.ServerEndpoint; - +import jakarta.servlet.ServletContext; +import jakarta.websocket.Endpoint; +import jakarta.websocket.EndpointConfig; +import jakarta.websocket.Session; +import jakarta.websocket.server.ServerContainer; +import jakarta.websocket.server.ServerEndpoint; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -56,7 +55,7 @@ public void setup() { this.serverContainer = mock(ServerContainer.class); this.servletContext = new MockServletContext(); - this.servletContext.setAttribute("javax.websocket.server.ServerContainer", this.serverContainer); + this.servletContext.setAttribute("jakarta.websocket.server.ServerContainer", this.serverContainer); this.webAppContext = new AnnotationConfigWebApplicationContext(); this.webAppContext.register(Config.class); @@ -129,7 +128,7 @@ public void addServerEndpointConfigBeanWithExplicitServletContext() throws Excep public void addServerEndpointConfigBeanWithExplicitServerContainer() throws Exception { ServerEndpointRegistration endpointRegistration = new ServerEndpointRegistration("/dummy", new DummyEndpoint()); this.webAppContext.getBeanFactory().registerSingleton("dummyEndpoint", endpointRegistration); - this.servletContext.removeAttribute("javax.websocket.server.ServerContainer"); + this.servletContext.removeAttribute("jakarta.websocket.server.ServerContainer"); this.exporter.setServerContainer(this.serverContainer); this.exporter.setApplicationContext(this.webAppContext); diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/server/standard/ServerEndpointRegistrationTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/server/standard/ServerEndpointRegistrationTests.java index 04f3740e5fce..64571a2dfd75 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/server/standard/ServerEndpointRegistrationTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/server/standard/ServerEndpointRegistrationTests.java @@ -16,10 +16,9 @@ package org.springframework.web.socket.server.standard; -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.Session; - +import jakarta.websocket.Endpoint; +import jakarta.websocket.EndpointConfig; +import jakarta.websocket.Session; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/server/standard/SpringConfiguratorTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/server/standard/SpringConfiguratorTests.java index ba77896f0a54..48f25ce7d828 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/server/standard/SpringConfiguratorTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/server/standard/SpringConfiguratorTests.java @@ -16,8 +16,7 @@ package org.springframework.web.socket.server.standard; -import javax.websocket.server.ServerEndpoint; - +import jakarta.websocket.server.ServerEndpoint; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandlerTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandlerTests.java index 77adaca9f8df..618e0441a92c 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandlerTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandlerTests.java @@ -20,8 +20,7 @@ import java.util.Collections; import java.util.Map; -import javax.servlet.ServletException; - +import jakarta.servlet.ServletException; import org.junit.jupiter.api.Test; import org.springframework.http.server.ServerHttpRequest; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/client/AbstractSockJsIntegrationTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/client/AbstractSockJsIntegrationTests.java index 5c6cbd0a627f..042ff8d15335 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/client/AbstractSockJsIntegrationTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/client/AbstractSockJsIntegrationTests.java @@ -29,15 +29,14 @@ import java.util.concurrent.TimeUnit; import java.util.function.BooleanSupplier; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.AfterEach; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/support/SockJsServiceTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/support/SockJsServiceTests.java index 16106bdccc85..39f9a619f1ad 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/support/SockJsServiceTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/support/SockJsServiceTests.java @@ -20,9 +20,8 @@ import java.util.Arrays; import java.util.Collections; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; From 5eac8555d9b115b40d6de6b2c8f935ffc35864de Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 17 Sep 2021 11:50:54 +0200 Subject: [PATCH 110/735] Temporarily exclude failing Jetty 11 tests See gh-27424 --- build.gradle | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/build.gradle b/build.gradle index c6cdde1364e8..b96029abf6cb 100644 --- a/build.gradle +++ b/build.gradle @@ -299,6 +299,18 @@ configure([rootProject] + javaProjects) { project -> test { useJUnitPlatform() include(["**/*Tests.class", "**/*Test.class"]) + // TODO Enable excluded tests (https://github.com/spring-projects/spring-framework/issues/27424) + filter { + excludeTestsMatching("*ErrorHandlerIntegrationTests") + excludeTestsMatching("*RequestPartIntegrationTests") + excludeTestsMatching("*WebSocketConfigurationTests") + excludeTestsMatching("*WebSocketHandshakeTests") + excludeTestsMatching("*StompWebSocketIntegrationTests") + excludeTestsMatching("*RequestMappingIntegrationTests") + excludeTestsMatching("*CrossOriginAnnotationIntegrationTests") + excludeTestsMatching("*NestedRouteIntegrationTests") + excludeTestsMatching("*WebSocketIntegrationTests") + } systemProperty("java.awt.headless", "true") systemProperty("testGroups", project.properties.get("testGroups")) systemProperty("io.netty.leakDetection.level", "paranoid") From 0d6cc122744df002e35f0788eab28bbd492c46ed Mon Sep 17 00:00:00 2001 From: Koy Date: Thu, 16 Sep 2021 16:13:29 +0800 Subject: [PATCH 111/735] Fix collectionToDelimitedString failure for null elements. Prior to this commit, calling `StringUtils#collectionToDelimitedString` would fail with an NPE if the collection contains null elements. This commit ensures that null elements are converted as `"null"` in the resulting String without failure. See gh-27419 --- .../src/main/java/org/springframework/util/StringUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 80a996d481fb..269257fd6024 100644 --- a/spring-core/src/main/java/org/springframework/util/StringUtils.java +++ b/spring-core/src/main/java/org/springframework/util/StringUtils.java @@ -1301,7 +1301,7 @@ public static String collectionToDelimitedString( int totalLength = coll.size() * (prefix.length() + suffix.length()) + (coll.size() - 1) * delim.length(); for (Object element : coll) { - totalLength += element.toString().length(); + totalLength += String.valueOf(element).length(); } StringBuilder sb = new StringBuilder(totalLength); From a50537fbaf3f6067071de5bcafa6052d1ac564fd Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Fri, 17 Sep 2021 15:15:51 +0200 Subject: [PATCH 112/735] Polish "Fix collectionToDelimitedString failure for null elements." Fixes gh-27419 --- .../java/org/springframework/util/StringUtilsTests.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java b/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java index 2aae6260dd0e..2b46f73a56aa 100644 --- a/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java @@ -17,6 +17,7 @@ package org.springframework.util; import java.util.Arrays; +import java.util.Collections; import java.util.Locale; import java.util.Properties; @@ -777,4 +778,9 @@ void splitWithEmptyStringOrNull() { assertThat(StringUtils.split(null, null)).isNull(); } + @Test + void collectionToDelimitedStringWithNullValuesShouldNotFail() { + assertThat(StringUtils.collectionToCommaDelimitedString(Collections.singletonList(null))).isEqualTo("null"); + } + } From b732ff349509d2b174978c71fe522ee6aa6b57a8 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 17 Sep 2021 12:50:10 +0100 Subject: [PATCH 113/735] Ensure mutable headers for Jetty WebFlux request In Jetty 10, request headers are immutable, see https://github.com/eclipse/jetty.project/pull/4777, but we need to remove/hide forwarded headers when they have been used. See gh-27424 --- .../server/reactive/JettyHeadersAdapter.java | 41 +++++-------------- .../reactive/JettyHttpHandlerAdapter.java | 4 +- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHeadersAdapter.java index b8d73163cea6..3e6700cf4eb8 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHeadersAdapter.java @@ -44,10 +44,10 @@ */ class JettyHeadersAdapter implements MultiValueMap { - private final HttpFields headers; + private final HttpFields.Mutable headers; - JettyHeadersAdapter(HttpFields headers) { + JettyHeadersAdapter(HttpFields.Mutable headers) { this.headers = headers; } @@ -59,10 +59,7 @@ public String getFirst(String key) { @Override public void add(String key, @Nullable String value) { - if (!(this.headers instanceof HttpFields.Mutable)) { - throw new IllegalStateException("Immutable headers"); - } - ((HttpFields.Mutable) this.headers).add(key, value); + this.headers.add(key, value); } @Override @@ -77,10 +74,7 @@ public void addAll(MultiValueMap values) { @Override public void set(String key, @Nullable String value) { - if (!(this.headers instanceof HttpFields.Mutable)) { - throw new IllegalStateException("Immutable headers"); - } - ((HttpFields.Mutable) this.headers).put(key, value); + this.headers.put(key, value); } @Override @@ -133,23 +127,17 @@ public List get(Object key) { @Nullable @Override public List put(String key, List value) { - if (!(this.headers instanceof HttpFields.Mutable)) { - throw new IllegalStateException("Immutable headers"); - } List oldValues = get(key); - ((HttpFields.Mutable) this.headers).put(key, value); + this.headers.put(key, value); return oldValues; } @Nullable @Override public List remove(Object key) { - if (!(this.headers instanceof HttpFields.Mutable)) { - throw new IllegalStateException("Immutable headers"); - } if (key instanceof String) { List oldValues = get(key); - ((HttpFields.Mutable) this.headers).remove((String) key); + this.headers.remove((String) key); return oldValues; } return null; @@ -162,10 +150,7 @@ public void putAll(Map> map) { @Override public void clear() { - if (!(this.headers instanceof HttpFields.Mutable)) { - throw new IllegalStateException("Immutable headers"); - } - ((HttpFields.Mutable) this.headers).clear(); + this.headers.clear(); } @Override @@ -181,7 +166,7 @@ public Collection> values() { @Override public Set>> entrySet() { - return new AbstractSet>>() { + return new AbstractSet<>() { @Override public Iterator>> iterator() { return new EntryIterator(); @@ -237,11 +222,8 @@ public List getValue() { @Override public List setValue(List value) { - if (!(headers instanceof HttpFields.Mutable)) { - throw new IllegalStateException("Immutable headers"); - } List previousValues = headers.getValuesList(this.key); - ((HttpFields.Mutable) headers).put(this.key, value); + headers.put(this.key, value); return previousValues; } } @@ -285,16 +267,13 @@ public String next() { @Override public void remove() { - if (!(headers instanceof HttpFields.Mutable)) { - throw new IllegalStateException("Immutable headers"); - } if (this.currentName == null) { throw new IllegalStateException("No current Header in iterator"); } if (!headers.contains(this.currentName)) { throw new IllegalStateException("Header not present: " + this.currentName); } - ((HttpFields.Mutable) headers).remove(this.currentName); + headers.remove(this.currentName); } } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java index 8f5f23be086a..8c1615e6d281 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java @@ -84,7 +84,7 @@ private static final class JettyServerHttpRequest extends ServletServerHttpReque private static MultiValueMap createHeaders(HttpServletRequest servletRequest) { Request request = getRequest(servletRequest); - HttpFields fields = request.getMetaData().getFields(); + HttpFields.Mutable fields = HttpFields.build(request.getHttpFields()); return new JettyHeadersAdapter(fields); } @@ -116,7 +116,7 @@ private static final class JettyServerHttpResponse extends ServletServerHttpResp private static HttpHeaders createHeaders(HttpServletResponse servletResponse) { Response response = getResponse(servletResponse); - HttpFields fields = response.getHttpFields(); + HttpFields.Mutable fields = response.getHttpFields(); return new HttpHeaders(new JettyHeadersAdapter(fields)); } From 48875dc44fc019350a3b02bd9d04ade583021523 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 17 Sep 2021 14:36:10 +0100 Subject: [PATCH 114/735] Fix Jetty WebSocket test failures See gh-27424 --- .../jetty/JettyRequestUpgradeStrategy.java | 86 +++---------------- .../web/socket/JettyWebSocketTestServer.java | 2 + 2 files changed, 14 insertions(+), 74 deletions(-) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java index 946f061af37d..34e6b89f01a5 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java @@ -16,7 +16,6 @@ package org.springframework.web.socket.server.jetty; -import java.lang.reflect.Method; import java.lang.reflect.UndeclaredThrowableException; import java.security.Principal; import java.util.Collections; @@ -26,19 +25,15 @@ import jakarta.servlet.ServletContext; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; +import org.eclipse.jetty.websocket.server.JettyWebSocketCreator; +import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer; -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.target.EmptyTargetSource; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.http.server.ServletServerHttpResponse; -import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; import org.springframework.web.socket.WebSocketExtension; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.adapter.jetty.JettyWebSocketHandlerAdapter; @@ -56,35 +51,6 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy { private static final String[] SUPPORTED_VERSIONS = new String[] { String.valueOf(13) }; - private static final Class webSocketCreatorClass; - - private static final Method getContainerMethod; - - private static final Method upgradeMethod; - - private static final Method setAcceptedSubProtocol; - - static { - // TODO: can switch to non-reflective implementation now - - ClassLoader loader = JettyRequestUpgradeStrategy.class.getClassLoader(); - try { - webSocketCreatorClass = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketCreator"); - - Class type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer"); - getContainerMethod = type.getMethod("getContainer", ServletContext.class); - Method upgrade = ReflectionUtils.findMethod(type, "upgrade", (Class[]) null); - Assert.state(upgrade != null, "Upgrade method not found"); - upgradeMethod = upgrade; - - type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse"); - setAcceptedSubProtocol = type.getMethod("setAcceptedSubProtocol", String.class); - } - catch (Exception ex) { - throw new IllegalStateException("No compatible Jetty version found", ex); - } - } - @Override public String[] getSupportedVersions() { @@ -113,10 +79,17 @@ public void upgrade(ServerHttpRequest request, ServerHttpResponse response, JettyWebSocketSession session = new JettyWebSocketSession(attributes, user); JettyWebSocketHandlerAdapter handlerAdapter = new JettyWebSocketHandlerAdapter(handler, session); + JettyWebSocketCreator webSocketCreator = (upgradeRequest, upgradeResponse) -> { + if (selectedProtocol != null) { + upgradeResponse.setAcceptedSubProtocol(selectedProtocol); + } + return handlerAdapter; + }; + + JettyWebSocketServerContainer container = JettyWebSocketServerContainer.getContainer(servletContext); + try { - Object creator = createJettyWebSocketCreator(handlerAdapter, selectedProtocol); - Object container = ReflectionUtils.invokeMethod(getContainerMethod, null, servletContext); - ReflectionUtils.invokeMethod(upgradeMethod, container, creator, servletRequest, servletResponse); + container.upgrade(webSocketCreator, servletRequest, servletResponse); } catch (UndeclaredThrowableException ex) { throw new HandshakeFailureException("Failed to upgrade", ex.getUndeclaredThrowable()); @@ -126,40 +99,5 @@ public void upgrade(ServerHttpRequest request, ServerHttpResponse response, } } - private static Object createJettyWebSocketCreator( - JettyWebSocketHandlerAdapter adapter, @Nullable String protocol) { - - ProxyFactory factory = new ProxyFactory(EmptyTargetSource.INSTANCE); - factory.addInterface(webSocketCreatorClass); - factory.addAdvice(new WebSocketCreatorInterceptor(adapter, protocol)); - return factory.getProxy(); - } - - - /** - * Proxy for a JettyWebSocketCreator to supply the WebSocket handler and set the sub-protocol. - */ - private static class WebSocketCreatorInterceptor implements MethodInterceptor { - - private final JettyWebSocketHandlerAdapter adapter; - - @Nullable - private final String protocol; - - public WebSocketCreatorInterceptor(JettyWebSocketHandlerAdapter adapter, @Nullable String protocol) { - this.adapter = adapter; - this.protocol = protocol; - } - - @Nullable - @Override - public Object invoke(@NonNull MethodInvocation invocation) { - if (this.protocol != null) { - ReflectionUtils.invokeMethod( - setAcceptedSubProtocol, invocation.getArguments()[2], this.protocol); - } - return this.adapter; - } - } } diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/JettyWebSocketTestServer.java b/spring-websocket/src/test/java/org/springframework/web/socket/JettyWebSocketTestServer.java index abe8c4d09591..67a677177948 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/JettyWebSocketTestServer.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/JettyWebSocketTestServer.java @@ -27,6 +27,7 @@ import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; @@ -57,6 +58,7 @@ public void deployConfig(WebApplicationContext wac, Filter... filters) { ServletHolder servletHolder = new ServletHolder(new DispatcherServlet(wac)); this.contextHandler = new ServletContextHandler(); this.contextHandler.addServlet(servletHolder, "/"); + this.contextHandler.addServletContainerInitializer(new JettyWebSocketServletContainerInitializer()); for (Filter filter : filters) { this.contextHandler.addFilter(new FilterHolder(filter), "/*", getDispatcherTypes()); } From 513cc1576e5860b5bd953351850cabd1a0d6e385 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 17 Sep 2021 12:51:51 +0100 Subject: [PATCH 115/735] Fix Jetty WebSocket test failures for WebFlux See gh-27424 --- spring-web/spring-web.gradle | 1 + .../reactive/bootstrap/JettyHttpServer.java | 4 +- .../socket/client/JettyWebSocketClient.java | 1 + .../upgrade/JettyRequestUpgradeStrategy.java | 95 +++---------------- 4 files changed, 19 insertions(+), 82 deletions(-) diff --git a/spring-web/spring-web.gradle b/spring-web/spring-web.gradle index f0e341db5d0a..f066790df20c 100644 --- a/spring-web/spring-web.gradle +++ b/spring-web/spring-web.gradle @@ -82,4 +82,5 @@ dependencies { testFixturesImplementation("org.bouncycastle:bcpkix-jdk15on") { because("needed by Netty's SelfSignedCertificate on JDK 15+") } + testFixturesImplementation("org.eclipse.jetty.websocket:websocket-jetty-server") } diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/http/server/reactive/bootstrap/JettyHttpServer.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/http/server/reactive/bootstrap/JettyHttpServer.java index 93f828bc3ddf..8b307134acfb 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/http/server/reactive/bootstrap/JettyHttpServer.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/http/server/reactive/bootstrap/JettyHttpServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; import org.springframework.http.server.reactive.JettyHttpHandlerAdapter; import org.springframework.http.server.reactive.ServletHttpHandlerAdapter; @@ -45,6 +46,7 @@ protected void initServer() throws Exception { this.contextHandler = new ServletContextHandler(this.jettyServer, "", false, false); this.contextHandler.addServlet(servletHolder, "/"); + this.contextHandler.addServletContainerInitializer(new JettyWebSocketServletContainerInitializer()); this.contextHandler.start(); ServerConnector connector = new ServerConnector(this.jettyServer); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/JettyWebSocketClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/JettyWebSocketClient.java index 4c98f03937e2..b95b7728bcf1 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/JettyWebSocketClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/JettyWebSocketClient.java @@ -142,6 +142,7 @@ private Mono executeInternal(URI url, HttpHeaders headers, WebSocketHandle Object jettyHandler = createHandler( url, ContextWebSocketHandler.decorate(handler, contextView), completionSink); ClientUpgradeRequest request = new ClientUpgradeRequest(); + request.setHeaders(headers); request.setSubProtocols(handler.getSubProtocols()); try { this.jettyClient.connect(jettyHandler, url, request); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java index b230bb587e98..c95782934866 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java @@ -16,27 +16,21 @@ package org.springframework.web.reactive.socket.server.upgrade; -import java.lang.reflect.Method; import java.util.function.Supplier; import jakarta.servlet.ServletContext; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; +import org.eclipse.jetty.websocket.server.JettyWebSocketCreator; +import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer; import reactor.core.publisher.Mono; -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.target.EmptyTargetSource; import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequestDecorator; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponseDecorator; -import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; import org.springframework.web.reactive.socket.HandshakeInfo; import org.springframework.web.reactive.socket.WebSocketHandler; import org.springframework.web.reactive.socket.adapter.ContextWebSocketHandler; @@ -53,36 +47,6 @@ */ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy { - private static final Class webSocketCreatorClass; - - private static final Method getContainerMethod; - - private static final Method upgradeMethod; - - private static final Method setAcceptedSubProtocol; - - static { - // TODO: can switch to non-reflective implementation now - - ClassLoader loader = JettyRequestUpgradeStrategy.class.getClassLoader(); - try { - webSocketCreatorClass = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketCreator"); - - Class type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer"); - getContainerMethod = type.getMethod("getContainer", ServletContext.class); - Method upgrade = ReflectionUtils.findMethod(type, "upgrade", (Class[]) null); - Assert.state(upgrade != null, "Upgrade method not found"); - upgradeMethod = upgrade; - - type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse"); - setAcceptedSubProtocol = type.getMethod("setAcceptedSubProtocol", String.class); - } - catch (Exception ex) { - throw new IllegalStateException("No compatible Jetty version found", ex); - } - } - - @Override public Mono upgrade( ServerWebExchange exchange, WebSocketHandler handler, @@ -98,62 +62,31 @@ public Mono upgrade( HandshakeInfo handshakeInfo = handshakeInfoFactory.get(); DataBufferFactory factory = response.bufferFactory(); - // Trigger WebFlux preCommit actions and upgrade + // Trigger WebFlux preCommit actions before upgrade return exchange.getResponse().setComplete() .then(Mono.deferContextual(contextView -> { JettyWebSocketHandlerAdapter adapter = new JettyWebSocketHandlerAdapter( ContextWebSocketHandler.decorate(handler, contextView), session -> new JettyWebSocketSession(session, handshakeInfo, factory)); + JettyWebSocketCreator webSocketCreator = (upgradeRequest, upgradeResponse) -> { + if (subProtocol != null) { + upgradeResponse.setAcceptedSubProtocol(subProtocol); + } + return adapter; + }; + + JettyWebSocketServerContainer container = JettyWebSocketServerContainer.getContainer(servletContext); + try { - Object creator = createJettyWebSocketCreator(adapter, subProtocol); - Object container = ReflectionUtils.invokeMethod(getContainerMethod, null, servletContext); - ReflectionUtils.invokeMethod(upgradeMethod, container, creator, servletRequest, servletResponse); + container.upgrade(webSocketCreator, servletRequest, servletResponse); } catch (Exception ex) { return Mono.error(ex); } + return Mono.empty(); })); } - private static Object createJettyWebSocketCreator( - JettyWebSocketHandlerAdapter adapter, @Nullable String protocol) { - - ProxyFactory factory = new ProxyFactory(EmptyTargetSource.INSTANCE); - factory.addInterface(webSocketCreatorClass); - factory.addAdvice(new WebSocketCreatorInterceptor(adapter, protocol)); - return factory.getProxy(); - } - - - /** - * Proxy for a JettyWebSocketCreator to supply the WebSocket handler and set the sub-protocol. - */ - private static class WebSocketCreatorInterceptor implements MethodInterceptor { - - private final JettyWebSocketHandlerAdapter adapter; - - @Nullable - private final String protocol; - - - public WebSocketCreatorInterceptor( - JettyWebSocketHandlerAdapter adapter, @Nullable String protocol) { - - this.adapter = adapter; - this.protocol = protocol; - } - - @Nullable - @Override - public Object invoke(@NonNull MethodInvocation invocation) { - if (this.protocol != null) { - ReflectionUtils.invokeMethod( - setAcceptedSubProtocol, invocation.getArguments()[2], this.protocol); - } - return this.adapter; - } - } - } From 853ab5d67b3336ae73ad962da7a60b19cc455667 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 17 Sep 2021 12:52:41 +0100 Subject: [PATCH 116/735] Fix Jetty 10+ test failure related to empty path handling See gh-27424 --- .../server/reactive/ErrorHandlerIntegrationTests.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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 79d0158eae99..f91779cba1be 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 @@ -27,6 +27,7 @@ import org.springframework.web.client.RestTemplate; import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpHandlerIntegrationTests; import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer; +import org.springframework.web.testfixture.http.server.reactive.bootstrap.JettyHttpServer; import static org.assertj.core.api.Assertions.assertThat; @@ -80,7 +81,14 @@ void emptyPathSegments(HttpServer httpServer) throws Exception { URI url = new URI("http://localhost:" + port + "//"); ResponseEntity response = restTemplate.getForEntity(url, String.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + // Jetty 10+ rejects empty path segments, see https://github.com/eclipse/jetty.project/issues/6302, + // but an application can apply CompactPathRule via RewriteHandler: + // https://www.eclipse.org/jetty/documentation/jetty-11/programming_guide.php + + HttpStatus expectedStatus = + (httpServer instanceof JettyHttpServer ? HttpStatus.BAD_REQUEST : HttpStatus.OK); + + assertThat(response.getStatusCode()).isEqualTo(expectedStatus); } From 8b5f5d9f653d0656787e285065f5bdd66fc9427e Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 17 Sep 2021 14:37:45 +0100 Subject: [PATCH 117/735] Fix multipart request test with Jetty server See gh-27424 --- .../annotation/RequestPartIntegrationTests.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartIntegrationTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartIntegrationTests.java index 4370f9a471e5..dd45fd080139 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartIntegrationTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartIntegrationTests.java @@ -139,17 +139,16 @@ public void standardMultipartResolver() throws Exception { @Test // SPR-13319 public void standardMultipartResolverWithEncodedFileName() throws Exception { - byte[] boundary = MimeTypeUtils.generateMultipartBoundary(); - String boundaryText = new String(boundary, "US-ASCII"); + String boundaryText = MimeTypeUtils.generateMultipartBoundaryString(); Map params = Collections.singletonMap("boundary", boundaryText); String content = - "--" + boundaryText + "\n" + - "Content-Disposition: form-data; name=\"file\"; filename*=\"utf-8''%C3%A9l%C3%A8ve.txt\"\n" + - "Content-Type: text/plain\n" + - "Content-Length: 7\n" + - "\n" + - "content\n" + + "--" + boundaryText + "\r\n" + + "Content-Disposition: form-data; name=\"file\"; filename*=\"utf-8''%C3%A9l%C3%A8ve.txt\"\r\n" + + "Content-Type: text/plain\r\n" + + "Content-Length: 7\r\n" + + "\r\n" + + "content\r\n" + "--" + boundaryText + "--"; RequestEntity requestEntity = From 01426481ea0287a7f2cf889493919031dcd41b14 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 17 Sep 2021 14:38:13 +0100 Subject: [PATCH 118/735] Enforce timeout in WebFlux multipart tests --- .../function/MultipartIntegrationTests.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/MultipartIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/MultipartIntegrationTests.java index a1f28b1b63fe..76c8b51bf46b 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/MultipartIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/MultipartIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.time.Duration; import java.util.Map; import reactor.core.publisher.Mono; @@ -72,7 +73,8 @@ void multipartData(HttpServer httpServer) throws Exception { StepVerifier .create(result) .consumeNextWith(entity -> assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK)) - .verifyComplete(); + .expectComplete() + .verify(Duration.ofSeconds(5)); } @ParameterizedHttpServerTest @@ -89,7 +91,8 @@ void parts(HttpServer httpServer) throws Exception { StepVerifier .create(result) .consumeNextWith(entity -> assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK)) - .verifyComplete(); + .expectComplete() + .verify(Duration.ofSeconds(5)); } @ParameterizedHttpServerTest @@ -119,7 +122,8 @@ void transferTo(HttpServer httpServer) throws Exception { fail("IOException", ex); } }) - .verifyComplete(); + .expectComplete() + .verify(Duration.ofSeconds(5)); } private MultiValueMap> generateBody() { @@ -193,8 +197,7 @@ private Mono createTempFile() { catch (IOException ex) { return Mono.error(ex); } - }) - .subscribeOn(Schedulers.boundedElastic()); + }).subscribeOn(Schedulers.boundedElastic()); } } From 958eb0f964ddef1ff1440fd10c5cb850f6ee96db Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 17 Sep 2021 14:54:09 +0100 Subject: [PATCH 119/735] Revert temporary exclusion of failing Jetty 11 tests Closes gh-27424 This reverts commit 5eac8555d9b115b40d6de6b2c8f935ffc35864de. --- build.gradle | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/build.gradle b/build.gradle index b96029abf6cb..c6cdde1364e8 100644 --- a/build.gradle +++ b/build.gradle @@ -299,18 +299,6 @@ configure([rootProject] + javaProjects) { project -> test { useJUnitPlatform() include(["**/*Tests.class", "**/*Test.class"]) - // TODO Enable excluded tests (https://github.com/spring-projects/spring-framework/issues/27424) - filter { - excludeTestsMatching("*ErrorHandlerIntegrationTests") - excludeTestsMatching("*RequestPartIntegrationTests") - excludeTestsMatching("*WebSocketConfigurationTests") - excludeTestsMatching("*WebSocketHandshakeTests") - excludeTestsMatching("*StompWebSocketIntegrationTests") - excludeTestsMatching("*RequestMappingIntegrationTests") - excludeTestsMatching("*CrossOriginAnnotationIntegrationTests") - excludeTestsMatching("*NestedRouteIntegrationTests") - excludeTestsMatching("*WebSocketIntegrationTests") - } systemProperty("java.awt.headless", "true") systemProperty("testGroups", project.properties.get("testGroups")) systemProperty("io.netty.leakDetection.level", "paranoid") From 0b552a3534e080ca842c7f08a9950233ce56e72e Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 15 Sep 2021 14:15:59 +0200 Subject: [PATCH 120/735] Migrate to TestNG Engine for the JUnit Platform in spring-test Prior to this commit, we had configured separate test tasks for JUnit and TestNG. In addition, we configured a standard `test` task that depended on the `junit` and `testNG` tasks, and we had an additional `aggregateTestReports` task that aggregated the reports from the JUnit and TestNG test tasks. Thanks to the introduction of the "TestNG Engine for the JUnit Platform", this commit simplifies our Gradle build in the spring-test module by running JUnit 4, JUnit Jupiter, and TestNG tests on the JUnit Platform in a single Gradle `test` task. See gh-27406 --- build.gradle | 1 + spring-test/spring-test.gradle | 34 +++++++--------------------------- 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/build.gradle b/build.gradle index 8a3207ccc859..e59131307316 100644 --- a/build.gradle +++ b/build.gradle @@ -188,6 +188,7 @@ configure(allprojects) { project -> exclude group: "junit", name: "junit" } dependency "org.testng:testng:7.4.0" + dependency "org.junit.support:testng-engine:1.0.1" dependency "org.hamcrest:hamcrest:2.1" dependency "org.awaitility:awaitility:3.1.6" dependency "org.assertj:assertj-core:3.20.2" diff --git a/spring-test/spring-test.gradle b/spring-test/spring-test.gradle index 365ce7d316f9..026507a0281b 100644 --- a/spring-test/spring-test.gradle +++ b/spring-test/spring-test.gradle @@ -77,43 +77,23 @@ dependencies { testRuntimeOnly("org.junit.vintage:junit-vintage-engine") { exclude group: "junit", module: "junit" } + testRuntimeOnly("org.junit.support:testng-engine") testRuntimeOnly("org.glassfish:javax.el") testRuntimeOnly("com.sun.xml.bind:jaxb-core") testRuntimeOnly("com.sun.xml.bind:jaxb-impl") } -task junit(type: Test) { - description = "Runs JUnit 4 and JUnit Jupiter tests." +test { + description = "Runs JUnit 4, JUnit Jupiter, and TestNG tests." useJUnitPlatform { + includeEngines "junit-vintage", "junit-jupiter", "testng" excludeTags "failing-test-case" } + // We use `include` instead of `filter.includeTestsMatching`, since + // the latter results in some tests being executed/reported + // multiple times. include(["**/*Tests.class", "**/*Test.class"]) - exclude(["**/testng/**/*.*"]) systemProperty("testGroups", project.properties.get("testGroups")) // Java Util Logging for the JUnit Platform. // systemProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager") } - -task testNG(type: Test) { - description = "Runs TestNG tests." - useTestNG() - include(["**/testng/**/*Tests.class", "**/testng/**/*Test.class"]) - systemProperty("testGroups", project.properties.get("testGroups")) - // Show STD_OUT & STD_ERR of the test JVM(s) on the console: - // testLogging.showStandardStreams = true - // forkEvery 1 -} - -test { - description = "Runs all tests." - dependsOn junit, testNG - exclude(["**/*.*"]) -} - -task aggregateTestReports(type: TestReport) { - description = "Aggregates JUnit and TestNG test reports." - destinationDir = test.reports.html.outputLocation.get().getAsFile() - reportOn junit, testNG -} - -check.dependsOn aggregateTestReports From e29867b96e835a53d0222ad666273b5e93c800a6 Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Wed, 15 Sep 2021 16:08:36 +0200 Subject: [PATCH 121/735] Exclude TestCase classes in spring-test build When not excluded, TestNG will pick up nested TestCase classes and run them. This commit therefore filters out `*TestCase` test classes from the build since these are not intended to be executed with the build. See gh-27406 --- spring-test/spring-test.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-test/spring-test.gradle b/spring-test/spring-test.gradle index 026507a0281b..0bc316636a7a 100644 --- a/spring-test/spring-test.gradle +++ b/spring-test/spring-test.gradle @@ -93,6 +93,7 @@ test { // the latter results in some tests being executed/reported // multiple times. include(["**/*Tests.class", "**/*Test.class"]) + filter.excludeTestsMatching("*TestCase") systemProperty("testGroups", project.properties.get("testGroups")) // Java Util Logging for the JUnit Platform. // systemProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager") From e439d6f64da2d616f2c6345444b1c7dd5640801b Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 20 Sep 2021 14:54:25 +0200 Subject: [PATCH 122/735] Upgrade to AssertJ 3.21.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e59131307316..33b6227dabb0 100644 --- a/build.gradle +++ b/build.gradle @@ -191,7 +191,7 @@ configure(allprojects) { project -> dependency "org.junit.support:testng-engine:1.0.1" dependency "org.hamcrest:hamcrest:2.1" dependency "org.awaitility:awaitility:3.1.6" - dependency "org.assertj:assertj-core:3.20.2" + dependency "org.assertj:assertj-core:3.21.0" dependencySet(group: 'org.xmlunit', version: '2.8.2') { entry 'xmlunit-assertj' entry('xmlunit-matchers') { From 3beb07427817069d405f22729c4f0c35b67f7948 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 21 Sep 2021 09:13:06 +0200 Subject: [PATCH 123/735] Remove support for RxJava 1.x Also removes unnecessary flowPublisherPresent check on JDK 9+, depending on Reactor presence for its JDK Flow adapter instead. Closes gh-27443 --- build.gradle | 2 - spring-core/spring-core.gradle | 2 - .../core/ReactiveAdapterRegistry.java | 66 ++++--------------- .../core/ReactiveAdapterRegistryTests.java | 64 +----------------- 4 files changed, 13 insertions(+), 121 deletions(-) diff --git a/build.gradle b/build.gradle index b02938e84c90..42f5225e9b92 100644 --- a/build.gradle +++ b/build.gradle @@ -64,8 +64,6 @@ configure(allprojects) { project -> entry 'groovy-xml' } - dependency "io.reactivex:rxjava:1.3.8" - dependency "io.reactivex:rxjava-reactive-streams:1.2.1" dependency "io.reactivex.rxjava2:rxjava:2.2.21" dependency "io.reactivex.rxjava3:rxjava:3.1.1" dependency "io.smallrye.reactive:mutiny:1.0.0" diff --git a/spring-core/spring-core.gradle b/spring-core/spring-core.gradle index de0f6a756e08..43ab833ddfe3 100644 --- a/spring-core/spring-core.gradle +++ b/spring-core/spring-core.gradle @@ -44,8 +44,6 @@ dependencies { optional("org.jetbrains.kotlinx:kotlinx-coroutines-core") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") optional("io.projectreactor:reactor-core") - optional("io.reactivex:rxjava") - optional("io.reactivex:rxjava-reactive-streams") optional("io.reactivex.rxjava2:rxjava") optional("io.reactivex.rxjava3:rxjava") optional("io.smallrye.reactive:mutiny") diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java index 5010538b6f67..37fc922b5b59 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -32,7 +32,6 @@ import reactor.blockhound.integration.BlockHoundIntegration; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import rx.RxReactiveStreams; import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; @@ -44,15 +43,12 @@ * {@code Observable}, and others. * *

    By default, depending on classpath availability, adapters are registered - * for Reactor, RxJava 2/3, or RxJava 1 (+ RxJava Reactive Streams bridge), - * {@link CompletableFuture}, Java 9+ {@code Flow.Publisher}, and Kotlin - * Coroutines' {@code Deferred} and {@code Flow}. - * - *

    Note: As of Spring Framework 5.3, support for RxJava 1.x - * is deprecated in favor of RxJava 2 and 3. + * for Reactor, RxJava 2/3, {@link CompletableFuture}, {@code Flow.Publisher}, + * and Kotlin Coroutines' {@code Deferred} and {@code Flow}. * * @author Rossen Stoyanchev * @author Sebastien Deleuze + * @author Juergen Hoeller * @since 5.0 */ public class ReactiveAdapterRegistry { @@ -62,14 +58,10 @@ public class ReactiveAdapterRegistry { private static final boolean reactorPresent; - private static final boolean rxjava1Present; - private static final boolean rxjava2Present; private static final boolean rxjava3Present; - private static final boolean flowPublisherPresent; - private static final boolean kotlinCoroutinesPresent; private static final boolean mutinyPresent; @@ -77,11 +69,8 @@ public class ReactiveAdapterRegistry { static { ClassLoader classLoader = ReactiveAdapterRegistry.class.getClassLoader(); reactorPresent = ClassUtils.isPresent("reactor.core.publisher.Flux", classLoader); - rxjava1Present = ClassUtils.isPresent("rx.Observable", classLoader) && - ClassUtils.isPresent("rx.RxReactiveStreams", classLoader); rxjava2Present = ClassUtils.isPresent("io.reactivex.Flowable", classLoader); rxjava3Present = ClassUtils.isPresent("io.reactivex.rxjava3.core.Flowable", classLoader); - flowPublisherPresent = ClassUtils.isPresent("java.util.concurrent.Flow.Publisher", classLoader); kotlinCoroutinesPresent = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt", classLoader); mutinyPresent = ClassUtils.isPresent("io.smallrye.mutiny.Multi", classLoader); } @@ -97,29 +86,17 @@ public ReactiveAdapterRegistry() { // Reactor if (reactorPresent) { new ReactorRegistrar().registerAdapters(this); + new ReactorJdkFlowAdapterRegistrar().registerAdapter(this); } - // RxJava1 (deprecated) - if (rxjava1Present) { - new RxJava1Registrar().registerAdapters(this); - } - - // RxJava2 + // RxJava if (rxjava2Present) { new RxJava2Registrar().registerAdapters(this); } - // RxJava3 if (rxjava3Present) { new RxJava3Registrar().registerAdapters(this); } - // Java 9+ Flow.Publisher - if (flowPublisherPresent) { - new ReactorJdkFlowAdapterRegistrar().registerAdapter(this); - } - // If not present, do nothing for the time being... - // We can fall back on "reactive-streams-flow-bridge" (once released) - // Kotlin Coroutines if (reactorPresent && kotlinCoroutinesPresent) { new CoroutinesRegistrar().registerAdapters(this); @@ -253,23 +230,14 @@ void registerAdapters(ReactiveAdapterRegistry registry) { } - private static class RxJava1Registrar { + private static class ReactorJdkFlowAdapterRegistrar { - void registerAdapters(ReactiveAdapterRegistry registry) { - registry.registerReactiveType( - ReactiveTypeDescriptor.multiValue(rx.Observable.class, rx.Observable::empty), - source -> RxReactiveStreams.toPublisher((rx.Observable) source), - RxReactiveStreams::toObservable - ); - registry.registerReactiveType( - ReactiveTypeDescriptor.singleRequiredValue(rx.Single.class), - source -> RxReactiveStreams.toPublisher((rx.Single) source), - RxReactiveStreams::toSingle - ); + void registerAdapter(ReactiveAdapterRegistry registry) { + Flow.Publisher emptyFlow = JdkFlowAdapter.publisherToFlowPublisher(Flux.empty()); registry.registerReactiveType( - ReactiveTypeDescriptor.noValue(rx.Completable.class, rx.Completable::complete), - source -> RxReactiveStreams.toPublisher((rx.Completable) source), - RxReactiveStreams::toCompletable + ReactiveTypeDescriptor.multiValue(Flow.Publisher.class, () -> emptyFlow), + source -> JdkFlowAdapter.flowPublisherToFlux((Flow.Publisher) source), + JdkFlowAdapter::publisherToFlowPublisher ); } } @@ -347,18 +315,6 @@ void registerAdapters(ReactiveAdapterRegistry registry) { } } - private static class ReactorJdkFlowAdapterRegistrar { - - void registerAdapter(ReactiveAdapterRegistry registry) { - Flow.Publisher emptyFlow = JdkFlowAdapter.publisherToFlowPublisher(Flux.empty()); - registry.registerReactiveType( - ReactiveTypeDescriptor.multiValue(Flow.Publisher.class, () -> emptyFlow), - source -> JdkFlowAdapter.flowPublisherToFlux((Flow.Publisher) source), - JdkFlowAdapter::publisherToFlowPublisher - ); - } - } - /** * ReactiveAdapter variant that wraps adapted Publishers as {@link Flux} or diff --git a/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java b/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java index 579e1a463afc..ea73cfbd7be0 100644 --- a/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java +++ b/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ /** * Unit tests for {@link ReactiveAdapterRegistry}. + * * @author Rossen Stoyanchev */ @SuppressWarnings("unchecked") @@ -117,67 +118,6 @@ void fromCompletableFuture() { } } - @Nested - class RxJava1 { - - @Test - void defaultAdapterRegistrations() { - assertThat(getAdapter(rx.Observable.class)).isNotNull(); - assertThat(getAdapter(rx.Single.class)).isNotNull(); - assertThat(getAdapter(rx.Completable.class)).isNotNull(); - } - - @Test - void toObservable() { - List sequence = Arrays.asList(1, 2, 3); - Publisher source = Flux.fromIterable(sequence); - Object target = getAdapter(rx.Observable.class).fromPublisher(source); - assertThat(target instanceof rx.Observable).isTrue(); - assertThat(((rx.Observable) target).toList().toBlocking().first()).isEqualTo(sequence); - } - - @Test - void toSingle() { - Publisher source = Flux.fromArray(new Integer[] {1}); - Object target = getAdapter(rx.Single.class).fromPublisher(source); - assertThat(target instanceof rx.Single).isTrue(); - assertThat(((rx.Single) target).toBlocking().value()).isEqualTo(Integer.valueOf(1)); - } - - @Test - void toCompletable() { - Publisher source = Flux.fromArray(new Integer[] {1, 2, 3}); - Object target = getAdapter(rx.Completable.class).fromPublisher(source); - assertThat(target instanceof rx.Completable).isTrue(); - assertThat(((rx.Completable) target).get()).isNull(); - } - - @Test - void fromObservable() { - List sequence = Arrays.asList(1, 2, 3); - Object source = rx.Observable.from(sequence); - Object target = getAdapter(rx.Observable.class).toPublisher(source); - assertThat(target instanceof Flux).as("Expected Flux Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Flux) target).collectList().block(ONE_SECOND)).isEqualTo(sequence); - } - - @Test - void fromSingle() { - Object source = rx.Single.just(1); - Object target = getAdapter(rx.Single.class).toPublisher(source); - assertThat(target instanceof Mono).as("Expected Mono Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Mono) target).block(ONE_SECOND)).isEqualTo(Integer.valueOf(1)); - } - - @Test - void fromCompletable() { - Object source = rx.Completable.complete(); - Object target = getAdapter(rx.Completable.class).toPublisher(source); - assertThat(target instanceof Mono).as("Expected Mono Publisher: " + target.getClass().getName()).isTrue(); - ((Mono) target).block(ONE_SECOND); - } - } - @Nested class RxJava2 { From 40c51efee806fbb36de4f3337d76c36cb31aac65 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 21 Sep 2021 10:33:25 +0200 Subject: [PATCH 124/735] Introduce @Suite for TestNG tests In order to allow developers to execute TestNG tests in Eclipse IDE without installing the TestNG plugin for Eclipse, this commit introduces a JUnit Platform @Suite class that can be executed within the IDE. See gh-27407 --- .../test/context/testng/TestNGTestSuite.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 spring-test/src/test/java/org/springframework/test/context/testng/TestNGTestSuite.java diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/TestNGTestSuite.java b/spring-test/src/test/java/org/springframework/test/context/testng/TestNGTestSuite.java new file mode 100644 index 000000000000..4e63b116cd72 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/testng/TestNGTestSuite.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.testng; + +import org.junit.platform.suite.api.IncludeEngines; +import org.junit.platform.suite.api.SelectPackages; +import org.junit.platform.suite.api.Suite; + +/** + * JUnit Platform based test suite for tests written in TestNG that involve the + * Spring TestContext Framework. + * + *

    This suite is only intended to be used manually within an IDE. + * + *

    Logging Configuration

    + * + *

    In order for our log4j2 configuration to be used in an IDE, you must set the + * following system property before running any tests — for example, in + * Run Configurations in Eclipse. + * + *

    + * -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
    + * 
    + * + * @author Sam Brannen + * @since 5.3.11 + */ +@Suite +@IncludeEngines("testng") +@SelectPackages("org.springframework.test.context.testng") +class TestNGTestSuite { +} From 28496059bca970fddf5591a3dba8533166b4aaf3 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 21 Sep 2021 10:35:34 +0200 Subject: [PATCH 125/735] Make TestNG test methods public due to bug in TestNG TestEngine This commit makes all test methods in our TestNG test classes public due to the following bug in the TestNG engine for the JUnit Platform. https://github.com/junit-team/testng-engine/issues/16 See gh-27407 --- ...AnnotationConfigTestNGSpringContextTests.java | 2 +- ...figTransactionalTestNGSpringContextTests.java | 4 ++-- ...eteTransactionalTestNGSpringContextTests.java | 16 ++++++++-------- .../TestNGApplicationEventsIntegrationTests.java | 4 ++-- ...tExecutionListenerTestNGIntegrationTests.java | 4 ++-- .../testng/web/TestNGSpringContextWebTests.java | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/AnnotationConfigTestNGSpringContextTests.java b/spring-test/src/test/java/org/springframework/test/context/testng/AnnotationConfigTestNGSpringContextTests.java index f36352cc9ffe..f334fb4f110e 100644 --- a/spring-test/src/test/java/org/springframework/test/context/testng/AnnotationConfigTestNGSpringContextTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/testng/AnnotationConfigTestNGSpringContextTests.java @@ -48,7 +48,7 @@ public class AnnotationConfigTestNGSpringContextTests extends AbstractTestNGSpri Pet pet; @Test - void autowiringFromConfigClass() { + public void autowiringFromConfigClass() { assertThat(employee).as("The employee should have been autowired.").isNotNull(); assertThat(employee.getName()).isEqualTo("John Smith"); diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/AnnotationConfigTransactionalTestNGSpringContextTests.java b/spring-test/src/test/java/org/springframework/test/context/testng/AnnotationConfigTransactionalTestNGSpringContextTests.java index eadcee96e89f..9b324b42d72f 100644 --- a/spring-test/src/test/java/org/springframework/test/context/testng/AnnotationConfigTransactionalTestNGSpringContextTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/testng/AnnotationConfigTransactionalTestNGSpringContextTests.java @@ -112,7 +112,7 @@ void afterClass() { @Test @Transactional(propagation = Propagation.NOT_SUPPORTED) - void autowiringFromConfigClass() { + public void autowiringFromConfigClass() { assertThat(employee).as("The employee should have been autowired.").isNotNull(); assertThat(employee.getName()).isEqualTo("John Smith"); @@ -136,7 +136,7 @@ void setUp() throws Exception { } @Test - void modifyTestDataWithinTransaction() { + public void modifyTestDataWithinTransaction() { assertThatTransaction().isActive(); assertAddPerson(JANE); assertAddPerson(SUE); diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/ConcreteTransactionalTestNGSpringContextTests.java b/spring-test/src/test/java/org/springframework/test/context/testng/ConcreteTransactionalTestNGSpringContextTests.java index 3da61007d1ee..f80cc68867aa 100644 --- a/spring-test/src/test/java/org/springframework/test/context/testng/ConcreteTransactionalTestNGSpringContextTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/testng/ConcreteTransactionalTestNGSpringContextTests.java @@ -151,7 +151,7 @@ void afterTransaction() { @Test @Transactional(propagation = Propagation.NOT_SUPPORTED) - void verifyBeanNameSet() { + public void verifyBeanNameSet() { assertThatTransaction().isNotActive(); assertThat(this.beanName) .as("The bean name of this test instance should have been set to the fully qualified class name due to BeanNameAware semantics.") @@ -160,7 +160,7 @@ void verifyBeanNameSet() { @Test @Transactional(propagation = Propagation.NOT_SUPPORTED) - void verifyApplicationContextSet() { + public void verifyApplicationContextSet() { assertThatTransaction().isNotActive(); assertThat(super.applicationContext) .as("The application context should have been set due to ApplicationContextAware semantics.") @@ -171,7 +171,7 @@ void verifyApplicationContextSet() { @Test @Transactional(propagation = Propagation.NOT_SUPPORTED) - void verifyBeanInitialized() { + public void verifyBeanInitialized() { assertThatTransaction().isNotActive(); assertThat(beanInitialized) .as("This test instance should have been initialized due to InitializingBean semantics.") @@ -180,7 +180,7 @@ void verifyBeanInitialized() { @Test @Transactional(propagation = Propagation.NOT_SUPPORTED) - void verifyAnnotationAutowiredFields() { + public void verifyAnnotationAutowiredFields() { assertThatTransaction().isNotActive(); assertThat(nonrequiredLong).as("The nonrequiredLong field should NOT have been autowired.").isNull(); assertThat(pet).as("The pet field should have been autowired.").isNotNull(); @@ -189,7 +189,7 @@ void verifyAnnotationAutowiredFields() { @Test @Transactional(propagation = Propagation.NOT_SUPPORTED) - void verifyAnnotationAutowiredMethods() { + public void verifyAnnotationAutowiredMethods() { assertThatTransaction().isNotActive(); assertThat(employee).as("The setEmployee() method should have been autowired.").isNotNull(); assertThat(employee.getName()).as("employee's name.").isEqualTo("John Smith"); @@ -197,20 +197,20 @@ void verifyAnnotationAutowiredMethods() { @Test @Transactional(propagation = Propagation.NOT_SUPPORTED) - void verifyResourceAnnotationInjectedFields() { + public void verifyResourceAnnotationInjectedFields() { assertThatTransaction().isNotActive(); assertThat(foo).as("The foo field should have been injected via @Resource.").isEqualTo("Foo"); } @Test @Transactional(propagation = Propagation.NOT_SUPPORTED) - void verifyResourceAnnotationInjectedMethods() { + public void verifyResourceAnnotationInjectedMethods() { assertThatTransaction().isNotActive(); assertThat(bar).as("The setBar() method should have been injected via @Resource.").isEqualTo("Bar"); } @Test - void modifyTestDataWithinTransaction() { + public void modifyTestDataWithinTransaction() { assertThatTransaction().isActive(); assertAddPerson(JANE); assertAddPerson(SUE); diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/event/TestNGApplicationEventsIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/testng/event/TestNGApplicationEventsIntegrationTests.java index e7f32e5ebc35..67748d840947 100644 --- a/spring-test/src/test/java/org/springframework/test/context/testng/event/TestNGApplicationEventsIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/testng/event/TestNGApplicationEventsIntegrationTests.java @@ -72,12 +72,12 @@ void beforeEach() { } @Test - void test1() { + public void test1() { assertTestExpectations("test1"); } @Test - void test2() { + public void test2() { assertTestExpectations("test2"); } diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/web/ServletTestExecutionListenerTestNGIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/testng/web/ServletTestExecutionListenerTestNGIntegrationTests.java index 9141c93f2e7c..6602f00caf4d 100644 --- a/spring-test/src/test/java/org/springframework/test/context/testng/web/ServletTestExecutionListenerTestNGIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/testng/web/ServletTestExecutionListenerTestNGIntegrationTests.java @@ -57,7 +57,7 @@ static class Config { * @see #ensureMocksAreReinjectedBetweenTests_2 */ @Test - void ensureMocksAreReinjectedBetweenTests_1() { + public void ensureMocksAreReinjectedBetweenTests_1() { assertInjectedServletRequestEqualsRequestInRequestContextHolder(); } @@ -67,7 +67,7 @@ void ensureMocksAreReinjectedBetweenTests_1() { * @see #ensureMocksAreReinjectedBetweenTests_1 */ @Test - void ensureMocksAreReinjectedBetweenTests_2() { + public void ensureMocksAreReinjectedBetweenTests_2() { assertInjectedServletRequestEqualsRequestInRequestContextHolder(); } diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/web/TestNGSpringContextWebTests.java b/spring-test/src/test/java/org/springframework/test/context/testng/web/TestNGSpringContextWebTests.java index 14bead449f18..1ca10f399ba0 100644 --- a/spring-test/src/test/java/org/springframework/test/context/testng/web/TestNGSpringContextWebTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/testng/web/TestNGSpringContextWebTests.java @@ -89,7 +89,7 @@ public void setServletContext(ServletContext servletContext) { } @Test - void basicWacFeatures() throws Exception { + public void basicWacFeatures() throws Exception { assertThat(wac.getServletContext()).as("ServletContext should be set in the WAC.").isNotNull(); assertThat(servletContext).as("ServletContext should have been set via ServletContextAware.").isNotNull(); @@ -114,7 +114,7 @@ void basicWacFeatures() throws Exception { } @Test - void fooEnigmaAutowired() { + public void fooEnigmaAutowired() { assertThat(foo).isEqualTo("enigma"); } From 070d087dbcc96360887fc6e97064c3cd2480881d Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 21 Sep 2021 11:30:30 +0200 Subject: [PATCH 126/735] Reinstate -Werror for Groovy compilation This commit partially reverts cf2429b0f0ce2a5278bdc2556663caf6cf0b0cae in order to reinstate -Werror for Groovy compilation in spring-beans. The `decorating` field in GroovyDynamicElementReader has been changed from boolean to Boolean in order to avoid the JDK 17 deprecation warning for use of `new Boolean(false)` which the Groovy compiler apparently uses behind the scenes when compiling Groovy source code. --- spring-beans/spring-beans.gradle | 3 +-- .../beans/factory/groovy/GroovyDynamicElementReader.groovy | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/spring-beans/spring-beans.gradle b/spring-beans/spring-beans.gradle index 9c4d0af79e1a..3c5d34179e77 100644 --- a/spring-beans/spring-beans.gradle +++ b/spring-beans/spring-beans.gradle @@ -23,8 +23,7 @@ sourceSets { } compileGroovy { - // Groovy generates Java code with "new Boolean" usage which is deprecated on JDK 17 - // options.compilerArgs += "-Werror" + options.compilerArgs += "-Werror" } // This module also builds Kotlin code and the compileKotlin task naturally depends on diff --git a/spring-beans/src/main/groovy/org/springframework/beans/factory/groovy/GroovyDynamicElementReader.groovy b/spring-beans/src/main/groovy/org/springframework/beans/factory/groovy/GroovyDynamicElementReader.groovy index d0171216948b..8157450773b4 100644 --- a/spring-beans/src/main/groovy/org/springframework/beans/factory/groovy/GroovyDynamicElementReader.groovy +++ b/spring-beans/src/main/groovy/org/springframework/beans/factory/groovy/GroovyDynamicElementReader.groovy @@ -40,7 +40,7 @@ class GroovyDynamicElementReader extends GroovyObjectSupport { private final GroovyBeanDefinitionWrapper beanDefinition - protected final boolean decorating; + protected final Boolean decorating; private boolean callAfterInvocation = true From a37dde9a1cdc0fcd1151def147f1b02651af9928 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 21 Sep 2021 12:09:05 +0200 Subject: [PATCH 127/735] Revise Eclipse/STS Project Import Guide based on status quo See gh-27407 --- gradle/ide.gradle | 4 ---- import-into-eclipse.md | 38 ++++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/gradle/ide.gradle b/gradle/ide.gradle index af4664e06018..1dddd7d63c09 100644 --- a/gradle/ide.gradle +++ b/gradle/ide.gradle @@ -87,10 +87,6 @@ task eclipseJdtSettings(type: Copy) { outputs.upToDateWhen { false } } -task eclipseBuildship { - dependsOn eclipseSettings, eclipseJdtSettings -} - task eclipseWstComponentSettings(type: Copy) { from rootProject.files('src/eclipse/org.eclipse.wst.common.component') into project.file('.settings/') diff --git a/import-into-eclipse.md b/import-into-eclipse.md index bb665d788a13..c09eef05a592 100644 --- a/import-into-eclipse.md +++ b/import-into-eclipse.md @@ -5,9 +5,9 @@ projects into Eclipse or the Spring Tool Suite (_STS_). It is recommended that y have a recent version of Eclipse. As a bare minimum you will need Eclipse with full Java 8 support, Eclipse Buildship, the Kotlin plugin, and the Groovy plugin. -The following instructions have been tested against [STS](https://spring.io/tools) 4.3.2 -([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-432-changelog)) -(based on Eclipse 4.12) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship). +The following instructions have been tested against [STS](https://spring.io/tools) 4.12.0 +([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-4120-changelog)) +(based on Eclipse 4.21) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship). The instructions should work with the latest Eclipse distribution as long as you install [Buildship](https://marketplace.eclipse.org/content/buildship-gradle-integration). Note that STS 4 comes with Buildship preinstalled. @@ -16,28 +16,30 @@ that STS 4 comes with Buildship preinstalled. _When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._ -1. Ensure that Eclipse launches with JDK 8. - - For example, on Mac OS this can be configured in the `Info.plist` file located in the `Contents` folder of the installed Eclipse or STS application (e.g., the `Eclipse.app` file). -1. Install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) in Eclipse. -1. Install the [Eclipse Groovy Development Tools](https://github.com/groovy/groovy-eclipse/wiki) in Eclipse. -1. Switch to Groovy 2.5 (Preferences -> Groovy -> Compiler -> Switch to 2.5...) in Eclipse. -1. Change the _Forbidden reference (access rule)_ in Eclipse from Error to Warning -(Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API -> Forbidden reference (access rule)). +1. Install the [Groovy Development Tools](https://marketplace.eclipse.org/content/groovy-development-tools). +1. Switch to Groovy 3.0 in Eclipse (Preferences → Groovy → Compiler → Switch to 3.0...). + - If you encounter build errors stating something similar to _"Groovy: compiler mismatch: project level is 2.5, workspace level is 3.0"_, change the Groovy compiler version to 3.0 for each affected project. +1. Ensure that the _Forbidden reference (access rule)_ in Eclipse is set to `Info` +(Preferences → Java → Compiler → Errors/Warnings → Deprecated and restricted API → Forbidden reference (access rule)). +1. Optionally install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) if you need to execute Kotlin-based tests or develop Kotlin extensions. 1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project. The AspectJ Development Tools available in the Eclipse Marketplace have been tested with these instructions using STS 4.5 (Eclipse 4.14). -1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute TestNG tests in the `spring-test` module. +1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute individual TestNG test classes or tests in the `spring-test` module. + - As an alternative to installing the TestNG plugin, you can execute the `org.springframework.test.context.testng.TestNGTestSuite` class as a "JUnit 5" test class in Eclipse. 1. Build `spring-oxm` from the command line with `./gradlew :spring-oxm:check`. -1. To apply project specific settings, run `./gradlew eclipseBuildship` from the command line. -1. Import into Eclipse (File -> Import -> Gradle -> Existing Gradle Project -> Navigate to the locally cloned `spring-framework` directory -> Select Finish). +1. To apply Spring Framework specific settings, run `./gradlew cleanEclipse eclipse` from the command line. +1. Import all projects into Eclipse (File → Import → Gradle → Existing Gradle Project → Navigate to the locally cloned `spring-framework` directory → Select Finish). - If you have not installed AJDT, exclude the `spring-aspects` project from the import, if prompted, or close it after the import. - - If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences -> Gradle -> Java home). -1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select `Build Path -> Use as Source Folder`). - - If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the small downward facing arrow in the upper right corner of the Package Explorer). + - If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences → Gradle → Java home). +1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select "Build Path → Use as Source Folder"). + - If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the _three vertical dots_ in the upper right corner of the Package Explorer). 1. Code away! ## Known Issues -1. `spring-core` and `spring-oxm` should be pre-compiled due to repackaged dependencies. - - See `*RepackJar` tasks in the build. +1. `spring-core` should be pre-compiled due to repackaged dependencies. + - See `*RepackJar` tasks in the `spring-core.gradle` build file. +1. `spring-oxm` should be pre-compiled due to JAXB types generated for tests. + - Note that executing `./gradlew :spring-oxm:check` as explained in the _Steps_ above will compile `spring-core` and generate JAXB types for `spring-oxm`. 1. `spring-aspects` does not compile due to references to aspect types unknown to Eclipse. - If you installed _AJDT_ into Eclipse it should work. 1. While JUnit tests pass from the command line with Gradle, some may fail when run from From 65c1eac11531bc3ee32f580b6c1ff5fa189444b1 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 21 Sep 2021 12:16:06 +0200 Subject: [PATCH 128/735] Fix formatting in Eclipse/STS Project Import Guide See gh-27407 --- import-into-eclipse.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/import-into-eclipse.md b/import-into-eclipse.md index c09eef05a592..00dc11a4a87e 100644 --- a/import-into-eclipse.md +++ b/import-into-eclipse.md @@ -24,7 +24,7 @@ _When instructed to execute `./gradlew` from the command line, be sure to execut 1. Optionally install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) if you need to execute Kotlin-based tests or develop Kotlin extensions. 1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project. The AspectJ Development Tools available in the Eclipse Marketplace have been tested with these instructions using STS 4.5 (Eclipse 4.14). 1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute individual TestNG test classes or tests in the `spring-test` module. - - As an alternative to installing the TestNG plugin, you can execute the `org.springframework.test.context.testng.TestNGTestSuite` class as a "JUnit 5" test class in Eclipse. + - As an alternative to installing the TestNG plugin, you can execute the `org.springframework.test.context.testng.TestNGTestSuite` class as a "JUnit 5" test class in Eclipse. 1. Build `spring-oxm` from the command line with `./gradlew :spring-oxm:check`. 1. To apply Spring Framework specific settings, run `./gradlew cleanEclipse eclipse` from the command line. 1. Import all projects into Eclipse (File → Import → Gradle → Existing Gradle Project → Navigate to the locally cloned `spring-framework` directory → Select Finish). From b0dceb484acf1c190421519a47463c7c59268d1a Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 21 Sep 2021 12:37:51 +0200 Subject: [PATCH 129/735] Remove Eclipse Web Tools Platform (WTP) configuration Since the team no longer needs the ability to treat Eclipse projects as WTP modules, this commit removes the obsolete custom WTP configuration for importing projects into Eclipse IDE. See gh-27407 --- gradle/ide.gradle | 26 +++---------------- src/eclipse/org.eclipse.wst.common.component | 6 ----- ....eclipse.wst.common.project.facet.core.xml | 7 ----- 3 files changed, 4 insertions(+), 35 deletions(-) delete mode 100644 src/eclipse/org.eclipse.wst.common.component delete mode 100644 src/eclipse/org.eclipse.wst.common.project.facet.core.xml diff --git a/gradle/ide.gradle b/gradle/ide.gradle index 1dddd7d63c09..d5215f2875f2 100644 --- a/gradle/ide.gradle +++ b/gradle/ide.gradle @@ -69,38 +69,20 @@ eclipse.classpath.file.whenMerged { } } -// Allow projects to be used as WTP modules -eclipse.project.natures 'org.eclipse.wst.common.project.facet.core.nature' - // Include project specific settings task eclipseSettings(type: Copy) { from rootProject.files( - 'src/eclipse/org.eclipse.jdt.ui.prefs', - 'src/eclipse/org.eclipse.wst.common.project.facet.core.xml') - into project.file('.settings/') - outputs.upToDateWhen { false } -} - -task eclipseJdtSettings(type: Copy) { - from rootProject.file('src/eclipse/org.eclipse.jdt.core.prefs') - into project.file('.settings/') - outputs.upToDateWhen { false } -} - -task eclipseWstComponentSettings(type: Copy) { - from rootProject.files('src/eclipse/org.eclipse.wst.common.component') + 'src/eclipse/org.eclipse.jdt.core.prefs', + 'src/eclipse/org.eclipse.jdt.ui.prefs') into project.file('.settings/') - expand(deployname: project.name) outputs.upToDateWhen { false } } task cleanEclipseSettings(type: Delete) { delete project.file('.settings/org.eclipse.jdt.core.prefs') delete project.file('.settings/org.eclipse.jdt.ui.prefs') - delete project.file('.settings/org.eclipse.wst.common.component') - delete project.file('.settings/org.eclipse.wst.common.project.facet.core.xml') } -tasks['eclipse'].dependsOn(eclipseSettings, eclipseJdtSettings, eclipseWstComponentSettings) -tasks['eclipseJdt'].dependsOn(eclipseJdtSettings) +tasks['eclipse'].dependsOn(eclipseSettings) +tasks['eclipseJdt'].dependsOn(eclipseSettings) tasks['cleanEclipse'].dependsOn(cleanEclipseSettings) diff --git a/src/eclipse/org.eclipse.wst.common.component b/src/eclipse/org.eclipse.wst.common.component deleted file mode 100644 index ce05d97c85ee..000000000000 --- a/src/eclipse/org.eclipse.wst.common.component +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/eclipse/org.eclipse.wst.common.project.facet.core.xml b/src/eclipse/org.eclipse.wst.common.project.facet.core.xml deleted file mode 100644 index 78e8ebb782bd..000000000000 --- a/src/eclipse/org.eclipse.wst.common.project.facet.core.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - From 34abc8f5779e227e52ac6a7c9711564bc7a2bb14 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 21 Sep 2021 13:04:29 +0200 Subject: [PATCH 130/735] The Kotlin plugin is no longer required for development in Eclipse As documented, it's only required if you with to run Kotlin tests or develop Kotlin extensions. See gh-27407 --- import-into-eclipse.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/import-into-eclipse.md b/import-into-eclipse.md index 00dc11a4a87e..c1833bc13a22 100644 --- a/import-into-eclipse.md +++ b/import-into-eclipse.md @@ -3,7 +3,7 @@ This document will guide you through the process of importing the Spring Framework projects into Eclipse or the Spring Tool Suite (_STS_). It is recommended that you have a recent version of Eclipse. As a bare minimum you will need Eclipse with full Java -8 support, Eclipse Buildship, the Kotlin plugin, and the Groovy plugin. +8 support, Eclipse Buildship, and the Groovy plugin. The following instructions have been tested against [STS](https://spring.io/tools) 4.12.0 ([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-4120-changelog)) From 09a1b87d37d074ee1ed96bf6a71ccab44018db0b Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 21 Sep 2021 14:23:02 +0200 Subject: [PATCH 131/735] About notes about AJDT and Kotlin not supported in Eclipse 4.21 See gh-27407 --- import-into-eclipse.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/import-into-eclipse.md b/import-into-eclipse.md index c1833bc13a22..fc3d36a8854b 100644 --- a/import-into-eclipse.md +++ b/import-into-eclipse.md @@ -22,7 +22,9 @@ _When instructed to execute `./gradlew` from the command line, be sure to execut 1. Ensure that the _Forbidden reference (access rule)_ in Eclipse is set to `Info` (Preferences → Java → Compiler → Errors/Warnings → Deprecated and restricted API → Forbidden reference (access rule)). 1. Optionally install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) if you need to execute Kotlin-based tests or develop Kotlin extensions. -1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project. The AspectJ Development Tools available in the Eclipse Marketplace have been tested with these instructions using STS 4.5 (Eclipse 4.14). + - **NOTE**: As of September 21, 2021, it appears that the Kotlin Plugin for Eclipse does not yet work with Eclipse 4.21. +1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project. + - **NOTE**: As of September 21, 2021, it appears that the AspectJ Development Tools do not yet work with Eclipse 4.21. 1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute individual TestNG test classes or tests in the `spring-test` module. - As an alternative to installing the TestNG plugin, you can execute the `org.springframework.test.context.testng.TestNGTestSuite` class as a "JUnit 5" test class in Eclipse. 1. Build `spring-oxm` from the command line with `./gradlew :spring-oxm:check`. From 774583dfa7dba5c3440c4a1341809ab2f3a88780 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 21 Sep 2021 17:07:42 +0200 Subject: [PATCH 132/735] Retain support for legacy PostConstruct/PreDestroy/Inject variants Also removes JAX-WS support from CommonAnnotationBeanPostProcessor. Closes gh-27444 See gh-27422 --- build.gradle | 1 - .../AutowiredAnnotationBeanPostProcessor.java | 26 +++- ...nitDestroyAnnotationBeanPostProcessor.java | 8 +- spring-context/spring-context.gradle | 5 +- .../annotation/AnnotationConfigUtils.java | 48 ++++-- .../CommonAnnotationBeanPostProcessor.java | 147 ++---------------- .../ClassPathBeanDefinitionScannerTests.java | 40 ++--- 7 files changed, 92 insertions(+), 183 deletions(-) diff --git a/build.gradle b/build.gradle index 42f5225e9b92..ac8e4863252b 100644 --- a/build.gradle +++ b/build.gradle @@ -230,7 +230,6 @@ configure(allprojects) { project -> dependency "jakarta.validation:jakarta.validation-api:3.0.0" dependency "jakarta.websocket:jakarta.websocket-api:2.0.0" dependency "jakarta.xml.bind:jakarta.xml.bind-api:3.0.1" - dependency "jakarta.xml.ws:jakarta.xml.ws-api:3.0.1" dependency "com.sun.activation:jakarta.activation:2.0.1" dependency "com.sun.mail:jakarta.mail:2.0.1" diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index fdbf93539128..d5c753e72912 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -75,8 +75,10 @@ * by default, Spring's {@link Autowired @Autowired} and {@link Value @Value} * annotations. * - *

    Also supports JSR-330's {@link jakarta.inject.Inject @Inject} annotation, + *

    Also supports the common {@link jakarta.inject.Inject @Inject} annotation, * if available, as a direct alternative to Spring's own {@code @Autowired}. + * Additionally, it retains support for the {@code javax.inject.Inject} variant + * dating back to the original JSR-330 specification (as known from Java EE 6-8). * *

    Autowired Constructors

    *

    Only one constructor of any given bean class may declare this annotation with @@ -154,20 +156,30 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA /** * Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's * standard {@link Autowired @Autowired} and {@link Value @Value} annotations. - *

    Also supports JSR-330's {@link jakarta.inject.Inject @Inject} annotation, - * if available. + *

    Also supports the common {@link jakarta.inject.Inject @Inject} annotation, + * if available, as well as the original {@code javax.inject.Inject} variant. */ @SuppressWarnings("unchecked") public AutowiredAnnotationBeanPostProcessor() { this.autowiredAnnotationTypes.add(Autowired.class); this.autowiredAnnotationTypes.add(Value.class); + try { this.autowiredAnnotationTypes.add((Class) ClassUtils.forName("jakarta.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader())); - logger.trace("JSR-330 'jakarta.inject.Inject' annotation found and supported for autowiring"); + logger.trace("'jakarta.inject.Inject' annotation found and supported for autowiring"); + } + catch (ClassNotFoundException ex) { + // jakarta.inject API not available - simply skip. + } + + try { + this.autowiredAnnotationTypes.add((Class) + ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader())); + logger.trace("'javax.inject.Inject' annotation found and supported for autowiring"); } catch (ClassNotFoundException ex) { - // JSR-330 API not available - simply skip. + // javax.inject API not available - simply skip. } } @@ -177,7 +189,7 @@ public AutowiredAnnotationBeanPostProcessor() { * setter methods, and arbitrary config methods. *

    The default autowired annotation types are the Spring-provided * {@link Autowired @Autowired} and {@link Value @Value} annotations as well - * as JSR-330's {@link jakarta.inject.Inject @Inject} annotation, if available. + * as the common {@code @Inject} annotation, if available. *

    This setter property exists so that developers can provide their own * (non-Spring-specific) annotation type to indicate that a member is supposed * to be autowired. @@ -193,7 +205,7 @@ public void setAutowiredAnnotationType(Class autowiredAnno * setter methods, and arbitrary config methods. *

    The default autowired annotation types are the Spring-provided * {@link Autowired @Autowired} and {@link Value @Value} annotations as well - * as JSR-330's {@link jakarta.inject.Inject @Inject} annotation, if available. + * as the common {@code @Inject} annotation, if available. *

    This setter property exists so that developers can provide their own * (non-Spring-specific) annotation types to indicate that a member is supposed * to be autowired. diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java index 6316848a5a77..2f1bd7763b2c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,7 +66,7 @@ * init method and destroy method, respectively. * *

    Spring's {@link org.springframework.context.annotation.CommonAnnotationBeanPostProcessor} - * supports the JSR-250 {@link jakarta.annotation.PostConstruct} and {@link jakarta.annotation.PreDestroy} + * supports the {@link jakarta.annotation.PostConstruct} and {@link jakarta.annotation.PreDestroy} * annotations out of the box, as init annotation and destroy annotation, respectively. * Furthermore, it also supports the {@link jakarta.annotation.Resource} annotation * for annotation-driven injection of named beans. @@ -117,7 +117,7 @@ public boolean hasDestroyMethods() { * methods to call after configuration of a bean. *

    Any custom annotation can be used, since there are no required * annotation attributes. There is no default, although a typical choice - * is the JSR-250 {@link jakarta.annotation.PostConstruct} annotation. + * is the {@link jakarta.annotation.PostConstruct} annotation. */ public void setInitAnnotationType(Class initAnnotationType) { this.initAnnotationType = initAnnotationType; @@ -128,7 +128,7 @@ public void setInitAnnotationType(Class initAnnotationType * methods to call when the context is shutting down. *

    Any custom annotation can be used, since there are no required * annotation attributes. There is no default, although a typical choice - * is the JSR-250 {@link jakarta.annotation.PreDestroy} annotation. + * is the {@link jakarta.annotation.PreDestroy} annotation. */ public void setDestroyAnnotationType(Class destroyAnnotationType) { this.destroyAnnotationType = destroyAnnotationType; diff --git a/spring-context/spring-context.gradle b/spring-context/spring-context.gradle index 9e4cf72ca954..f7bb843fcc17 100644 --- a/spring-context/spring-context.gradle +++ b/spring-context/spring-context.gradle @@ -14,9 +14,8 @@ dependencies { optional("jakarta.enterprise.concurrent:jakarta.enterprise.concurrent-api") optional("jakarta.inject:jakarta.inject-api") optional("jakarta.interceptor:jakarta.interceptor-api") - optional("javax.money:money-api") optional("jakarta.validation:jakarta.validation-api") - optional("jakarta.xml.ws:jakarta.xml.ws-api") + optional("javax.money:money-api") optional("org.aspectj:aspectjweaver") optional("org.codehaus.groovy:groovy") optional("org.apache-extras.beanshell:bsh") @@ -32,8 +31,8 @@ dependencies { testImplementation("org.codehaus.groovy:groovy-test") testImplementation("org.codehaus.groovy:groovy-xml") testImplementation("org.apache.commons:commons-pool2") - testImplementation("jakarta.inject:jakarta.inject-tck") testImplementation("org.awaitility:awaitility") + testImplementation("jakarta.inject:jakarta.inject-tck") testRuntimeOnly("jakarta.xml.bind:jakarta.xml.bind-api") testRuntimeOnly("org.glassfish:jakarta.el") // Substitute for javax.management:jmxremote_optional:1.0.1_04 (not available on Maven Central) diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java index 9c253124eea9..20ed51eff6da 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor; +import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; @@ -91,11 +92,17 @@ public abstract class AnnotationConfigUtils { "org.springframework.context.annotation.internalRequiredAnnotationProcessor"; /** - * The bean name of the internally managed JSR-250 annotation processor. + * The bean name of the internally managed common annotation processor. */ public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME = "org.springframework.context.annotation.internalCommonAnnotationProcessor"; + /** + * The bean name of the internally managed JSR-250 annotation processor. + */ + private static final String JSR250_ANNOTATION_PROCESSOR_BEAN_NAME = + "org.springframework.context.annotation.internalJsr250AnnotationProcessor"; + /** * The bean name of the internally managed JPA annotation processor. */ @@ -117,16 +124,18 @@ public abstract class AnnotationConfigUtils { public static final String EVENT_LISTENER_FACTORY_BEAN_NAME = "org.springframework.context.event.internalEventListenerFactory"; - private static final boolean jsr250Present; - private static final boolean jpaPresent; + private static final ClassLoader classLoader = AnnotationConfigUtils.class.getClassLoader(); - static { - ClassLoader classLoader = AnnotationConfigUtils.class.getClassLoader(); - jsr250Present = ClassUtils.isPresent("jakarta.annotation.Resource", classLoader); - jpaPresent = ClassUtils.isPresent("jakarta.persistence.EntityManagerFactory", classLoader) && - ClassUtils.isPresent(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, classLoader); - } + private static final boolean jakartaAnnotationsPresent = + ClassUtils.isPresent("jakarta.annotation.PostConstruct", classLoader); + + private static final boolean jsr250Present = + ClassUtils.isPresent("javax.annotation.PostConstruct", classLoader); + + private static final boolean jpaPresent = + ClassUtils.isPresent("jakarta.persistence.EntityManagerFactory", classLoader) && + ClassUtils.isPresent(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, classLoader); /** @@ -172,13 +181,28 @@ public static Set registerAnnotationConfigProcessors( beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } - // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. - if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { + // Check for Jakarta Annotations support, and if present add the CommonAnnotationBeanPostProcessor. + if (jakartaAnnotationsPresent && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } + // Check for JSR-250 support, and if present add an InitDestroyAnnotationBeanPostProcessor + // for the javax variant of PostConstruct/PreDestroy. + if (jsr250Present && !registry.containsBeanDefinition(JSR250_ANNOTATION_PROCESSOR_BEAN_NAME)) { + try { + RootBeanDefinition def = new RootBeanDefinition(InitDestroyAnnotationBeanPostProcessor.class); + def.getPropertyValues().add("initAnnotationType", classLoader.loadClass("javax.annotation.PostConstruct")); + def.getPropertyValues().add("destroyAnnotationType", classLoader.loadClass("javax.annotation.PreDestroy")); + def.setSource(source); + beanDefs.add(registerPostProcessor(registry, def, JSR250_ANNOTATION_PROCESSOR_BEAN_NAME)); + } + catch (ClassNotFoundException ex) { + // Failed to load javax variants of the annotation types -> ignore. + } + } + // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); diff --git a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java index 75b7d08afec6..3bd70bc53cb6 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,13 +21,10 @@ import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.net.MalformedURLException; -import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -37,15 +34,10 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import javax.xml.namespace.QName; - import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.annotation.Resource; import jakarta.ejb.EJB; -import jakarta.xml.ws.Service; -import jakarta.xml.ws.WebServiceClient; -import jakarta.xml.ws.WebServiceRef; import org.springframework.aop.TargetSource; import org.springframework.aop.framework.ProxyFactory; @@ -77,10 +69,9 @@ /** * {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation - * that supports common Java annotations out of the box, in particular the JSR-250 + * that supports common Java annotations out of the box, in particular the common * annotations in the {@code jakarta.annotation} package. These common Java - * annotations are supported in many Jakarta EE technologies (e.g. JSF 1.2), - * as well as in Java 6's JAX-WS. + * annotations are supported in many Jakarta EE technologies (e.g. JSF and JAX-RS). * *

    This post-processor includes support for the {@link jakarta.annotation.PostConstruct} * and {@link jakarta.annotation.PreDestroy} annotations - as init annotation @@ -95,12 +86,8 @@ * and default names as well. The target beans can be simple POJOs, with no special * requirements other than the type having to match. * - *

    The JAX-WS {@link javax.xml.ws.WebServiceRef} annotation is supported too, - * analogous to {@link jakarta.annotation.Resource} but with the capability of creating - * specific JAX-WS service endpoints. This may either point to an explicitly defined - * resource by name or operate on a locally specified JAX-WS service class. Finally, - * this post-processor also supports the EJB 3 {@link jakarta.ejb.EJB} annotation, - * analogous to {@link jakarta.annotation.Resource} as well, with the capability to + *

    This post-processor also supports the EJB 3 {@link jakarta.ejb.EJB} annotation, + * analogous to {@link jakarta.annotation.Resource}, with the capability to * specify both a local bean name and a global JNDI name for fallback retrieval. * The target beans can be plain POJOs as well as EJB 3 Session Beans in this case. * @@ -143,22 +130,15 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable { - @Nullable - private static final Class webServiceRefClass; + private static final Set> resourceAnnotationTypes = new LinkedHashSet<>(4); @Nullable private static final Class ejbClass; - private static final Set> resourceAnnotationTypes = new LinkedHashSet<>(4); - static { - webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef"); - ejbClass = loadAnnotationType("jakarta.ejb.EJB"); - resourceAnnotationTypes.add(Resource.class); - if (webServiceRefClass != null) { - resourceAnnotationTypes.add(webServiceRefClass); - } + + ejbClass = loadAnnotationType("jakarta.ejb.EJB"); if (ejbClass != null) { resourceAnnotationTypes.add(ejbClass); } @@ -195,15 +175,11 @@ public CommonAnnotationBeanPostProcessor() { setOrder(Ordered.LOWEST_PRECEDENCE - 3); setInitAnnotationType(PostConstruct.class); setDestroyAnnotationType(PreDestroy.class); - ignoreResourceType("javax.xml.ws.WebServiceContext"); } /** - * Ignore the given resource type when resolving {@code @Resource} - * annotations. - *

    By default, the {@code javax.xml.ws.WebServiceContext} interface - * will be ignored, since it will be resolved by the JAX-WS runtime. + * Ignore the given resource type when resolving {@code @Resource} annotations. * @param resourceType the resource type to ignore */ public void ignoreResourceType(String resourceType) { @@ -361,13 +337,7 @@ private InjectionMetadata buildResourceMetadata(final Class clazz) { final List currElements = new ArrayList<>(); ReflectionUtils.doWithLocalFields(targetClass, field -> { - if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) { - if (Modifier.isStatic(field.getModifiers())) { - throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields"); - } - currElements.add(new WebServiceRefElement(field, field, null)); - } - else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) { + if (ejbClass != null && field.isAnnotationPresent(ejbClass)) { if (Modifier.isStatic(field.getModifiers())) { throw new IllegalStateException("@EJB annotation is not supported on static fields"); } @@ -389,17 +359,7 @@ else if (field.isAnnotationPresent(Resource.class)) { return; } if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { - if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) { - if (Modifier.isStatic(method.getModifiers())) { - throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods"); - } - if (method.getParameterCount() != 1) { - throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method); - } - PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); - currElements.add(new WebServiceRefElement(method, bridgedMethod, pd)); - } - else if (ejbClass != null && bridgedMethod.isAnnotationPresent(ejbClass)) { + if (ejbClass != null && bridgedMethod.isAnnotationPresent(ejbClass)) { if (Modifier.isStatic(method.getModifiers())) { throw new IllegalStateException("@EJB annotation is not supported on static methods"); } @@ -649,91 +609,6 @@ protected Object getResourceToInject(Object target, @Nullable String requestingB } - /** - * Class representing injection information about an annotated field - * or setter method, supporting the @WebServiceRef annotation. - */ - private class WebServiceRefElement extends LookupElement { - - private final Class elementType; - - private final String wsdlLocation; - - public WebServiceRefElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) { - super(member, pd); - WebServiceRef resource = ae.getAnnotation(WebServiceRef.class); - String resourceName = resource.name(); - Class resourceType = resource.type(); - this.isDefaultName = !StringUtils.hasLength(resourceName); - if (this.isDefaultName) { - resourceName = this.member.getName(); - if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) { - resourceName = Introspector.decapitalize(resourceName.substring(3)); - } - } - if (Object.class != resourceType) { - checkResourceType(resourceType); - } - else { - // No resource type specified... check field/method. - resourceType = getResourceType(); - } - this.name = resourceName; - this.elementType = resourceType; - if (Service.class.isAssignableFrom(resourceType)) { - this.lookupType = resourceType; - } - else { - this.lookupType = resource.value(); - } - this.mappedName = resource.mappedName(); - this.wsdlLocation = resource.wsdlLocation(); - } - - @Override - protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) { - Service service; - try { - service = (Service) getResource(this, requestingBeanName); - } - catch (NoSuchBeanDefinitionException notFound) { - // Service to be created through generated class. - if (Service.class == this.lookupType) { - throw new IllegalStateException("No resource with name '" + this.name + "' found in context, " + - "and no specific JAX-WS Service subclass specified. The typical solution is to either specify " + - "a LocalJaxWsServiceFactoryBean with the given name or to specify the (generated) Service " + - "subclass as @WebServiceRef(...) value."); - } - if (StringUtils.hasLength(this.wsdlLocation)) { - try { - Constructor ctor = this.lookupType.getConstructor(URL.class, QName.class); - WebServiceClient clientAnn = this.lookupType.getAnnotation(WebServiceClient.class); - if (clientAnn == null) { - throw new IllegalStateException("JAX-WS Service class [" + this.lookupType.getName() + - "] does not carry a WebServiceClient annotation"); - } - service = (Service) BeanUtils.instantiateClass(ctor, - new URL(this.wsdlLocation), new QName(clientAnn.targetNamespace(), clientAnn.name())); - } - catch (NoSuchMethodException ex) { - throw new IllegalStateException("JAX-WS Service class [" + this.lookupType.getName() + - "] does not have a (URL, QName) constructor. Cannot apply specified WSDL location [" + - this.wsdlLocation + "]."); - } - catch (MalformedURLException ex) { - throw new IllegalArgumentException( - "Specified WSDL location [" + this.wsdlLocation + "] isn't a valid URL"); - } - } - else { - service = (Service) BeanUtils.instantiateClass(this.lookupType); - } - } - return service.getPort(this.elementType); - } - } - - /** * Class representing injection information about an annotated field * or setter method, supporting the @EJB annotation. diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ClassPathBeanDefinitionScannerTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ClassPathBeanDefinitionScannerTests.java index cfb389e6a464..99f604181d5e 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ClassPathBeanDefinitionScannerTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ClassPathBeanDefinitionScannerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,7 +61,7 @@ public void testSimpleScanWithDefaultFiltersAndPostProcessors() { GenericApplicationContext context = new GenericApplicationContext(); ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(12); + assertThat(beanCount).isGreaterThanOrEqualTo(12); assertThat(context.containsBean("serviceInvocationCounter")).isTrue(); assertThat(context.containsBean("fooServiceImpl")).isTrue(); assertThat(context.containsBean("stubFooDao")).isTrue(); @@ -110,7 +110,7 @@ public void testDoubleScan() { ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(12); + assertThat(beanCount).isGreaterThanOrEqualTo(12); ClassPathBeanDefinitionScanner scanner2 = new ClassPathBeanDefinitionScanner(context) { @Override @@ -138,7 +138,7 @@ public void testWithIndex() { ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(12); + assertThat(beanCount).isGreaterThanOrEqualTo(12); assertThat(context.containsBean("serviceInvocationCounter")).isTrue(); assertThat(context.containsBean("fooServiceImpl")).isTrue(); @@ -157,7 +157,7 @@ public void testDoubleScanWithIndex() { ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(12); + assertThat(beanCount).isGreaterThanOrEqualTo(12); ClassPathBeanDefinitionScanner scanner2 = new ClassPathBeanDefinitionScanner(context) { @Override @@ -182,7 +182,7 @@ public void testSimpleScanWithDefaultFiltersAndNoPostProcessors() { ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); scanner.setIncludeAnnotationConfig(false); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(7); + assertThat(beanCount).isGreaterThanOrEqualTo(7); assertThat(context.containsBean("serviceInvocationCounter")).isTrue(); assertThat(context.containsBean("fooServiceImpl")).isTrue(); @@ -222,7 +222,7 @@ public void testSimpleScanWithDefaultFiltersAndOverriddenEqualNamedBean() { scanner.setIncludeAnnotationConfig(false); int scannedBeanCount = scanner.scan(BASE_PACKAGE); - assertThat(scannedBeanCount).isEqualTo(6); + assertThat(scannedBeanCount).isGreaterThanOrEqualTo(6); assertThat(context.getBeanDefinitionCount()).isEqualTo((initialBeanCount + scannedBeanCount)); assertThat(context.containsBean("serviceInvocationCounter")).isTrue(); assertThat(context.containsBean("fooServiceImpl")).isTrue(); @@ -242,7 +242,7 @@ public void testSimpleScanWithDefaultFiltersAndOverriddenCompatibleNamedBean() { scanner.setIncludeAnnotationConfig(false); int scannedBeanCount = scanner.scan(BASE_PACKAGE); - assertThat(scannedBeanCount).isEqualTo(6); + assertThat(scannedBeanCount).isGreaterThanOrEqualTo(6); assertThat(context.getBeanDefinitionCount()).isEqualTo((initialBeanCount + scannedBeanCount)); assertThat(context.containsBean("serviceInvocationCounter")).isTrue(); assertThat(context.containsBean("fooServiceImpl")).isTrue(); @@ -281,7 +281,7 @@ public void testCustomIncludeFilterWithoutDefaultsButIncludingPostProcessors() { scanner.addIncludeFilter(new AnnotationTypeFilter(CustomComponent.class)); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(6); + assertThat(beanCount).isGreaterThanOrEqualTo(6); assertThat(context.containsBean("messageBean")).isTrue(); assertThat(context.containsBean(AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)).isTrue(); assertThat(context.containsBean(AnnotationConfigUtils.COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)).isTrue(); @@ -296,7 +296,7 @@ public void testCustomIncludeFilterWithoutDefaultsAndNoPostProcessors() { scanner.addIncludeFilter(new AnnotationTypeFilter(CustomComponent.class)); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(6); + assertThat(beanCount).isGreaterThanOrEqualTo(6); assertThat(context.containsBean("messageBean")).isTrue(); assertThat(context.containsBean("serviceInvocationCounter")).isFalse(); assertThat(context.containsBean("fooServiceImpl")).isFalse(); @@ -316,7 +316,7 @@ public void testCustomIncludeFilterAndDefaults() { scanner.addIncludeFilter(new AnnotationTypeFilter(CustomComponent.class)); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(13); + assertThat(beanCount).isGreaterThanOrEqualTo(13); assertThat(context.containsBean("messageBean")).isTrue(); assertThat(context.containsBean("serviceInvocationCounter")).isTrue(); assertThat(context.containsBean("fooServiceImpl")).isTrue(); @@ -336,7 +336,7 @@ public void testCustomAnnotationExcludeFilterAndDefaults() { scanner.addExcludeFilter(new AnnotationTypeFilter(Aspect.class)); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(11); + assertThat(beanCount).isGreaterThanOrEqualTo(11); assertThat(context.containsBean("serviceInvocationCounter")).isFalse(); assertThat(context.containsBean("fooServiceImpl")).isTrue(); assertThat(context.containsBean("stubFooDao")).isTrue(); @@ -354,7 +354,7 @@ public void testCustomAssignableTypeExcludeFilterAndDefaults() { scanner.addExcludeFilter(new AssignableTypeFilter(FooService.class)); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(11); + assertThat(beanCount).isGreaterThanOrEqualTo(11); assertThat(context.containsBean("fooServiceImpl")).isFalse(); assertThat(context.containsBean("serviceInvocationCounter")).isTrue(); assertThat(context.containsBean("stubFooDao")).isTrue(); @@ -374,7 +374,7 @@ public void testCustomAssignableTypeExcludeFilterAndDefaultsWithoutPostProcessor scanner.addExcludeFilter(new AssignableTypeFilter(FooService.class)); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(6); + assertThat(beanCount).isGreaterThanOrEqualTo(6); assertThat(context.containsBean("fooServiceImpl")).isFalse(); assertThat(context.containsBean("serviceInvocationCounter")).isTrue(); assertThat(context.containsBean("stubFooDao")).isTrue(); @@ -392,7 +392,7 @@ public void testMultipleCustomExcludeFiltersAndDefaults() { scanner.addExcludeFilter(new AnnotationTypeFilter(Aspect.class)); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(10); + assertThat(beanCount).isGreaterThanOrEqualTo(10); assertThat(context.containsBean("fooServiceImpl")).isFalse(); assertThat(context.containsBean("serviceInvocationCounter")).isFalse(); assertThat(context.containsBean("stubFooDao")).isTrue(); @@ -411,7 +411,7 @@ public void testCustomBeanNameGenerator() { scanner.setBeanNameGenerator(new TestBeanNameGenerator()); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(12); + assertThat(beanCount).isGreaterThanOrEqualTo(12); assertThat(context.containsBean("fooServiceImpl")).isFalse(); assertThat(context.containsBean("fooService")).isTrue(); assertThat(context.containsBean("serviceInvocationCounter")).isTrue(); @@ -431,7 +431,7 @@ public void testMultipleBasePackagesWithDefaultsOnly() { GenericApplicationContext multiPackageContext = new GenericApplicationContext(); ClassPathBeanDefinitionScanner multiPackageScanner = new ClassPathBeanDefinitionScanner(multiPackageContext); int singlePackageBeanCount = singlePackageScanner.scan(BASE_PACKAGE); - assertThat(singlePackageBeanCount).isEqualTo(12); + assertThat(singlePackageBeanCount).isGreaterThanOrEqualTo(12); multiPackageScanner.scan(BASE_PACKAGE, "org.springframework.dao.annotation"); // assertTrue(multiPackageBeanCount > singlePackageBeanCount); } @@ -442,7 +442,7 @@ public void testMultipleScanCalls() { ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); int initialBeanCount = context.getBeanDefinitionCount(); int scannedBeanCount = scanner.scan(BASE_PACKAGE); - assertThat(scannedBeanCount).isEqualTo(12); + assertThat(scannedBeanCount).isGreaterThanOrEqualTo(12); assertThat((context.getBeanDefinitionCount() - initialBeanCount)).isEqualTo(scannedBeanCount); int addedBeanCount = scanner.scan("org.springframework.aop.aspectj.annotation"); assertThat(context.getBeanDefinitionCount()).isEqualTo((initialBeanCount + scannedBeanCount + addedBeanCount)); @@ -455,7 +455,7 @@ public void testBeanAutowiredWithAnnotationConfigEnabled() { ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); scanner.setBeanNameGenerator(new TestBeanNameGenerator()); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(12); + assertThat(beanCount).isGreaterThanOrEqualTo(12); context.refresh(); FooServiceImpl fooService = context.getBean("fooService", FooServiceImpl.class); @@ -485,7 +485,7 @@ public void testBeanNotAutowiredWithAnnotationConfigDisabled() { scanner.setIncludeAnnotationConfig(false); scanner.setBeanNameGenerator(new TestBeanNameGenerator()); int beanCount = scanner.scan(BASE_PACKAGE); - assertThat(beanCount).isEqualTo(7); + assertThat(beanCount).isGreaterThanOrEqualTo(7); context.refresh(); try { From eabe946a5385b690228c1141bad3fc131ac7f1b3 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 21 Sep 2021 17:41:56 +0200 Subject: [PATCH 133/735] Skip readStream optimization for compatibility with misbehaving InputStreams Closes gh-27429 --- .../src/main/java/org/springframework/asm/ClassReader.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 d53564c2a9a8..e5c2113993ff 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassReader.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassReader.java @@ -324,7 +324,9 @@ private static byte[] readStream(final InputStream inputStream, final boolean cl } outputStream.flush(); if (readCount == 1) { - return data; + // SPRING PATCH: some misbehaving InputStreams return -1 but still write to buffer (gh-27429) + // return data; + // END OF PATCH } return outputStream.toByteArray(); } finally { From 49d003857d1dc98e5f1fa0274e9e5eb6b09a2f78 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 21 Sep 2021 17:42:19 +0200 Subject: [PATCH 134/735] Skip CGLIB class validation in case of optimize flag Closes gh-27439 --- .../springframework/aop/framework/CglibAopProxy.java | 4 ++-- .../org/springframework/aop/framework/ProxyConfig.java | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java index e2b822816dbf..43d747f90cee 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -237,7 +237,7 @@ protected Enhancer createEnhancer() { * validates it if not. */ private void validateClassIfNecessary(Class proxySuperClass, @Nullable ClassLoader proxyClassLoader) { - if (logger.isWarnEnabled()) { + if (!this.advised.isOptimize() && logger.isInfoEnabled()) { synchronized (validatedClasses) { if (!validatedClasses.containsKey(proxySuperClass)) { doValidateClass(proxySuperClass, proxyClassLoader, diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/ProxyConfig.java b/spring-aop/src/main/java/org/springframework/aop/framework/ProxyConfig.java index 38665cafbc61..3b6010f8f58c 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/ProxyConfig.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/ProxyConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,11 +73,9 @@ public boolean isProxyTargetClass() { * The exact meaning of "aggressive optimizations" will differ * between proxies, but there is usually some tradeoff. * Default is "false". - *

    For example, optimization will usually mean that advice changes won't - * take effect after a proxy has been created. For this reason, optimization - * is disabled by default. An optimize value of "true" may be ignored - * if other settings preclude optimization: for example, if "exposeProxy" - * is set to "true" and that's not compatible with the optimization. + *

    With Spring's current proxy options, this flag effectively + * enforces CGLIB proxies (similar to {@link #setProxyTargetClass}) + * but without any class validation checks (for final methods etc). */ public void setOptimize(boolean optimize) { this.optimize = optimize; From 0dc5d2794fa6716f26c228a8cef8aa60a8d4a4ae Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 21 Sep 2021 17:42:50 +0200 Subject: [PATCH 135/735] Avoid early ConversionService determination in StandardBeanExpressionResolver Closes gh-27446 --- .../StandardBeanExpressionResolver.java | 11 +++++----- .../spel/support/StandardTypeConverter.java | 22 ++++++++++++++----- 2 files changed, 23 insertions(+), 10 deletions(-) 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 c2a0235d1972..b58795014b98 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-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import org.springframework.beans.factory.config.BeanExpressionContext; import org.springframework.beans.factory.config.BeanExpressionResolver; import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.ParserContext; @@ -156,10 +157,10 @@ public Object evaluate(@Nullable String value, BeanExpressionContext evalContext sec.addPropertyAccessor(new EnvironmentAccessor()); sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory())); sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader())); - ConversionService conversionService = evalContext.getBeanFactory().getConversionService(); - if (conversionService != null) { - sec.setTypeConverter(new StandardTypeConverter(conversionService)); - } + sec.setTypeConverter(new StandardTypeConverter(() -> { + ConversionService cs = evalContext.getBeanFactory().getConversionService(); + return (cs != null ? cs : DefaultConversionService.getSharedInstance()); + })); customizeEvaluationContext(sec); this.evaluationCache.put(evalContext, sec); } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java index 8d1a25028874..eeb1c09397db 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package org.springframework.expression.spel.support; +import java.util.function.Supplier; + import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; @@ -37,7 +39,7 @@ */ public class StandardTypeConverter implements TypeConverter { - private final ConversionService conversionService; + private final Supplier conversionService; /** @@ -45,7 +47,7 @@ public class StandardTypeConverter implements TypeConverter { * @see DefaultConversionService#getSharedInstance() */ public StandardTypeConverter() { - this.conversionService = DefaultConversionService.getSharedInstance(); + this.conversionService = DefaultConversionService::getSharedInstance; } /** @@ -54,20 +56,30 @@ public StandardTypeConverter() { */ public StandardTypeConverter(ConversionService conversionService) { Assert.notNull(conversionService, "ConversionService must not be null"); + this.conversionService = () -> conversionService; + } + + /** + * Create a StandardTypeConverter for the given ConversionService. + * @param conversionService a Supplier for the ConversionService to delegate to + * @since 5.3.11 + */ + public StandardTypeConverter(Supplier conversionService) { + Assert.notNull(conversionService, "Supplier must not be null"); this.conversionService = conversionService; } @Override public boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType) { - return this.conversionService.canConvert(sourceType, targetType); + return this.conversionService.get().canConvert(sourceType, targetType); } @Override @Nullable public Object convertValue(@Nullable Object value, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType) { try { - return this.conversionService.convert(value, sourceType, targetType); + return this.conversionService.get().convert(value, sourceType, targetType); } catch (ConversionException ex) { throw new SpelEvaluationException(ex, SpelMessage.TYPE_CONVERSION_ERROR, From 1f8c233dfcef62781467cbb58a774933208f94cf Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 21 Sep 2021 17:43:03 +0200 Subject: [PATCH 136/735] Polishing --- spring-context/spring-context.gradle | 2 +- ...nClassPostConstructAndAutowiringTests.java | 5 +- .../core/ReactiveAdapterRegistry.java | 72 +++++++++---------- 3 files changed, 38 insertions(+), 41 deletions(-) diff --git a/spring-context/spring-context.gradle b/spring-context/spring-context.gradle index 221e0f12fe1a..fe3faea9f9e6 100644 --- a/spring-context/spring-context.gradle +++ b/spring-context/spring-context.gradle @@ -34,8 +34,8 @@ dependencies { testImplementation("org.codehaus.groovy:groovy-test") testImplementation("org.codehaus.groovy:groovy-xml") testImplementation("org.apache.commons:commons-pool2") - testImplementation("javax.inject:javax.inject-tck") testImplementation("org.awaitility:awaitility") + testImplementation("javax.inject:javax.inject-tck") testRuntimeOnly("javax.xml.bind:jaxb-api") testRuntimeOnly("org.glassfish:javax.el") // Substitute for javax.management:jmxremote_optional:1.0.1_04 (not available on Maven Central) diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostConstructAndAutowiringTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostConstructAndAutowiringTests.java index 0aaf4c00a069..420de4c5bda6 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostConstructAndAutowiringTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostConstructAndAutowiringTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import static org.assertj.core.api.Assertions.assertThat; - /** * Tests cornering the issue reported in SPR-8080. If the product of a @Bean method * was @Autowired into a configuration class while at the same time the declaring @@ -34,7 +33,7 @@ * 'currently in creation' status of the autowired bean and result in creating multiple * instances of the given @Bean, violating container scoping / singleton semantics. * - * This is resolved through no longer relying on 'currently in creation' status, but + *

    This is resolved through no longer relying on 'currently in creation' status, but * rather on a thread local that informs the enhanced bean method implementation whether * the factory is the caller or not. * diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java index cfeaffcaf734..cbed55a289c4 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -77,11 +77,11 @@ public class ReactiveAdapterRegistry { static { ClassLoader classLoader = ReactiveAdapterRegistry.class.getClassLoader(); reactorPresent = ClassUtils.isPresent("reactor.core.publisher.Flux", classLoader); + flowPublisherPresent = ClassUtils.isPresent("java.util.concurrent.Flow.Publisher", classLoader); rxjava1Present = ClassUtils.isPresent("rx.Observable", classLoader) && ClassUtils.isPresent("rx.RxReactiveStreams", classLoader); rxjava2Present = ClassUtils.isPresent("io.reactivex.Flowable", classLoader); rxjava3Present = ClassUtils.isPresent("io.reactivex.rxjava3.core.Flowable", classLoader); - flowPublisherPresent = ClassUtils.isPresent("java.util.concurrent.Flow.Publisher", classLoader); kotlinCoroutinesPresent = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt", classLoader); mutinyPresent = ClassUtils.isPresent("io.smallrye.mutiny.Multi", classLoader); } @@ -97,13 +97,16 @@ public ReactiveAdapterRegistry() { // Reactor if (reactorPresent) { new ReactorRegistrar().registerAdapters(this); + if (flowPublisherPresent) { + // Java 9+ Flow.Publisher + new ReactorJdkFlowAdapterRegistrar().registerAdapter(this); + } } // RxJava1 (deprecated) if (rxjava1Present) { new RxJava1Registrar().registerAdapters(this); } - // RxJava2 if (rxjava2Present) { new RxJava2Registrar().registerAdapters(this); @@ -113,13 +116,6 @@ public ReactiveAdapterRegistry() { new RxJava3Registrar().registerAdapters(this); } - // Java 9+ Flow.Publisher - if (flowPublisherPresent) { - new ReactorJdkFlowAdapterRegistrar().registerAdapter(this); - } - // If not present, do nothing for the time being... - // We can fall back on "reactive-streams-flow-bridge" (once released) - // Kotlin Coroutines if (reactorPresent && kotlinCoroutinesPresent) { new CoroutinesRegistrar().registerAdapters(this); @@ -253,6 +249,35 @@ void registerAdapters(ReactiveAdapterRegistry registry) { } + private static class ReactorJdkFlowAdapterRegistrar { + + void registerAdapter(ReactiveAdapterRegistry registry) { + // Reflectively access optional JDK 9+ API (for runtime compatibility with JDK 8) + + try { + String publisherName = "java.util.concurrent.Flow.Publisher"; + Class publisherClass = ClassUtils.forName(publisherName, getClass().getClassLoader()); + + String adapterName = "reactor.adapter.JdkFlowAdapter"; + Class flowAdapterClass = ClassUtils.forName(adapterName, getClass().getClassLoader()); + + Method toFluxMethod = flowAdapterClass.getMethod("flowPublisherToFlux", publisherClass); + Method toFlowMethod = flowAdapterClass.getMethod("publisherToFlowPublisher", Publisher.class); + Object emptyFlow = ReflectionUtils.invokeMethod(toFlowMethod, null, Flux.empty()); + + registry.registerReactiveType( + ReactiveTypeDescriptor.multiValue(publisherClass, () -> emptyFlow), + source -> (Publisher) ReflectionUtils.invokeMethod(toFluxMethod, null, source), + publisher -> ReflectionUtils.invokeMethod(toFlowMethod, null, publisher) + ); + } + catch (Throwable ex) { + // Ignore + } + } + } + + private static class RxJava1Registrar { void registerAdapters(ReactiveAdapterRegistry registry) { @@ -307,6 +332,7 @@ void registerAdapters(ReactiveAdapterRegistry registry) { } } + private static class RxJava3Registrar { void registerAdapters(ReactiveAdapterRegistry registry) { @@ -347,34 +373,6 @@ void registerAdapters(ReactiveAdapterRegistry registry) { } } - private static class ReactorJdkFlowAdapterRegistrar { - - void registerAdapter(ReactiveAdapterRegistry registry) { - // TODO: remove reflection when build requires JDK 9+ - - try { - String publisherName = "java.util.concurrent.Flow.Publisher"; - Class publisherClass = ClassUtils.forName(publisherName, getClass().getClassLoader()); - - String adapterName = "reactor.adapter.JdkFlowAdapter"; - Class flowAdapterClass = ClassUtils.forName(adapterName, getClass().getClassLoader()); - - Method toFluxMethod = flowAdapterClass.getMethod("flowPublisherToFlux", publisherClass); - Method toFlowMethod = flowAdapterClass.getMethod("publisherToFlowPublisher", Publisher.class); - Object emptyFlow = ReflectionUtils.invokeMethod(toFlowMethod, null, Flux.empty()); - - registry.registerReactiveType( - ReactiveTypeDescriptor.multiValue(publisherClass, () -> emptyFlow), - source -> (Publisher) ReflectionUtils.invokeMethod(toFluxMethod, null, source), - publisher -> ReflectionUtils.invokeMethod(toFlowMethod, null, publisher) - ); - } - catch (Throwable ex) { - // Ignore - } - } - } - /** * ReactiveAdapter variant that wraps adapted Publishers as {@link Flux} or From b808b53bcc4633f0622c7038df310b04e34bfe7b Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 22 Sep 2021 16:06:58 +0200 Subject: [PATCH 137/735] Remove unnecessary cast in ContentRequestMatchers --- .../test/web/client/match/ContentRequestMatchers.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java b/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java index 0ce6350a5da6..7762bb279323 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java @@ -240,7 +240,7 @@ private RequestMatcher multipartData(MultiValueMap expectedMap, boole } if (expected instanceof byte[]) { assertTrue("Multipart is not a file", actual instanceof byte[]); - assertEquals("Multipart content", expected, (byte[]) actual); + assertEquals("Multipart content", expected, actual); } else if (expected instanceof String) { assertTrue("Multipart is not a String", actual instanceof String); From a247b83cd9c9aefd3c329d493c5ce7cd11d0cdfa Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 22 Sep 2021 16:22:27 +0200 Subject: [PATCH 138/735] Ensure projects can be imported into Eclipse IDE with JDK 17 Prior to this commit, the Spring Framework projects could not be imported into Eclipse IDE when using JDK 17 to build the projects. The primary obstacle is the fact that Eclipse enforces a strict "no split packages between the unnamed module and a system module" rule when building with a "modular JDK" (such as JDK 17). Resources: - https://bugs.eclipse.org/bugs/show_bug.cgi?id=536928 - https://bugs.openjdk.java.net/browse/JDK-8215739 - http://mail.openjdk.java.net/pipermail/jigsaw-dev/2018-December/014077.html - https://stackoverflow.com/questions/51094274/eclipse-cant-find-xml-related-classes-after-switching-build-path-to-jdk-10/53824670#53824670 Since the bug (JDK-8215739) has not been fixed in OpenJDK, the strict "no split packages" rule does not apply to the Java compiler used in Spring Framework's Gradle build or the compiler in IntelliJ IDEA. Hence, this issue only arrises when building the framework in Eclipse IDE. This commit addresses this issue in the following affected projects. - spring-oxm: removal of the dependency on XPP3 which publishes javax.xml.namespace.QName as part of the JAR. The QName type is also published by the java.xml JDK 17 system module. To make the tests pass, we have switched to using the DomDriver instead of the XppDriver in our XStream tests. - spring-test: HtmlUnit has a transitive dependency on xml-apis which publishes several packages also published by java.xml JDK 17 system module. Thus, we have explicitly excluded the transitive dependency on xml-apis for our `optional` configuration. See gh-27407 --- gradle/ide.gradle | 4 ++-- import-into-eclipse.md | 6 +++++- spring-oxm/spring-oxm.gradle | 1 - .../oxm/xstream/XStreamMarshallerTests.java | 15 +++++++++------ .../oxm/xstream/XStreamUnmarshallerTests.java | 3 +++ spring-test/spring-test.gradle | 9 +++++++++ 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/gradle/ide.gradle b/gradle/ide.gradle index d5215f2875f2..9d3db1023813 100644 --- a/gradle/ide.gradle +++ b/gradle/ide.gradle @@ -4,8 +4,8 @@ import org.gradle.plugins.ide.eclipse.model.SourceFolder apply plugin: 'eclipse' eclipse.jdt { - sourceCompatibility = 1.8 - targetCompatibility = 1.8 + sourceCompatibility = 17 + targetCompatibility = 17 } // Replace classpath entries with project dependencies (GRADLE-1116) diff --git a/import-into-eclipse.md b/import-into-eclipse.md index fc3d36a8854b..1ab36c1fcfd3 100644 --- a/import-into-eclipse.md +++ b/import-into-eclipse.md @@ -3,7 +3,7 @@ This document will guide you through the process of importing the Spring Framework projects into Eclipse or the Spring Tool Suite (_STS_). It is recommended that you have a recent version of Eclipse. As a bare minimum you will need Eclipse with full Java -8 support, Eclipse Buildship, and the Groovy plugin. +17 support, Eclipse Buildship, and the Groovy plugin. The following instructions have been tested against [STS](https://spring.io/tools) 4.12.0 ([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-4120-changelog)) @@ -12,6 +12,10 @@ The instructions should work with the latest Eclipse distribution as long as you [Buildship](https://marketplace.eclipse.org/content/buildship-gradle-integration). Note that STS 4 comes with Buildship preinstalled. +If you are using Eclipse 4.21, you will need to install +[Java 17 Support for Eclipse 2021-09 (4.21)](https://marketplace.eclipse.org/content/java-17-support-eclipse-2021-09-421) +from the Eclipse Marketplace. + ## Steps _When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._ diff --git a/spring-oxm/spring-oxm.gradle b/spring-oxm/spring-oxm.gradle index bce9c1517691..0778059690c2 100644 --- a/spring-oxm/spring-oxm.gradle +++ b/spring-oxm/spring-oxm.gradle @@ -22,7 +22,6 @@ dependencies { optional("com.thoughtworks.xstream:xstream") testImplementation(project(":spring-context")) testImplementation(testFixtures(project(":spring-core"))) - testImplementation("org.ogce:xpp3") testImplementation("org.codehaus.jettison:jettison") { exclude group: "stax", module: "stax-api" } diff --git a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java index 304d3fcc771b..ece6236ecd75 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java @@ -43,6 +43,8 @@ import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver; import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver; import com.thoughtworks.xstream.io.json.JsonWriter; +import com.thoughtworks.xstream.io.xml.DomDriver; +import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; import com.thoughtworks.xstream.security.AnyTypePermission; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -84,6 +86,7 @@ void createMarshaller() { marshaller = new XStreamMarshaller(); marshaller.setTypePermissions(AnyTypePermission.ANY); marshaller.setAliases(Collections.singletonMap("flight", Flight.class.getName())); + marshaller.setStreamDriver(new DomDriver("UTF-8", new XmlFriendlyNameCoder())); flight.setFlightNumber(42L); } @@ -139,7 +142,7 @@ void marshalStreamResultWriter() throws Exception { StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); marshaller.marshal(flight, result); - assertThat(XmlContent.from(writer)).isSimilarTo(EXPECTED_STRING); + assertThat(XmlContent.from(writer)).isSimilarToIgnoringWhitespace(EXPECTED_STRING); } @Test @@ -148,7 +151,7 @@ void marshalStreamResultOutputStream() throws Exception { StreamResult result = new StreamResult(os); marshaller.marshal(flight, result); String s = os.toString("UTF-8"); - assertThat(XmlContent.of(s)).isSimilarTo(EXPECTED_STRING); + assertThat(XmlContent.of(s)).isSimilarToIgnoringWhitespace(EXPECTED_STRING); } @Test @@ -254,7 +257,7 @@ void aliasesByTypeStringClassMap() throws Exception { Writer writer = new StringWriter(); marshaller.marshal(flight, new StreamResult(writer)); - assertThat(XmlContent.from(writer)).isSimilarTo(EXPECTED_STRING); + assertThat(XmlContent.from(writer)).isSimilarToIgnoringWhitespace(EXPECTED_STRING); } @Test @@ -267,7 +270,7 @@ void aliasesByTypeStringStringMap() throws Exception { Writer writer = new StringWriter(); marshaller.marshal(flight, new StreamResult(writer)); - assertThat(XmlContent.from(writer)).isSimilarTo(EXPECTED_STRING); + assertThat(XmlContent.from(writer)).isSimilarToIgnoringWhitespace(EXPECTED_STRING); } @Test @@ -276,7 +279,7 @@ void fieldAliases() throws Exception { Writer writer = new StringWriter(); marshaller.marshal(flight, new StreamResult(writer)); String expected = "42"; - assertThat(XmlContent.from(writer)).isSimilarTo(expected); + assertThat(XmlContent.from(writer)).isSimilarToIgnoringWhitespace(expected); } @Test @@ -351,7 +354,7 @@ void annotatedMarshalStreamResultWriter() throws Exception { flight.setFlightNumber(42); marshaller.marshal(flight, result); String expected = "42"; - assertThat(XmlContent.from(writer)).isSimilarTo(expected); + assertThat(XmlContent.from(writer)).isSimilarToIgnoringWhitespace(expected); } diff --git a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamUnmarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamUnmarshallerTests.java index 7c87eda2253b..9d8d61b7bea6 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamUnmarshallerTests.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamUnmarshallerTests.java @@ -30,6 +30,8 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamSource; +import com.thoughtworks.xstream.io.xml.DomDriver; +import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; import com.thoughtworks.xstream.security.AnyTypePermission; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -55,6 +57,7 @@ public class XStreamUnmarshallerTests { public void createUnmarshaller() { unmarshaller = new XStreamMarshaller(); unmarshaller.setTypePermissions(AnyTypePermission.ANY); + unmarshaller.setStreamDriver(new DomDriver("UTF-8", new XmlFriendlyNameCoder())); Map> aliases = new HashMap<>(); aliases.put("flight", Flight.class); unmarshaller.setAliases(aliases); diff --git a/spring-test/spring-test.gradle b/spring-test/spring-test.gradle index ea64eb6f2764..1cb742f451a9 100644 --- a/spring-test/spring-test.gradle +++ b/spring-test/spring-test.gradle @@ -79,6 +79,15 @@ dependencies { testRuntimeOnly("com.sun.xml.bind:jaxb-impl") } +// Prevent xml-apis from being used so that the corresponding XML APIs from +// the JDK's `java.xml` module are used instead. This allows spring-test to +// build in Eclipse IDE which fails to compile if there is a split package +// between a JDK system module and the unnamed module (for JARs on the +// classpath). +configurations.optional { + exclude group: "xml-apis", module: "xml-apis" +} + test { description = "Runs JUnit 4, JUnit Jupiter, and TestNG tests." useJUnitPlatform { From 134c0e29167e3d80b7cc3e94ac39691f08e2cc07 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 22 Sep 2021 22:08:38 +0200 Subject: [PATCH 139/735] Upgrade to JUnit 5.8.1 Closes gh-27450 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 33b6227dabb0..81193a9f2f1d 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,7 @@ configure(allprojects) { project -> mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.30" mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2" mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2" - mavenBom "org.junit:junit-bom:5.8.0" + mavenBom "org.junit:junit-bom:5.8.1" } dependencies { dependencySet(group: 'org.apache.logging.log4j', version: '2.14.1') { @@ -384,7 +384,7 @@ configure([rootProject] + javaProjects) { project -> "https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/", "https://projectreactor.io/docs/test/release/api/", "https://junit.org/junit4/javadoc/4.13.2/", - "https://junit.org/junit5/docs/5.8.0/api/", + "https://junit.org/junit5/docs/5.8.1/api/", "https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/", "https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/", "https://r2dbc.io/spec/0.8.5.RELEASE/api/" From 66b15efa215ee5b1cd060825681e366cb437e4ba Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Thu, 23 Sep 2021 13:57:39 +0200 Subject: [PATCH 140/735] Upgrade CI image to JDK 17+35 --- ci/images/get-jdk-url.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/images/get-jdk-url.sh b/ci/images/get-jdk-url.sh index 48072fd2f9e2..a3babd3ae7d4 100755 --- a/ci/images/get-jdk-url.sh +++ b/ci/images/get-jdk-url.sh @@ -3,7 +3,7 @@ set -e case "$1" in java17) - echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk17-2021-09-15-08-15-beta/OpenJDK17-jdk_x64_linux_hotspot_2021-09-15-08-15.tar.gz" + echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17%2B35/OpenJDK17-jdk_x64_linux_hotspot_17_35.tar.gz" ;; *) echo $"Unknown java version" From f9d63e7bb1acaa4c752ab73a53513c08e3817021 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 23 Sep 2021 15:53:54 +0200 Subject: [PATCH 141/735] BeanUtils.getResolvableConstructor falls back to single non-public constructor Closes gh-27437 --- .../org/springframework/beans/BeanUtils.java | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index 8ddd6ff74467..f7708247d786 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -226,32 +226,46 @@ public static T instantiateClass(Constructor ctor, Object... args) throws } /** - * Return a resolvable constructor for the provided class, either a primary constructor - * or single public constructor or simply a default constructor. Callers have to be - * prepared to resolve arguments for the returned constructor's parameters, if any. + * Return a resolvable constructor for the provided class, either a primary or single + * public constructor with arguments, or a single non-public constructor with arguments, + * or simply a default constructor. Callers have to be prepared to resolve arguments + * for the returned constructor's parameters, if any. * @param clazz the class to check + * @throws IllegalStateException in case of no unique constructor found at all * @since 5.3 * @see #findPrimaryConstructor */ @SuppressWarnings("unchecked") public static Constructor getResolvableConstructor(Class clazz) { Constructor ctor = findPrimaryConstructor(clazz); - if (ctor == null) { - Constructor[] ctors = clazz.getConstructors(); + if (ctor != null) { + return ctor; + } + + Constructor[] ctors = clazz.getConstructors(); + if (ctors.length == 1) { + // A single public constructor + return (Constructor) ctors[0]; + } + else if (ctors.length == 0){ + ctors = clazz.getDeclaredConstructors(); if (ctors.length == 1) { - ctor = (Constructor) ctors[0]; + // A single non-public constructor, e.g. from a non-public record type + return (Constructor) ctors[0]; } - else { - try { - ctor = clazz.getDeclaredConstructor(); - } - catch (NoSuchMethodException ex) { - throw new IllegalStateException("No primary or single public constructor found for " + - clazz + " - and no default constructor found either"); - } + } + else { + // Several public constructors -> let's take the default constructor + try { + return clazz.getDeclaredConstructor(); + } + catch (NoSuchMethodException ex) { + // Giving up... } } - return ctor; + + // No unique constructor at all + throw new IllegalStateException("No primary or single unique constructor found for " + clazz); } /** From 58898de5429c43ae676a7643fcd20d684af1c9ec Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 23 Sep 2021 15:54:40 +0200 Subject: [PATCH 142/735] Provide accessors for externallyManagedConfigMembers and Init/DestroyMethods Closes gh-27449 --- .../factory/support/RootBeanDefinition.java | 63 +++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java index 863873499266..f4fdafa3767e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java @@ -21,7 +21,8 @@ import java.lang.reflect.Executable; import java.lang.reflect.Member; import java.lang.reflect.Method; -import java.util.HashSet; +import java.util.Collections; +import java.util.LinkedHashSet; import java.util.Set; import java.util.function.Supplier; @@ -422,15 +423,21 @@ public Method getResolvedFactoryMethod() { return this.factoryMethodToIntrospect; } + /** + * Register an externally managed configuration method or field. + */ public void registerExternallyManagedConfigMember(Member configMember) { synchronized (this.postProcessingLock) { if (this.externallyManagedConfigMembers == null) { - this.externallyManagedConfigMembers = new HashSet<>(1); + this.externallyManagedConfigMembers = new LinkedHashSet<>(1); } this.externallyManagedConfigMembers.add(configMember); } } + /** + * Check whether the given method or field is an externally managed configuration member. + */ public boolean isExternallyManagedConfigMember(Member configMember) { synchronized (this.postProcessingLock) { return (this.externallyManagedConfigMembers != null && @@ -438,15 +445,33 @@ public boolean isExternallyManagedConfigMember(Member configMember) { } } + /** + * Return all externally managed configuration methods and fields (as an immutable Set). + * @since 5.3.11 + */ + public Set getExternallyManagedConfigMembers() { + synchronized (this.postProcessingLock) { + return (this.externallyManagedConfigMembers != null ? + Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedConfigMembers)) : + Collections.emptySet()); + } + } + + /** + * Register an externally managed configuration initialization method. + */ public void registerExternallyManagedInitMethod(String initMethod) { synchronized (this.postProcessingLock) { if (this.externallyManagedInitMethods == null) { - this.externallyManagedInitMethods = new HashSet<>(1); + this.externallyManagedInitMethods = new LinkedHashSet<>(1); } this.externallyManagedInitMethods.add(initMethod); } } + /** + * Check whether the given method name indicates an externally managed initialization method. + */ public boolean isExternallyManagedInitMethod(String initMethod) { synchronized (this.postProcessingLock) { return (this.externallyManagedInitMethods != null && @@ -454,15 +479,33 @@ public boolean isExternallyManagedInitMethod(String initMethod) { } } + /** + * Return all externally managed initialization methods (as an immutable Set). + * @since 5.3.11 + */ + public Set getExternallyManagedInitMethods() { + synchronized (this.postProcessingLock) { + return (this.externallyManagedInitMethods != null ? + Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedInitMethods)) : + Collections.emptySet()); + } + } + + /** + * Register an externally managed configuration destruction method. + */ public void registerExternallyManagedDestroyMethod(String destroyMethod) { synchronized (this.postProcessingLock) { if (this.externallyManagedDestroyMethods == null) { - this.externallyManagedDestroyMethods = new HashSet<>(1); + this.externallyManagedDestroyMethods = new LinkedHashSet<>(1); } this.externallyManagedDestroyMethods.add(destroyMethod); } } + /** + * Check whether the given method name indicates an externally managed destruction method. + */ public boolean isExternallyManagedDestroyMethod(String destroyMethod) { synchronized (this.postProcessingLock) { return (this.externallyManagedDestroyMethods != null && @@ -470,6 +513,18 @@ public boolean isExternallyManagedDestroyMethod(String destroyMethod) { } } + /** + * Return all externally managed destruction methods (as an immutable Set). + * @since 5.3.11 + */ + public Set getExternallyManagedDestroyMethods() { + synchronized (this.postProcessingLock) { + return (this.externallyManagedDestroyMethods != null ? + Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedDestroyMethods)) : + Collections.emptySet()); + } + } + @Override public RootBeanDefinition cloneBeanDefinition() { From 5cbc972a0de195ebb09645f65a1dea8fb85880c9 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 23 Sep 2021 15:56:06 +0200 Subject: [PATCH 143/735] Log rejected listener container tasks at warn level Closes gh-27451 --- .../jms/listener/AbstractJmsListeningContainer.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractJmsListeningContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractJmsListeningContainer.java index b7e1734bb99f..a9061e162fc5 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractJmsListeningContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractJmsListeningContainer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -582,13 +582,13 @@ protected void doRescheduleTask(Object task) { /** * Log a task that has been rejected by {@link #doRescheduleTask}. *

    The default implementation simply logs a corresponding message - * at debug level. + * at warn level. * @param task the rejected task object * @param ex the exception thrown from {@link #doRescheduleTask} */ protected void logRejectedTask(Object task, RuntimeException ex) { - if (logger.isDebugEnabled()) { - logger.debug("Listener container task [" + task + "] has been rejected and paused: " + ex); + if (logger.isWarnEnabled()) { + logger.warn("Listener container task [" + task + "] has been rejected and paused: " + ex); } } From 208fafa4a3b358519eb2005868dee437e28df22a Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 23 Sep 2021 15:56:49 +0200 Subject: [PATCH 144/735] Fix contract violations in ConcurrentReferenceHashMap's EntrySet/Iterator Closes gh-27454 --- .../util/ConcurrentReferenceHashMap.java | 3 ++- .../util/ConcurrentReferenceHashMapTests.java | 25 ++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java b/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java index f3af11b50a97..3291ca6e079a 100644 --- a/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java +++ b/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java @@ -858,7 +858,7 @@ public boolean contains(@Nullable Object o) { Reference ref = ConcurrentReferenceHashMap.this.getReference(entry.getKey(), Restructure.NEVER); Entry otherEntry = (ref != null ? ref.get() : null); if (otherEntry != null) { - return ObjectUtils.nullSafeEquals(otherEntry.getValue(), otherEntry.getValue()); + return ObjectUtils.nullSafeEquals(entry.getValue(), otherEntry.getValue()); } } return false; @@ -966,6 +966,7 @@ private void moveToNextSegment() { public void remove() { Assert.state(this.last != null, "No element to remove"); ConcurrentReferenceHashMap.this.remove(this.last.getKey()); + this.last = null; } } diff --git a/spring-core/src/test/java/org/springframework/util/ConcurrentReferenceHashMapTests.java b/spring-core/src/test/java/org/springframework/util/ConcurrentReferenceHashMapTests.java index b8ddb11aa0c8..e50168ee4e9e 100644 --- a/spring-core/src/test/java/org/springframework/util/ConcurrentReferenceHashMapTests.java +++ b/spring-core/src/test/java/org/springframework/util/ConcurrentReferenceHashMapTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,11 +41,13 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; /** * Tests for {@link ConcurrentReferenceHashMap}. * * @author Phillip Webb + * @author Juergen Hoeller */ class ConcurrentReferenceHashMapTests { @@ -466,6 +468,7 @@ void shouldRemoveViaEntrySet() { iterator.next(); iterator.next(); iterator.remove(); + assertThatIllegalStateException().isThrownBy(iterator::remove); iterator.next(); assertThat(iterator.hasNext()).isFalse(); assertThat(this.map).hasSize(2); @@ -486,6 +489,26 @@ void shouldSetViaEntrySet() { assertThat(this.map.get(2)).isEqualTo("2b"); } + @Test + void containsViaEntrySet() { + this.map.put(1, "1"); + this.map.put(2, "2"); + this.map.put(3, "3"); + Set> entrySet = this.map.entrySet(); + Set> copy = new HashMap<>(this.map).entrySet(); + copy.forEach(entry -> assertThat(entrySet.contains(entry)).isTrue()); + this.map.put(1, "A"); + this.map.put(2, "B"); + this.map.put(3, "C"); + copy.forEach(entry -> assertThat(entrySet.contains(entry)).isFalse()); + this.map.put(1, "1"); + this.map.put(2, "2"); + this.map.put(3, "3"); + copy.forEach(entry -> assertThat(entrySet.contains(entry)).isTrue()); + entrySet.clear(); + copy.forEach(entry -> assertThat(entrySet.contains(entry)).isFalse()); + } + @Test @Disabled("Intended for use during development only") void shouldBeFasterThanSynchronizedMap() throws InterruptedException { From e29cfa350106d8811072159748e41a4ef0d0b697 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 23 Sep 2021 15:57:43 +0200 Subject: [PATCH 145/735] Polishing --- spring-core/spring-core.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spring-core/spring-core.gradle b/spring-core/spring-core.gradle index a6e5e309b073..e4c568f84b13 100644 --- a/spring-core/spring-core.gradle +++ b/spring-core/spring-core.gradle @@ -50,21 +50,21 @@ dependencies { optional("io.reactivex.rxjava3:rxjava") optional("io.smallrye.reactive:mutiny") optional("io.netty:netty-buffer") - testImplementation("io.projectreactor:reactor-test") - testImplementation("com.google.code.findbugs:jsr305") testImplementation("javax.annotation:javax.annotation-api") testImplementation("javax.xml.bind:jaxb-api") + testImplementation("com.google.code.findbugs:jsr305") testImplementation("com.fasterxml.woodstox:woodstox-core") testImplementation("org.xmlunit:xmlunit-assertj") testImplementation("org.xmlunit:xmlunit-matchers") + testImplementation("io.projectreactor:reactor-test") testImplementation("io.projectreactor.tools:blockhound") - testFixturesImplementation("io.projectreactor:reactor-test") testFixturesImplementation("com.google.code.findbugs:jsr305") testFixturesImplementation("org.junit.platform:junit-platform-launcher") testFixturesImplementation("org.junit.jupiter:junit-jupiter-api") testFixturesImplementation("org.junit.jupiter:junit-jupiter-params") testFixturesImplementation("org.assertj:assertj-core") testFixturesImplementation("org.xmlunit:xmlunit-assertj") + testFixturesImplementation("io.projectreactor:reactor-test") } jar { @@ -92,7 +92,7 @@ jar { } test { - // Make sure the classes dir is used on the test classpath (required by ResourceTests) - // When test fixtures are involved, the JAR is used by default + // Make sure the classes dir is used on the test classpath (required by ResourceTests). + // When test fixtures are involved, the JAR is used by default. classpath = sourceSets.main.output.classesDirs + classpath - files(jar.archiveFile) } From f440fb8bafc1277c8a6f85851179d1a7985a83dc Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 23 Sep 2021 16:13:20 +0200 Subject: [PATCH 146/735] Unit tests for record binding See gh-27437 --- .../jdbc/core/AbstractRowMapperTests.java | 2 +- .../jdbc/core/DataClassRowMapperTests.java | 24 +++ ...nnotationControllerHandlerMethodTests.java | 181 ++++++++++-------- 3 files changed, 128 insertions(+), 79 deletions(-) diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java index 601bbdfd7a1d..633e86c4c281 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java @@ -89,7 +89,7 @@ protected void verifyPerson(ConstructorPerson person) { verifyPersonViaBeanWrapper(person); } - private void verifyPersonViaBeanWrapper(Object person) { + protected void verifyPersonViaBeanWrapper(Object person) { BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(person); assertThat(bw.getPropertyValue("name")).isEqualTo("Bubba"); assertThat(bw.getPropertyValue("age")).isEqualTo(22L); diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/DataClassRowMapperTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/DataClassRowMapperTests.java index 48b0f7f03134..b9fb7ad44df4 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/DataClassRowMapperTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/DataClassRowMapperTests.java @@ -79,4 +79,28 @@ public void testStaticQueryWithDataClassAndSetters() throws Exception { mock.verifyClosed(); } + @Test + public void testStaticQueryWithDataRecord() throws Exception { + Mock mock = new Mock(); + List result = mock.getJdbcTemplate().query( + "select name, age, birth_date, balance from people", + new DataClassRowMapper<>(RecordPerson.class)); + assertThat(result.size()).isEqualTo(1); + verifyPerson(result.get(0)); + + mock.verifyClosed(); + } + + protected void verifyPerson(RecordPerson person) { + assertThat(person.name()).isEqualTo("Bubba"); + assertThat(person.age()).isEqualTo(22L); + assertThat(person.birth_date()).usingComparator(Date::compareTo).isEqualTo(new java.util.Date(1221222L)); + assertThat(person.balance()).isEqualTo(new BigDecimal("1234.56")); + verifyPersonViaBeanWrapper(person); + } + + + static record RecordPerson(String name, long age, Date birth_date, BigDecimal balance) { + } + } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java index 8f07c7071f8e..46f4d2577311 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java @@ -2202,6 +2202,19 @@ void dataClassBindingWithLocalDate(boolean usePathPatterns) throws Exception { assertThat(response.getContentAsString()).isEqualTo("2010-01-01"); } + @PathPatternsParameterizedTest + void dataRecordBinding(boolean usePathPatterns) throws Exception { + initDispatcherServlet(DataRecordController.class, usePathPatterns); + + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/bind"); + request.addParameter("param1", "value1"); + request.addParameter("param2", "true"); + request.addParameter("param3", "3"); + MockHttpServletResponse response = new MockHttpServletResponse(); + getServlet().service(request, response); + assertThat(response.getContentAsString()).isEqualTo("value1-true-3"); + } + @Test void routerFunction() throws ServletException, IOException { GenericWebApplicationContext wac = new GenericWebApplicationContext(); @@ -2397,7 +2410,7 @@ public void nonEmptyParameterListHandler(HttpServletResponse response) { @Controller @RequestMapping("/myPage") @SessionAttributes(names = { "object1", "object2" }) - public static class MySessionAttributesController { + static class MySessionAttributesController { @RequestMapping(method = RequestMethod.GET) public String get(Model model) { @@ -2417,7 +2430,7 @@ public String post(@ModelAttribute("object1") Object object1) { @RequestMapping("/myPage") @SessionAttributes({"object1", "object2"}) @Controller - public interface MySessionAttributesControllerIfc { + interface MySessionAttributesControllerIfc { @RequestMapping(method = RequestMethod.GET) String get(Model model); @@ -2426,7 +2439,7 @@ public interface MySessionAttributesControllerIfc { String post(@ModelAttribute("object1") Object object1); } - public static class MySessionAttributesControllerImpl implements MySessionAttributesControllerIfc { + static class MySessionAttributesControllerImpl implements MySessionAttributesControllerIfc { @Override public String get(Model model) { @@ -2444,7 +2457,7 @@ public String post(@ModelAttribute("object1") Object object1) { @RequestMapping("/myPage") @SessionAttributes({"object1", "object2"}) - public interface MyParameterizedControllerIfc { + interface MyParameterizedControllerIfc { @ModelAttribute("testBeanList") List getTestBeans(); @@ -2453,14 +2466,14 @@ public interface MyParameterizedControllerIfc { String get(Model model); } - public interface MyEditableParameterizedControllerIfc extends MyParameterizedControllerIfc { + interface MyEditableParameterizedControllerIfc extends MyParameterizedControllerIfc { @RequestMapping(method = RequestMethod.POST) String post(@ModelAttribute("object1") T object); } @Controller - public static class MyParameterizedControllerImpl implements MyEditableParameterizedControllerIfc { + static class MyParameterizedControllerImpl implements MyEditableParameterizedControllerIfc { @Override public List getTestBeans() { @@ -2485,7 +2498,7 @@ public String post(TestBean object) { } @Controller - public static class MyParameterizedControllerImplWithOverriddenMappings + static class MyParameterizedControllerImplWithOverriddenMappings implements MyEditableParameterizedControllerIfc { @Override @@ -2514,7 +2527,7 @@ public String post(@ModelAttribute("object1") TestBean object1) { } @Controller - public static class MyFormController { + static class MyFormController { @ModelAttribute("testBeanList") public List getTestBeans() { @@ -2536,7 +2549,7 @@ public String myHandle(@ModelAttribute("myCommand") TestBean tb, BindingResult e } } - public static class ValidTestBean extends TestBean { + static class ValidTestBean extends TestBean { @NotNull private String validCountry; @@ -2551,7 +2564,7 @@ public String getValidCountry() { } @Controller - public static class MyModelFormController { + static class MyModelFormController { @ModelAttribute public List getTestBeans() { @@ -2572,7 +2585,7 @@ public String myHandle(@ModelAttribute("myCommand") TestBean tb, BindingResult e } @Controller - public static class LateBindingFormController { + static class LateBindingFormController { @ModelAttribute("testBeanList") public List getTestBeans(@ModelAttribute(name="myCommand", binding=false) TestBean tb) { @@ -2915,7 +2928,7 @@ public void render(@Nullable Map model, HttpServletRequest request, HttpServletR } } - public static class ModelExposingViewResolver implements ViewResolver { + static class ModelExposingViewResolver implements ViewResolver { @Override public View resolveViewName(String viewName, Locale locale) { @@ -2926,7 +2939,7 @@ public View resolveViewName(String viewName, Locale locale) { } } - public static class ParentController { + static class ParentController { @RequestMapping(method = RequestMethod.GET) public void doGet(HttpServletRequest req, HttpServletResponse resp) { @@ -2935,7 +2948,7 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) { @Controller @RequestMapping("/child/test") - public static class ChildController extends ParentController { + static class ChildController extends ParentController { @RequestMapping(method = RequestMethod.GET) public void doGet(HttpServletRequest req, HttpServletResponse resp, @RequestParam("childId") String id) { @@ -2969,7 +2982,7 @@ public void get(Writer writer) throws IOException { } @MyControllerAnnotation - public static class CustomAnnotationController { + static class CustomAnnotationController { @RequestMapping("/myPath.do") public void myHandle() { @@ -2977,7 +2990,7 @@ public void myHandle() { } @Controller - public static class RequiredParamController { + static class RequiredParamController { @RequestMapping("/myPath.do") public void myHandle(@RequestParam(value = "id", required = true) int id, @@ -2986,7 +2999,7 @@ public void myHandle(@RequestParam(value = "id", required = true) int id, } @Controller - public static class OptionalParamController { + static class OptionalParamController { @RequestMapping("/myPath.do") public void myHandle(@RequestParam(required = false) String id, @@ -2998,7 +3011,7 @@ public void myHandle(@RequestParam(required = false) String id, } @Controller - public static class DefaultValueParamController { + static class DefaultValueParamController { @RequestMapping("/myPath.do") public void myHandle(@RequestParam(value = "id", defaultValue = "foo") String id, @@ -3010,7 +3023,7 @@ public void myHandle(@RequestParam(value = "id", defaultValue = "foo") String id } @Controller - public static class DefaultExpressionValueParamController { + static class DefaultExpressionValueParamController { @RequestMapping("/myPath.do") public void myHandle(@RequestParam(value = "id", defaultValue = "${myKey}") String id, @@ -3022,7 +3035,7 @@ public void myHandle(@RequestParam(value = "id", defaultValue = "${myKey}") Stri } @Controller - public static class NestedSetController { + static class NestedSetController { @RequestMapping("/myPath.do") public void myHandle(GenericBean gb, HttpServletResponse response) throws Exception { @@ -3031,7 +3044,7 @@ public void myHandle(GenericBean gb, HttpServletResponse response) throws Exc } } - public static class TestBeanConverter implements Converter { + static class TestBeanConverter implements Converter { @Override public ITestBean convert(String source) { @@ -3040,14 +3053,14 @@ public ITestBean convert(String source) { } @Controller - public static class PathVariableWithCustomConverterController { + static class PathVariableWithCustomConverterController { @RequestMapping("/myPath/{id}") public void myHandle(@PathVariable("id") ITestBean bean) throws Exception { } } - public static class AnnotatedExceptionRaisingConverter implements Converter { + static class AnnotatedExceptionRaisingConverter implements Converter { @Override public ITestBean convert(String source) { @@ -3061,7 +3074,7 @@ private static class NotFoundException extends RuntimeException { } @Controller - public static class MethodNotAllowedController { + static class MethodNotAllowedController { @RequestMapping(value = "/myPath.do", method = RequestMethod.DELETE) public void delete() { @@ -3093,7 +3106,7 @@ public void get() { } @Controller - public static class PathOrderingController { + static class PathOrderingController { @RequestMapping(value = {"/dir/myPath1.do", "/*/*.do"}) public void method1(Writer writer) throws IOException { @@ -3107,7 +3120,7 @@ public void method2(Writer writer) throws IOException { } @Controller - public static class RequestResponseBodyController { + static class RequestResponseBodyController { @RequestMapping(value = "/something", method = RequestMethod.PUT) @ResponseBody @@ -3123,7 +3136,7 @@ public String handlePartialUpdate(@RequestBody String content) throws IOExceptio } @Controller - public static class RequestResponseBodyProducesController { + static class RequestResponseBodyProducesController { @RequestMapping(value = "/something", method = RequestMethod.PUT, produces = "text/plain") @ResponseBody @@ -3133,7 +3146,7 @@ public String handle(@RequestBody String body) throws IOException { } @Controller - public static class ResponseBodyVoidController { + static class ResponseBodyVoidController { @RequestMapping("/something") @ResponseBody @@ -3142,7 +3155,7 @@ public void handle() throws IOException { } @Controller - public static class RequestBodyArgMismatchController { + static class RequestBodyArgMismatchController { @RequestMapping(value = "/something", method = RequestMethod.PUT) public void handle(@RequestBody A a) throws IOException { @@ -3150,14 +3163,14 @@ public void handle(@RequestBody A a) throws IOException { } @XmlRootElement - public static class A { + static class A { } @XmlRootElement - public static class B { + static class B { } - public static class NotReadableMessageConverter implements HttpMessageConverter { + static class NotReadableMessageConverter implements HttpMessageConverter { @Override public boolean canRead(Class clazz, @Nullable MediaType mediaType) { @@ -3185,7 +3198,7 @@ public void write(Object o, @Nullable MediaType contentType, HttpOutputMessage o } } - public static class SimpleMessageConverter implements HttpMessageConverter { + static class SimpleMessageConverter implements HttpMessageConverter { private final List supportedMediaTypes; @@ -3223,7 +3236,7 @@ public void write(Object o, @Nullable MediaType contentType, HttpOutputMessage o } @Controller - public static class ContentTypeHeadersController { + static class ContentTypeHeadersController { @RequestMapping(value = "/something", headers = "content-type=application/pdf") public void handlePdf(Writer writer) throws IOException { @@ -3237,7 +3250,7 @@ public void handleHtml(Writer writer) throws IOException { } @Controller - public static class ConsumesController { + static class ConsumesController { @RequestMapping(value = "/something", consumes = "application/pdf") public void handlePdf(Writer writer) throws IOException { @@ -3251,7 +3264,7 @@ public void handleHtml(Writer writer) throws IOException { } @Controller - public static class NegatedContentTypeHeadersController { + static class NegatedContentTypeHeadersController { @RequestMapping(value = "/something", headers = "content-type=application/pdf") public void handlePdf(Writer writer) throws IOException { @@ -3266,7 +3279,7 @@ public void handleNonPdf(Writer writer) throws IOException { } @Controller - public static class AcceptHeadersController { + static class AcceptHeadersController { @RequestMapping(value = "/something", headers = "accept=text/html") public void handleHtml(Writer writer) throws IOException { @@ -3280,7 +3293,7 @@ public void handleXml(Writer writer) throws IOException { } @Controller - public static class ProducesController { + static class ProducesController { @GetMapping(path = "/something", produces = "text/html") public void handleHtml(Writer writer) throws IOException { @@ -3304,7 +3317,7 @@ public ResponseEntity> handle(IllegalArgumentException ex) { } @Controller - public static class ResponseStatusController { + static class ResponseStatusController { @RequestMapping("/something") @ResponseStatus(code = HttpStatus.CREATED, reason = "It's alive!") @@ -3314,7 +3327,7 @@ public void handle(Writer writer) throws IOException { } @Controller - public static class ModelAndViewResolverController { + static class ModelAndViewResolverController { @RequestMapping("/") public MySpecialArg handle() { @@ -3322,7 +3335,7 @@ public MySpecialArg handle() { } } - public static class MyModelAndViewResolver implements ModelAndViewResolver { + static class MyModelAndViewResolver implements ModelAndViewResolver { @Override public ModelAndView resolveModelAndView(Method handlerMethod, Class handlerType, Object returnValue, @@ -3376,7 +3389,7 @@ public void patternMatch(Writer writer) throws IOException { @Controller @RequestMapping("/test*") - public static class BindingCookieValueController { + static class BindingCookieValueController { @InitBinder public void initBinder(WebDataBinder binder) { @@ -3393,16 +3406,16 @@ public void handle(@CookieValue("date") Date date, Writer writer) throws IOExcep } } - public interface TestController { + interface TestController { ModelAndView method(T object); } - public static class MyEntity { + static class MyEntity { } @Controller - public static class TestControllerImpl implements TestController { + static class TestControllerImpl implements TestController { @Override @RequestMapping("/method") @@ -3413,7 +3426,7 @@ public ModelAndView method(MyEntity object) { @RestController @RequestMapping(path = ApiConstants.ARTICLES_PATH) - public static class ArticleController implements ApiConstants, ResourceEndpoint { + static class ArticleController implements ApiConstants, ResourceEndpoint { @Override @GetMapping(params = "page") @@ -3435,14 +3448,14 @@ interface ApiConstants { String ARTICLES_PATH = API_V1 + "/articles"; } - public interface ResourceEndpoint> { + interface ResourceEndpoint> { Collection find(String pageable, P predicate) throws IOException; List find(boolean sort, P predicate) throws IOException; } - public static abstract class Entity { + static abstract class Entity { public UUID id; @@ -3451,7 +3464,7 @@ public static abstract class Entity { public Instant createdDate; } - public static class Article extends Entity { + static class Article extends Entity { public String slug; @@ -3460,7 +3473,7 @@ public static class Article extends Entity { public String content; } - public static abstract class EntityPredicate { + static abstract class EntityPredicate { public String createdBy; @@ -3475,7 +3488,7 @@ public boolean accept(E entity) { } } - public static class ArticlePredicate extends EntityPredicate
    { + static class ArticlePredicate extends EntityPredicate
    { public String query; @@ -3486,7 +3499,7 @@ public boolean accept(Article entity) { } @Controller - public static class RequestParamMapController { + static class RequestParamMapController { @RequestMapping("/map") public void map(@RequestParam Map params, Writer writer) throws IOException { @@ -3521,7 +3534,7 @@ public void multiValueMap(@RequestParam MultiValueMap params, Wr } @Controller - public static class RequestHeaderMapController { + static class RequestHeaderMapController { @RequestMapping("/map") public void map(@RequestHeader Map headers, Writer writer) throws IOException { @@ -3564,14 +3577,14 @@ public void httpHeaders(@RequestHeader HttpHeaders headers, Writer writer) throw } @Controller - public interface IMyController { + interface IMyController { @RequestMapping("/handle") void handle(Writer writer, @RequestParam(value="p", required=false) String param) throws IOException; } @Controller - public static class IMyControllerImpl implements IMyController { + static class IMyControllerImpl implements IMyController { @Override public void handle(Writer writer, @RequestParam(value="p", required=false) String param) throws IOException { @@ -3579,14 +3592,14 @@ public void handle(Writer writer, @RequestParam(value="p", required=false) Strin } } - public static abstract class MyAbstractController { + static abstract class MyAbstractController { @RequestMapping("/handle") public abstract void handle(Writer writer) throws IOException; } @Controller - public static class MyAbstractControllerImpl extends MyAbstractController { + static class MyAbstractControllerImpl extends MyAbstractController { @Override public void handle(Writer writer) throws IOException { @@ -3595,7 +3608,7 @@ public void handle(Writer writer) throws IOException { } @Controller - public static class TrailingSlashController { + static class TrailingSlashController { @RequestMapping(value = "/", method = RequestMethod.GET) public void root(Writer writer) throws IOException { @@ -3609,7 +3622,7 @@ public void templatePath(Writer writer) throws IOException { } @Controller - public static class ResponseEntityController { + static class ResponseEntityController { @PostMapping("/foo") public ResponseEntity foo(HttpEntity requestEntity) throws Exception { @@ -3666,7 +3679,7 @@ public void setName(String name) { } @Controller - public static class CustomMapEditorController { + static class CustomMapEditorController { @InitBinder public void initBinder(WebDataBinder binder) { @@ -3681,7 +3694,7 @@ public void handle(@RequestParam("map") Map map, Writer writer) throws IOExcepti } } - public static class CustomMapEditor extends PropertyEditorSupport { + static class CustomMapEditor extends PropertyEditorSupport { @Override public void setAsText(String text) throws IllegalArgumentException { @@ -3695,7 +3708,7 @@ public void setAsText(String text) throws IllegalArgumentException { } @Controller - public static class MultipartController { + static class MultipartController { @InitBinder public void initBinder(WebDataBinder binder) { @@ -3716,7 +3729,7 @@ public void processMultipart(@RequestParam("content") String[] content, HttpServ } @Controller - public static class CsvController { + static class CsvController { @RequestMapping("/singleInteger") public void processCsv(@RequestParam("content") Integer content, HttpServletResponse response) throws IOException { @@ -3840,7 +3853,7 @@ public HttpHeaders createNoHeader() { } @RestController - public static class TextRestController { + static class TextRestController { @RequestMapping(path = "/a1", method = RequestMethod.GET) public String a1(@RequestBody String body) { @@ -3864,7 +3877,7 @@ public String a4(@RequestBody String body) { } @Controller - public static class ModelAndViewController { + static class ModelAndViewController { @RequestMapping("/path") public ModelAndView methodWithHttpStatus(MyEntity object) { @@ -3886,7 +3899,7 @@ private static class TestException extends Exception { } } - public static class DataClass { + static class DataClass { @NotNull private final String param1; @@ -3921,7 +3934,7 @@ public int getParam3() { } @RestController - public static class DataClassController { + static class DataClassController { @RequestMapping("/bind") public String handle(DataClass data) { @@ -3930,7 +3943,7 @@ public String handle(DataClass data) { } @RestController - public static class PathVariableDataClassController { + static class PathVariableDataClassController { @RequestMapping("/bind/{param2}") public String handle(DataClass data) { @@ -3939,7 +3952,7 @@ public String handle(DataClass data) { } @RestController - public static class ValidatedDataClassController { + static class ValidatedDataClassController { @InitBinder public void initBinder(WebDataBinder binder) { @@ -3960,7 +3973,7 @@ public BindStatusView handle(@Valid DataClass data, BindingResult result) { } } - public static class BindStatusView extends AbstractView { + static class BindStatusView extends AbstractView { private final String content; @@ -3980,7 +3993,7 @@ protected void renderMergedOutputModel( } } - public static class MultipartFileDataClass { + static class MultipartFileDataClass { @NotNull public final MultipartFile param1; @@ -4003,7 +4016,7 @@ public void setParam3(int param3) { } @RestController - public static class MultipartFileDataClassController { + static class MultipartFileDataClassController { @RequestMapping("/bind") public String handle(MultipartFileDataClass data) throws IOException { @@ -4012,7 +4025,7 @@ public String handle(MultipartFileDataClass data) throws IOException { } } - public static class ServletPartDataClass { + static class ServletPartDataClass { @NotNull public final Part param1; @@ -4035,7 +4048,7 @@ public void setParam3(int param3) { } @RestController - public static class ServletPartDataClassController { + static class ServletPartDataClassController { @RequestMapping("/bind") public String handle(ServletPartDataClass data) throws IOException { @@ -4045,7 +4058,7 @@ public String handle(ServletPartDataClass data) throws IOException { } @RestController - public static class NullableDataClassController { + static class NullableDataClassController { @RequestMapping("/bind") public String handle(@Nullable DataClass data, BindingResult result) { @@ -4060,7 +4073,7 @@ public String handle(@Nullable DataClass data, BindingResult result) { } @RestController - public static class OptionalDataClassController { + static class OptionalDataClassController { @RequestMapping("/bind") public String handle(Optional optionalData, BindingResult result) { @@ -4074,7 +4087,7 @@ public String handle(Optional optionalData, BindingResult result) { } } - public static class DateClass { + static class DateClass { @DateTimeFormat(pattern = "yyyy-MM-dd") public LocalDate date; @@ -4085,7 +4098,7 @@ public DateClass(LocalDate date) { } @RestController - public static class DateClassController { + static class DateClassController { @InitBinder public void initBinder(WebDataBinder binder) { @@ -4107,4 +4120,16 @@ public String handle(DateClass data, BindingResult result) { } } + static record DataRecord(String param1, boolean param2, int param3) { + } + + @RestController + static class DataRecordController { + + @RequestMapping("/bind") + public String handle(DataRecord data) { + return data.param1 + "-" + data.param2 + "-" + data.param3; + } + } + } From 93f8706dd335f03d0bbb044f25c23e71a6a7d81d Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 24 Sep 2021 15:57:15 +0100 Subject: [PATCH 147/735] Update docs for ControllerAdvice In 5.3 it became possible to handle exceptions from any handler through ExceptionHandler's in a ControllerAdvice class, but this is not mentioned in the docs See gh-22619, gh-27338 --- src/docs/asciidoc/web/webmvc.adoc | 40 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/docs/asciidoc/web/webmvc.adoc b/src/docs/asciidoc/web/webmvc.adoc index d12b6ab923e8..b49666303e98 100644 --- a/src/docs/asciidoc/web/webmvc.adoc +++ b/src/docs/asciidoc/web/webmvc.adoc @@ -4021,27 +4021,25 @@ necessary methods, and declare it as a Spring bean. === Controller Advice [.small]#<># -Typically `@ExceptionHandler`, `@InitBinder`, and `@ModelAttribute` methods apply within -the `@Controller` class (or class hierarchy) in which they are declared. If you want such -methods to apply more globally (across controllers), you can declare them in a class -annotated with `@ControllerAdvice` or `@RestControllerAdvice`. - -`@ControllerAdvice` is annotated with `@Component`, which means such classes can be -registered as Spring beans through <>. `@RestControllerAdvice` is a composed annotation that is annotated -with both `@ControllerAdvice` and `@ResponseBody`, which essentially means -`@ExceptionHandler` methods are rendered to the response body through message conversion -(versus view resolution or template rendering). - -On startup, the infrastructure classes for `@RequestMapping` and `@ExceptionHandler` -methods detect Spring beans annotated with `@ControllerAdvice` and then apply their -methods at runtime. Global `@ExceptionHandler` methods (from a `@ControllerAdvice`) are -applied _after_ local ones (from the `@Controller`). By contrast, global `@ModelAttribute` -and `@InitBinder` methods are applied _before_ local ones. - -By default, `@ControllerAdvice` methods apply to every request (that is, all controllers), -but you can narrow that down to a subset of controllers by using attributes on the -annotation, as the following example shows: +`@ExceptionHandler`, `@InitBinder`, and `@ModelAttribute` methods apply only to the +`@Controller` class, or class hierarchy, in which they are declared. If, instead, they +are declared in an `@ControllerAdvice` or `@RestControllerAdvice` class, then they apply +to any controller. Moreover, as of 5.3, `@ExceptionHandler` methods in `@ControllerAdvice` +can be used to handle exceptions from any `@Controller` or any other handler. + +`@ControllerAdvice` is meta-annotated with `@Component` and therefore can be registered as +a Spring bean through <>. `@RestControllerAdvice` is meta-annotated with `@ControllerAdvice` +and `@ResponseBody`, and that means `@ExceptionHandler` methods will have their return +value rendered via response body message conversion, rather than via HTML views. + +On startup, `RequestMappingHandlerMapping` and `ExceptionHandlerExceptionResolver` detect +controller advice beans and apply them at runtime. Global `@ExceptionHandler` methods, +from an `@ControllerAdvice`, are applied _after_ local ones, from the `@Controller`. +By contrast, global `@ModelAttribute` and `@InitBinder` methods are applied _before_ local ones. + +The `@ControllerAdvice` annotation has attributes that let you narrow the set of controllers +and handlers that they apply to. For example: [source,java,indent=0,subs="verbatim,quotes",role="primary"] .Java From 50f20162934c1d3282615dce6696e3b56141f7ac Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Fri, 24 Sep 2021 16:33:51 -0700 Subject: [PATCH 148/735] Fix timezone specific failing test Update `MvcNamespaceTests` so that the asserted time is in UTC. --- .../springframework/web/servlet/config/MvcNamespaceTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java index 05a9745896ac..60406a002623 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java @@ -246,7 +246,7 @@ public void testDefaultConfig() throws Exception { adapter.handle(request, response, handlerMethod); assertThat(handler.recordedValidationError).isTrue(); - assertThat(handler.date).isInSameDayAs("2009-10-31"); + assertThat(handler.date).isInSameDayAs("2009-10-31T00:00:00+00:00"); assertThat(handler.percent).isEqualTo(Double.valueOf(0.9999)); CompositeUriComponentsContributor uriComponentsContributor = this.appContext.getBean( From 30efa4d478d6673ecfc735bef1ce65decadf4e77 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 25 Sep 2021 15:06:39 +0200 Subject: [PATCH 149/735] Change default driver in XStreamMarshaller from XppDriver to DomDriver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As explained in commit a247b83cd9c9aefd3c329d493c5ce7cd11d0cdfa, the XppDriver from XStream relies on the XPP3 library which publishes javax.xml.namespace.QName as part of its JAR. The QName type is also published by the java.xml system module in modular JREs (i.e., Java 9 or higher). This results in a split package between the unnamed module and the java.xml system module, which the Java Language Specification defines as illegal (see §6.5.5.2 and §7.4.3). Most Java compilers do not currently enforce this rule; however, the Eclipse compiler does. This makes it impossible to use spring-oxm out of the box in the Eclipse IDE. In addition, if bug JDK-8215739 is fixed in future versions of other JDK implementations, this rule will affect any users using spring-oxm with those JDKs. This commit therefore switches the default driver in XStreamMarshaller from XppDriver to DomDriver. Users can naturally switch back to the XppDriver if they wish, since the driver is configurable. Closes gh-27464 --- .../oxm/xstream/XStreamMarshaller.java | 11 ++++++++--- .../oxm/xstream/XStreamMarshallerTests.java | 3 --- .../oxm/xstream/XStreamUnmarshallerTests.java | 3 --- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java index ccb10d27c172..342f9a41edac 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java @@ -52,6 +52,7 @@ import com.thoughtworks.xstream.io.StreamException; import com.thoughtworks.xstream.io.naming.NameCoder; import com.thoughtworks.xstream.io.xml.CompactWriter; +import com.thoughtworks.xstream.io.xml.DomDriver; import com.thoughtworks.xstream.io.xml.DomReader; import com.thoughtworks.xstream.io.xml.DomWriter; import com.thoughtworks.xstream.io.xml.QNameMap; @@ -59,7 +60,6 @@ import com.thoughtworks.xstream.io.xml.StaxReader; import com.thoughtworks.xstream.io.xml.StaxWriter; import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; -import com.thoughtworks.xstream.io.xml.XppDriver; import com.thoughtworks.xstream.mapper.CannotResolveClassException; import com.thoughtworks.xstream.mapper.Mapper; import com.thoughtworks.xstream.mapper.MapperWrapper; @@ -112,6 +112,11 @@ * Note that {@link XStream} construction has been reworked in 4.0, with the * stream driver and the class loader getting passed into XStream itself now. * + *

    As of Spring Framework 6.0, the default {@link HierarchicalStreamDriver} is + * a {@link DomDriver} that uses the configured {@linkplain #setEncoding(String) + * encoding} and {@link #setNameCoder(NameCoder) NameCoder}. The driver can be + * changed via {@link #setStreamDriver(HierarchicalStreamDriver)}. + * * @author Peter Meijer * @author Arjen Poutsma * @author Juergen Hoeller @@ -205,7 +210,7 @@ public void setReflectionProvider(ReflectionProvider reflectionProvider) { } /** - * Set a XStream {@link HierarchicalStreamDriver} to be used for readers and writers. + * Set an XStream {@link HierarchicalStreamDriver} to be used for readers and writers. *

    As of Spring 4.0, this stream driver will also be passed to the {@link XStream} * constructor and therefore used by streaming-related native API methods themselves. */ @@ -216,7 +221,7 @@ public void setStreamDriver(HierarchicalStreamDriver streamDriver) { private HierarchicalStreamDriver getDefaultDriver() { if (this.defaultDriver == null) { - this.defaultDriver = new XppDriver(); + this.defaultDriver = new DomDriver(this.encoding, this.nameCoder); } return this.defaultDriver; } diff --git a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java index ece6236ecd75..b408c6611be3 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java @@ -43,8 +43,6 @@ import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver; import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver; import com.thoughtworks.xstream.io.json.JsonWriter; -import com.thoughtworks.xstream.io.xml.DomDriver; -import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; import com.thoughtworks.xstream.security.AnyTypePermission; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -86,7 +84,6 @@ void createMarshaller() { marshaller = new XStreamMarshaller(); marshaller.setTypePermissions(AnyTypePermission.ANY); marshaller.setAliases(Collections.singletonMap("flight", Flight.class.getName())); - marshaller.setStreamDriver(new DomDriver("UTF-8", new XmlFriendlyNameCoder())); flight.setFlightNumber(42L); } diff --git a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamUnmarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamUnmarshallerTests.java index 9d8d61b7bea6..7c87eda2253b 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamUnmarshallerTests.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamUnmarshallerTests.java @@ -30,8 +30,6 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamSource; -import com.thoughtworks.xstream.io.xml.DomDriver; -import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; import com.thoughtworks.xstream.security.AnyTypePermission; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -57,7 +55,6 @@ public class XStreamUnmarshallerTests { public void createUnmarshaller() { unmarshaller = new XStreamMarshaller(); unmarshaller.setTypePermissions(AnyTypePermission.ANY); - unmarshaller.setStreamDriver(new DomDriver("UTF-8", new XmlFriendlyNameCoder())); Map> aliases = new HashMap<>(); aliases.put("flight", Flight.class); unmarshaller.setAliases(aliases); From e6112344d20b9a744ca44073cc1331a0a9e691b4 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 27 Sep 2021 13:01:32 +0200 Subject: [PATCH 150/735] Remove support for RxJava 2.x as well Includes realignment of Reactor adapter registration. Closes gh-27443 --- build.gradle | 1 - spring-core/spring-core.gradle | 1 - .../core/ReactiveAdapterRegistry.java | 141 ++++++------------ .../core/ReactiveAdapterRegistryTests.java | 124 +++------------ src/docs/asciidoc/web-reactive.adoc | 12 +- 5 files changed, 65 insertions(+), 214 deletions(-) diff --git a/build.gradle b/build.gradle index 48b3bebced7c..7a0565cc6456 100644 --- a/build.gradle +++ b/build.gradle @@ -64,7 +64,6 @@ configure(allprojects) { project -> entry 'groovy-xml' } - dependency "io.reactivex.rxjava2:rxjava:2.2.21" dependency "io.reactivex.rxjava3:rxjava:3.1.1" dependency "io.smallrye.reactive:mutiny:1.0.0" dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE" diff --git a/spring-core/spring-core.gradle b/spring-core/spring-core.gradle index 1999580d0c14..79dd105c9e0b 100644 --- a/spring-core/spring-core.gradle +++ b/spring-core/spring-core.gradle @@ -44,7 +44,6 @@ dependencies { optional("org.jetbrains.kotlinx:kotlinx-coroutines-core") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") optional("io.projectreactor:reactor-core") - optional("io.reactivex.rxjava2:rxjava") optional("io.reactivex.rxjava3:rxjava") optional("io.smallrye.reactive:mutiny") optional("io.netty:netty-buffer") diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java index 1b62cc5655a7..b63831462153 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -58,8 +58,6 @@ public class ReactiveAdapterRegistry { private static final boolean reactorPresent; - private static final boolean rxjava2Present; - private static final boolean rxjava3Present; private static final boolean kotlinCoroutinesPresent; @@ -69,7 +67,6 @@ public class ReactiveAdapterRegistry { static { ClassLoader classLoader = ReactiveAdapterRegistry.class.getClassLoader(); reactorPresent = ClassUtils.isPresent("reactor.core.publisher.Flux", classLoader); - rxjava2Present = ClassUtils.isPresent("io.reactivex.Flowable", classLoader); rxjava3Present = ClassUtils.isPresent("io.reactivex.rxjava3.core.Flowable", classLoader); kotlinCoroutinesPresent = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt", classLoader); mutinyPresent = ClassUtils.isPresent("io.smallrye.mutiny.Multi", classLoader); @@ -86,13 +83,9 @@ public ReactiveAdapterRegistry() { // Reactor if (reactorPresent) { new ReactorRegistrar().registerAdapters(this); - new ReactorJdkFlowAdapterRegistrar().registerAdapter(this); } // RxJava - if (rxjava2Present) { - new RxJava2Registrar().registerAdapters(this); - } if (rxjava3Present) { new RxJava3Registrar().registerAdapters(this); } @@ -200,16 +193,40 @@ public static ReactiveAdapterRegistry getSharedInstance() { } + /** + * ReactiveAdapter variant that wraps adapted Publishers as {@link Flux} or + * {@link Mono} depending on {@link ReactiveTypeDescriptor#isMultiValue()}. + * This is important in places where only the stream and stream element type + * information is available like encoders and decoders. + */ + private static class ReactorAdapter extends ReactiveAdapter { + + ReactorAdapter(ReactiveTypeDescriptor descriptor, + Function> toPublisherFunction, + Function, Object> fromPublisherFunction) { + + super(descriptor, toPublisherFunction, fromPublisherFunction); + } + + @Override + public Publisher toPublisher(@Nullable Object source) { + Publisher publisher = super.toPublisher(source); + return (isMultiValue() ? Flux.from(publisher) : Mono.from(publisher)); + } + } + + private static class ReactorRegistrar { + private static final Flow.Publisher EMPTY_FLOW = JdkFlowAdapter.publisherToFlowPublisher(Flux.empty()); + void registerAdapters(ReactiveAdapterRegistry registry) { // Register Flux and Mono before Publisher... registry.registerReactiveType( ReactiveTypeDescriptor.singleOptionalValue(Mono.class, Mono::empty), source -> (Mono) source, - Mono::from - ); + Mono::from); registry.registerReactiveType( ReactiveTypeDescriptor.multiValue(Flux.class, Flux::empty), @@ -224,54 +241,20 @@ void registerAdapters(ReactiveAdapterRegistry registry) { registry.registerReactiveType( ReactiveTypeDescriptor.nonDeferredAsyncValue(CompletionStage.class, EmptyCompletableFuture::new), source -> Mono.fromCompletionStage((CompletionStage) source), - source -> Mono.from(source).toFuture() - ); - } - } - + source -> Mono.from(source).toFuture()); - private static class ReactorJdkFlowAdapterRegistrar { - - void registerAdapter(ReactiveAdapterRegistry registry) { - Flow.Publisher emptyFlow = JdkFlowAdapter.publisherToFlowPublisher(Flux.empty()); registry.registerReactiveType( - ReactiveTypeDescriptor.multiValue(Flow.Publisher.class, () -> emptyFlow), + ReactiveTypeDescriptor.multiValue(Flow.Publisher.class, () -> EMPTY_FLOW), source -> JdkFlowAdapter.flowPublisherToFlux((Flow.Publisher) source), - JdkFlowAdapter::publisherToFlowPublisher - ); + JdkFlowAdapter::publisherToFlowPublisher); } } - private static class RxJava2Registrar { + private static class EmptyCompletableFuture extends CompletableFuture { - void registerAdapters(ReactiveAdapterRegistry registry) { - registry.registerReactiveType( - ReactiveTypeDescriptor.multiValue(io.reactivex.Flowable.class, io.reactivex.Flowable::empty), - source -> (io.reactivex.Flowable) source, - io.reactivex.Flowable::fromPublisher - ); - registry.registerReactiveType( - ReactiveTypeDescriptor.multiValue(io.reactivex.Observable.class, io.reactivex.Observable::empty), - source -> ((io.reactivex.Observable) source).toFlowable(io.reactivex.BackpressureStrategy.BUFFER), - io.reactivex.Observable::fromPublisher - ); - registry.registerReactiveType( - ReactiveTypeDescriptor.singleRequiredValue(io.reactivex.Single.class), - source -> ((io.reactivex.Single) source).toFlowable(), - io.reactivex.Single::fromPublisher - ); - registry.registerReactiveType( - ReactiveTypeDescriptor.singleOptionalValue(io.reactivex.Maybe.class, io.reactivex.Maybe::empty), - source -> ((io.reactivex.Maybe) source).toFlowable(), - source -> io.reactivex.Flowable.fromPublisher(source) - .toObservable().singleElement() - ); - registry.registerReactiveType( - ReactiveTypeDescriptor.noValue(io.reactivex.Completable.class, io.reactivex.Completable::complete), - source -> ((io.reactivex.Completable) source).toFlowable(), - io.reactivex.Completable::fromPublisher - ); + EmptyCompletableFuture() { + complete(null); } } @@ -284,66 +267,34 @@ void registerAdapters(ReactiveAdapterRegistry registry) { io.reactivex.rxjava3.core.Flowable.class, io.reactivex.rxjava3.core.Flowable::empty), source -> (io.reactivex.rxjava3.core.Flowable) source, - io.reactivex.rxjava3.core.Flowable::fromPublisher - ); + io.reactivex.rxjava3.core.Flowable::fromPublisher); + registry.registerReactiveType( ReactiveTypeDescriptor.multiValue( io.reactivex.rxjava3.core.Observable.class, io.reactivex.rxjava3.core.Observable::empty), source -> ((io.reactivex.rxjava3.core.Observable) source).toFlowable( io.reactivex.rxjava3.core.BackpressureStrategy.BUFFER), - io.reactivex.rxjava3.core.Observable::fromPublisher - ); + io.reactivex.rxjava3.core.Observable::fromPublisher); + registry.registerReactiveType( ReactiveTypeDescriptor.singleRequiredValue(io.reactivex.rxjava3.core.Single.class), source -> ((io.reactivex.rxjava3.core.Single) source).toFlowable(), - io.reactivex.rxjava3.core.Single::fromPublisher - ); + io.reactivex.rxjava3.core.Single::fromPublisher); + registry.registerReactiveType( ReactiveTypeDescriptor.singleOptionalValue( io.reactivex.rxjava3.core.Maybe.class, io.reactivex.rxjava3.core.Maybe::empty), source -> ((io.reactivex.rxjava3.core.Maybe) source).toFlowable(), - io.reactivex.rxjava3.core.Maybe::fromPublisher - ); + io.reactivex.rxjava3.core.Maybe::fromPublisher); + registry.registerReactiveType( ReactiveTypeDescriptor.noValue( io.reactivex.rxjava3.core.Completable.class, io.reactivex.rxjava3.core.Completable::complete), source -> ((io.reactivex.rxjava3.core.Completable) source).toFlowable(), - io.reactivex.rxjava3.core.Completable::fromPublisher - ); - } - } - - - /** - * ReactiveAdapter variant that wraps adapted Publishers as {@link Flux} or - * {@link Mono} depending on {@link ReactiveTypeDescriptor#isMultiValue()}. - * This is important in places where only the stream and stream element type - * information is available like encoders and decoders. - */ - private static class ReactorAdapter extends ReactiveAdapter { - - ReactorAdapter(ReactiveTypeDescriptor descriptor, - Function> toPublisherFunction, - Function, Object> fromPublisherFunction) { - - super(descriptor, toPublisherFunction, fromPublisherFunction); - } - - @Override - public Publisher toPublisher(@Nullable Object source) { - Publisher publisher = super.toPublisher(source); - return (isMultiValue() ? Flux.from(publisher) : Mono.from(publisher)); - } - } - - - private static class EmptyCompletableFuture extends CompletableFuture { - - EmptyCompletableFuture() { - complete(null); + io.reactivex.rxjava3.core.Completable::fromPublisher); } } @@ -361,8 +312,7 @@ void registerAdapters(ReactiveAdapterRegistry registry) { registry.registerReactiveType( ReactiveTypeDescriptor.multiValue(kotlinx.coroutines.flow.Flow.class, kotlinx.coroutines.flow.FlowKt::emptyFlow), source -> kotlinx.coroutines.reactor.ReactorFlowKt.asFlux((kotlinx.coroutines.flow.Flow) source), - kotlinx.coroutines.reactive.ReactiveFlowKt::asFlow - ); + kotlinx.coroutines.reactive.ReactiveFlowKt::asFlow); } } @@ -375,16 +325,14 @@ void registerAdapters(ReactiveAdapterRegistry registry) { io.smallrye.mutiny.Uni.class, () -> io.smallrye.mutiny.Uni.createFrom().nothing()), uni -> ((io.smallrye.mutiny.Uni) uni).convert().toPublisher(), - publisher -> io.smallrye.mutiny.Uni.createFrom().publisher(publisher) - ); + publisher -> io.smallrye.mutiny.Uni.createFrom().publisher(publisher)); registry.registerReactiveType( ReactiveTypeDescriptor.multiValue( io.smallrye.mutiny.Multi.class, () -> io.smallrye.mutiny.Multi.createFrom().empty()), multi -> (io.smallrye.mutiny.Multi) multi, - publisher -> io.smallrye.mutiny.Multi.createFrom().publisher(publisher) - ); + publisher -> io.smallrye.mutiny.Multi.createFrom().publisher(publisher)); } } @@ -402,7 +350,6 @@ public static class SpringCoreBlockHoundIntegration implements BlockHoundIntegra @Override public void applyTo(BlockHound.Builder builder) { - // Avoid hard references potentially anywhere in spring-core (no need for structural dependency) builder.allowBlockingCallsInside( diff --git a/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java b/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java index ea73cfbd7be0..8dff68cfe0a3 100644 --- a/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java +++ b/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java @@ -43,16 +43,13 @@ class ReactiveAdapterRegistryTests { private static final Duration ONE_SECOND = Duration.ofSeconds(1); - private final ReactiveAdapterRegistry registry = ReactiveAdapterRegistry.getSharedInstance(); @Test void getAdapterForReactiveSubType() { - ReactiveAdapter adapter1 = getAdapter(Flux.class); ReactiveAdapter adapter2 = getAdapter(ExtendedFlux.class); - assertThat(adapter2).isSameAs(adapter1); this.registry.registerReactiveType( @@ -61,17 +58,32 @@ void getAdapterForReactiveSubType() { ExtendedFlux::from); ReactiveAdapter adapter3 = getAdapter(ExtendedFlux.class); - assertThat(adapter3).isNotNull(); assertThat(adapter3).isNotSameAs(adapter1); } + + private ReactiveAdapter getAdapter(Class reactiveType) { + ReactiveAdapter adapter = this.registry.getAdapter(reactiveType); + assertThat(adapter).isNotNull(); + return adapter; + } + + + private static class ExtendedFlux extends Flux { + + @Override + public void subscribe(CoreSubscriber actual) { + throw new UnsupportedOperationException(); + } + } + + @Nested class Reactor { @Test void defaultAdapterRegistrations() { - // Reactor assertThat(getAdapter(Mono.class)).isNotNull(); assertThat(getAdapter(Flux.class)).isNotNull(); @@ -118,95 +130,12 @@ void fromCompletableFuture() { } } - @Nested - class RxJava2 { - - @Test - void defaultAdapterRegistrations() { - - // RxJava 2 - assertThat(getAdapter(io.reactivex.Flowable.class)).isNotNull(); - assertThat(getAdapter(io.reactivex.Observable.class)).isNotNull(); - assertThat(getAdapter(io.reactivex.Single.class)).isNotNull(); - assertThat(getAdapter(io.reactivex.Maybe.class)).isNotNull(); - assertThat(getAdapter(io.reactivex.Completable.class)).isNotNull(); - } - - @Test - void toFlowable() { - List sequence = Arrays.asList(1, 2, 3); - Publisher source = Flux.fromIterable(sequence); - Object target = getAdapter(io.reactivex.Flowable.class).fromPublisher(source); - assertThat(target instanceof io.reactivex.Flowable).isTrue(); - assertThat(((io.reactivex.Flowable) target).toList().blockingGet()).isEqualTo(sequence); - } - - @Test - void toObservable() { - List sequence = Arrays.asList(1, 2, 3); - Publisher source = Flux.fromIterable(sequence); - Object target = getAdapter(io.reactivex.Observable.class).fromPublisher(source); - assertThat(target instanceof io.reactivex.Observable).isTrue(); - assertThat(((io.reactivex.Observable) target).toList().blockingGet()).isEqualTo(sequence); - } - - @Test - void toSingle() { - Publisher source = Flux.fromArray(new Integer[] {1}); - Object target = getAdapter(io.reactivex.Single.class).fromPublisher(source); - assertThat(target instanceof io.reactivex.Single).isTrue(); - assertThat(((io.reactivex.Single) target).blockingGet()).isEqualTo(Integer.valueOf(1)); - } - - @Test - void toCompletable() { - Publisher source = Flux.fromArray(new Integer[] {1, 2, 3}); - Object target = getAdapter(io.reactivex.Completable.class).fromPublisher(source); - assertThat(target instanceof io.reactivex.Completable).isTrue(); - ((io.reactivex.Completable) target).blockingAwait(); - } - - @Test - void fromFlowable() { - List sequence = Arrays.asList(1, 2, 3); - Object source = io.reactivex.Flowable.fromIterable(sequence); - Object target = getAdapter(io.reactivex.Flowable.class).toPublisher(source); - assertThat(target instanceof Flux).as("Expected Flux Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Flux) target).collectList().block(ONE_SECOND)).isEqualTo(sequence); - } - - @Test - void fromObservable() { - List sequence = Arrays.asList(1, 2, 3); - Object source = io.reactivex.Observable.fromIterable(sequence); - Object target = getAdapter(io.reactivex.Observable.class).toPublisher(source); - assertThat(target instanceof Flux).as("Expected Flux Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Flux) target).collectList().block(ONE_SECOND)).isEqualTo(sequence); - } - - @Test - void fromSingle() { - Object source = io.reactivex.Single.just(1); - Object target = getAdapter(io.reactivex.Single.class).toPublisher(source); - assertThat(target instanceof Mono).as("Expected Mono Publisher: " + target.getClass().getName()).isTrue(); - assertThat(((Mono) target).block(ONE_SECOND)).isEqualTo(Integer.valueOf(1)); - } - - @Test - void fromCompletable() { - Object source = io.reactivex.Completable.complete(); - Object target = getAdapter(io.reactivex.Completable.class).toPublisher(source); - assertThat(target instanceof Mono).as("Expected Mono Publisher: " + target.getClass().getName()).isTrue(); - ((Mono) target).block(ONE_SECOND); - } - } @Nested class RxJava3 { @Test void defaultAdapterRegistrations() { - // RxJava 3 assertThat(getAdapter(io.reactivex.rxjava3.core.Flowable.class)).isNotNull(); assertThat(getAdapter(io.reactivex.rxjava3.core.Observable.class)).isNotNull(); @@ -284,12 +213,12 @@ void fromCompletable() { } } + @Nested class Kotlin { @Test void defaultAdapterRegistrations() { - // Coroutines assertThat(getAdapter(Deferred.class)).isNotNull(); } @@ -302,6 +231,7 @@ void deferred() { } } + @Nested class Mutiny { @@ -344,22 +274,6 @@ void fromMulti() { assertThat(target).isInstanceOf(Flux.class); assertThat(((Flux) target).blockLast(ONE_SECOND)).isEqualTo(Integer.valueOf(3)); } - - } - - private ReactiveAdapter getAdapter(Class reactiveType) { - ReactiveAdapter adapter = this.registry.getAdapter(reactiveType); - assertThat(adapter).isNotNull(); - return adapter; - } - - - private static class ExtendedFlux extends Flux { - - @Override - public void subscribe(CoreSubscriber actual) { - throw new UnsupportedOperationException(); - } } } diff --git a/src/docs/asciidoc/web-reactive.adoc b/src/docs/asciidoc/web-reactive.adoc index 5609f0ba5361..c6bf754011f1 100644 --- a/src/docs/asciidoc/web-reactive.adoc +++ b/src/docs/asciidoc/web-reactive.adoc @@ -34,8 +34,6 @@ discussion of mock objects. response objects to provide support for testing WebFlux applications without an HTTP server. You can use the `WebTestClient` for end-to-end integration tests, too. - - include::rsocket.adoc[leveloffset=+1] @@ -55,14 +53,8 @@ For annotated controllers, WebFlux transparently adapts to the reactive library the application. This is done with the help of the {api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which provides pluggable support for reactive library and other asynchronous types. The registry -has built-in support for RxJava 2/3, RxJava 1 (via RxJava Reactive Streams bridge), and -`CompletableFuture`, but you can register others, too. - -[NOTE] -==== -As of Spring Framework 5.3, support for RxJava 1 is deprecated. -==== - +has built-in support for RxJava 3, Kotlin coroutines and SmallRye Mutiny, but you can +register others, too. For functional APIs (such as <>, the `WebClient`, and others), the general rules for WebFlux APIs apply -- `Flux` and `Mono` as return values and a Reactive Streams From 9ff0d717f2b0c56ff78701d62c88c1cc82cdce1a Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 27 Sep 2021 16:52:11 +0200 Subject: [PATCH 151/735] Restore lenient fallback in case of several non-public constructors See gh-27437 --- .../java/org/springframework/beans/BeanUtils.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index f7708247d786..9483d18871f5 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -254,14 +254,13 @@ else if (ctors.length == 0){ return (Constructor) ctors[0]; } } - else { - // Several public constructors -> let's take the default constructor - try { - return clazz.getDeclaredConstructor(); - } - catch (NoSuchMethodException ex) { - // Giving up... - } + + // Several constructors -> let's try to take the default constructor + try { + return clazz.getDeclaredConstructor(); + } + catch (NoSuchMethodException ex) { + // Giving up... } // No unique constructor at all From b0c424b37645c79447216e28b85a3da496bb11b5 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 27 Sep 2021 16:56:28 +0200 Subject: [PATCH 152/735] Deprecate RxJava 2 in favor of RxJava 3 Closes gh-27474 --- .../core/ReactiveAdapterRegistry.java | 143 ++++++++---------- .../core/ReactiveAdapterRegistryTests.java | 49 +++--- src/docs/asciidoc/web-reactive.adoc | 22 ++- 3 files changed, 99 insertions(+), 115 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java index cbed55a289c4..0193dff6c256 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -44,12 +44,11 @@ * {@code Observable}, and others. * *

    By default, depending on classpath availability, adapters are registered - * for Reactor, RxJava 2/3, or RxJava 1 (+ RxJava Reactive Streams bridge), - * {@link CompletableFuture}, Java 9+ {@code Flow.Publisher}, and Kotlin - * Coroutines' {@code Deferred} and {@code Flow}. + * for Reactor, RxJava 3, {@link CompletableFuture}, {@code Flow.Publisher}, + * and Kotlin Coroutines' {@code Deferred} and {@code Flow}. * - *

    Note: As of Spring Framework 5.3, support for RxJava 1.x - * is deprecated in favor of RxJava 2 and 3. + *

    Note: As of Spring Framework 5.3.11, support for + * RxJava 1.x and 2.x is deprecated in favor of RxJava 3. * * @author Rossen Stoyanchev * @author Sebastien Deleuze @@ -103,15 +102,13 @@ public ReactiveAdapterRegistry() { } } - // RxJava1 (deprecated) + // RxJava if (rxjava1Present) { new RxJava1Registrar().registerAdapters(this); } - // RxJava2 if (rxjava2Present) { new RxJava2Registrar().registerAdapters(this); } - // RxJava3 if (rxjava3Present) { new RxJava3Registrar().registerAdapters(this); } @@ -219,6 +216,29 @@ public static ReactiveAdapterRegistry getSharedInstance() { } + /** + * ReactiveAdapter variant that wraps adapted Publishers as {@link Flux} or + * {@link Mono} depending on {@link ReactiveTypeDescriptor#isMultiValue()}. + * This is important in places where only the stream and stream element type + * information is available like encoders and decoders. + */ + private static class ReactorAdapter extends ReactiveAdapter { + + ReactorAdapter(ReactiveTypeDescriptor descriptor, + Function> toPublisherFunction, + Function, Object> fromPublisherFunction) { + + super(descriptor, toPublisherFunction, fromPublisherFunction); + } + + @Override + public Publisher toPublisher(@Nullable Object source) { + Publisher publisher = super.toPublisher(source); + return (isMultiValue() ? Flux.from(publisher) : Mono.from(publisher)); + } + } + + private static class ReactorRegistrar { void registerAdapters(ReactiveAdapterRegistry registry) { @@ -227,8 +247,7 @@ void registerAdapters(ReactiveAdapterRegistry registry) { registry.registerReactiveType( ReactiveTypeDescriptor.singleOptionalValue(Mono.class, Mono::empty), source -> (Mono) source, - Mono::from - ); + Mono::from); registry.registerReactiveType( ReactiveTypeDescriptor.multiValue(Flux.class, Flux::empty), @@ -243,8 +262,15 @@ void registerAdapters(ReactiveAdapterRegistry registry) { registry.registerReactiveType( ReactiveTypeDescriptor.nonDeferredAsyncValue(CompletionStage.class, EmptyCompletableFuture::new), source -> Mono.fromCompletionStage((CompletionStage) source), - source -> Mono.from(source).toFuture() - ); + source -> Mono.from(source).toFuture()); + } + } + + + private static class EmptyCompletableFuture extends CompletableFuture { + + EmptyCompletableFuture() { + complete(null); } } @@ -268,8 +294,7 @@ void registerAdapter(ReactiveAdapterRegistry registry) { registry.registerReactiveType( ReactiveTypeDescriptor.multiValue(publisherClass, () -> emptyFlow), source -> (Publisher) ReflectionUtils.invokeMethod(toFluxMethod, null, source), - publisher -> ReflectionUtils.invokeMethod(toFlowMethod, null, publisher) - ); + publisher -> ReflectionUtils.invokeMethod(toFlowMethod, null, publisher)); } catch (Throwable ex) { // Ignore @@ -284,18 +309,17 @@ void registerAdapters(ReactiveAdapterRegistry registry) { registry.registerReactiveType( ReactiveTypeDescriptor.multiValue(rx.Observable.class, rx.Observable::empty), source -> RxReactiveStreams.toPublisher((rx.Observable) source), - RxReactiveStreams::toObservable - ); + RxReactiveStreams::toObservable); + registry.registerReactiveType( ReactiveTypeDescriptor.singleRequiredValue(rx.Single.class), source -> RxReactiveStreams.toPublisher((rx.Single) source), - RxReactiveStreams::toSingle - ); + RxReactiveStreams::toSingle); + registry.registerReactiveType( ReactiveTypeDescriptor.noValue(rx.Completable.class, rx.Completable::complete), source -> RxReactiveStreams.toPublisher((rx.Completable) source), - RxReactiveStreams::toCompletable - ); + RxReactiveStreams::toCompletable); } } @@ -306,29 +330,28 @@ void registerAdapters(ReactiveAdapterRegistry registry) { registry.registerReactiveType( ReactiveTypeDescriptor.multiValue(io.reactivex.Flowable.class, io.reactivex.Flowable::empty), source -> (io.reactivex.Flowable) source, - io.reactivex.Flowable::fromPublisher - ); + io.reactivex.Flowable::fromPublisher); + registry.registerReactiveType( ReactiveTypeDescriptor.multiValue(io.reactivex.Observable.class, io.reactivex.Observable::empty), source -> ((io.reactivex.Observable) source).toFlowable(io.reactivex.BackpressureStrategy.BUFFER), - io.reactivex.Observable::fromPublisher - ); + io.reactivex.Observable::fromPublisher); + registry.registerReactiveType( ReactiveTypeDescriptor.singleRequiredValue(io.reactivex.Single.class), source -> ((io.reactivex.Single) source).toFlowable(), - io.reactivex.Single::fromPublisher - ); + io.reactivex.Single::fromPublisher); + registry.registerReactiveType( ReactiveTypeDescriptor.singleOptionalValue(io.reactivex.Maybe.class, io.reactivex.Maybe::empty), source -> ((io.reactivex.Maybe) source).toFlowable(), source -> io.reactivex.Flowable.fromPublisher(source) - .toObservable().singleElement() - ); + .toObservable().singleElement()); + registry.registerReactiveType( ReactiveTypeDescriptor.noValue(io.reactivex.Completable.class, io.reactivex.Completable::complete), source -> ((io.reactivex.Completable) source).toFlowable(), - io.reactivex.Completable::fromPublisher - ); + io.reactivex.Completable::fromPublisher); } } @@ -341,66 +364,34 @@ void registerAdapters(ReactiveAdapterRegistry registry) { io.reactivex.rxjava3.core.Flowable.class, io.reactivex.rxjava3.core.Flowable::empty), source -> (io.reactivex.rxjava3.core.Flowable) source, - io.reactivex.rxjava3.core.Flowable::fromPublisher - ); + io.reactivex.rxjava3.core.Flowable::fromPublisher); + registry.registerReactiveType( ReactiveTypeDescriptor.multiValue( io.reactivex.rxjava3.core.Observable.class, io.reactivex.rxjava3.core.Observable::empty), source -> ((io.reactivex.rxjava3.core.Observable) source).toFlowable( io.reactivex.rxjava3.core.BackpressureStrategy.BUFFER), - io.reactivex.rxjava3.core.Observable::fromPublisher - ); + io.reactivex.rxjava3.core.Observable::fromPublisher); + registry.registerReactiveType( ReactiveTypeDescriptor.singleRequiredValue(io.reactivex.rxjava3.core.Single.class), source -> ((io.reactivex.rxjava3.core.Single) source).toFlowable(), - io.reactivex.rxjava3.core.Single::fromPublisher - ); + io.reactivex.rxjava3.core.Single::fromPublisher); + registry.registerReactiveType( ReactiveTypeDescriptor.singleOptionalValue( io.reactivex.rxjava3.core.Maybe.class, io.reactivex.rxjava3.core.Maybe::empty), source -> ((io.reactivex.rxjava3.core.Maybe) source).toFlowable(), - io.reactivex.rxjava3.core.Maybe::fromPublisher - ); + io.reactivex.rxjava3.core.Maybe::fromPublisher); + registry.registerReactiveType( ReactiveTypeDescriptor.noValue( io.reactivex.rxjava3.core.Completable.class, io.reactivex.rxjava3.core.Completable::complete), source -> ((io.reactivex.rxjava3.core.Completable) source).toFlowable(), - io.reactivex.rxjava3.core.Completable::fromPublisher - ); - } - } - - - /** - * ReactiveAdapter variant that wraps adapted Publishers as {@link Flux} or - * {@link Mono} depending on {@link ReactiveTypeDescriptor#isMultiValue()}. - * This is important in places where only the stream and stream element type - * information is available like encoders and decoders. - */ - private static class ReactorAdapter extends ReactiveAdapter { - - ReactorAdapter(ReactiveTypeDescriptor descriptor, - Function> toPublisherFunction, - Function, Object> fromPublisherFunction) { - - super(descriptor, toPublisherFunction, fromPublisherFunction); - } - - @Override - public Publisher toPublisher(@Nullable Object source) { - Publisher publisher = super.toPublisher(source); - return (isMultiValue() ? Flux.from(publisher) : Mono.from(publisher)); - } - } - - - private static class EmptyCompletableFuture extends CompletableFuture { - - EmptyCompletableFuture() { - complete(null); + io.reactivex.rxjava3.core.Completable::fromPublisher); } } @@ -418,8 +409,7 @@ void registerAdapters(ReactiveAdapterRegistry registry) { registry.registerReactiveType( ReactiveTypeDescriptor.multiValue(kotlinx.coroutines.flow.Flow.class, kotlinx.coroutines.flow.FlowKt::emptyFlow), source -> kotlinx.coroutines.reactor.ReactorFlowKt.asFlux((kotlinx.coroutines.flow.Flow) source), - kotlinx.coroutines.reactive.ReactiveFlowKt::asFlow - ); + kotlinx.coroutines.reactive.ReactiveFlowKt::asFlow); } } @@ -432,16 +422,14 @@ void registerAdapters(ReactiveAdapterRegistry registry) { io.smallrye.mutiny.Uni.class, () -> io.smallrye.mutiny.Uni.createFrom().nothing()), uni -> ((io.smallrye.mutiny.Uni) uni).convert().toPublisher(), - publisher -> io.smallrye.mutiny.Uni.createFrom().publisher(publisher) - ); + publisher -> io.smallrye.mutiny.Uni.createFrom().publisher(publisher)); registry.registerReactiveType( ReactiveTypeDescriptor.multiValue( io.smallrye.mutiny.Multi.class, () -> io.smallrye.mutiny.Multi.createFrom().empty()), multi -> (io.smallrye.mutiny.Multi) multi, - publisher -> io.smallrye.mutiny.Multi.createFrom().publisher(publisher) - ); + publisher -> io.smallrye.mutiny.Multi.createFrom().publisher(publisher)); } } @@ -459,7 +447,6 @@ public static class SpringCoreBlockHoundIntegration implements BlockHoundIntegra @Override public void applyTo(BlockHound.Builder builder) { - // Avoid hard references potentially anywhere in spring-core (no need for structural dependency) builder.allowBlockingCallsInside( diff --git a/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java b/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java index 579e1a463afc..25269a4c40fa 100644 --- a/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java +++ b/spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ /** * Unit tests for {@link ReactiveAdapterRegistry}. + * * @author Rossen Stoyanchev */ @SuppressWarnings("unchecked") @@ -42,16 +43,13 @@ class ReactiveAdapterRegistryTests { private static final Duration ONE_SECOND = Duration.ofSeconds(1); - private final ReactiveAdapterRegistry registry = ReactiveAdapterRegistry.getSharedInstance(); @Test void getAdapterForReactiveSubType() { - ReactiveAdapter adapter1 = getAdapter(Flux.class); ReactiveAdapter adapter2 = getAdapter(ExtendedFlux.class); - assertThat(adapter2).isSameAs(adapter1); this.registry.registerReactiveType( @@ -60,17 +58,32 @@ void getAdapterForReactiveSubType() { ExtendedFlux::from); ReactiveAdapter adapter3 = getAdapter(ExtendedFlux.class); - assertThat(adapter3).isNotNull(); assertThat(adapter3).isNotSameAs(adapter1); } + + private ReactiveAdapter getAdapter(Class reactiveType) { + ReactiveAdapter adapter = this.registry.getAdapter(reactiveType); + assertThat(adapter).isNotNull(); + return adapter; + } + + + private static class ExtendedFlux extends Flux { + + @Override + public void subscribe(CoreSubscriber actual) { + throw new UnsupportedOperationException(); + } + } + + @Nested class Reactor { @Test void defaultAdapterRegistrations() { - // Reactor assertThat(getAdapter(Mono.class)).isNotNull(); assertThat(getAdapter(Flux.class)).isNotNull(); @@ -117,6 +130,7 @@ void fromCompletableFuture() { } } + @Nested class RxJava1 { @@ -178,12 +192,12 @@ void fromCompletable() { } } + @Nested class RxJava2 { @Test void defaultAdapterRegistrations() { - // RxJava 2 assertThat(getAdapter(io.reactivex.Flowable.class)).isNotNull(); assertThat(getAdapter(io.reactivex.Observable.class)).isNotNull(); @@ -261,12 +275,12 @@ void fromCompletable() { } } + @Nested class RxJava3 { @Test void defaultAdapterRegistrations() { - // RxJava 3 assertThat(getAdapter(io.reactivex.rxjava3.core.Flowable.class)).isNotNull(); assertThat(getAdapter(io.reactivex.rxjava3.core.Observable.class)).isNotNull(); @@ -344,12 +358,12 @@ void fromCompletable() { } } + @Nested class Kotlin { @Test void defaultAdapterRegistrations() { - // Coroutines assertThat(getAdapter(Deferred.class)).isNotNull(); } @@ -362,6 +376,7 @@ void deferred() { } } + @Nested class Mutiny { @@ -404,22 +419,6 @@ void fromMulti() { assertThat(target).isInstanceOf(Flux.class); assertThat(((Flux) target).blockLast(ONE_SECOND)).isEqualTo(Integer.valueOf(3)); } - - } - - private ReactiveAdapter getAdapter(Class reactiveType) { - ReactiveAdapter adapter = this.registry.getAdapter(reactiveType); - assertThat(adapter).isNotNull(); - return adapter; - } - - - private static class ExtendedFlux extends Flux { - - @Override - public void subscribe(CoreSubscriber actual) { - throw new UnsupportedOperationException(); - } } } diff --git a/src/docs/asciidoc/web-reactive.adoc b/src/docs/asciidoc/web-reactive.adoc index 5609f0ba5361..00d358f97d36 100644 --- a/src/docs/asciidoc/web-reactive.adoc +++ b/src/docs/asciidoc/web-reactive.adoc @@ -34,8 +34,6 @@ discussion of mock objects. response objects to provide support for testing WebFlux applications without an HTTP server. You can use the `WebTestClient` for end-to-end integration tests, too. - - include::rsocket.adoc[leveloffset=+1] @@ -51,21 +49,21 @@ it helps to express cardinality -- for example, whether a single or multiple asy values are expected, and that can be essential for making decisions (for example, when encoding or decoding HTTP messages). -For annotated controllers, WebFlux transparently adapts to the reactive library chosen by -the application. This is done with the help of the -{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which -provides pluggable support for reactive library and other asynchronous types. The registry -has built-in support for RxJava 2/3, RxJava 1 (via RxJava Reactive Streams bridge), and -`CompletableFuture`, but you can register others, too. +For annotated controllers, WebFlux transparently adapts to the reactive library chosen +by the application. This is done with the help of the +{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] +which provides pluggable support for reactive library and other asynchronous types. +The registry has built-in support for RxJava 3, Kotlin coroutines and SmallRye Mutiny, +but you can register other third-party adapters as well. [NOTE] ==== -As of Spring Framework 5.3, support for RxJava 1 is deprecated. +As of Spring Framework 5.3.11, support for RxJava 1 and 2 is deprecated, following +RxJava's own EOL advice and the upgrade recommendation towards RxJava 3. ==== - -For functional APIs (such as <>, the `WebClient`, and others), the general rules -for WebFlux APIs apply -- `Flux` and `Mono` as return values and a Reactive Streams +For functional APIs (such as <>, the `WebClient`, and others), the general +rules for WebFlux APIs apply -- `Flux` and `Mono` as return values and a Reactive Streams `Publisher` as input. When a `Publisher`, whether custom or from another reactive library, is provided, it can be treated only as a stream with unknown semantics (0..N). If, however, the semantics are known, you can wrap it with `Flux` or `Mono.from(Publisher)` instead From 211f0bbf885a3d291f45c4a10db6cc5c0243b14f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 27 Sep 2021 16:57:54 +0200 Subject: [PATCH 153/735] Fix invalid characters in source files Closes gh-27475 --- .../beans/factory/support/AbstractBeanFactory.java | 4 ++-- .../java/org/springframework/expression/BeanResolver.java | 6 +++--- .../org/springframework/expression/TypeComparator.java | 7 ++++--- .../springframework/expression/spel/ast/BeanReference.java | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index 562c00fd55f1..e36cef415730 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -361,7 +361,7 @@ else if (mbd.isPrototype()) { else { String scopeName = mbd.getScope(); if (!StringUtils.hasLength(scopeName)) { - throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'"); + throw new IllegalStateException("No scope name defined for bean '" + beanName + "'"); } Scope scope = this.scopes.get(scopeName); if (scope == null) { diff --git a/spring-expression/src/main/java/org/springframework/expression/BeanResolver.java b/spring-expression/src/main/java/org/springframework/expression/BeanResolver.java index eabeb9f495b5..7530c36f6ee3 100644 --- a/spring-expression/src/main/java/org/springframework/expression/BeanResolver.java +++ b/spring-expression/src/main/java/org/springframework/expression/BeanResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ /** * A bean resolver can be registered with the evaluation context and will kick in * for bean references: {@code @myBeanName} and {@code &myBeanName} expressions. - * The & variant syntax allows access to the factory bean where relevant. + * The {@code &} variant syntax allows access to the factory bean where relevant. * * @author Andy Clement * @since 3.0.3 @@ -28,7 +28,7 @@ public interface BeanResolver { /** * Look up a bean by the given name and return a corresponding instance for it. - * For attempting access to a factory bean, the name needs a & prefix. + * For attempting access to a factory bean, the name needs a {@code &} prefix. * @param context the current evaluation context * @param beanName the name of the bean to look up * @return an object representing the bean diff --git a/spring-expression/src/main/java/org/springframework/expression/TypeComparator.java b/spring-expression/src/main/java/org/springframework/expression/TypeComparator.java index 7696cd7f6dcb..88d07d39fb8e 100644 --- a/spring-expression/src/main/java/org/springframework/expression/TypeComparator.java +++ b/spring-expression/src/main/java/org/springframework/expression/TypeComparator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,10 +40,11 @@ public interface TypeComparator { * Compare two given objects. * @param firstObject the first object * @param secondObject the second object - * @return 0 if they are equal, <0 if the first is smaller than the second, - * or >0 if the first is larger than the second + * @return 0 if they are equal, a negative integer if the first is smaller than + * the second, or a positive integer if the first is larger than the second * @throws EvaluationException if a problem occurs during comparison * (or if they are not comparable in the first place) + * @see Comparable#compareTo */ int compare(@Nullable Object firstObject, @Nullable Object secondObject) throws EvaluationException; diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/BeanReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/BeanReference.java index 6e128dae6119..5f1d2adeb315 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/BeanReference.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/BeanReference.java @@ -25,8 +25,8 @@ import org.springframework.expression.spel.SpelMessage; /** - * Represents a bean reference to a type, for example @foo or @'foo.bar'. - * For a FactoryBean the syntax &foo can be used to access the factory itself. + * Represents a bean reference to a type, for example {@code @foo} or {@code @'foo.bar'}. + * For a FactoryBean the syntax {@code &foo} can be used to access the factory itself. * * @author Andy Clement */ From d8e18f56e1e0e9395bcac437cb39c0454dcf56da Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 27 Sep 2021 17:01:18 +0200 Subject: [PATCH 154/735] Upgrade to Protobuf 3.18, Rome 1.16, BlockHound 1.0.6, Caffeine 2.9.2, Groovy 3.0.9, Tomcat 9.0.53 --- build.gradle | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 81193a9f2f1d..7ce2cb25d185 100644 --- a/build.gradle +++ b/build.gradle @@ -56,7 +56,7 @@ configure(allprojects) { project -> entry 'aspectjtools' entry 'aspectjweaver' } - dependencySet(group: 'org.codehaus.groovy', version: '3.0.8') { + dependencySet(group: 'org.codehaus.groovy', version: '3.0.9') { entry 'groovy' entry 'groovy-jsr223' entry 'groovy-templates' // requires findbugs for warning-free compilation @@ -69,7 +69,7 @@ configure(allprojects) { project -> dependency "io.reactivex.rxjava2:rxjava:2.2.21" dependency "io.reactivex.rxjava3:rxjava:3.1.1" dependency "io.smallrye.reactive:mutiny:1.0.0" - dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE" + dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE" dependency "com.caucho:hessian:4.0.63" dependency "com.fasterxml:aalto-xml:1.3.0" @@ -77,7 +77,7 @@ configure(allprojects) { project -> exclude group: "stax", name: "stax-api" } dependency "com.google.code.gson:gson:2.8.8" - dependency "com.google.protobuf:protobuf-java-util:3.17.3" + dependency "com.google.protobuf:protobuf-java-util:3.18.0" dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4" dependency("com.thoughtworks.xstream:xstream:1.4.18") { exclude group: "xpp3", name: "xpp3_min" @@ -95,9 +95,9 @@ configure(allprojects) { project -> dependency "org.yaml:snakeyaml:1.29" dependency "com.h2database:h2:1.4.200" - dependency "com.github.ben-manes.caffeine:caffeine:2.9.1" + dependency "com.github.ben-manes.caffeine:caffeine:2.9.2" dependency "com.github.librepdf:openpdf:1.3.26" - dependency "com.rometools:rome:1.15.0" + dependency "com.rometools:rome:1.16.0" dependency "commons-io:commons-io:2.5" dependency "io.vavr:vavr:0.10.3" dependency "net.sf.jopt-simple:jopt-simple:5.0.4" @@ -128,14 +128,14 @@ configure(allprojects) { project -> dependency "org.webjars:webjars-locator-core:0.47" dependency "org.webjars:underscorejs:1.8.3" - dependencySet(group: 'org.apache.tomcat', version: '9.0.52') { + dependencySet(group: 'org.apache.tomcat', version: '9.0.53') { entry 'tomcat-util' entry('tomcat-websocket') { exclude group: "org.apache.tomcat", name: "tomcat-websocket-api" exclude group: "org.apache.tomcat", name: "tomcat-servlet-api" } } - dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.52') { + dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.53') { entry 'tomcat-embed-core' entry 'tomcat-embed-websocket' } From 119c78b1c98364b244aaa9e082660b8d559a6c52 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 27 Sep 2021 17:11:12 +0200 Subject: [PATCH 155/735] Skip flaky StopWatch time assertions --- .../src/test/java/org/springframework/util/StopWatchTests.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spring-core/src/test/java/org/springframework/util/StopWatchTests.java b/spring-core/src/test/java/org/springframework/util/StopWatchTests.java index 792c2f546aab..83eb5adbec63 100644 --- a/spring-core/src/test/java/org/springframework/util/StopWatchTests.java +++ b/spring-core/src/test/java/org/springframework/util/StopWatchTests.java @@ -97,6 +97,8 @@ void validUsage() throws Exception { assertThat(stopWatch.currentTaskName()).isEqualTo(name2); stopWatch.stop(); assertThat(stopWatch.isRunning()).isFalse(); + + /* Flaky StopWatch time assertions... assertThat(stopWatch.getLastTaskTimeNanos()) .as("last task time in nanoseconds for task #2") .isGreaterThanOrEqualTo(millisToNanos(duration2)) @@ -109,6 +111,7 @@ void validUsage() throws Exception { .as("total time in seconds for task #2") .isGreaterThanOrEqualTo((duration1 + duration2 - fudgeFactor) / 1000.0) .isLessThanOrEqualTo((duration1 + duration2 + fudgeFactor) / 1000.0); + */ assertThat(stopWatch.getTaskCount()).isEqualTo(2); assertThat(stopWatch.prettyPrint()).contains(name1, name2); From d4839921776c92de5b78d455ed78d8f86298f2b3 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 27 Sep 2021 18:30:09 +0200 Subject: [PATCH 156/735] Upgrade to Caffeine 3.0.4 and Vavr 0.10.4 Includes removal of unused Hessian dependency. --- build.gradle | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index a98d4bff62d7..14fc6abb2138 100644 --- a/build.gradle +++ b/build.gradle @@ -68,7 +68,6 @@ configure(allprojects) { project -> dependency "io.smallrye.reactive:mutiny:1.0.0" dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE" - dependency "com.caucho:hessian:4.0.63" dependency "com.fasterxml:aalto-xml:1.3.0" dependency("com.fasterxml.woodstox:woodstox-core:6.2.6") { exclude group: "stax", name: "stax-api" @@ -88,11 +87,11 @@ configure(allprojects) { project -> dependency "org.yaml:snakeyaml:1.29" dependency "com.h2database:h2:1.4.200" - dependency "com.github.ben-manes.caffeine:caffeine:2.9.2" + dependency "com.github.ben-manes.caffeine:caffeine:3.0.4" dependency "com.github.librepdf:openpdf:1.3.26" dependency "com.rometools:rome:1.16.0" dependency "commons-io:commons-io:2.5" - dependency "io.vavr:vavr:0.10.3" + dependency "io.vavr:vavr:0.10.4" dependency "net.sf.jopt-simple:jopt-simple:5.0.4" dependencySet(group: 'org.apache.activemq', version: '5.16.2') { entry 'activemq-broker' From 2567b2094962e7f779a6e85ca1af2a727a521107 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 28 Sep 2021 10:28:19 +0200 Subject: [PATCH 157/735] Upgrade to spring-javaformat 0.0.28 and downgrade to Checkstyle 8.41 In order to be able to use text blocks and other new Java language features, we are upgrading to a recent version of Checkstyle. The latest version of spring-javaformat-checkstyle (0.0.28) is built against Checkstyle 8.32 which does not include support for language features such as text blocks. Support for text blocks was added in Checkstyle 8.36. In addition, there is a binary compatibility issue between spring-javaformat-checkstyle 0.0.28 and Checkstyle 8.42. Thus we cannot use Checkstyle 8.42 or higher. In this commit, we therefore upgrade to spring-javaformat-checkstyle 0.0.28 and downgrade to Checkstyle 8.41. This change is being applied to `5.3.x` as well as `main` in order to benefit from the enhanced checking provided in more recent versions of Checkstyle. Closes gh-27481 --- build.gradle | 5 +++-- .../aop/support/ControlFlowPointcut.java | 4 ++-- .../aop/support/ClassUtilsTests.java | 8 +++++--- .../factory/aspectj/ConfigurableObject.java | 6 +++--- .../aspectj/ClassWithPrivateAnnotatedMember.java | 2 ++ .../ClassWithProtectedAnnotatedMember.java | 2 ++ .../security/support/CustomCallbackBean.java | 4 +++- .../support/security/support/DestroyBean.java | 4 +++- .../support/security/support/FactoryBean.java | 4 +++- .../support/security/support/InitBean.java | 4 +++- .../support/security/support/PropertyBean.java | 4 +++- .../beans/testfixture/beans/DummyBean.java | 4 +++- .../format/FormatterRegistrar.java | 3 ++- .../scheduling/support/CronExpression.java | 1 - .../aspectj/ImplicitJPArgumentMatchingTests.java | 1 + ...InvalidConfigurationClassDefinitionTests.java | 1 + .../core/codec/StringDecoderBenchmark.java | 3 ++- .../core/annotation/TypeMappedAnnotation.java | 2 +- .../core/codec/DecodingException.java | 1 + .../core/codec/EncodingException.java | 1 + .../core/env/AbstractEnvironment.java | 16 ++++++++-------- .../core/io/buffer/DataBufferLimitException.java | 3 ++- .../core/io/buffer/LimitedDataBufferList.java | 3 ++- .../SpringCoreBlockHoundIntegrationTests.java | 3 ++- .../io/buffer/LimitedDataBufferListTests.java | 3 ++- .../MonoToListenableFutureAdapterTests.java | 3 ++- .../spel/DefaultComparatorUnitTests.java | 15 ++++++++------- .../spel/StandardTypeLocatorTests.java | 11 ++++++----- .../spel/testdata/PersonInOtherPackage.java | 5 +++-- .../jdbc/core/CallableStatementCallback.java | 3 +-- .../jms/core/support/JmsGatewaySupportTests.java | 9 +++++---- .../reactive/MessageMappingMessageHandler.java | 1 - .../reactive/PayloadMethodArgumentResolver.java | 2 -- .../messaging/rsocket/MetadataEncoder.java | 1 + .../messaging/rsocket/MetadataExtractor.java | 1 + .../rsocket/RSocketConnectorConfigurer.java | 1 + .../RSocketFrameTypeMessageCondition.java | 1 + .../support/RSocketMessageHandler.java | 1 - .../stomp/StompBrokerRelayMessageHandler.java | 4 ++-- .../simp/stomp/StompConversionException.java | 1 + .../simp/stomp/StompReactorNettyCodec.java | 1 + .../simp/stomp/StompTcpConnectionHandler.java | 1 + .../simp/user/DestinationUserNameProvider.java | 1 + .../messaging/tcp/reactor/ReactorNettyCodec.java | 1 + .../handler/annotation/MessagingPredicates.java | 1 + .../MessageMappingMessageHandlerTests.java | 1 + .../PayloadMethodArgumentResolverTests.java | 1 + .../invocation/TestExceptionResolver.java | 1 + .../EncoderMethodReturnValueHandlerTests.java | 1 + .../TestEncoderMethodReturnValueHandler.java | 2 ++ .../rsocket/DefaultMetadataExtractorTests.java | 1 + .../rsocket/LeakAwareNettyDataBufferFactory.java | 1 + .../messaging/rsocket/MetadataEncoderTests.java | 1 + .../messaging/rsocket/PayloadUtilsTests.java | 1 + .../support/RSocketMessageHandlerTests.java | 1 + .../client/reactive/MockClientHttpRequest.java | 1 - .../test/context/support/PropertyProvider.java | 1 - .../context/support/TestConstructorUtils.java | 7 ------- .../testng/AbstractTestNGSpringContextTests.java | 1 - .../context/util/TestContextResourceUtils.java | 1 - .../web/client/RequestExpectationManager.java | 1 - .../server/MockServerClientHttpResponse.java | 1 + .../test/web/reactive/server/WebTestClient.java | 1 - .../test/web/servlet/ResultActions.java | 3 --- .../test/web/servlet/ResultHandler.java | 1 - .../test/web/servlet/SmartRequestBuilder.java | 1 - .../client/AbstractMockMvcServerSpec.java | 1 + .../client/ApplicationContextMockMvcSpec.java | 1 + .../web/servlet/client/MockMvcHttpConnector.java | 1 + .../web/servlet/client/MockMvcWebTestClient.java | 3 +-- .../servlet/client/StandaloneMockMvcSpec.java | 1 + .../test/web/client/samples/SampleTests.java | 1 + .../server/ApplicationContextSpecTests.java | 1 + .../reactive/server/CookieAssertionTests.java | 1 + .../server/DefaultRouterFunctionSpecTests.java | 1 + .../web/reactive/server/MockServerSpecTests.java | 1 + .../web/reactive/server/MockServerTests.java | 1 + .../server/samples/ExchangeMutatorTests.java | 1 + .../samples/GlobalEntityResultConsumerTests.java | 1 + .../test/web/reactive/server/samples/Person.java | 1 + .../result/HeaderResultMatchersTests.java | 1 + .../samples/client/standalone/AsyncTests.java | 1 + .../standalone/ReactiveReturnTypeTests.java | 1 + .../client/standalone/RequestParameterTests.java | 1 + .../samples/client/standalone/SseTests.java | 1 + .../standalone/ReactiveReturnTypeTests.java | 1 + .../standalone/RequestParameterTests.java | 1 + .../SimpleBufferingAsyncClientHttpRequest.java | 4 ++-- .../client/reactive/JettyResourceFactory.java | 2 +- .../codec/multipart/MultipartWriterSupport.java | 1 + .../http/codec/protobuf/ProtobufDecoder.java | 5 ++--- .../springframework/http/server/RequestPath.java | 1 + .../reactive/ServerHttpResponseDecorator.java | 1 + .../web/bind/MissingRequestValueException.java | 1 + .../web/client/DefaultResponseErrorHandler.java | 1 - .../web/client/RestOperations.java | 1 - .../request/AsyncWebRequestInterceptor.java | 2 +- .../web/cors/reactive/CorsUtils.java | 1 - .../cors/reactive/PreFlightRequestWebFilter.java | 1 + .../filter/RelativeRedirectResponseWrapper.java | 1 + .../web/filter/ServletRequestPathFilter.java | 1 + .../web/server/ServerWebExchangeDecorator.java | 1 + .../web/util/ServletRequestPathUtils.java | 6 +++--- .../org/springframework/web/util/WebUtils.java | 1 - .../web/util/pattern/PathPatternParser.java | 2 -- .../reactive/ReactorResourceFactoryTests.java | 1 + .../codec/CancelWithoutDemandCodecTests.java | 1 + .../codec/ResourceHttpMessageReaderTests.java | 1 + .../multipart/PartHttpMessageWriterTests.java | 1 + .../http/server/DefaultRequestPathTests.java | 1 + .../reactive/HttpHeadResponseDecoratorTests.java | 1 + .../web/cors/reactive/CorsWebFilterTests.java | 2 +- .../ContentCachingResponseWrapperTests.java | 1 + .../web/method/HandlerTypePredicateTests.java | 1 + .../session/CookieWebSessionIdResolverTests.java | 1 + .../session/HeaderWebSessionIdResolverTests.java | 1 + .../web/util/ServletRequestPathUtilsTests.java | 1 + .../server/MockServerWebExchange.java | 1 + .../accept/ParameterContentTypeResolver.java | 1 + .../config/ResourceHandlerRegistration.java | 12 +++++------- .../function/client/ExchangeFilterFunction.java | 1 - .../function/client/ExchangeFunction.java | 1 - .../function/server/RequestPredicates.java | 12 ++++++------ .../reactive/function/server/ServerResponse.java | 1 - .../resource/ResourceTransformerSupport.java | 1 - .../annotation/ArgumentResolverConfigurer.java | 1 + .../annotation/SessionAttributesHandler.java | 1 + .../web/reactive/result/view/Rendering.java | 2 -- .../result/view/RequestDataValueProcessor.java | 1 + .../web/reactive/socket/WebSocketHandler.java | 7 +++---- .../web/reactive/socket/WebSocketMessage.java | 1 + .../web/reactive/socket/WebSocketSession.java | 1 + .../socket/adapter/ContextWebSocketHandler.java | 1 + .../reactive/socket/client/WebSocketClient.java | 1 + .../server/support/WebSocketHandlerAdapter.java | 1 + .../ParameterContentTypeResolverTests.java | 1 + ...RequestedContentTypeResolverBuilderTests.java | 1 + .../config/ViewResolverRegistryTests.java | 1 + .../handler/CorsUrlHandlerMappingTests.java | 1 + .../resource/PathResourceResolverTests.java | 1 + ...xVariablesMapMethodArgumentResolverTests.java | 1 + ...trixVariablesMethodArgumentResolverTests.java | 1 + .../WebSessionMethodArgumentResolverTests.java | 1 + .../reactive/result/view/ZeroDemandResponse.java | 1 + .../WebSocketUpgradeHandlerPredicateTests.java | 1 + .../ReactorNettyRequestUpgradeStrategyTests.java | 1 + .../servlet/function/DefaultServerRequest.java | 1 + .../web/servlet/function/RequestPredicates.java | 12 ++++++------ .../web/servlet/function/ServerRequest.java | 1 - .../web/servlet/function/ServerResponse.java | 2 -- .../PathPatternMatchableHandlerMapping.java | 1 + .../annotation/MvcUriComponentsBuilder.java | 2 -- .../method/annotation/StreamingResponseBody.java | 1 + .../servlet/handler/MappedInterceptorTests.java | 1 + .../servlet/handler/PathPatternsTestUtils.java | 1 + .../mvc/method/annotation/SseEmitterTests.java | 1 + .../resource/PathResourceResolverTests.java | 1 + .../ResourceTransformerSupportTests.java | 1 + .../resource/ResourceUrlEncodingFilterTests.java | 1 + .../resource/VersionResourceResolverTests.java | 1 + .../servlet/support/MockFilterRegistration.java | 1 + .../support/WebContentGeneratorTests.java | 1 + .../view/tiles3/TilesViewResolverTests.java | 4 +++- .../web/servlet/view/tiles3/TilesViewTests.java | 3 ++- .../StompWebSocketEndpointRegistration.java | 1 - .../annotation/WebSocketHandlerRegistration.java | 1 - .../support/OriginHandshakeInterceptor.java | 1 - .../sockjs/support/AbstractSockJsService.java | 1 - .../socket/handler/BlockingWebSocketSession.java | 1 + .../OrderedMessageSendingIntegrationTests.java | 1 + .../StompSubProtocolErrorHandlerTests.java | 1 + .../support/WebSocketHandlerMappingTests.java | 1 + src/checkstyle/checkstyle.xml | 2 -- 173 files changed, 221 insertions(+), 138 deletions(-) diff --git a/build.gradle b/build.gradle index 7ce2cb25d185..ba209903d9b2 100644 --- a/build.gradle +++ b/build.gradle @@ -340,7 +340,7 @@ configure([rootProject] + javaProjects) { project -> } checkstyle { - toolVersion = "8.45.1" + toolVersion = "8.41" configDirectory.set(rootProject.file("src/checkstyle")) } @@ -362,7 +362,8 @@ configure([rootProject] + javaProjects) { project -> // JSR-305 only used for non-required meta-annotations compileOnly("com.google.code.findbugs:jsr305") testCompileOnly("com.google.code.findbugs:jsr305") - checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.15") + checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.28") + checkstyle("com.puppycrawl.tools:checkstyle:8.41") } ext.javadocLinks = [ diff --git a/spring-aop/src/main/java/org/springframework/aop/support/ControlFlowPointcut.java b/spring-aop/src/main/java/org/springframework/aop/support/ControlFlowPointcut.java index 6adeea047758..1c4dd8bf43fa 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/ControlFlowPointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/ControlFlowPointcut.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -146,7 +146,7 @@ public int hashCode() { @Override public String toString() { - return getClass().getName() + ": class = " + this.clazz.getName() + "; methodName = " + methodName; + return getClass().getName() + ": class = " + this.clazz.getName() + "; methodName = " + this.methodName; } } diff --git a/spring-aop/src/test/java/org/springframework/aop/support/ClassUtilsTests.java b/spring-aop/src/test/java/org/springframework/aop/support/ClassUtilsTests.java index 6eac64eb77b8..f1fffbdf9cb4 100644 --- a/spring-aop/src/test/java/org/springframework/aop/support/ClassUtilsTests.java +++ b/spring-aop/src/test/java/org/springframework/aop/support/ClassUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.aop.support; import org.junit.jupiter.api.Test; @@ -29,10 +30,10 @@ * @author Rob Harrop * @author Rick Evans */ -public class ClassUtilsTests { +class ClassUtilsTests { @Test - public void getShortNameForCglibClass() { + void getShortNameForCglibClass() { TestBean tb = new TestBean(); ProxyFactory pf = new ProxyFactory(); pf.setTarget(tb); @@ -41,4 +42,5 @@ public void getShortNameForCglibClass() { String className = ClassUtils.getShortName(proxy.getClass()); assertThat(className).as("Class name did not match").isEqualTo("TestBean"); } + } diff --git a/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/ConfigurableObject.java b/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/ConfigurableObject.java index c670dfc06927..02e0d6391fb4 100644 --- a/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/ConfigurableObject.java +++ b/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/ConfigurableObject.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.beans.factory.aspectj; /** - * Marker interface for domain object that need DI through aspects. + * Marker interface for domain objects that need DI through aspects. * * @author Ramnivas Laddad * @since 2.5 */ public interface ConfigurableObject { - } diff --git a/spring-aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithPrivateAnnotatedMember.java b/spring-aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithPrivateAnnotatedMember.java index 7d5b2e6d8376..d0d824c1db73 100644 --- a/spring-aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithPrivateAnnotatedMember.java +++ b/spring-aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithPrivateAnnotatedMember.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.transaction.aspectj; import org.springframework.transaction.annotation.Transactional; @@ -29,4 +30,5 @@ public void doSomething() { @Transactional private void doInTransaction() {} + } diff --git a/spring-aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithProtectedAnnotatedMember.java b/spring-aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithProtectedAnnotatedMember.java index 359eab233cb0..12c5db965d87 100644 --- a/spring-aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithProtectedAnnotatedMember.java +++ b/spring-aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithProtectedAnnotatedMember.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.transaction.aspectj; import org.springframework.transaction.annotation.Transactional; @@ -29,4 +30,5 @@ public void doSomething() { @Transactional protected void doInTransaction() {} + } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomCallbackBean.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomCallbackBean.java index 4874306e6e12..5f46a7b57b60 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomCallbackBean.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomCallbackBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.beans.factory.support.security.support; /** @@ -27,4 +28,5 @@ public void init() { public void destroy() { System.setProperty("security.destroy", "true"); } + } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/DestroyBean.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/DestroyBean.java index 67005abf7836..4ec5a23a5b9d 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/DestroyBean.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/DestroyBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.beans.factory.support.security.support; import org.springframework.beans.factory.DisposableBean; @@ -26,4 +27,5 @@ public class DestroyBean implements DisposableBean { public void destroy() throws Exception { System.setProperty("security.destroy", "true"); } + } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/FactoryBean.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/FactoryBean.java index 4f7fb62e5be2..71258d70f04b 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/FactoryBean.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/FactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.beans.factory.support.security.support; /** @@ -33,4 +34,5 @@ public Object makeInstance() { System.getProperties(); return new Object(); } + } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/InitBean.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/InitBean.java index 3693bb9d749e..b079dae5cb2d 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/InitBean.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/InitBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.beans.factory.support.security.support; import org.springframework.beans.factory.InitializingBean; @@ -26,4 +27,5 @@ public class InitBean implements InitializingBean { public void afterPropertiesSet() throws Exception { System.getProperties(); } + } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/PropertyBean.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/PropertyBean.java index 51933137f0da..d9091163f5d0 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/PropertyBean.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/security/support/PropertyBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.beans.factory.support.security.support; /** @@ -27,4 +28,5 @@ public void setSecurityProperty(Object property) { public void setProperty(Object property) { } + } diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/DummyBean.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/DummyBean.java index cac5cced1c8a..82f40bae28ab 100644 --- a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/DummyBean.java +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/DummyBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.beans.testfixture.beans; /** @@ -65,4 +66,5 @@ public int getAge() { public TestBean getSpouse() { return spouse; } + } diff --git a/spring-context/src/main/java/org/springframework/format/FormatterRegistrar.java b/spring-context/src/main/java/org/springframework/format/FormatterRegistrar.java index 84c1fba83338..dc4bc542dbbb 100644 --- a/spring-context/src/main/java/org/springframework/format/FormatterRegistrar.java +++ b/spring-context/src/main/java/org/springframework/format/FormatterRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.format; import org.springframework.core.convert.converter.Converter; diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/CronExpression.java b/spring-context/src/main/java/org/springframework/scheduling/support/CronExpression.java index f3845847a3ce..e2e6687055e3 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/CronExpression.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/CronExpression.java @@ -171,7 +171,6 @@ private CronExpression( *

  • {@code "@daily"} (or {@code "@midnight"}) to run once a day, i.e. {@code "0 0 0 * * *"},
  • *
  • {@code "@hourly"} to run once an hour, i.e. {@code "0 0 * * * *"}.
  • * - * * @param expression the expression string to parse * @return the parsed {@code CronExpression} object * @throws IllegalArgumentException in the expression does not conform to diff --git a/spring-context/src/test/java/org/springframework/aop/aspectj/ImplicitJPArgumentMatchingTests.java b/spring-context/src/test/java/org/springframework/aop/aspectj/ImplicitJPArgumentMatchingTests.java index 7e3b0e761a3c..1ed5f07faf39 100644 --- a/spring-context/src/test/java/org/springframework/aop/aspectj/ImplicitJPArgumentMatchingTests.java +++ b/spring-context/src/test/java/org/springframework/aop/aspectj/ImplicitJPArgumentMatchingTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.aop.aspectj; import org.aspectj.lang.ProceedingJoinPoint; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/InvalidConfigurationClassDefinitionTests.java b/spring-context/src/test/java/org/springframework/context/annotation/InvalidConfigurationClassDefinitionTests.java index d2114d8c345e..2885637b0605 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/InvalidConfigurationClassDefinitionTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/InvalidConfigurationClassDefinitionTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.context.annotation; import org.junit.jupiter.api.Test; diff --git a/spring-core/src/jmh/java/org/springframework/core/codec/StringDecoderBenchmark.java b/spring-core/src/jmh/java/org/springframework/core/codec/StringDecoderBenchmark.java index cbf36d01ad10..8badd54f6f8d 100644 --- a/spring-core/src/jmh/java/org/springframework/core/codec/StringDecoderBenchmark.java +++ b/spring-core/src/jmh/java/org/springframework/core/codec/StringDecoderBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.core.codec; import java.nio.charset.Charset; 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 ede74c09baf7..06aa93d7d5a3 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 @@ -573,7 +573,7 @@ private ClassLoader getClassLoader() { } if (this.source != null) { if (this.source instanceof Class) { - return ((Class) source).getClassLoader(); + return ((Class) this.source).getClassLoader(); } if (this.source instanceof Member) { ((Member) this.source).getDeclaringClass().getClassLoader(); diff --git a/spring-core/src/main/java/org/springframework/core/codec/DecodingException.java b/spring-core/src/main/java/org/springframework/core/codec/DecodingException.java index f2ec58abffcb..c825f08e8a38 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/DecodingException.java +++ b/spring-core/src/main/java/org/springframework/core/codec/DecodingException.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.core.codec; import org.springframework.lang.Nullable; diff --git a/spring-core/src/main/java/org/springframework/core/codec/EncodingException.java b/spring-core/src/main/java/org/springframework/core/codec/EncodingException.java index 015c01344fcc..7d9f7a1a1b12 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/EncodingException.java +++ b/spring-core/src/main/java/org/springframework/core/codec/EncodingException.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.core.codec; import org.springframework.lang.Nullable; diff --git a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java index 5fa9aa45d2c8..d4027e16f367 100644 --- a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java +++ b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java @@ -138,7 +138,6 @@ protected AbstractEnvironment(MutablePropertySources propertySources) { customizePropertySources(propertySources); } - /** * Factory method used to create the {@link ConfigurablePropertyResolver} * instance used by the Environment. @@ -168,6 +167,7 @@ protected final ConfigurablePropertyResolver getPropertyResolver() { * sources using {@link MutablePropertySources#addLast(PropertySource)} such that * further subclasses may call {@code super.customizePropertySources()} with * predictable results. For example: + * *
     	 * public class Level1Environment extends AbstractEnvironment {
     	 *     @Override
    @@ -187,11 +187,13 @@ protected final ConfigurablePropertyResolver getPropertyResolver() {
     	 *     }
     	 * }
     	 * 
    - * In this arrangement, properties will be resolved against sources A, B, C, D in that + * + *

    In this arrangement, properties will be resolved against sources A, B, C, D in that * order. That is to say that property source "A" has precedence over property source * "D". If the {@code Level2Environment} subclass wished to give property sources C * and D higher precedence than A and B, it could simply call * {@code super.customizePropertySources} after, rather than before adding its own: + * *

     	 * public class Level2Environment extends Level1Environment {
     	 *     @Override
    @@ -202,25 +204,24 @@ protected final ConfigurablePropertyResolver getPropertyResolver() {
     	 *     }
     	 * }
     	 * 
    - * The search order is now C, D, A, B as desired. * - *

    Beyond these recommendations, subclasses may use any of the {@code add*}, + *

    The search order is now C, D, A, B as desired. + *

    Beyond these recommendations, subclasses may use any of the {@code add*}, * {@code remove}, or {@code replace} methods exposed by {@link MutablePropertySources} * in order to create the exact arrangement of property sources desired. - * *

    The base implementation registers no property sources. - * *

    Note that clients of any {@link ConfigurableEnvironment} may further customize * property sources via the {@link #getPropertySources()} accessor, typically within * an {@link org.springframework.context.ApplicationContextInitializer * ApplicationContextInitializer}. For example: + * *

     	 * ConfigurableEnvironment env = new StandardEnvironment();
     	 * env.getPropertySources().addLast(new PropertySourceX(...));
     	 * 
    * *

    A warning about instance variable access

    - * Instance variables declared in subclasses and having default initial values should + *

    Instance variables declared in subclasses and having default initial values should * not be accessed from within this method. Due to Java object creation * lifecycle constraints, any initial value will not yet be assigned when this * callback is invoked by the {@link #AbstractEnvironment()} constructor, which may @@ -229,7 +230,6 @@ protected final ConfigurablePropertyResolver getPropertyResolver() { * property source manipulation and instance variable access directly within the * subclass constructor. Note that assigning values to instance variables is * not problematic; it is only attempting to read default values that must be avoided. - * * @see MutablePropertySources * @see PropertySourcesPropertyResolver * @see org.springframework.context.ApplicationContextInitializer diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferLimitException.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferLimitException.java index c03839056bb3..709e21e6abfa 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferLimitException.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferLimitException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.core.io.buffer; /** diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/LimitedDataBufferList.java b/spring-core/src/main/java/org/springframework/core/io/buffer/LimitedDataBufferList.java index d95e426d3852..62fa289e7c37 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/LimitedDataBufferList.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/LimitedDataBufferList.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.core.io.buffer; import java.util.ArrayList; diff --git a/spring-core/src/test/java/org/springframework/core/SpringCoreBlockHoundIntegrationTests.java b/spring-core/src/test/java/org/springframework/core/SpringCoreBlockHoundIntegrationTests.java index f2245eff20dd..ea4b7fbbd552 100644 --- a/spring-core/src/test/java/org/springframework/core/SpringCoreBlockHoundIntegrationTests.java +++ b/spring-core/src/test/java/org/springframework/core/SpringCoreBlockHoundIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.core; import java.lang.reflect.Method; diff --git a/spring-core/src/test/java/org/springframework/core/io/buffer/LimitedDataBufferListTests.java b/spring-core/src/test/java/org/springframework/core/io/buffer/LimitedDataBufferListTests.java index 971cd1212061..20a48616b82b 100644 --- a/spring-core/src/test/java/org/springframework/core/io/buffer/LimitedDataBufferListTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/buffer/LimitedDataBufferListTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.core.io.buffer; import java.nio.charset.StandardCharsets; diff --git a/spring-core/src/test/java/org/springframework/util/concurrent/MonoToListenableFutureAdapterTests.java b/spring-core/src/test/java/org/springframework/util/concurrent/MonoToListenableFutureAdapterTests.java index bea1a0dac0f5..e40e8aa79e24 100644 --- a/spring-core/src/test/java/org/springframework/util/concurrent/MonoToListenableFutureAdapterTests.java +++ b/spring-core/src/test/java/org/springframework/util/concurrent/MonoToListenableFutureAdapterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.util.concurrent; import java.time.Duration; diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/DefaultComparatorUnitTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/DefaultComparatorUnitTests.java index edc88bdebeb8..eeb23b4d4152 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/DefaultComparatorUnitTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/DefaultComparatorUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.expression.spel; import java.math.BigDecimal; @@ -31,10 +32,10 @@ * @author Andy Clement * @author Giovanni Dall'Oglio Risso */ -public class DefaultComparatorUnitTests { +class DefaultComparatorUnitTests { @Test - public void testPrimitives() throws EvaluationException { + void testPrimitives() throws EvaluationException { TypeComparator comparator = new StandardTypeComparator(); // primitive int assertThat(comparator.compare(1, 2) < 0).isTrue(); @@ -63,7 +64,7 @@ public void testPrimitives() throws EvaluationException { } @Test - public void testNonPrimitiveNumbers() throws EvaluationException { + void testNonPrimitiveNumbers() throws EvaluationException { TypeComparator comparator = new StandardTypeComparator(); BigDecimal bdOne = new BigDecimal("1"); @@ -92,7 +93,7 @@ public void testNonPrimitiveNumbers() throws EvaluationException { } @Test - public void testNulls() throws EvaluationException { + void testNulls() throws EvaluationException { TypeComparator comparator = new StandardTypeComparator(); assertThat(comparator.compare(null,"abc")<0).isTrue(); assertThat(comparator.compare(null,null)==0).isTrue(); @@ -100,7 +101,7 @@ public void testNulls() throws EvaluationException { } @Test - public void testObjects() throws EvaluationException { + void testObjects() throws EvaluationException { TypeComparator comparator = new StandardTypeComparator(); assertThat(comparator.compare("a","a")==0).isTrue(); assertThat(comparator.compare("a","b")<0).isTrue(); @@ -108,7 +109,7 @@ public void testObjects() throws EvaluationException { } @Test - public void testCanCompare() throws EvaluationException { + void testCanCompare() throws EvaluationException { TypeComparator comparator = new StandardTypeComparator(); assertThat(comparator.canCompare(null,1)).isTrue(); assertThat(comparator.canCompare(1,null)).isTrue(); diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/StandardTypeLocatorTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/StandardTypeLocatorTests.java index a41ac5691ac8..bdd022d80c77 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/StandardTypeLocatorTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/StandardTypeLocatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.expression.spel; import java.util.List; @@ -26,14 +27,14 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** - * Unit tests for type comparison + * Unit tests for type comparison. * * @author Andy Clement */ -public class StandardTypeLocatorTests { +class StandardTypeLocatorTests { @Test - public void testImports() throws EvaluationException { + void testImports() throws EvaluationException { StandardTypeLocator locator = new StandardTypeLocator(); assertThat(locator.findType("java.lang.Integer")).isEqualTo(Integer.class); assertThat(locator.findType("java.lang.String")).isEqualTo(String.class); @@ -45,7 +46,7 @@ public void testImports() throws EvaluationException { assertThat(locator.findType("Boolean")).isEqualTo(Boolean.class); // currently does not know about java.util by default -// assertEquals(java.util.List.class,locator.findType("List")); + // assertEquals(java.util.List.class,locator.findType("List")); assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() -> locator.findType("URL")) diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/testdata/PersonInOtherPackage.java b/spring-expression/src/test/java/org/springframework/expression/spel/testdata/PersonInOtherPackage.java index 4c1371d53a70..68eae427e8ec 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/testdata/PersonInOtherPackage.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/testdata/PersonInOtherPackage.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.expression.spel.testdata; /** - * * @author Andy Clement * @since 4.1.2 */ @@ -35,4 +35,5 @@ public int getAge() { public void setAge(int age) { this.age = age; } + } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/CallableStatementCallback.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/CallableStatementCallback.java index 0ec86ab44d9b..7fb2ad7f0aca 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/CallableStatementCallback.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/CallableStatementCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,7 +68,6 @@ public interface CallableStatementCallback { * a domain object or a collection of domain objects. A thrown RuntimeException * is treated as application exception: it gets propagated to the caller of * the template. - * * @param cs active JDBC CallableStatement * @return a result object, or {@code null} if none * @throws SQLException if thrown by a JDBC method, to be auto-converted diff --git a/spring-jms/src/test/java/org/springframework/jms/core/support/JmsGatewaySupportTests.java b/spring-jms/src/test/java/org/springframework/jms/core/support/JmsGatewaySupportTests.java index b4b7d3ab4452..ac1064ed071f 100644 --- a/spring-jms/src/test/java/org/springframework/jms/core/support/JmsGatewaySupportTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/core/support/JmsGatewaySupportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.jms.core.support; import java.util.ArrayList; @@ -31,10 +32,10 @@ * @author Mark Pollack * @since 24.9.2004 */ -public class JmsGatewaySupportTests { +class JmsGatewaySupportTests { @Test - public void testJmsGatewaySupportWithConnectionFactory() throws Exception { + void testJmsGatewaySupportWithConnectionFactory() throws Exception { ConnectionFactory mockConnectionFactory = mock(ConnectionFactory.class); final List test = new ArrayList<>(1); JmsGatewaySupport gateway = new JmsGatewaySupport() { @@ -51,7 +52,7 @@ protected void initGateway() { } @Test - public void testJmsGatewaySupportWithJmsTemplate() throws Exception { + void testJmsGatewaySupportWithJmsTemplate() throws Exception { JmsTemplate template = new JmsTemplate(); final List test = new ArrayList<>(1); JmsGatewaySupport gateway = new JmsGatewaySupport() { diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandler.java index d8d3e55f19c3..0804bff2d0a1 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandler.java @@ -208,7 +208,6 @@ public void setEmbeddedValueResolver(StringValueResolver resolver) { * // delegate all methods * } * - * * @param bean the bean to check for {@code @MessageExceptionHandler} methods * @since 5.3.5 */ diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolver.java index c36a99ba97a4..3e3c930f05e5 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolver.java @@ -146,11 +146,9 @@ public boolean supportsParameter(MethodParameter parameter) { * {@code @javax.validation.Valid} or * {@link org.springframework.validation.annotation.Validated}. Validation * failure results in an {@link MethodArgumentNotValidException}. - * * @param parameter the target method argument that we are decoding to * @param message the message from which the content was extracted * @return a Mono with the result of argument resolution - * * @see #extractContent(MethodParameter, Message) * @see #getMimeType(Message) */ diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/MetadataEncoder.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/MetadataEncoder.java index 7e22c01882e4..24fde3c2d988 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/MetadataEncoder.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/MetadataEncoder.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.rsocket; import java.util.ArrayList; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/MetadataExtractor.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/MetadataExtractor.java index 37c4b47c961a..34088b282874 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/MetadataExtractor.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/MetadataExtractor.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.rsocket; import java.util.Map; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/RSocketConnectorConfigurer.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/RSocketConnectorConfigurer.java index f2247642485c..11768122c9a5 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/RSocketConnectorConfigurer.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/RSocketConnectorConfigurer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.rsocket; import io.rsocket.core.RSocketConnector; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java index 71dcee0940b9..b8e1f303e8d8 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.rsocket.annotation.support; import java.util.Arrays; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandler.java index 27c6ee47e0bb..4bcd5c0f4ef5 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandler.java @@ -471,7 +471,6 @@ private boolean isDataMimeTypeSupported(MimeType dataMimeType) { * for more advanced scenarios, e.g. discovering handlers through a custom * stereotype annotation, consider declaring {@code RSocketMessageHandler} * as a bean, and then obtain the responder from it. - * * @param strategies the strategies to set on the created * {@code RSocketMessageHandler} * @param candidateHandlers a list of Objects and/or Classes with annotated diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java index c95f208b338b..f756b0b1f9ea 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -797,7 +797,7 @@ protected boolean shouldSendHeartbeatForIgnoredMessage() { * @since 5.3 */ void updateClientSendMessageCount(long now) { - if (this.clientSendMessageCount != null && this.clientSendInterval > (now - clientSendMessageTimestamp)) { + if (this.clientSendMessageCount != null && this.clientSendInterval > (now - this.clientSendMessageTimestamp)) { this.clientSendMessageCount.set(0); this.clientSendMessageTimestamp = now; } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompConversionException.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompConversionException.java index c5226b4fcbc9..e839400cca8a 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompConversionException.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompConversionException.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.simp.stomp; import org.springframework.core.NestedRuntimeException; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompReactorNettyCodec.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompReactorNettyCodec.java index f8dc36022711..3c84cd0cdb57 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompReactorNettyCodec.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompReactorNettyCodec.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.simp.stomp; import java.nio.ByteBuffer; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompTcpConnectionHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompTcpConnectionHandler.java index 098f985cb303..03c124296650 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompTcpConnectionHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompTcpConnectionHandler.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.simp.stomp; import org.springframework.messaging.simp.SimpMessageHeaderAccessor; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/DestinationUserNameProvider.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/DestinationUserNameProvider.java index 53dfe75eeb07..4971e7df6205 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/DestinationUserNameProvider.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/DestinationUserNameProvider.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.simp.user; /** diff --git a/spring-messaging/src/main/java/org/springframework/messaging/tcp/reactor/ReactorNettyCodec.java b/spring-messaging/src/main/java/org/springframework/messaging/tcp/reactor/ReactorNettyCodec.java index 4df0e33225ac..49c2fbc10715 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/tcp/reactor/ReactorNettyCodec.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/tcp/reactor/ReactorNettyCodec.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.tcp.reactor; import java.util.Collection; diff --git a/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/MessagingPredicates.java b/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/MessagingPredicates.java index 8abde0e13258..1c3c826fb0c4 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/MessagingPredicates.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/MessagingPredicates.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.handler.annotation; import java.util.function.Predicate; diff --git a/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandlerTests.java b/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandlerTests.java index 947412ba2c67..fe4c46e742bf 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandlerTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandlerTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.handler.annotation.reactive; import java.time.Duration; diff --git a/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolverTests.java b/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolverTests.java index 58d7200fac8a..b0c7df33aeca 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolverTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.handler.annotation.reactive; import java.nio.charset.StandardCharsets; diff --git a/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/TestExceptionResolver.java b/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/TestExceptionResolver.java index d044ffed283b..bf30e67416e6 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/TestExceptionResolver.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/TestExceptionResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.handler.invocation; import java.lang.reflect.Method; diff --git a/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/reactive/EncoderMethodReturnValueHandlerTests.java b/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/reactive/EncoderMethodReturnValueHandlerTests.java index 4c6b122280d6..bc79a0a88962 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/reactive/EncoderMethodReturnValueHandlerTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/reactive/EncoderMethodReturnValueHandlerTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.handler.invocation.reactive; import java.util.Collections; diff --git a/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/reactive/TestEncoderMethodReturnValueHandler.java b/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/reactive/TestEncoderMethodReturnValueHandler.java index e16ee6ea706e..c10a936c014d 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/reactive/TestEncoderMethodReturnValueHandler.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/reactive/TestEncoderMethodReturnValueHandler.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.handler.invocation.reactive; import java.util.List; @@ -65,4 +66,5 @@ protected Mono handleNoContent(MethodParameter returnType, Message mess this.encodedContent = Flux.empty(); return Mono.empty(); } + } diff --git a/spring-messaging/src/test/java/org/springframework/messaging/rsocket/DefaultMetadataExtractorTests.java b/spring-messaging/src/test/java/org/springframework/messaging/rsocket/DefaultMetadataExtractorTests.java index 66061ec9c2ff..1c3cd882f5d1 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/rsocket/DefaultMetadataExtractorTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/rsocket/DefaultMetadataExtractorTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.rsocket; import java.nio.charset.StandardCharsets; diff --git a/spring-messaging/src/test/java/org/springframework/messaging/rsocket/LeakAwareNettyDataBufferFactory.java b/spring-messaging/src/test/java/org/springframework/messaging/rsocket/LeakAwareNettyDataBufferFactory.java index 1f2e9271fa94..23c0f020b2ba 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/rsocket/LeakAwareNettyDataBufferFactory.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/rsocket/LeakAwareNettyDataBufferFactory.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.rsocket; import java.time.Duration; diff --git a/spring-messaging/src/test/java/org/springframework/messaging/rsocket/MetadataEncoderTests.java b/spring-messaging/src/test/java/org/springframework/messaging/rsocket/MetadataEncoderTests.java index d2b9445ba18a..eaea5c2b429a 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/rsocket/MetadataEncoderTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/rsocket/MetadataEncoderTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.rsocket; import java.time.Duration; diff --git a/spring-messaging/src/test/java/org/springframework/messaging/rsocket/PayloadUtilsTests.java b/spring-messaging/src/test/java/org/springframework/messaging/rsocket/PayloadUtilsTests.java index 73b1d45779b5..8346fab1b43b 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/rsocket/PayloadUtilsTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/rsocket/PayloadUtilsTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.rsocket; import java.nio.charset.StandardCharsets; diff --git a/spring-messaging/src/test/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandlerTests.java b/spring-messaging/src/test/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandlerTests.java index c7d0a80a1d87..2c00e831b126 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandlerTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandlerTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.rsocket.annotation.support; import java.util.Arrays; diff --git a/spring-test/src/main/java/org/springframework/mock/http/client/reactive/MockClientHttpRequest.java b/spring-test/src/main/java/org/springframework/mock/http/client/reactive/MockClientHttpRequest.java index 873dab64dd0e..3291de25fb74 100644 --- a/spring-test/src/main/java/org/springframework/mock/http/client/reactive/MockClientHttpRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/http/client/reactive/MockClientHttpRequest.java @@ -79,7 +79,6 @@ public MockClientHttpRequest(HttpMethod httpMethod, URI url) { *

    The default write handler consumes and caches the request body so it * may be accessed subsequently, e.g. in test assertions. Use this property * when the request body is an infinite stream. - * * @param writeHandler the write handler to use returning {@code Mono} * when the body has been "written" (i.e. consumed). */ diff --git a/spring-test/src/main/java/org/springframework/test/context/support/PropertyProvider.java b/spring-test/src/main/java/org/springframework/test/context/support/PropertyProvider.java index 3878ecbde0de..564ed078a936 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/PropertyProvider.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/PropertyProvider.java @@ -32,7 +32,6 @@ public interface PropertyProvider { /** * Get the value of the named property. - * * @param name the name of the property to retrieve * @return the value of the property or {@code null} if not found */ diff --git a/spring-test/src/main/java/org/springframework/test/context/support/TestConstructorUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/TestConstructorUtils.java index df82bef780fa..9c59804ef0b9 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/TestConstructorUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/TestConstructorUtils.java @@ -44,10 +44,8 @@ private TestConstructorUtils() { /** * Determine if the supplied executable for the given test class is an * autowirable constructor. - * *

    This method delegates to {@link #isAutowirableConstructor(Executable, Class, PropertyProvider)} * will a value of {@code null} for the fallback {@link PropertyProvider}. - * * @param executable an executable for the test class * @param testClass the test class * @return {@code true} if the executable is an autowirable constructor @@ -60,10 +58,8 @@ public static boolean isAutowirableConstructor(Executable executable, Class t /** * Determine if the supplied constructor for the given test class is * autowirable. - * *

    This method delegates to {@link #isAutowirableConstructor(Constructor, Class, PropertyProvider)} * will a value of {@code null} for the fallback {@link PropertyProvider}. - * * @param constructor a constructor for the test class * @param testClass the test class * @return {@code true} if the constructor is autowirable @@ -76,10 +72,8 @@ public static boolean isAutowirableConstructor(Constructor constructor, Class /** * Determine if the supplied executable for the given test class is an * autowirable constructor. - * *

    This method delegates to {@link #isAutowirableConstructor(Constructor, Class, PropertyProvider)} * if the supplied executable is a constructor and otherwise returns {@code false}. - * * @param executable an executable for the test class * @param testClass the test class * @param fallbackPropertyProvider fallback property provider used to look up @@ -114,7 +108,6 @@ public static boolean isAutowirableConstructor(Executable executable, Class t * {@link PropertyProvider} (see * {@link TestConstructor#TEST_CONSTRUCTOR_AUTOWIRE_MODE_PROPERTY_NAME}). * - * * @param constructor a constructor for the test class * @param testClass the test class * @param fallbackPropertyProvider fallback property provider used to look up diff --git a/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTestNGSpringContextTests.java b/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTestNGSpringContextTests.java index 4581b1d00990..6b45deb821ad 100644 --- a/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTestNGSpringContextTests.java +++ b/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTestNGSpringContextTests.java @@ -203,7 +203,6 @@ public void run(IHookCallBack callBack, ITestResult testResult) { * Delegates to the configured {@link TestContextManager} to * {@linkplain TestContextManager#afterTestMethod(Object, Method, Throwable) * post-process} the test method after the actual test has executed. - * * @param testMethod the test method which has just been executed on the * test instance * @throws Exception allows all exceptions to propagate diff --git a/spring-test/src/main/java/org/springframework/test/context/util/TestContextResourceUtils.java b/spring-test/src/main/java/org/springframework/test/context/util/TestContextResourceUtils.java index aeda69be0207..632e7a90432f 100644 --- a/spring-test/src/main/java/org/springframework/test/context/util/TestContextResourceUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/util/TestContextResourceUtils.java @@ -52,7 +52,6 @@ public abstract class TestContextResourceUtils { /** * Convert the supplied paths to classpath resource paths. - * *

    Delegates to {@link #convertToClasspathResourcePaths(Class, boolean, String...)} * with {@code false} supplied for the {@code preservePlaceholders} flag. * @param clazz the class with which the paths are associated diff --git a/spring-test/src/main/java/org/springframework/test/web/client/RequestExpectationManager.java b/spring-test/src/main/java/org/springframework/test/web/client/RequestExpectationManager.java index 734a6073904a..35a8c68c7778 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/RequestExpectationManager.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/RequestExpectationManager.java @@ -42,7 +42,6 @@ public interface RequestExpectationManager { * used to add more expectations and define a response. *

    This is a delegate for * {@link MockRestServiceServer#expect(ExpectedCount, RequestMatcher)}. - * * @param requestMatcher a request expectation * @return for setting up further expectations and define a response * @see MockRestServiceServer#expect(RequestMatcher) diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/MockServerClientHttpResponse.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/MockServerClientHttpResponse.java index 8fe12d926596..e836cfdaccc1 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/MockServerClientHttpResponse.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/MockServerClientHttpResponse.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.reactive.server; import org.springframework.http.client.reactive.ClientHttpResponse; diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java index 84adf85013c5..878a901c2267 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java @@ -862,7 +862,6 @@ interface ResponseSpec { /** * Exit the chained flow in order to consume the response body * externally, e.g. via {@link reactor.test.StepVerifier}. - * *

    Note that when {@code Void.class} is passed in, the response body * is consumed and released. If no content is expected, then consider * using {@code .expectBody().isEmpty()} instead which asserts that diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java index f4fd6da14b58..3b99f1b5d0e1 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultActions.java @@ -47,7 +47,6 @@ public interface ResultActions { * .andExpect(content().contentType(MediaType.APPLICATION_JSON)) * .andExpect(jsonPath("$.person.name").value("Jason")); * - * * @see #andExpectAll(ResultMatcher...) */ ResultActions andExpect(ResultMatcher matcher) throws Exception; @@ -78,7 +77,6 @@ public interface ResultActions { * jsonPath("$.person.name").value("Jason") * ); * - * * @since 5.3.10 * @see #andExpect(ResultMatcher) */ @@ -105,7 +103,6 @@ default ResultActions andExpectAll(ResultMatcher... matchers) throws Exception { /** * Return the result of the executed request for direct access to the results. - * * @return the result of the request */ MvcResult andReturn(); diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultHandler.java b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultHandler.java index e5559f5724ce..04724d661687 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/ResultHandler.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/ResultHandler.java @@ -49,7 +49,6 @@ public interface ResultHandler { /** * Perform an action on the given result. - * * @param result the result of the executed request * @throws Exception if a failure occurs */ diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/SmartRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/SmartRequestBuilder.java index 648115851b96..13e57d2e9f77 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/SmartRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/SmartRequestBuilder.java @@ -31,7 +31,6 @@ public interface SmartRequestBuilder extends RequestBuilder { /** * Apply request post processing. Typically that means invoking one or more * {@link org.springframework.test.web.servlet.request.RequestPostProcessor org.springframework.test.web.servlet.request.RequestPostProcessors}. - * * @param request the request to initialize * @return the request to use, either the one passed in or a wrapped one */ diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java index cf1b2d60fe8a..37e419381154 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.servlet.client; import javax.servlet.Filter; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/ApplicationContextMockMvcSpec.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/ApplicationContextMockMvcSpec.java index 1c6c3577798d..ba555792e979 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/ApplicationContextMockMvcSpec.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/ApplicationContextMockMvcSpec.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.servlet.client; import org.springframework.test.web.servlet.setup.ConfigurableMockMvcBuilder; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcHttpConnector.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcHttpConnector.java index 705e89432b7c..ba6b040b10ea 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcHttpConnector.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcHttpConnector.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.servlet.client; import java.io.StringWriter; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java index a59879f795d4..1ace31756746 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.servlet.client; import java.util.function.Supplier; @@ -112,7 +113,6 @@ static WebTestClient.Builder bindTo(MockMvc mockMvc) { /** * This method can be used to apply further assertions on a given * {@link ExchangeResult} based the state of the server response. - * *

    Normally {@link WebTestClient} is used to assert the client response * including HTTP status, headers, and body. That is all that is available * when making a live request over HTTP. However when the server is @@ -134,7 +134,6 @@ static WebTestClient.Builder bindTo(MockMvc mockMvc) { * .andExpect(flash().attributeCount(1)) * .andExpect(flash().attribute("message", "success!")); * - * *

    Note: this method works only if the {@link WebTestClient} used to * perform the request was initialized through one of bind method in this * class, and therefore requests are handled by {@link MockMvc}. diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/StandaloneMockMvcSpec.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/StandaloneMockMvcSpec.java index 63cdee1d5d84..d935bd8b1b40 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/StandaloneMockMvcSpec.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/StandaloneMockMvcSpec.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.servlet.client; import java.util.function.Supplier; diff --git a/spring-test/src/test/java/org/springframework/test/web/client/samples/SampleTests.java b/spring-test/src/test/java/org/springframework/test/web/client/samples/SampleTests.java index 7488fc94e54f..5198c95025c9 100644 --- a/spring-test/src/test/java/org/springframework/test/web/client/samples/SampleTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/client/samples/SampleTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.client.samples; import java.io.IOException; diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/ApplicationContextSpecTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/ApplicationContextSpecTests.java index 99e5e6a07496..617c9b12aeae 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/ApplicationContextSpecTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/ApplicationContextSpecTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.reactive.server; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/CookieAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/CookieAssertionTests.java index 70a823302fb8..0e105afd9387 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/CookieAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/CookieAssertionTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.reactive.server; import java.net.URI; diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/DefaultRouterFunctionSpecTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/DefaultRouterFunctionSpecTests.java index b81d3d3ca3d8..514f81a33eef 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/DefaultRouterFunctionSpecTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/DefaultRouterFunctionSpecTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.reactive.server; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/MockServerSpecTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/MockServerSpecTests.java index 1e47439fb959..5f2fa3fd5bbb 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/MockServerSpecTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/MockServerSpecTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.reactive.server; import java.nio.charset.StandardCharsets; diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/MockServerTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/MockServerTests.java index 2b42028b2bc5..7b423d92c8c1 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/MockServerTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/MockServerTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.reactive.server; import java.util.Arrays; diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ExchangeMutatorTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ExchangeMutatorTests.java index f8fc1ea89c10..d5dbbd597ce9 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ExchangeMutatorTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ExchangeMutatorTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.reactive.server.samples; import java.security.Principal; diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/GlobalEntityResultConsumerTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/GlobalEntityResultConsumerTests.java index 8404c9ed7ea3..24bf92ecbb31 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/GlobalEntityResultConsumerTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/GlobalEntityResultConsumerTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.reactive.server.samples; import java.nio.charset.StandardCharsets; diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/Person.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/Person.java index 23c2115e1d76..802144a810a4 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/Person.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/Person.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.reactive.server.samples; import javax.xml.bind.annotation.XmlRootElement; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/result/HeaderResultMatchersTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/result/HeaderResultMatchersTests.java index 496e9e7834b8..75c20a1d0b58 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/result/HeaderResultMatchersTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/result/HeaderResultMatchersTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.servlet.result; import java.time.ZoneId; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/AsyncTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/AsyncTests.java index 77259b29648e..674dc80fa06d 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/AsyncTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/AsyncTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.servlet.samples.client.standalone; import java.nio.charset.StandardCharsets; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/ReactiveReturnTypeTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/ReactiveReturnTypeTests.java index 9229ef6839d6..7a3974262723 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/ReactiveReturnTypeTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/ReactiveReturnTypeTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.servlet.samples.client.standalone; import java.time.Duration; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/RequestParameterTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/RequestParameterTests.java index d21e283e0190..bb9f0efd4085 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/RequestParameterTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/RequestParameterTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.servlet.samples.client.standalone; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/SseTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/SseTests.java index a22cd2a1b86a..bb3ab30c322e 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/SseTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/SseTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.servlet.samples.client.standalone; import org.junit.jupiter.api.Test; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/ReactiveReturnTypeTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/ReactiveReturnTypeTests.java index 12d72f1a2e64..065ea0fe882a 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/ReactiveReturnTypeTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/ReactiveReturnTypeTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.servlet.samples.standalone; import java.time.Duration; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/RequestParameterTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/RequestParameterTests.java index ff67744cc395..584af36911c2 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/RequestParameterTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/RequestParameterTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.test.web.servlet.samples.standalone; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/main/java/org/springframework/http/client/SimpleBufferingAsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/SimpleBufferingAsyncClientHttpRequest.java index c2cdaae97ea1..ec2672534d11 100644 --- a/spring-web/src/main/java/org/springframework/http/client/SimpleBufferingAsyncClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/SimpleBufferingAsyncClientHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -81,7 +81,7 @@ protected ListenableFuture executeInternal( if (getMethod() == HttpMethod.DELETE && bufferedOutput.length == 0) { this.connection.setDoOutput(false); } - if (this.connection.getDoOutput() && outputStreaming) { + if (this.connection.getDoOutput() && this.outputStreaming) { this.connection.setFixedLengthStreamingMode(bufferedOutput.length); } this.connection.connect(); diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyResourceFactory.java b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyResourceFactory.java index b31e86ae1ea6..415cdfcdbb7d 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyResourceFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyResourceFactory.java @@ -132,7 +132,7 @@ public void afterPropertiesSet() throws Exception { if (this.byteBufferPool == null) { this.byteBufferPool = new MappedByteBufferPool(2048, this.executor instanceof ThreadPool.SizedThreadPool - ? ((ThreadPool.SizedThreadPool) executor).getMaxThreads() / 2 + ? ((ThreadPool.SizedThreadPool) this.executor).getMaxThreads() / 2 : ProcessorUtils.availableProcessors() * 2); } if (this.scheduler == null) { diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartWriterSupport.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartWriterSupport.java index 3a086287b130..fe0e97c3b2bc 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartWriterSupport.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartWriterSupport.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.http.codec.multipart; import java.nio.charset.Charset; diff --git a/spring-web/src/main/java/org/springframework/http/codec/protobuf/ProtobufDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/protobuf/ProtobufDecoder.java index 2ba3a8da94c7..4804dcf1f4f5 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/protobuf/ProtobufDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/protobuf/ProtobufDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -265,7 +265,6 @@ public Iterable apply(DataBuffer input) { * Parse message size as a varint from the input stream, updating {@code messageBytesToRead} and * {@code offset} fields if needed to allow processing of upcoming chunks. * Inspired from {@link CodedInputStream#readRawVarint32(int, java.io.InputStream)} - * * @return {code true} when the message size is parsed successfully, {code false} when the message size is * truncated * @see Base 128 Varints @@ -290,7 +289,7 @@ private boolean readMessageSize(DataBuffer input) { return false; } final int b = input.read(); - this.messageBytesToRead |= (b & 0x7f) << offset; + this.messageBytesToRead |= (b & 0x7f) << this.offset; if ((b & 0x80) == 0) { this.offset = 0; return true; diff --git a/spring-web/src/main/java/org/springframework/http/server/RequestPath.java b/spring-web/src/main/java/org/springframework/http/server/RequestPath.java index cdca6a784614..6b748da1d43a 100644 --- a/spring-web/src/main/java/org/springframework/http/server/RequestPath.java +++ b/spring-web/src/main/java/org/springframework/http/server/RequestPath.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.http.server; import java.net.URI; diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpResponseDecorator.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpResponseDecorator.java index 125a7bb7d65b..79a6c0c8bd44 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpResponseDecorator.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpResponseDecorator.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.http.server.reactive; import java.util.function.Supplier; diff --git a/spring-web/src/main/java/org/springframework/web/bind/MissingRequestValueException.java b/spring-web/src/main/java/org/springframework/web/bind/MissingRequestValueException.java index 1de083e3a8b5..de873b0adf81 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/MissingRequestValueException.java +++ b/spring-web/src/main/java/org/springframework/web/bind/MissingRequestValueException.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.bind; /** diff --git a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java index 8200adb1682f..31355571c685 100644 --- a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java @@ -169,7 +169,6 @@ private String getErrorMessage( * {@link HttpClientErrorException#create} for errors in the 4xx range, to * {@link HttpServerErrorException#create} for errors in the 5xx range, * or otherwise raises {@link UnknownHttpStatusCodeException}. - * * @since 5.0 * @see HttpClientErrorException#create * @see HttpServerErrorException#create diff --git a/spring-web/src/main/java/org/springframework/web/client/RestOperations.java b/spring-web/src/main/java/org/springframework/web/client/RestOperations.java index e799385bd249..b7997534e5e5 100644 --- a/spring-web/src/main/java/org/springframework/web/client/RestOperations.java +++ b/spring-web/src/main/java/org/springframework/web/client/RestOperations.java @@ -448,7 +448,6 @@ T patchForObject(URI url, @Nullable Object request, Class responseType) /** * Delete the resources at the specified URI. *

    URI Template variables are expanded using the given map. - * * @param url the URL * @param uriVariables the variables to expand the template */ diff --git a/spring-web/src/main/java/org/springframework/web/context/request/AsyncWebRequestInterceptor.java b/spring-web/src/main/java/org/springframework/web/context/request/AsyncWebRequestInterceptor.java index 8e02e8650134..7582388b12b0 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/AsyncWebRequestInterceptor.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/AsyncWebRequestInterceptor.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.context.request; /** @@ -41,7 +42,6 @@ public interface AsyncWebRequestInterceptor extends WebRequestInterceptor{ /** * Called instead of {@code postHandle} and {@code afterCompletion}, when the * handler started handling the request concurrently. - * * @param request the current request */ void afterConcurrentHandlingStarted(WebRequest request); 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 a9f52082a5fe..1d78ed9aab0c 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 @@ -63,7 +63,6 @@ public static boolean isPreFlightRequest(ServerHttpRequest request) { * {@code "Forwarded"} and {@code "X-Forwarded-*"} headers that specify the * client-originated address. Consider using the {@code ForwardedHeaderFilter} * to extract and use, or to discard such headers. - * * @return {@code true} if the request is a same-origin one, {@code false} in case * of a cross-origin request * @deprecated as of 5.2, same-origin checks are performed directly by {@link #isCorsRequest} diff --git a/spring-web/src/main/java/org/springframework/web/cors/reactive/PreFlightRequestWebFilter.java b/spring-web/src/main/java/org/springframework/web/cors/reactive/PreFlightRequestWebFilter.java index 1b9f6adf42bd..7c04c565d343 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/reactive/PreFlightRequestWebFilter.java +++ b/spring-web/src/main/java/org/springframework/web/cors/reactive/PreFlightRequestWebFilter.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.cors.reactive; import reactor.core.publisher.Mono; diff --git a/spring-web/src/main/java/org/springframework/web/filter/RelativeRedirectResponseWrapper.java b/spring-web/src/main/java/org/springframework/web/filter/RelativeRedirectResponseWrapper.java index baf4ab53ce9b..d532c6251321 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/RelativeRedirectResponseWrapper.java +++ b/spring-web/src/main/java/org/springframework/web/filter/RelativeRedirectResponseWrapper.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.filter; import javax.servlet.http.HttpServletResponse; diff --git a/spring-web/src/main/java/org/springframework/web/filter/ServletRequestPathFilter.java b/spring-web/src/main/java/org/springframework/web/filter/ServletRequestPathFilter.java index cc9e85015f47..a6dc490af03d 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/ServletRequestPathFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/ServletRequestPathFilter.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.filter; import java.io.IOException; diff --git a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchangeDecorator.java b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchangeDecorator.java index 87a27156052a..0559a5681792 100644 --- a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchangeDecorator.java +++ b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchangeDecorator.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.server; import java.security.Principal; diff --git a/spring-web/src/main/java/org/springframework/web/util/ServletRequestPathUtils.java b/spring-web/src/main/java/org/springframework/web/util/ServletRequestPathUtils.java index b757f3e59f81..1c4455dbbe99 100644 --- a/spring-web/src/main/java/org/springframework/web/util/ServletRequestPathUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/ServletRequestPathUtils.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.util; import java.nio.charset.StandardCharsets; @@ -53,11 +54,10 @@ public abstract class ServletRequestPathUtils { * {@link RequestPath} and save it in the request attribute * {@link #PATH_ATTRIBUTE} for subsequent use with * {@link org.springframework.web.util.pattern.PathPattern parsed patterns}. - * The returned {@code RequestPath} will have both the contextPath and any + *

    The returned {@code RequestPath} will have both the contextPath and any * servletPath prefix omitted from the {@link RequestPath#pathWithinApplication() * pathWithinApplication} it exposes. - * - *

    This method is typically called by the {@code DispatcherServlet} to + *

    This method is typically called by the {@code DispatcherServlet} to determine * if any {@code HandlerMapping} indicates that it uses parsed patterns. * After that the pre-parsed and cached {@code RequestPath} can be accessed * through {@link #getParsedRequestPath(ServletRequest)}. diff --git a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java index 8a0e76127ae8..6e64f214863d 100644 --- a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java @@ -757,7 +757,6 @@ public static MultiValueMap parseMatrixVariables(String matrixVa * {@code "Forwarded"} and {@code "X-Forwarded-*"} headers that specify the * client-originated address. Consider using the {@code ForwardedHeaderFilter} * to extract and use, or to discard such headers. - * * @return {@code true} if the request origin is valid, {@code false} otherwise * @since 4.1.5 * @see RFC 6454: The Web Origin Concept diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/PathPatternParser.java b/spring-web/src/main/java/org/springframework/web/util/pattern/PathPatternParser.java index 7843a05b7521..12488ffa4be9 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/PathPatternParser.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/PathPatternParser.java @@ -44,12 +44,10 @@ public class PathPatternParser { /** * Whether a {@link PathPattern} produced by this parser should * automatically match request paths with a trailing slash. - * *

    If set to {@code true} a {@code PathPattern} without a trailing slash * will also match request paths with a trailing slash. If set to * {@code false} a {@code PathPattern} will only match request paths with * a trailing slash. - * *

    The default is {@code true}. */ public void setMatchOptionalTrailingSeparator(boolean matchOptionalTrailingSeparator) { diff --git a/spring-web/src/test/java/org/springframework/http/client/reactive/ReactorResourceFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/reactive/ReactorResourceFactoryTests.java index 1924e319f026..d85b08194558 100644 --- a/spring-web/src/test/java/org/springframework/http/client/reactive/ReactorResourceFactoryTests.java +++ b/spring-web/src/test/java/org/springframework/http/client/reactive/ReactorResourceFactoryTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.http.client.reactive; import java.time.Duration; diff --git a/spring-web/src/test/java/org/springframework/http/codec/CancelWithoutDemandCodecTests.java b/spring-web/src/test/java/org/springframework/http/codec/CancelWithoutDemandCodecTests.java index 2935e9fa2337..8fad5f68ede9 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/CancelWithoutDemandCodecTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/CancelWithoutDemandCodecTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.http.codec; import java.time.Duration; diff --git a/spring-web/src/test/java/org/springframework/http/codec/ResourceHttpMessageReaderTests.java b/spring-web/src/test/java/org/springframework/http/codec/ResourceHttpMessageReaderTests.java index 151eae3288d0..fad3a3c095a9 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/ResourceHttpMessageReaderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/ResourceHttpMessageReaderTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.http.codec; import java.io.IOException; diff --git a/spring-web/src/test/java/org/springframework/http/codec/multipart/PartHttpMessageWriterTests.java b/spring-web/src/test/java/org/springframework/http/codec/multipart/PartHttpMessageWriterTests.java index c519b83d827a..6fe88f458b1c 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/multipart/PartHttpMessageWriterTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/multipart/PartHttpMessageWriterTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.http.codec.multipart; import java.nio.charset.StandardCharsets; diff --git a/spring-web/src/test/java/org/springframework/http/server/DefaultRequestPathTests.java b/spring-web/src/test/java/org/springframework/http/server/DefaultRequestPathTests.java index 3fa688017169..71a4bacd4f7c 100644 --- a/spring-web/src/test/java/org/springframework/http/server/DefaultRequestPathTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/DefaultRequestPathTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.http.server; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/HttpHeadResponseDecoratorTests.java b/spring-web/src/test/java/org/springframework/http/server/reactive/HttpHeadResponseDecoratorTests.java index 479bc3fc1116..182016ecea6e 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/HttpHeadResponseDecoratorTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/HttpHeadResponseDecoratorTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.http.server.reactive; import java.nio.charset.StandardCharsets; diff --git a/spring-web/src/test/java/org/springframework/web/cors/reactive/CorsWebFilterTests.java b/spring-web/src/test/java/org/springframework/web/cors/reactive/CorsWebFilterTests.java index 2a269ad5534b..dc8069cdbb68 100644 --- a/spring-web/src/test/java/org/springframework/web/cors/reactive/CorsWebFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/cors/reactive/CorsWebFilterTests.java @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.web.cors.reactive; +package org.springframework.web.cors.reactive; import java.io.IOException; import java.util.Arrays; diff --git a/spring-web/src/test/java/org/springframework/web/filter/ContentCachingResponseWrapperTests.java b/spring-web/src/test/java/org/springframework/web/filter/ContentCachingResponseWrapperTests.java index 576d0287d17b..464198916a07 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/ContentCachingResponseWrapperTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/ContentCachingResponseWrapperTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.filter; import java.nio.charset.StandardCharsets; diff --git a/spring-web/src/test/java/org/springframework/web/method/HandlerTypePredicateTests.java b/spring-web/src/test/java/org/springframework/web/method/HandlerTypePredicateTests.java index 144bb4e36fd3..c43e77377514 100644 --- a/spring-web/src/test/java/org/springframework/web/method/HandlerTypePredicateTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/HandlerTypePredicateTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.method; import java.util.function.Predicate; diff --git a/spring-web/src/test/java/org/springframework/web/server/session/CookieWebSessionIdResolverTests.java b/spring-web/src/test/java/org/springframework/web/server/session/CookieWebSessionIdResolverTests.java index 71d950c736ce..68fdb229cd03 100644 --- a/spring-web/src/test/java/org/springframework/web/server/session/CookieWebSessionIdResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/server/session/CookieWebSessionIdResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.server.session; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/server/session/HeaderWebSessionIdResolverTests.java b/spring-web/src/test/java/org/springframework/web/server/session/HeaderWebSessionIdResolverTests.java index a787356f6ff1..e2209af98263 100644 --- a/spring-web/src/test/java/org/springframework/web/server/session/HeaderWebSessionIdResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/server/session/HeaderWebSessionIdResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.server.session; import org.junit.jupiter.api.Test; diff --git a/spring-web/src/test/java/org/springframework/web/util/ServletRequestPathUtilsTests.java b/spring-web/src/test/java/org/springframework/web/util/ServletRequestPathUtilsTests.java index 6814bd55df70..0e84f13ee8f6 100644 --- a/spring-web/src/test/java/org/springframework/web/util/ServletRequestPathUtilsTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/ServletRequestPathUtilsTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.util; import javax.servlet.http.MappingMatch; diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/server/MockServerWebExchange.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/server/MockServerWebExchange.java index 000eadd6a244..82635bd18133 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/server/MockServerWebExchange.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/server/MockServerWebExchange.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.testfixture.server; import reactor.core.publisher.Mono; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/ParameterContentTypeResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/ParameterContentTypeResolver.java index 12bd6b408238..d0ac319ec086 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/ParameterContentTypeResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/ParameterContentTypeResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.accept; import java.util.ArrayList; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistration.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistration.java index 45556ce4c0fc..8ee0e87eafb1 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistration.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistration.java @@ -75,15 +75,13 @@ public ResourceHandlerRegistration(ResourceLoader resourceLoader, String... path /** * Add one or more resource locations from which to serve static content. - * Each location must point to a valid directory. Multiple locations may + *

    Each location must point to a valid directory. Multiple locations may * be specified as a comma-separated list, and the locations will be checked * for a given resource in the order specified. - * - *

    For example, {{@code "/"}, - * {@code "classpath:/META-INF/public-web-resources/"}} allows resources to - * be served both from the web application root and from any JAR on the - * classpath that contains a {@code /META-INF/public-web-resources/} directory, - * with resources in the web application root taking precedence. + *

    For example, {@code "/", "classpath:/META-INF/public-web-resources/"} + * allows resources to be served both from the web application root and from + * any JAR on the classpath that contains a {@code /META-INF/public-web-resources/} + * directory, with resources in the web application root taking precedence. * @return the same {@link ResourceHandlerRegistration} instance, for * chained method invocation */ diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunction.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunction.java index d11bc4eabca9..7203b38e9a34 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunction.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunction.java @@ -45,7 +45,6 @@ public interface ExchangeFilterFunction { * always consume its content or otherwise propagate it downstream for * further handling, for example by the {@link WebClient}. Please, see the * reference documentation for more details on this. - * * @param request the current request * @param next the next exchange function in the chain * @return the filtered response diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFunction.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFunction.java index 6d35b6594cc5..fddb3389c56a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFunction.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFunction.java @@ -50,7 +50,6 @@ public interface ExchangeFunction { * propagate it downstream for further handling, for example by the * {@link WebClient}. Please, see the reference documentation for more * details on this. - * * @param request the request to exchange * @return the delayed response */ diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java index 6b72b545d934..d2c68f6760fe 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -796,10 +796,10 @@ public void accept(Visitor visitor) { @Override public void changeParser(PathPatternParser parser) { if (this.left instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) left).changeParser(parser); + ((ChangePathPatternParserVisitor.Target) this.left).changeParser(parser); } if (this.right instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) right).changeParser(parser); + ((ChangePathPatternParserVisitor.Target) this.right).changeParser(parser); } } @@ -841,7 +841,7 @@ public void accept(Visitor visitor) { @Override public void changeParser(PathPatternParser parser) { if (this.delegate instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) delegate).changeParser(parser); + ((ChangePathPatternParserVisitor.Target) this.delegate).changeParser(parser); } } @@ -908,10 +908,10 @@ public void accept(Visitor visitor) { @Override public void changeParser(PathPatternParser parser) { if (this.left instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) left).changeParser(parser); + ((ChangePathPatternParserVisitor.Target) this.left).changeParser(parser); } if (this.right instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) right).changeParser(parser); + ((ChangePathPatternParserVisitor.Target) this.right).changeParser(parser); } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java index 9395f4287a67..51c654fd653c 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java @@ -265,7 +265,6 @@ interface HeadersBuilder> { /** * Set the set of allowed {@link HttpMethod HTTP methods}, as specified * by the {@code Allow} header. - * * @param allowedMethods the allowed methods * @return this builder * @see HttpHeaders#setAllow(Set) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceTransformerSupport.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceTransformerSupport.java index 628e12fe90f7..e9f34b874751 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceTransformerSupport.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceTransformerSupport.java @@ -89,7 +89,6 @@ protected Mono resolveUrlPath(String resourcePath, ServerWebExchange exc * Transform the given relative request path to an absolute path, * taking the path of the given request as a point of reference. * The resulting path is also cleaned from sequences like "path/..". - * * @param path the relative path to transform * @param exchange the current exchange * @return the absolute request path for the given resource path diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ArgumentResolverConfigurer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ArgumentResolverConfigurer.java index b7b3ee6fd160..749b0a780114 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ArgumentResolverConfigurer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ArgumentResolverConfigurer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.method.annotation; import java.util.ArrayList; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/SessionAttributesHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/SessionAttributesHandler.java index 9acbe85ec0ff..2ecc6881b4cc 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/SessionAttributesHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/SessionAttributesHandler.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.method.annotation; import java.util.Collections; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/Rendering.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/Rendering.java index 2376f97ee163..9bd56f965bab 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/Rendering.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/Rendering.java @@ -149,7 +149,6 @@ interface RedirectBuilder extends Builder { * Whether to the provided redirect URL should be prepended with the * application context path (if any). *

    By default this is set to {@code true}. - * * @see RedirectView#setContextRelative(boolean) */ RedirectBuilder contextRelative(boolean contextRelative); @@ -158,7 +157,6 @@ interface RedirectBuilder extends Builder { * Whether to append the query string of the current URL to the target * redirect URL or not. *

    By default this is set to {@code false}. - * * @see RedirectView#setPropagateQuery(boolean) */ RedirectBuilder propagateQuery(boolean propagate); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestDataValueProcessor.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestDataValueProcessor.java index c3b084b7b0f1..fee25884cddf 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestDataValueProcessor.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestDataValueProcessor.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.view; import java.util.Map; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketHandler.java index 85e7b232af49..616931ebda3d 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ * *

      * class ExampleHandler implements WebSocketHandler {
    -
    + *
      * 	@Override
      * 	public Mono<Void> handle(WebSocketSession session) {
      *
    @@ -63,7 +63,7 @@
      *
      * 
      * class ExampleHandler implements WebSocketHandler {
    -
    + *
      * 	@Override
      * 	public Mono<Void> handle(WebSocketSession session) {
      *
    @@ -110,7 +110,6 @@ default List getSubProtocols() {
     	 *
     	 * 

    See the class-level doc and the reference manual for more details and * examples of how to handle the session. - * * @param session the session to handle * @return indicates when application handling of the session is complete, * which should reflect the completion of the inbound message stream diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketMessage.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketMessage.java index 7d2d3d8136a4..32175f160b54 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketMessage.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketMessage.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket; import java.nio.charset.Charset; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketSession.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketSession.java index b3e3053ab4dd..d0113770e2e8 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketSession.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketSession.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket; import java.util.Map; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/ContextWebSocketHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/ContextWebSocketHandler.java index 816dc147bd57..f58af98ff1bc 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/ContextWebSocketHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/ContextWebSocketHandler.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket.adapter; import java.util.List; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/WebSocketClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/WebSocketClient.java index ce561705a6d3..19de63694ee7 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/WebSocketClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/WebSocketClient.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket.client; import java.net.URI; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/support/WebSocketHandlerAdapter.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/support/WebSocketHandlerAdapter.java index a2b01c6afd08..a988a2e23647 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/support/WebSocketHandlerAdapter.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/support/WebSocketHandlerAdapter.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket.server.support; import reactor.core.publisher.Mono; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/accept/ParameterContentTypeResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/accept/ParameterContentTypeResolverTests.java index 70f8a8e7741d..0df725357b80 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/accept/ParameterContentTypeResolverTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/accept/ParameterContentTypeResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.accept; import java.util.Collections; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilderTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilderTests.java index 2020bc23686d..f4b7dc36fab5 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilderTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilderTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.accept; import java.util.Collections; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/config/ViewResolverRegistryTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/config/ViewResolverRegistryTests.java index 93a93eb99071..1f69cb33f35f 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/config/ViewResolverRegistryTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/config/ViewResolverRegistryTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.config; import java.util.List; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/handler/CorsUrlHandlerMappingTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/handler/CorsUrlHandlerMappingTests.java index 7f10816c408e..7616980a4bbc 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/handler/CorsUrlHandlerMappingTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/handler/CorsUrlHandlerMappingTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.handler; import java.util.Collections; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/PathResourceResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/PathResourceResolverTests.java index 8ec93d52e369..b9da1c45c623 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/PathResourceResolverTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/PathResourceResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.resource; import java.io.IOException; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MatrixVariablesMapMethodArgumentResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MatrixVariablesMapMethodArgumentResolverTests.java index 1b41388d1307..a6dfd8554b80 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MatrixVariablesMapMethodArgumentResolverTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MatrixVariablesMapMethodArgumentResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.method.annotation; import java.time.Duration; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MatrixVariablesMethodArgumentResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MatrixVariablesMethodArgumentResolverTests.java index ac1e9aaade4b..419ed2eab766 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MatrixVariablesMethodArgumentResolverTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MatrixVariablesMethodArgumentResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.method.annotation; import java.time.Duration; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/WebSessionMethodArgumentResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/WebSessionMethodArgumentResolverTests.java index c304f5c36e34..1914b8c41da8 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/WebSessionMethodArgumentResolverTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/WebSessionMethodArgumentResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.method.annotation; import io.reactivex.rxjava3.core.Single; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/ZeroDemandResponse.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/ZeroDemandResponse.java index 59b3c9460281..d0bd3bd6b511 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/ZeroDemandResponse.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/ZeroDemandResponse.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.view; import java.util.function.Supplier; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/socket/server/support/WebSocketUpgradeHandlerPredicateTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/socket/server/support/WebSocketUpgradeHandlerPredicateTests.java index 2e06acd07232..e0b98eb40226 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/socket/server/support/WebSocketUpgradeHandlerPredicateTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/socket/server/support/WebSocketUpgradeHandlerPredicateTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket.server.support; import java.util.Collections; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/socket/server/upgrade/ReactorNettyRequestUpgradeStrategyTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/socket/server/upgrade/ReactorNettyRequestUpgradeStrategyTests.java index 409dc06b20d1..b397f22a25bc 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/socket/server/upgrade/ReactorNettyRequestUpgradeStrategyTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/socket/server/upgrade/ReactorNettyRequestUpgradeStrategyTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket.server.upgrade; import org.junit.jupiter.api.Test; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java index 26f76e7ca0ab..6b0a5a45666a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.function; import java.io.IOException; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java index 664d6a851dc1..febe35bb1fd6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -794,10 +794,10 @@ public void accept(Visitor visitor) { @Override public void changeParser(PathPatternParser parser) { if (this.left instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) left).changeParser(parser); + ((ChangePathPatternParserVisitor.Target) this.left).changeParser(parser); } if (this.right instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) right).changeParser(parser); + ((ChangePathPatternParserVisitor.Target) this.right).changeParser(parser); } } @@ -839,7 +839,7 @@ public void accept(Visitor visitor) { @Override public void changeParser(PathPatternParser parser) { if (this.delegate instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) delegate).changeParser(parser); + ((ChangePathPatternParserVisitor.Target) this.delegate).changeParser(parser); } } @@ -906,10 +906,10 @@ public void accept(Visitor visitor) { @Override public void changeParser(PathPatternParser parser) { if (this.left instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) left).changeParser(parser); + ((ChangePathPatternParserVisitor.Target) this.left).changeParser(parser); } if (this.right instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) right).changeParser(parser); + ((ChangePathPatternParserVisitor.Target) this.right).changeParser(parser); } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java index 6bbb3a43391e..d8f2f2d013c1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java @@ -85,7 +85,6 @@ default HttpMethod method() { /** * Get a {@code UriBuilderComponents} from the URI associated with this * {@code ServerRequest}. - * * @return a URI builder */ UriBuilder uriBuilder(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java index 11efe5b02232..2c1479ca70f3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java @@ -367,7 +367,6 @@ interface HeadersBuilder> { /** * Set the set of allowed {@link HttpMethod HTTP methods}, as specified * by the {@code Allow} header. - * * @param allowedMethods the allowed methods * @return this builder * @see HttpHeaders#setAllow(Set) @@ -492,7 +491,6 @@ interface BodyBuilder extends HeadersBuilder { /** * Set the body of the response to the given {@code Object} and return it. The parameter * {@code bodyType} is used to capture the generic type. - * * @param body the body of the response * @param bodyType the type of the body, used to capture the generic type * @return the built response diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/PathPatternMatchableHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/PathPatternMatchableHandlerMapping.java index 4b7a906732bb..91a3c43908a7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/PathPatternMatchableHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/PathPatternMatchableHandlerMapping.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.handler; import java.util.Map; 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 7c60bee6675a..f6b2bf26c68a 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 @@ -353,7 +353,6 @@ public static UriComponentsBuilder fromMethodCall(UriComponentsBuilder builder, *

    *

    Note: This method extracts values from "Forwarded" * and "X-Forwarded-*" headers if found. See class-level docs. - * * @param controllerType the target controller */ public static T on(Class controllerType) { @@ -423,7 +422,6 @@ public static T controller(Class controllerType) { * *

    Note: This method extracts values from "Forwarded" * and "X-Forwarded-*" headers if found. See class-level docs. - * * @param mappingName the mapping name * @return a builder to prepare the URI String * @throws IllegalArgumentException if the mapping name is not found or diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/StreamingResponseBody.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/StreamingResponseBody.java index 830269f5d6a7..eb307b4a62ab 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/StreamingResponseBody.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/StreamingResponseBody.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.mvc.method.annotation; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/MappedInterceptorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/MappedInterceptorTests.java index d404c32346ab..799969a25e8d 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/MappedInterceptorTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/MappedInterceptorTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.handler; import java.util.Comparator; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/PathPatternsTestUtils.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/PathPatternsTestUtils.java index cf034fd1608a..04291a3c9ded 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/PathPatternsTestUtils.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/PathPatternsTestUtils.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.handler; import java.util.function.Consumer; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitterTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitterTests.java index 6b6e35d4f3e1..47844e7e00ec 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitterTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitterTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.mvc.method.annotation; import java.io.IOException; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/PathResourceResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/PathResourceResolverTests.java index a4a931900747..c67b360b0c75 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/PathResourceResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/PathResourceResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.resource; import java.io.IOException; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceTransformerSupportTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceTransformerSupportTests.java index 0e6da211e4ec..0f3215838d6e 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceTransformerSupportTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceTransformerSupportTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.resource; import java.util.ArrayList; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java index 0e7ba7745869..bcec3b51ed18 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.resource; import java.io.IOException; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/VersionResourceResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/VersionResourceResolverTests.java index dde2a6f8e3c9..740548a336ab 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/VersionResourceResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/VersionResourceResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.resource; import java.util.ArrayList; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/MockFilterRegistration.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/MockFilterRegistration.java index 59443780c583..273197f0b8a2 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/MockFilterRegistration.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/MockFilterRegistration.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.support; import java.util.Collection; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/WebContentGeneratorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/WebContentGeneratorTests.java index bcfe10c061a3..531d5ebdb800 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/WebContentGeneratorTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/WebContentGeneratorTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.support; import java.util.Arrays; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewResolverTests.java index 11515bc2215d..6e3349887428 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.view.tiles3; import java.util.Locale; @@ -69,4 +70,5 @@ public void testResolve() throws Exception { verify(this.renderer).isRenderable(eq("/template.test"), isA(Request.class)); verify(this.renderer).isRenderable(eq("/nonexistent.test"), isA(Request.class)); } + } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewTests.java index 90cb4d6171d7..c588e3a06aa7 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.view.tiles3; import java.util.HashMap; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/StompWebSocketEndpointRegistration.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/StompWebSocketEndpointRegistration.java index e00ecdb924e5..c28ba61ea278 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/StompWebSocketEndpointRegistration.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/StompWebSocketEndpointRegistration.java @@ -61,7 +61,6 @@ public interface StompWebSocketEndpointRegistration { * that do not allow to check request origin (Iframe based transports) are * disabled. As a consequence, IE 6 to 9 are not supported when origins are * restricted. - * * @since 4.1.2 * @see #setAllowedOriginPatterns(String...) * @see RFC 6454: The Web Origin Concept diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistration.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistration.java index cf145dd71ae0..19ed6bfacb77 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistration.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistration.java @@ -63,7 +63,6 @@ public interface WebSocketHandlerRegistration { * that do not allow to check request origin (Iframe based transports) are * disabled. As a consequence, IE 6 to 9 are not supported when origins are * restricted. - * * @since 4.1.2 * @see #setAllowedOriginPatterns(String...) * @see RFC 6454: The Web Origin Concept diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/OriginHandshakeInterceptor.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/OriginHandshakeInterceptor.java index 245e43340709..5e3cc4d8dda3 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/OriginHandshakeInterceptor.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/OriginHandshakeInterceptor.java @@ -82,7 +82,6 @@ public OriginHandshakeInterceptor(Collection allowedOrigins) { * that do not allow to check request origin (Iframe based transports) are * disabled. As a consequence, IE 6 to 9 are not supported when origins are * restricted. - * * @see #setAllowedOriginPatterns(Collection) * @see RFC 6454: The Web Origin Concept */ diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java index e3a941937107..84502556bd65 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java @@ -325,7 +325,6 @@ public boolean shouldSuppressCors() { * that do not allow to check request origin (Iframe based transports) are * disabled. As a consequence, IE 6 to 9 are not supported when origins are * restricted. - * * @since 4.1.2 * @see #setAllowedOriginPatterns(Collection) * @see RFC 6454: The Web Origin Concept diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/handler/BlockingWebSocketSession.java b/spring-websocket/src/test/java/org/springframework/web/socket/handler/BlockingWebSocketSession.java index 6e592719becb..793d5bfe47ef 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/handler/BlockingWebSocketSession.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/handler/BlockingWebSocketSession.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.socket.handler; import java.io.IOException; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/messaging/OrderedMessageSendingIntegrationTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/messaging/OrderedMessageSendingIntegrationTests.java index 5f8cf79331f9..0db9c71debae 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/messaging/OrderedMessageSendingIntegrationTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/messaging/OrderedMessageSendingIntegrationTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.socket.messaging; import java.nio.charset.StandardCharsets; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompSubProtocolErrorHandlerTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompSubProtocolErrorHandlerTests.java index b204b03b5d87..66526090f8bc 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompSubProtocolErrorHandlerTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompSubProtocolErrorHandlerTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.socket.messaging; import org.junit.jupiter.api.BeforeEach; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/server/support/WebSocketHandlerMappingTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/server/support/WebSocketHandlerMappingTests.java index b5ec3cdfdbd9..30e9aab5be4b 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/server/support/WebSocketHandlerMappingTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/server/support/WebSocketHandlerMappingTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.socket.server.support; import java.util.Collections; diff --git a/src/checkstyle/checkstyle.xml b/src/checkstyle/checkstyle.xml index 96d98fb239a7..6358bc47e753 100644 --- a/src/checkstyle/checkstyle.xml +++ b/src/checkstyle/checkstyle.xml @@ -144,9 +144,7 @@ - - From bfdc99ab799f652f33379bf8cc50d0cc5d08fd8a Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 28 Sep 2021 11:43:40 +0200 Subject: [PATCH 158/735] Fix Javadoc errors See gh-27480 --- .../autoproxy/BeanNameAutoProxyCreator.java | 2 +- .../groovy/GroovyBeanDefinitionReader.java | 10 +-- .../context/annotation/Configuration.java | 10 +-- .../annotation/EnableAspectJAutoProxy.java | 4 +- .../GenericGroovyApplicationContext.java | 12 +-- ...ReloadableResourceBundleMessageSource.java | 4 +- .../DefaultFormattingConversionService.java | 4 +- .../springframework/validation/Validator.java | 6 +- .../core/env/CommandLinePropertySource.java | 6 +- .../env/JOptCommandLinePropertySource.java | 4 +- .../env/SimpleCommandLinePropertySource.java | 4 +- .../jms/annotation/EnableJms.java | 8 +- .../handler/AbstractMessageCondition.java | 4 +- .../orm/hibernate5/HibernateOperations.java | 8 +- .../org/springframework/http/HttpStatus.java | 6 +- .../json/Jackson2ObjectMapperBuilder.java | 2 +- .../json/Jackson2ObjectMapperFactoryBean.java | 84 +++++++++---------- .../springframework/web/util/HtmlUtils.java | 22 ++--- .../springframework/web/util/UriTemplate.java | 6 +- .../springframework/web/util/UriUtils.java | 6 +- .../condition/CompositeRequestCondition.java | 4 +- .../condition/HeadersRequestCondition.java | 4 +- .../condition/ParamsRequestCondition.java | 4 +- .../condition/CompositeRequestCondition.java | 4 +- .../condition/HeadersRequestCondition.java | 4 +- .../mvc/condition/ParamsRequestCondition.java | 4 +- .../annotation/MvcUriComponentsBuilder.java | 2 +- .../web/servlet/tags/UrlTag.java | 2 +- 28 files changed, 120 insertions(+), 120 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/BeanNameAutoProxyCreator.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/BeanNameAutoProxyCreator.java index 8c49d4ff7d28..297ab0cd1f63 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/BeanNameAutoProxyCreator.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/BeanNameAutoProxyCreator.java @@ -61,7 +61,7 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator { * FactoryBean will get proxied. This default behavior applies as of Spring 2.0. * If you intend to proxy a FactoryBean instance itself (a rare use case, but * Spring 1.2's default behavior), specify the bean name of the FactoryBean - * including the factory-bean prefix "&": e.g. "&myFactoryBean". + * including the factory-bean prefix "&": e.g. "&myFactoryBean". * @see org.springframework.beans.factory.FactoryBean * @see org.springframework.beans.factory.BeanFactory#FACTORY_BEAN_PREFIX */ diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java b/spring-beans/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java index da1ebc58c5fd..9ef7aa3799f3 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java @@ -75,18 +75,18 @@ * * def reader = new GroovyBeanDefinitionReader(myApplicationContext) * reader.beans { - * dataSource(BasicDataSource) { // <--- invokeMethod + * dataSource(BasicDataSource) { // <--- invokeMethod * driverClassName = "org.hsqldb.jdbcDriver" * url = "jdbc:hsqldb:mem:grailsDB" - * username = "sa" // <-- setProperty + * username = "sa" // <-- setProperty * password = "" * settings = [mynew:"setting"] * } * sessionFactory(SessionFactory) { - * dataSource = dataSource // <-- getProperty for retrieving references + * dataSource = dataSource // <-- getProperty for retrieving references * } * myService(MyService) { - * nestedBean = { AnotherBean bean -> // <-- setProperty with closure for nested bean + * nestedBean = { AnotherBean bean -> // <-- setProperty with closure for nested bean * dataSource = dataSource * } * } @@ -113,7 +113,7 @@ * dataSource = dataSource * } * myService(MyService) { - * nestedBean = { AnotherBean bean -> + * nestedBean = { AnotherBean bean -> * dataSource = dataSource * } * } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java b/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java index 725999d89c82..39856654f907 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -129,7 +129,7 @@ * @Configuration * public class AppConfig { * - * @Autowired Environment env; + * @Autowired Environment env; * * @Bean * public MyBean myBean() { @@ -149,7 +149,7 @@ * @PropertySource("classpath:/com/acme/app.properties") * public class AppConfig { * - * @Inject Environment env; + * @Inject Environment env; * * @Bean * public MyBean myBean() { @@ -170,7 +170,7 @@ * @PropertySource("classpath:/com/acme/app.properties") * public class AppConfig { * - * @Value("${bean.name}") String beanName; + * @Value("${bean.name}") String beanName; * * @Bean * public MyBean myBean() { @@ -297,7 +297,7 @@ * @ImportResource("classpath:/com/acme/database-config.xml") * public class AppConfig { * - * @Inject DataSource dataSource; // from XML + * @Inject DataSource dataSource; // from XML * * @Bean * public MyBean myBean() { diff --git a/spring-context/src/main/java/org/springframework/context/annotation/EnableAspectJAutoProxy.java b/spring-context/src/main/java/org/springframework/context/annotation/EnableAspectJAutoProxy.java index 8e2646340668..62cb6404c493 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/EnableAspectJAutoProxy.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/EnableAspectJAutoProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -98,7 +98,7 @@ * @EnableAspectJAutoProxy * public class AppConfig { * - * // no explicit @Bean definitions required + * // no explicit @Bean definitions required * }

    * * Note: {@code @EnableAspectJAutoProxy} applies to its local application context only, diff --git a/spring-context/src/main/java/org/springframework/context/support/GenericGroovyApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/GenericGroovyApplicationContext.java index 8e1f74ba45d8..4f4c07017347 100644 --- a/spring-context/src/main/java/org/springframework/context/support/GenericGroovyApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/GenericGroovyApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,18 +46,18 @@ * * def context = new GenericGroovyApplicationContext() * context.reader.beans { - * dataSource(BasicDataSource) { // <--- invokeMethod + * dataSource(BasicDataSource) { // <--- invokeMethod * driverClassName = "org.hsqldb.jdbcDriver" * url = "jdbc:hsqldb:mem:grailsDB" - * username = "sa" // <-- setProperty + * username = "sa" // <-- setProperty * password = "" * settings = [mynew:"setting"] * } * sessionFactory(SessionFactory) { - * dataSource = dataSource // <-- getProperty for retrieving references + * dataSource = dataSource // <-- getProperty for retrieving references * } * myService(MyService) { - * nestedBean = { AnotherBean bean -> // <-- setProperty with closure for nested bean + * nestedBean = { AnotherBean bean -> // <-- setProperty with closure for nested bean * dataSource = dataSource * } * } @@ -84,7 +84,7 @@ * dataSource = dataSource * } * myService(MyService) { - * nestedBean = { AnotherBean bean -> + * nestedBean = { AnotherBean bean -> * dataSource = dataSource * } * } diff --git a/spring-context/src/main/java/org/springframework/context/support/ReloadableResourceBundleMessageSource.java b/spring-context/src/main/java/org/springframework/context/support/ReloadableResourceBundleMessageSource.java index e7f78f83f647..6b6ff96af18e 100644 --- a/spring-context/src/main/java/org/springframework/context/support/ReloadableResourceBundleMessageSource.java +++ b/spring-context/src/main/java/org/springframework/context/support/ReloadableResourceBundleMessageSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -229,7 +229,7 @@ protected MessageFormat resolveCode(String code, Locale locale) { * for a Locale, after merging all specified resource bundles. * Either fetches the holder from the cache or freshly loads it. *

    Only used when caching resource bundle contents forever, i.e. - * with cacheSeconds < 0. Therefore, merged properties are always + * with cacheSeconds < 0. Therefore, merged properties are always * cached forever. */ protected PropertiesHolder getMergedProperties(Locale locale) { diff --git a/spring-context/src/main/java/org/springframework/format/support/DefaultFormattingConversionService.java b/spring-context/src/main/java/org/springframework/format/support/DefaultFormattingConversionService.java index 805a9828c4c5..3ffbba9ef09b 100644 --- a/spring-context/src/main/java/org/springframework/format/support/DefaultFormattingConversionService.java +++ b/spring-context/src/main/java/org/springframework/format/support/DefaultFormattingConversionService.java @@ -37,7 +37,7 @@ * as {@code DefaultConversionService} exposes its own * {@link DefaultConversionService#addDefaultConverters addDefaultConverters} method. * - *

    Automatically registers formatters for JSR-354 Money & Currency, JSR-310 Date-Time + *

    Automatically registers formatters for JSR-354 Money & Currency, JSR-310 Date-Time * and/or Joda-Time 2.x, depending on the presence of the corresponding API on the classpath. * * @author Chris Beams @@ -100,7 +100,7 @@ public DefaultFormattingConversionService( /** * Add formatters appropriate for most environments: including number formatters, - * JSR-354 Money & Currency formatters, JSR-310 Date-Time and/or Joda-Time formatters, + * JSR-354 Money & Currency formatters, JSR-310 Date-Time and/or Joda-Time formatters, * depending on the presence of the corresponding API on the classpath. * @param formatterRegistry the service to register default formatters with */ diff --git a/spring-context/src/main/java/org/springframework/validation/Validator.java b/spring-context/src/main/java/org/springframework/validation/Validator.java index d95b054872b4..b67b6d5d8b77 100644 --- a/spring-context/src/main/java/org/springframework/validation/Validator.java +++ b/spring-context/src/main/java/org/springframework/validation/Validator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ * wholly of whitespace), and that any password that is present is * at least {@code 'MINIMUM_PASSWORD_LENGTH'} characters in length. * - *

     public class UserLoginValidator implements Validator {
    + * 
    public class UserLoginValidator implements Validator {
      *
      *    private static final int MINIMUM_PASSWORD_LENGTH = 6;
      *
    @@ -46,7 +46,7 @@
      *       ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "field.required");
      *       UserLogin login = (UserLogin) target;
      *       if (login.getPassword() != null
    - *             && login.getPassword().trim().length() < MINIMUM_PASSWORD_LENGTH) {
    + *             && login.getPassword().trim().length() < MINIMUM_PASSWORD_LENGTH) {
      *          errors.rejectValue("password", "field.min.length",
      *                new Object[]{Integer.valueOf(MINIMUM_PASSWORD_LENGTH)},
      *                "The password must be at least [" + MINIMUM_PASSWORD_LENGTH + "] characters in length.");
    diff --git a/spring-core/src/main/java/org/springframework/core/env/CommandLinePropertySource.java b/spring-core/src/main/java/org/springframework/core/env/CommandLinePropertySource.java
    index 321629954d4b..a7ee178a3e41 100644
    --- a/spring-core/src/main/java/org/springframework/core/env/CommandLinePropertySource.java
    +++ b/spring-core/src/main/java/org/springframework/core/env/CommandLinePropertySource.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright 2002-2018 the original author or authors.
    + * Copyright 2002-2021 the original author or authors.
      *
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
    @@ -110,7 +110,7 @@
      * evaluate true:
      *
      * 
    - * CommandLinePropertySource ps = ...
    + * CommandLinePropertySource<?> ps = ...
      * assert ps.containsProperty("o1") == true;
      * assert ps.containsProperty("o2") == true;
      * assert ps.containsProperty("o3") == false;
    @@ -149,7 +149,7 @@
      * will evaluate true:
      *
      * 
    - * CommandLinePropertySource ps = ...
    + * CommandLinePropertySource<?> ps = ...
      * assert ps.containsProperty("o1") == true;
      * assert ps.containsProperty("o2") == true;
      * assert ps.containsProperty("nonOptionArgs") == true;
    diff --git a/spring-core/src/main/java/org/springframework/core/env/JOptCommandLinePropertySource.java b/spring-core/src/main/java/org/springframework/core/env/JOptCommandLinePropertySource.java
    index 64f67e3321b4..22353e098951 100644
    --- a/spring-core/src/main/java/org/springframework/core/env/JOptCommandLinePropertySource.java
    +++ b/spring-core/src/main/java/org/springframework/core/env/JOptCommandLinePropertySource.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright 2002-2018 the original author or authors.
    + * Copyright 2002-2021 the original author or authors.
      *
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
    @@ -42,7 +42,7 @@
      *     parser.accepts("option1");
      *     parser.accepts("option2").withRequiredArg();
      *     OptionSet options = parser.parse(args);
    - *     PropertySource ps = new JOptCommandLinePropertySource(options);
    + *     PropertySource<?> ps = new JOptCommandLinePropertySource(options);
      *     // ...
      * }
    * diff --git a/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLinePropertySource.java b/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLinePropertySource.java index a4a25397ac9f..c4f34a13e504 100644 --- a/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLinePropertySource.java +++ b/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLinePropertySource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,7 +66,7 @@ *

    Typical usage

    *
      * public static void main(String[] args) {
    - *     PropertySource ps = new SimpleCommandLinePropertySource(args);
    + *     PropertySource<?> ps = new SimpleCommandLinePropertySource(args);
      *     // ...
      * }
    * diff --git a/spring-jms/src/main/java/org/springframework/jms/annotation/EnableJms.java b/spring-jms/src/main/java/org/springframework/jms/annotation/EnableJms.java index 79c4a3bca051..e4d97367d1ff 100644 --- a/spring-jms/src/main/java/org/springframework/jms/annotation/EnableJms.java +++ b/spring-jms/src/main/java/org/springframework/jms/annotation/EnableJms.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -138,7 +138,7 @@ * } * * @Bean - * public JmsListenerContainerFactory myJmsListenerContainerFactory() { + * public JmsListenerContainerFactory<?> myJmsListenerContainerFactory() { * // factory settings * } * @@ -184,7 +184,7 @@ * } * * @Bean - * public JmsListenerEndpointRegistry myJmsListenerEndpointRegistry() { + * public JmsListenerEndpointRegistry<?> myJmsListenerEndpointRegistry() { * // registry configuration * } * @@ -246,7 +246,7 @@ * } * * @Bean - * public JmsListenerContainerFactory anotherJmsListenerContainerFactory() { + * public JmsListenerContainerFactory<?> anotherJmsListenerContainerFactory() { * // ... * } * diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/AbstractMessageCondition.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/AbstractMessageCondition.java index 835020e90f61..93bb26fcac18 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/AbstractMessageCondition.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/AbstractMessageCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +67,7 @@ public String toString() { /** * The notation to use when printing discrete items of content. - * For example " || " for URL patterns or " && " for param expressions. + * For example " || " for URL patterns or " && " for param expressions. */ protected abstract String getToStringInfix(); diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateOperations.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateOperations.java index fe2fd028b3c7..0bd481af29f9 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateOperations.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -606,7 +606,7 @@ public interface HibernateOperations { * @param firstResult the index of the first result object to be retrieved * (numbered from 0) * @param maxResults the maximum number of result objects to retrieve - * (or <=0 for no limit) + * (or <=0 for no limit) * @return a {@link List} containing 0 or more persistent instances * @throws DataAccessException in case of Hibernate errors * @see DetachedCriteria#getExecutableCriteria(org.hibernate.Session) @@ -643,7 +643,7 @@ public interface HibernateOperations { * @param firstResult the index of the first result object to be retrieved * (numbered from 0) * @param maxResults the maximum number of result objects to retrieve - * (or <=0 for no limit) + * (or <=0 for no limit) * @return a {@link List} containing 0 or more persistent instances * @throws DataAccessException in case of Hibernate errors * @see org.hibernate.criterion.Example#create(Object) @@ -660,7 +660,7 @@ public interface HibernateOperations { * @param firstResult the index of the first result object to be retrieved * (numbered from 0) * @param maxResults the maximum number of result objects to retrieve - * (or <=0 for no limit) + * (or <=0 for no limit) * @return a {@link List} containing 0 or more persistent instances * @throws DataAccessException in case of Hibernate errors * @see org.hibernate.criterion.Example#create(Object) diff --git a/spring-web/src/main/java/org/springframework/http/HttpStatus.java b/spring-web/src/main/java/org/springframework/http/HttpStatus.java index a02e5e1680a8..f6a9911d1ab5 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpStatus.java +++ b/spring-web/src/main/java/org/springframework/http/HttpStatus.java @@ -285,21 +285,21 @@ public enum HttpStatus { I_AM_A_TEAPOT(418, Series.CLIENT_ERROR, "I'm a teapot"), /** * @deprecated See - * + * * WebDAV Draft Changes */ @Deprecated INSUFFICIENT_SPACE_ON_RESOURCE(419, Series.CLIENT_ERROR, "Insufficient Space On Resource"), /** * @deprecated See - * + * * WebDAV Draft Changes */ @Deprecated METHOD_FAILURE(420, Series.CLIENT_ERROR, "Method Failure"), /** * @deprecated - * See + * See * WebDAV Draft Changes */ @Deprecated diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java index 415113ff0596..bdd1e577283a 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java @@ -83,7 +83,7 @@ *
  • jackson-datatype-jdk8: * support for other Java 8 types like {@link java.util.Optional}
  • *
  • jackson-datatype-jsr310: - * support for Java 8 Date & Time API types
  • + * support for Java 8 Date & Time API types *
  • jackson-datatype-joda: * support for Joda-Time types
  • *
  • jackson-module-kotlin: diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java index 57d3e63e184f..376e6b277372 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,54 +62,54 @@ *

    Example usage with * {@link MappingJackson2HttpMessageConverter}: * - *

    - * <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    - *   <property name="objectMapper">
    - *     <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
    + * 
    {@code
    + * 
    + *   
    + *     
    - *   </property>
    - * </bean>
    - * 
    + * + * + * }
    * *

    Example usage with MappingJackson2JsonView: * - *

    - * <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
    - *   <property name="objectMapper">
    - *     <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
    + * 
    {@code
    + * 
    + *   
    + *     
    - *       <property name="serializers">
    - *         <array>
    - *           <bean class="org.mycompany.MyCustomSerializer" />
    - *         </array>
    - *       </property>
    - *     </bean>
    - *   </property>
    - * </bean>
    - * 
    + * + * + * + * + * + * + * + * + * }
    * *

    In case there are no specific setters provided (for some rarely used options), * you can still use the more general methods {@link #setFeaturesToEnable} and * {@link #setFeaturesToDisable}. * - *

    - * <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
    - *   <property name="featuresToEnable">
    - *     <array>
    - *       <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.WRAP_ROOT_VALUE"/>
    - *       <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.CLOSE_CLOSEABLE"/>
    - *     </array>
    - *   </property>
    - *   <property name="featuresToDisable">
    - *     <array>
    - *       <util:constant static-field="com.fasterxml.jackson.databind.MapperFeature.USE_ANNOTATIONS"/>
    - *     </array>
    - *   </property>
    - * </bean>
    - * 
    + *
    {@code
    + * 
    + *   
    + *     
    + *       
    + *       
    + *     
    + *   
    + *   
    + *     
    + *       
    + *     
    + *   
    + * 
    + * }
    * *

    It also automatically registers the following well-known modules if they are * detected on the classpath: @@ -119,7 +119,7 @@ *

  • jackson-datatype-jdk8: * support for other Java 8 types like {@link java.util.Optional}
  • *
  • jackson-datatype-jsr310: - * support for Java 8 Date & Time API types
  • + * support for Java 8 Date & Time API types *
  • jackson-datatype-joda: * support for Joda-Time types
  • *
  • jackson-module-kotlin: @@ -129,11 +129,11 @@ *

    In case you want to configure Jackson's {@link ObjectMapper} with a custom {@link Module}, * you can register one or more such Modules by class name via {@link #setModulesToInstall}: * - *

    - * <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
    - *   <property name="modulesToInstall" value="myapp.jackson.MySampleModule,myapp.jackson.MyOtherModule"/>
    - * </bean
    - * 
    + *
    {@code
    + * 
    + *   
    + * 
      *
      * 

    Compatible with Jackson 2.9 to 2.12, as of Spring 5.3. * diff --git a/spring-web/src/main/java/org/springframework/web/util/HtmlUtils.java b/spring-web/src/main/java/org/springframework/web/util/HtmlUtils.java index 3cac0b07bbe2..07a200dc2011 100644 --- a/spring-web/src/main/java/org/springframework/web/util/HtmlUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/HtmlUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,7 +49,7 @@ public abstract class HtmlUtils { /** * Turn special characters into HTML character references. - *

    Handles complete character set defined in HTML 4.01 recommendation. + *

    Handles the complete character set defined in the HTML 4.01 recommendation. *

    Escapes all special characters to their corresponding * entity reference (e.g. {@code <}). *

    Reference: @@ -65,7 +65,7 @@ public static String htmlEscape(String input) { /** * Turn special characters into HTML character references. - *

    Handles complete character set defined in HTML 4.01 recommendation. + *

    Handles the complete character set defined in the HTML 4.01 recommendation. *

    Escapes all special characters to their corresponding * entity reference (e.g. {@code <}) at least as required by the * specified encoding. In other words, if a special character does @@ -98,9 +98,9 @@ public static String htmlEscape(String input, String encoding) { /** * Turn special characters into HTML character references. - *

    Handles complete character set defined in HTML 4.01 recommendation. + *

    Handles the complete character set defined in the HTML 4.01 recommendation. *

    Escapes all special characters to their corresponding numeric - * reference in decimal format (&#Decimal;). + * reference in decimal format (&#Decimal;). *

    Reference: * * https://www.w3.org/TR/html4/sgml/entities.html @@ -114,9 +114,9 @@ public static String htmlEscapeDecimal(String input) { /** * Turn special characters into HTML character references. - *

    Handles complete character set defined in HTML 4.01 recommendation. + *

    Handles the complete character set defined in the HTML 4.01 recommendation. *

    Escapes all special characters to their corresponding numeric - * reference in decimal format (&#Decimal;) at least as required by the + * reference in decimal format (&#Decimal;) at least as required by the * specified encoding. In other words, if a special character does * not have to be escaped for the given encoding, it may not be. *

    Reference: @@ -148,9 +148,9 @@ public static String htmlEscapeDecimal(String input, String encoding) { /** * Turn special characters into HTML character references. - *

    Handles complete character set defined in HTML 4.01 recommendation. + *

    Handles the complete character set defined in the HTML 4.01 recommendation. *

    Escapes all special characters to their corresponding numeric - * reference in hex format (&#xHex;). + * reference in hex format (&#xHex;). *

    Reference: * * https://www.w3.org/TR/html4/sgml/entities.html @@ -164,9 +164,9 @@ public static String htmlEscapeHex(String input) { /** * Turn special characters into HTML character references. - *

    Handles complete character set defined in HTML 4.01 recommendation. + *

    Handles the complete character set defined in the HTML 4.01 recommendation. *

    Escapes all special characters to their corresponding numeric - * reference in hex format (&#xHex;) at least as required by the + * reference in hex format (&#xHex;) at least as required by the * specified encoding. In other words, if a special character does * not have to be escaped for the given encoding, it may not be. *

    Reference: diff --git a/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java b/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java index 1abf615c8b85..770c6ad7498e 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -92,7 +92,7 @@ public List getVariableNames() { * UriTemplate template = new UriTemplate("https://example.com/hotels/{hotel}/bookings/{booking}"); * Map<String, String> uriVariables = new HashMap<String, String>(); * uriVariables.put("booking", "42"); - * uriVariables.put("hotel", "Rest & Relax"); + * uriVariables.put("hotel", "Rest & Relax"); * System.out.println(template.expand(uriVariables)); *

    * will print:
    {@code https://example.com/hotels/Rest%20%26%20Relax/bookings/42}
    @@ -113,7 +113,7 @@ public URI expand(Map uriVariables) { *

    Example: *

     	 * UriTemplate template = new UriTemplate("https://example.com/hotels/{hotel}/bookings/{booking}");
    -	 * System.out.println(template.expand("Rest & Relax", 42));
    +	 * System.out.println(template.expand("Rest & Relax", 42));
     	 * 
    * will print:
    {@code https://example.com/hotels/Rest%20%26%20Relax/bookings/42}
    * @param uriVariableValues the array of URI variables diff --git a/spring-web/src/main/java/org/springframework/web/util/UriUtils.java b/spring-web/src/main/java/org/springframework/web/util/UriUtils.java index 4697b3affc61..a67be402e567 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriUtils.java @@ -246,15 +246,15 @@ public static String encodeQueryParam(String queryParam, Charset charset) { * Encode the query parameters from the given {@code MultiValueMap} with UTF-8. *

    This can be used with {@link UriComponentsBuilder#queryParams(MultiValueMap)} * when building a URI from an already encoded template. - *

    -	 * MultiValueMap<String, String> params = new LinkedMultiValueMap<>(2);
    +	 * 
    {@code
    +	 * MultiValueMap params = new LinkedMultiValueMap<>(2);
     	 * // add to params...
     	 *
     	 * ServletUriComponentsBuilder.fromCurrentRequest()
     	 *         .queryParams(UriUtils.encodeQueryParams(params))
     	 *         .build(true)
     	 *         .toUriString();
    -	 * 
    + * }
    * @param params the parameters to encode * @return a new {@code MultiValueMap} with the encoded names and values * @since 5.2.3 diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/CompositeRequestCondition.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/CompositeRequestCondition.java index 003f47caa240..afaf28433e75 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/CompositeRequestCondition.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/CompositeRequestCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ /** * Implements the {@link RequestCondition} contract by delegating to multiple - * {@code RequestCondition} types and using a logical conjunction (' && ') to + * {@code RequestCondition} types and using a logical conjunction ({@code ' && '}) to * ensure all conditions match a given request. * *

    When {@code CompositeRequestCondition} instances are combined or compared diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/HeadersRequestCondition.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/HeadersRequestCondition.java index 229b610b8449..8a785dcb0ff5 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/HeadersRequestCondition.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/HeadersRequestCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import org.springframework.web.server.ServerWebExchange; /** - * A logical conjunction (' && ') request condition that matches a request against + * A logical conjunction ({@code ' && '}) request condition that matches a request against * a set of header expressions with syntax defined in {@link RequestMapping#headers()}. * *

    Expressions passed to the constructor with header names 'Accept' or diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/ParamsRequestCondition.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/ParamsRequestCondition.java index 9b1bc9f904ea..81ff4416ef95 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/ParamsRequestCondition.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/ParamsRequestCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import org.springframework.web.server.ServerWebExchange; /** - * A logical conjunction (' && ') request condition that matches a request against + * A logical conjunction ({@code ' && '}) request condition that matches a request against * a set parameter expressions with syntax defined in {@link RequestMapping#params()}. * * @author Rossen Stoyanchev diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/CompositeRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/CompositeRequestCondition.java index 5857fdc5eb56..d2bf8da0ac27 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/CompositeRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/CompositeRequestCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ /** * Implements the {@link RequestCondition} contract by delegating to multiple - * {@code RequestCondition} types and using a logical conjunction (' && ') to + * {@code RequestCondition} types and using a logical conjunction ({@code ' && '}) to * ensure all conditions match a given request. * *

    When {@code CompositeRequestCondition} instances are combined or compared diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/HeadersRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/HeadersRequestCondition.java index e3f1773318ee..2f7fac423f40 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/HeadersRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/HeadersRequestCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ import org.springframework.web.cors.CorsUtils; /** - * A logical conjunction (' && ') request condition that matches a request against + * A logical conjunction ({@code ' && '}) request condition that matches a request against * a set of header expressions with syntax defined in {@link RequestMapping#headers()}. * *

    Expressions passed to the constructor with header names 'Accept' or diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ParamsRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ParamsRequestCondition.java index f06f363aa2c3..ead4ec3d0495 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ParamsRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ParamsRequestCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ import org.springframework.web.util.WebUtils; /** - * A logical conjunction (' && ') request condition that matches a request against + * A logical conjunction ({@code ' && '}) request condition that matches a request against * a set parameter expressions with syntax defined in {@link RequestMapping#params()}. * * @author Arjen Poutsma 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 f6b2bf26c68a..db1ca29c5c4d 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 @@ -413,7 +413,7 @@ public static T controller(Class controllerType) { * A JSP can prepare a URL to the controller method as follows: * *

    -	 * <%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
    +	 * <%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
     	 *
     	 * <a href="${s:mvcUrl('PC#getPerson').arg(0,"123").build()}">Get Person</a>
     	 * 
    diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java index 079b3214846f..9b0043b3639b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java @@ -313,7 +313,7 @@ String createUrl() throws JspException { * @param usedParams set of parameter names that have been applied as * template params * @param includeQueryStringDelimiter true if the query string should start - * with a '?' instead of '&' + * with a '?' instead of '&' * @return the query string */ protected String createQueryString(List params, Set usedParams, boolean includeQueryStringDelimiter) From 93efb20a53365fea87cf3ef422f06959fcf9c313 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 28 Sep 2021 13:34:33 +0200 Subject: [PATCH 159/735] Fix broken links in Javadoc This commit removes several links that were broken due to the removal of various APIs in 6.0. See gh-27480 --- .../concurrent/ConcurrentMapCacheManager.java | 5 +- .../scheduling/SchedulingAwareRunnable.java | 9 +- .../scheduling/SchedulingTaskExecutor.java | 5 +- .../core/ConfigurableObjectInputStream.java | 8 +- .../springframework/core/io/VfsResource.java | 3 +- .../org/springframework/core/io/VfsUtils.java | 7 +- .../core/task/SimpleAsyncTaskExecutor.java | 3 +- .../DefaultMessageListenerContainer.java | 10 +- .../SimpleMessageListenerContainer.java | 3 +- .../support/converter/MessageConverter.java | 4 +- .../GenericMessageEndpointManager.java | 126 +++++++++--------- .../support/LocalConnectionFactoryBean.java | 8 +- .../json/Jackson2ObjectMapperFactoryBean.java | 80 ++++++----- .../web/HttpRequestHandler.java | 10 +- .../support/HttpRequestHandlerServlet.java | 9 +- .../web/multipart/MultipartFile.java | 3 - .../MultipartHttpServletRequest.java | 3 +- .../web/multipart/MultipartResolver.java | 7 +- .../AbstractMultipartHttpServletRequest.java | 6 +- .../DefaultMultipartHttpServletRequest.java | 4 +- .../StandardServletMultipartResolver.java | 19 +-- .../web/servlet/DispatcherServlet.java | 7 +- .../ViewResolversBeanDefinitionParser.java | 5 +- .../WebSphereRequestUpgradeStrategy.java | 4 +- 24 files changed, 150 insertions(+), 198 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java b/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java index aea913288d8b..8a29d1fd2900 100644 --- a/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java +++ b/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,8 +38,7 @@ *

    Note: This is by no means a sophisticated CacheManager; it comes with no * cache configuration options. However, it may be useful for testing or simple * caching scenarios. For advanced local caching needs, consider - * {@link org.springframework.cache.jcache.JCacheCacheManager}, - * {@link org.springframework.cache.ehcache.EhCacheCacheManager}, + * {@link org.springframework.cache.jcache.JCacheCacheManager} or * {@link org.springframework.cache.caffeine.CaffeineCacheManager}. * * @author Juergen Hoeller diff --git a/spring-context/src/main/java/org/springframework/scheduling/SchedulingAwareRunnable.java b/spring-context/src/main/java/org/springframework/scheduling/SchedulingAwareRunnable.java index d6de8c160aa1..09a54d2f44d3 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/SchedulingAwareRunnable.java +++ b/spring-context/src/main/java/org/springframework/scheduling/SchedulingAwareRunnable.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,22 +17,17 @@ package org.springframework.scheduling; /** - * Extension of the Runnable interface, adding special callbacks + * Extension of the {@link Runnable} interface, adding special callbacks * for long-running operations. * - *

    This interface closely corresponds to the CommonJ Work interface, - * but is kept separate to avoid a required CommonJ dependency. - * *

    Scheduling-capable TaskExecutors are encouraged to check a submitted * Runnable, detecting whether this interface is implemented and reacting * as appropriately as they are able to. * * @author Juergen Hoeller * @since 2.0 - * @see commonj.work.Work * @see org.springframework.core.task.TaskExecutor * @see SchedulingTaskExecutor - * @see org.springframework.scheduling.commonj.WorkManagerTaskExecutor */ public interface SchedulingAwareRunnable extends Runnable { diff --git a/spring-context/src/main/java/org/springframework/scheduling/SchedulingTaskExecutor.java b/spring-context/src/main/java/org/springframework/scheduling/SchedulingTaskExecutor.java index 2f1dd004aeb3..7f7d497eb1bb 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/SchedulingTaskExecutor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/SchedulingTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ * *

    Note: {@link SchedulingTaskExecutor} implementations are encouraged to also * implement the {@link org.springframework.core.task.AsyncListenableTaskExecutor} - * interface. This is not required due to the dependency on Spring 4.0's new + * interface. This is not required due to the dependency on Spring 4.0's * {@link org.springframework.util.concurrent.ListenableFuture} interface, * which would make it impossible for third-party executor implementations * to remain compatible with both Spring 4.0 and Spring 3.x. @@ -37,7 +37,6 @@ * @since 2.0 * @see SchedulingAwareRunnable * @see org.springframework.core.task.TaskExecutor - * @see org.springframework.scheduling.commonj.WorkManagerTaskExecutor */ public interface SchedulingTaskExecutor extends AsyncTaskExecutor { diff --git a/spring-core/src/main/java/org/springframework/core/ConfigurableObjectInputStream.java b/spring-core/src/main/java/org/springframework/core/ConfigurableObjectInputStream.java index 52c11eeddf2b..eb845e47977d 100644 --- a/spring-core/src/main/java/org/springframework/core/ConfigurableObjectInputStream.java +++ b/spring-core/src/main/java/org/springframework/core/ConfigurableObjectInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,12 +26,12 @@ import org.springframework.util.ClassUtils; /** - * Special ObjectInputStream subclass that resolves class names - * against a specific ClassLoader. Serves as base class for - * {@link org.springframework.remoting.rmi.CodebaseAwareObjectInputStream}. + * Special {@link ObjectInputStream} subclass that resolves class names + * against a specific {@link ClassLoader}. * * @author Juergen Hoeller * @since 2.5.5 + * @see org.springframework.core.serializer.DefaultDeserializer */ public class ConfigurableObjectInputStream extends ObjectInputStream { diff --git a/spring-core/src/main/java/org/springframework/core/io/VfsResource.java b/spring-core/src/main/java/org/springframework/core/io/VfsResource.java index 6751d60e699b..5caf8c5ff0e0 100644 --- a/spring-core/src/main/java/org/springframework/core/io/VfsResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/VfsResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,6 @@ * @author Costin Leau * @author Sam Brannen * @since 3.0 - * @see org.jboss.vfs.VirtualFile */ public class VfsResource extends AbstractResource { diff --git a/spring-core/src/main/java/org/springframework/core/io/VfsUtils.java b/spring-core/src/main/java/org/springframework/core/io/VfsUtils.java index c2e3c3537a71..1dad62fb18b0 100644 --- a/spring-core/src/main/java/org/springframework/core/io/VfsUtils.java +++ b/spring-core/src/main/java/org/springframework/core/io/VfsUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,8 +35,9 @@ * (package {@code org.jboss.vfs}) and is in particular compatible with * JBoss AS 7 and WildFly 8+. * - *

    Thanks go to Marius Bogoevici for the initial patch. - * Note: This is an internal class and should not be used outside the framework. + *

    Thanks go to Marius Bogoevici for the initial implementation. + * + *

    Note: This is an internal class and should not be used outside the framework. * * @author Costin Leau * @author Juergen Hoeller diff --git a/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java b/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java index fe0104f58982..035e87317758 100644 --- a/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java +++ b/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,7 +45,6 @@ * @see #setConcurrencyLimit * @see SyncTaskExecutor * @see org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - * @see org.springframework.scheduling.commonj.WorkManagerTaskExecutor */ @SuppressWarnings("serial") public class SimpleAsyncTaskExecutor extends CustomizableThreadCreator diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java index 41fc11034f65..4f2435ff5c74 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java @@ -62,11 +62,10 @@ * abstraction. By default, the specified number of invoker tasks will be created * on startup, according to the {@link #setConcurrentConsumers "concurrentConsumers"} * setting. Specify an alternative {@code TaskExecutor} to integrate with an existing - * thread pool facility (such as a Jakarta EE server's), for example using a - * {@link org.springframework.scheduling.commonj.WorkManagerTaskExecutor CommonJ WorkManager}. - * With a native JMS setup, each of those listener threads is going to use a - * cached JMS {@code Session} and {@code MessageConsumer} (only refreshed in case - * of failure), using the JMS provider's resources as efficiently as possible. + * thread pool facility (such as a Jakarta EE server's). With a native JMS setup, + * each of those listener threads is going to use a cached JMS {@code Session} and + * {@code MessageConsumer} (only refreshed in case of failure), using the JMS provider's + * resources as efficiently as possible. * *

    Message reception and listener execution can automatically be wrapped * in transactions by passing a Spring @@ -224,7 +223,6 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe * will occupy a number of threads for its entire lifetime. * @see #setConcurrentConsumers * @see org.springframework.core.task.SimpleAsyncTaskExecutor - * @see org.springframework.scheduling.commonj.WorkManagerTaskExecutor */ public void setTaskExecutor(Executor taskExecutor) { this.taskExecutor = taskExecutor; diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java index b45de7781a6f..12e4eba04543 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -177,7 +177,6 @@ public void setConcurrentConsumers(int concurrentConsumers) { * {@link jakarta.jms.MessageListener} will work fine, in general. * @see #setConcurrentConsumers * @see org.springframework.core.task.SimpleAsyncTaskExecutor - * @see org.springframework.scheduling.commonj.WorkManagerTaskExecutor */ public void setTaskExecutor(Executor taskExecutor) { this.taskExecutor = taskExecutor; diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageConverter.java index 433123d19535..23b1bdb2e8a2 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,8 +31,6 @@ * @since 1.1 * @see org.springframework.jms.core.JmsTemplate#setMessageConverter * @see org.springframework.jms.listener.adapter.MessageListenerAdapter#setMessageConverter - * @see org.springframework.jms.remoting.JmsInvokerClientInterceptor#setMessageConverter - * @see org.springframework.jms.remoting.JmsInvokerServiceExporter#setMessageConverter */ public interface MessageConverter { diff --git a/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java b/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java index 090c2a20a52e..97e0369ef17d 100644 --- a/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java +++ b/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,21 +39,22 @@ * *

      * <bean class="org.springframework.jca.endpoint.GenericMessageEndpointManager">
    - * 	 <property name="resourceAdapter" ref="resourceAdapter"/>
    - * 	 <property name="messageEndpointFactory">
    - *     <bean class="org.springframework.jca.endpoint.GenericMessageEndpointFactory">
    - *       <property name="messageListener" ref="messageListener"/>
    - *     </bean>
    - * 	 </property>
    - * 	 <property name="activationSpec">
    - *     <bean class="org.apache.activemq.ra.ActiveMQActivationSpec">
    - *       <property name="destination" value="myQueue"/>
    - *       <property name="destinationType" value="jakarta.jms.Queue"/>
    - *     </bean>
    - *   </property>
    - * </bean>
    + * <property name="resourceAdapter" ref="resourceAdapter"/> + * <property name="messageEndpointFactory"> + * <bean class="org.springframework.jca.endpoint.GenericMessageEndpointFactory"> + * <property name="messageListener" ref="messageListener"/> + * </bean> + * </property> + * <property name="activationSpec"> + * <bean class="org.apache.activemq.ra.ActiveMQActivationSpec"> + * <property name="destination" value="myQueue"/> + * <property name="destinationType" value="jakarta.jms.Queue"/> + * </bean> + * </property> + * </bean> + *
  • * - * In this example, Spring's own {@link GenericMessageEndpointFactory} is used + *

    In this example, Spring's own {@link GenericMessageEndpointFactory} is used * to point to a standard message listener object that happens to be supported * by the specified target ResourceAdapter: in this case, a JMS * {@link jakarta.jms.MessageListener} object as supported by the ActiveMQ @@ -61,37 +62,38 @@ * *

      * <bean id="messageListener" class="com.myorg.messaging.myMessageListener">
    - *   ...
    - * </bean>
    + * <!-- ... --> + * </bean> + *
    * - * The target ResourceAdapter may be configured as a local Spring bean as well + *

    The target ResourceAdapter may be configured as a local Spring bean as well * (the typical case) or obtained from JNDI (e.g. on WebLogic). For the * example above, a local ResourceAdapter bean could be defined as follows * (matching the "resourceAdapter" bean reference above): * *

      * <bean id="resourceAdapter" class="org.springframework.jca.support.ResourceAdapterFactoryBean">
    - *   <property name="resourceAdapter">
    - *     <bean class="org.apache.activemq.ra.ActiveMQResourceAdapter">
    - *       <property name="serverUrl" value="tcp://localhost:61616"/>
    - *     </bean>
    - *   </property>
    - *   <property name="workManager">
    - *     <bean class="org.springframework.jca.work.SimpleTaskWorkManager"/>
    - *   </property>
    - * </bean>
    + * <property name="resourceAdapter"> + * <bean class="org.apache.activemq.ra.ActiveMQResourceAdapter"> + * <property name="serverUrl" value="tcp://localhost:61616"/> + * </bean> + * </property> + * <property name="workManager"> + * <bean class="..."/> + * </property> + * </bean> + *
    * - * For a different target resource, the configuration would simply point to a + *

    For a different target resource, the configuration would simply point to a * different ResourceAdapter and a different ActivationSpec object (which are * both specific to the resource provider), and possibly a different message * listener (e.g. a CCI {@link jakarta.resource.cci.MessageListener} for a * resource adapter which is based on the JCA Common Client Interface). * *

    The asynchronous execution strategy can be customized through the - * "workManager" property on the ResourceAdapterFactoryBean (as shown above). - * Check out {@link org.springframework.jca.work.SimpleTaskWorkManager}'s - * javadoc for its configuration options; alternatively, any other - * JCA-compliant WorkManager can be used (e.g. Geronimo's). + * "workManager" property on the ResourceAdapterFactoryBean as shown above, + * where {@code } should be replaced with configuration for + * any JCA-compliant {@code WorkManager}. * *

    Transactional execution is a responsibility of the concrete message endpoint, * as built by the specified MessageEndpointFactory. {@link GenericMessageEndpointFactory} @@ -101,43 +103,45 @@ * *

      * <bean class="org.springframework.jca.endpoint.GenericMessageEndpointManager">
    - * 	 <property name="resourceAdapter" ref="resourceAdapter"/>
    - * 	 <property name="messageEndpointFactory">
    - *     <bean class="org.springframework.jca.endpoint.GenericMessageEndpointFactory">
    - *       <property name="messageListener" ref="messageListener"/>
    - *       <property name="transactionManager" ref="transactionManager"/>
    - *     </bean>
    - * 	 </property>
    - * 	 <property name="activationSpec">
    - *     <bean class="org.apache.activemq.ra.ActiveMQActivationSpec">
    - *       <property name="destination" value="myQueue"/>
    - *       <property name="destinationType" value="jakarta.jms.Queue"/>
    - *     </bean>
    - *   </property>
    + *  <property name="resourceAdapter" ref="resourceAdapter"/>
    + *  <property name="messageEndpointFactory">
    + *    <bean class="org.springframework.jca.endpoint.GenericMessageEndpointFactory">
    + *      <property name="messageListener" ref="messageListener"/>
    + *      <property name="transactionManager" ref="transactionManager"/>
    + *    </bean>
    + *  </property>
    + *  <property name="activationSpec">
    + *    <bean class="org.apache.activemq.ra.ActiveMQActivationSpec">
    + *      <property name="destination" value="myQueue"/>
    + *      <property name="destinationType" value="jakarta.jms.Queue"/>
    + *    </bean>
    + *  </property>
      * </bean>
      *
    - * <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
    + * <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/> + * * - * Alternatively, check out your resource provider's ActivationSpec object, + *

    Alternatively, check out your resource provider's ActivationSpec object, * which should support local transactions through a provider-specific config flag, * e.g. ActiveMQActivationSpec's "useRAManagedTransaction" bean property. * *

      * <bean class="org.springframework.jca.endpoint.GenericMessageEndpointManager">
    - * 	 <property name="resourceAdapter" ref="resourceAdapter"/>
    - * 	 <property name="messageEndpointFactory">
    - *     <bean class="org.springframework.jca.endpoint.GenericMessageEndpointFactory">
    - *       <property name="messageListener" ref="messageListener"/>
    - *     </bean>
    - * 	 </property>
    - * 	 <property name="activationSpec">
    - *     <bean class="org.apache.activemq.ra.ActiveMQActivationSpec">
    - *       <property name="destination" value="myQueue"/>
    - *       <property name="destinationType" value="jakarta.jms.Queue"/>
    - *       <property name="useRAManagedTransaction" value="true"/>
    - *     </bean>
    - *   </property>
    - * </bean>
    + * <property name="resourceAdapter" ref="resourceAdapter"/> + * <property name="messageEndpointFactory"> + * <bean class="org.springframework.jca.endpoint.GenericMessageEndpointFactory"> + * <property name="messageListener" ref="messageListener"/> + * </bean> + * </property> + * <property name="activationSpec"> + * <bean class="org.apache.activemq.ra.ActiveMQActivationSpec"> + * <property name="destination" value="myQueue"/> + * <property name="destinationType" value="jakarta.jms.Queue"/> + * <property name="useRAManagedTransaction" value="true"/> + * </bean> + * </property> + * </bean> + * * * @author Juergen Hoeller * @since 2.5 diff --git a/spring-tx/src/main/java/org/springframework/jca/support/LocalConnectionFactoryBean.java b/spring-tx/src/main/java/org/springframework/jca/support/LocalConnectionFactoryBean.java index fe49bafdf5e8..2a514d2a32f3 100644 --- a/spring-tx/src/main/java/org/springframework/jca/support/LocalConnectionFactoryBean.java +++ b/spring-tx/src/main/java/org/springframework/jca/support/LocalConnectionFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,9 +57,8 @@ * order to make the connector interact with an XA transaction coordinator. * Alternatively, simply use the native local transaction facilities of the * exposed API (e.g. CCI local transactions), or use a corresponding - * implementation of Spring's PlatformTransactionManager SPI - * (e.g. {@link org.springframework.jca.cci.connection.CciLocalTransactionManager}) - * to drive local transactions. + * implementation of Spring's PlatformTransactionManager SPI to drive local + * transactions. * * @author Juergen Hoeller * @since 1.2 @@ -67,7 +66,6 @@ * @see #setConnectionManager * @see jakarta.resource.cci.ConnectionFactory * @see jakarta.resource.cci.Connection#getLocalTransaction - * @see org.springframework.jca.cci.connection.CciLocalTransactionManager */ public class LocalConnectionFactoryBean implements FactoryBean, InitializingBean { diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java index 08f89e9ac798..adc81d96b164 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java @@ -62,54 +62,51 @@ *

    Example usage with * {@link MappingJackson2HttpMessageConverter}: * - *

    {@code
    - * 
    - *   
    - *     
    + * <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    + *   <property name="objectMapper">
    + *     <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
      *       p:autoDetectFields="false"
      *       p:autoDetectGettersSetters="false"
    - *       p:annotationIntrospector-ref="jaxbAnnotationIntrospector" />
    - *   
    - * 
    - * }
    + * p:annotationIntrospector-ref="jaxbAnnotationIntrospector" /> + * </property> + * </bean> * *

    Example usage with MappingJackson2JsonView: * - *

    {@code
    - * 
    - *   
    - *     
    + * <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
    + *   <property name="objectMapper">
    + *     <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
      *       p:failOnEmptyBeans="false"
    - *       p:indentOutput="true">
    - *       
    - *         
    - *           
    - *         
    - *       
    - *     
    - *   
    - * 
    - * }
    + * p:indentOutput="true"> + * <property name="serializers"> + * <array> + * <bean class="org.mycompany.MyCustomSerializer" /> + * </array> + * </property> + * </bean> + * </property> + * </bean> * *

    In case there are no specific setters provided (for some rarely used options), * you can still use the more general methods {@link #setFeaturesToEnable} and * {@link #setFeaturesToDisable}. * - *

    {@code
    - * 
    - *   
    - *     
    - *       
    - *       
    - *     
    - *   
    - *   
    - *     
    - *       
    - *     
    - *   
    - * 
    - * }
    + *
    + * <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
    + *   <property name="featuresToEnable">
    + *     <array>
    + *       <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.WRAP_ROOT_VALUE"/>
    + *       <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.CLOSE_CLOSEABLE"/>
    + *     </array>
    + *   </property>
    + *   <property name="featuresToDisable">
    + *     <array>
    + *       <util:constant static-field="com.fasterxml.jackson.databind.MapperFeature.USE_ANNOTATIONS"/>
    + *     </array>
    + *   </property>
    + * </bean>
    * *

    It also automatically registers the following well-known modules if they are * detected on the classpath: @@ -127,11 +124,10 @@ *

    In case you want to configure Jackson's {@link ObjectMapper} with a custom {@link Module}, * you can register one or more such Modules by class name via {@link #setModulesToInstall}: * - *

    {@code
    - * 
    - *   
    - * 
    + * 
    + * <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
    + *   <property name="modulesToInstall" value="myapp.jackson.MySampleModule,myapp.jackson.MyOtherModule"/>
    + * </bean>
    * *

    Compatible with Jackson 2.9 to 2.12, as of Spring 5.3. * diff --git a/spring-web/src/main/java/org/springframework/web/HttpRequestHandler.java b/spring-web/src/main/java/org/springframework/web/HttpRequestHandler.java index 542e60809448..94b155c3c3d4 100644 --- a/spring-web/src/main/java/org/springframework/web/HttpRequestHandler.java +++ b/spring-web/src/main/java/org/springframework/web/HttpRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,12 +49,6 @@ * return value gives a clearer signature to callers other than the * DispatcherServlet, indicating that there will never be a view to render. * - *

    As of Spring 2.0, Spring's HTTP-based remote exporters, such as - * {@link org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter} - * and {@link org.springframework.remoting.caucho.HessianServiceExporter}, - * implement this interface rather than the more extensive Controller interface, - * for minimal dependencies on Spring-specific web infrastructure. - * *

    Note that HttpRequestHandlers may optionally implement the * {@link org.springframework.web.servlet.mvc.LastModified} interface, * just like Controllers can, provided that they run within Spring's @@ -71,8 +65,6 @@ * @see org.springframework.web.servlet.mvc.Controller * @see org.springframework.web.servlet.mvc.LastModified * @see org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter - * @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter - * @see org.springframework.remoting.caucho.HessianServiceExporter */ @FunctionalInterface public interface HttpRequestHandler { diff --git a/spring-web/src/main/java/org/springframework/web/context/support/HttpRequestHandlerServlet.java b/spring-web/src/main/java/org/springframework/web/context/support/HttpRequestHandlerServlet.java index a97b402c36ab..958559b6d622 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/HttpRequestHandlerServlet.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/HttpRequestHandlerServlet.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,13 +36,6 @@ * in Spring's root web application context. The target bean name must match the * HttpRequestHandlerServlet servlet-name as defined in {@code web.xml}. * - *

    This can for example be used to expose a single Spring remote exporter, - * such as {@link org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter} - * or {@link org.springframework.remoting.caucho.HessianServiceExporter}, - * per HttpRequestHandlerServlet definition. This is a minimal alternative - * to defining remote exporters as beans in a DispatcherServlet context - * (with advanced mapping and interception facilities being available there). - * * @author Juergen Hoeller * @since 2.0 * @see org.springframework.web.HttpRequestHandler diff --git a/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java b/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java index 725bbfc0dc80..25790e5f3d1e 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java @@ -61,8 +61,6 @@ public interface MultipartFile extends InputStreamSource { * this one one somewhere for reference, if necessary. * @return the original filename, or the empty String if no file has been chosen * in the multipart form, or {@code null} if not defined or not available - * @see org.apache.commons.fileupload.FileItem#getName() - * @see org.springframework.web.multipart.commons.CommonsMultipartFile#setPreserveFilename * @see RFC 7578, Section 4.2 * @see Unrestricted File Upload */ @@ -133,7 +131,6 @@ default Resource getResource() { * @throws IOException in case of reading or writing errors * @throws IllegalStateException if the file has already been moved * in the filesystem and is not available anymore for another transfer - * @see org.apache.commons.fileupload.FileItem#write(File) * @see jakarta.servlet.http.Part#write(String) */ void transferTo(File dest) throws IOException, IllegalStateException; diff --git a/spring-web/src/main/java/org/springframework/web/multipart/MultipartHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/MultipartHttpServletRequest.java index 692dd710d22a..0fa6a8b726fa 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/MultipartHttpServletRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/MultipartHttpServletRequest.java @@ -25,7 +25,8 @@ /** * Provides additional methods for dealing with multipart content within a * servlet request, allowing to access uploaded files. - * Implementations also need to override the standard + * + *

    Implementations also need to override the standard * {@link jakarta.servlet.ServletRequest} methods for parameter access, making * multipart parameters available. * diff --git a/spring-web/src/main/java/org/springframework/web/multipart/MultipartResolver.java b/spring-web/src/main/java/org/springframework/web/multipart/MultipartResolver.java index cd18292d2606..a9c79dfbb82b 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/MultipartResolver.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/MultipartResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,10 +24,8 @@ * Implementations are typically usable both within an application context * and standalone. * - *

    There are two concrete implementations included in Spring, as of Spring 3.1: + *

    Spring provides the following concrete implementation: *

      - *
    • {@link org.springframework.web.multipart.commons.CommonsMultipartResolver} - * for Apache Commons FileUpload *
    • {@link org.springframework.web.multipart.support.StandardServletMultipartResolver} * for the Servlet 3.0+ Part API *
    @@ -77,7 +75,6 @@ * @since 29.09.2003 * @see MultipartHttpServletRequest * @see MultipartFile - * @see org.springframework.web.multipart.commons.CommonsMultipartResolver * @see org.springframework.web.multipart.support.ByteArrayMultipartFileEditor * @see org.springframework.web.multipart.support.StringMultipartFileEditor * @see org.springframework.web.servlet.DispatcherServlet diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/AbstractMultipartHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/AbstractMultipartHttpServletRequest.java index 8504b96816c9..fb705a9445e3 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/AbstractMultipartHttpServletRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/AbstractMultipartHttpServletRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,8 +34,8 @@ import org.springframework.web.multipart.MultipartHttpServletRequest; /** - * Abstract base implementation of the MultipartHttpServletRequest interface. - * Provides management of pre-generated MultipartFile instances. + * Abstract base implementation of the {@link MultipartHttpServletRequest} interface. + *

    Provides management of pre-generated {@link MultipartFile} instances. * * @author Juergen Hoeller * @author Arjen Poutsma diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java index 3a7859e56159..3ac4ddeed77d 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,8 +35,6 @@ * {@link org.springframework.web.multipart.MultipartHttpServletRequest} * interface. Provides management of pre-generated parameter values. * - *

    Used by {@link org.springframework.web.multipart.commons.CommonsMultipartResolver}. - * * @author Trevor D. Cook * @author Juergen Hoeller * @author Arjen Poutsma diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java index 3a29473a4afb..b09dac0ba20a 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java @@ -34,11 +34,8 @@ * *

    This resolver variant uses your Servlet container's multipart parser as-is, * potentially exposing the application to container implementation differences. - * See {@link org.springframework.web.multipart.commons.CommonsMultipartResolver} - * for an alternative implementation using a local Commons FileUpload library - * within the application, providing maximum portability across Servlet containers. * Also, see this resolver's configuration option for - * {@link #setStrictServletCompliance strict Servlet compliance}, narrowing the + * {@linkplain #setStrictServletCompliance strict Servlet compliance}, narrowing the * applicability of Spring's {@link MultipartHttpServletRequest} to form data only. * *

    Note: In order to use Servlet 3.0 based multipart parsing, @@ -52,21 +49,19 @@ * *

      * public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    - *	 // ...
    - *	 @Override
    - *	 protected void customizeRegistration(ServletRegistration.Dynamic registration) {
    + *   // ...
    + *   @Override
    + *   protected void customizeRegistration(ServletRegistration.Dynamic registration) {
      *     // Optionally also set maxFileSize, maxRequestSize, fileSizeThreshold
      *     registration.setMultipartConfig(new MultipartConfigElement("/tmp"));
      *   }
    - * }
    - * 
    + * }
    * * @author Juergen Hoeller * @since 3.1 * @see #setResolveLazily * @see #setStrictServletCompliance * @see HttpServletRequest#getParts() - * @see org.springframework.web.multipart.commons.CommonsMultipartResolver */ public class StandardServletMultipartResolver implements MultipartResolver { @@ -99,10 +94,6 @@ public void setResolveLazily(boolean resolveLazily) { * switch this flag to "true": Only "multipart/form-data" requests will be * wrapped with a {@link MultipartHttpServletRequest} then; other kinds of * requests will be left as-is, allowing for custom processing in user code. - *

    Note that Commons FileUpload and therefore - * {@link org.springframework.web.multipart.commons.CommonsMultipartResolver} - * supports any "multipart/" request type. However, it restricts processing - * to POST requests which standard Servlet multipart parsers might not do. * @since 5.3.9 */ public void setStrictServletCompliance(boolean strictServletCompliance) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java index 45ee3a9bc51c..de87a28f4785 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java @@ -117,10 +117,9 @@ * {@link org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator}. * *

  • The dispatcher's strategy for resolving multipart requests is determined by a - * {@link org.springframework.web.multipart.MultipartResolver} implementation. - * Implementations for Apache Commons FileUpload and Servlet 3 are included; the typical - * choice is {@link org.springframework.web.multipart.commons.CommonsMultipartResolver}. - * The MultipartResolver bean name is "multipartResolver"; default is none. + * {@link org.springframework.web.multipart.MultipartResolver} implementation. An + * implementation for Servlet 3 is included. The MultipartResolver bean name is + * "multipartResolver"; default is none. * *
  • Its locale resolution strategy is determined by a {@link LocaleResolver}. * Out-of-the-box implementations work via HTTP accept header, cookie, or session. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java index 421d7c182c61..e6cd60308c8f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java @@ -39,7 +39,7 @@ import org.springframework.web.servlet.view.script.ScriptTemplateViewResolver; /** - * Parse the {@code view-resolvers} MVC namespace element and register + * Parses the {@code view-resolvers} MVC namespace element and registers * {@link org.springframework.web.servlet.ViewResolver} bean definitions. * *

    All registered resolvers are wrapped in a single (composite) ViewResolver @@ -49,13 +49,12 @@ *

    When content negotiation is enabled the order property is set to highest priority * instead with the ContentNegotiatingViewResolver encapsulating all other registered * view resolver instances. That way the resolvers registered through the MVC namespace - * form self-encapsulated resolver chain. + * form a self-encapsulated resolver chain. * * @author Sivaprasad Valluru * @author Sebastien Deleuze * @author Rossen Stoyanchev * @since 4.1 - * @see TilesConfigurerBeanDefinitionParser * @see FreeMarkerConfigurerBeanDefinitionParser * @see GroovyMarkupConfigurerBeanDefinitionParser * @see ScriptTemplateConfigurerBeanDefinitionParser diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebSphereRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebSphereRequestUpgradeStrategy.java index 6a69ec0769f2..24014d476775 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebSphereRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebSphereRequestUpgradeStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ /** * WebSphere support for upgrading an {@link HttpServletRequest} during a * WebSocket handshake. To modify properties of the underlying - * {@link javax.websocket.server.ServerContainer} you can use + * {@link jakarta.websocket.server.ServerContainer} you can use * {@link ServletServerContainerFactoryBean} in XML configuration or, when using * Java configuration, access the container instance through the * "javax.websocket.server.ServerContainer" ServletContext attribute. From 85bdea6f47ed3654b12d696b6936671d7e6b5a2d Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 28 Sep 2021 13:41:25 +0200 Subject: [PATCH 160/735] Fix code formatting in Javadoc See gh-27480 --- .../json/Jackson2ObjectMapperFactoryBean.java | 82 +++++++++---------- 1 file changed, 38 insertions(+), 44 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java index 376e6b277372..adc81d96b164 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java @@ -62,54 +62,51 @@ *

    Example usage with * {@link MappingJackson2HttpMessageConverter}: * - *

    {@code
    - * 
    - *   
    - *     
    + * <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    + *   <property name="objectMapper">
    + *     <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
      *       p:autoDetectFields="false"
      *       p:autoDetectGettersSetters="false"
    - *       p:annotationIntrospector-ref="jaxbAnnotationIntrospector" />
    - *   
    - * 
    - * }
    + * p:annotationIntrospector-ref="jaxbAnnotationIntrospector" /> + * </property> + * </bean> * *

    Example usage with MappingJackson2JsonView: * - *

    {@code
    - * 
    - *   
    - *     
    + * <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
    + *   <property name="objectMapper">
    + *     <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
      *       p:failOnEmptyBeans="false"
    - *       p:indentOutput="true">
    - *       
    - *         
    - *           
    - *         
    - *       
    - *     
    - *   
    - * 
    - * }
    + * p:indentOutput="true"> + * <property name="serializers"> + * <array> + * <bean class="org.mycompany.MyCustomSerializer" /> + * </array> + * </property> + * </bean> + * </property> + * </bean> * *

    In case there are no specific setters provided (for some rarely used options), * you can still use the more general methods {@link #setFeaturesToEnable} and * {@link #setFeaturesToDisable}. * - *

    {@code
    - * 
    - *   
    - *     
    - *       
    - *       
    - *     
    - *   
    - *   
    - *     
    - *       
    - *     
    - *   
    - * 
    - * }
    + *
    + * <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
    + *   <property name="featuresToEnable">
    + *     <array>
    + *       <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.WRAP_ROOT_VALUE"/>
    + *       <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.CLOSE_CLOSEABLE"/>
    + *     </array>
    + *   </property>
    + *   <property name="featuresToDisable">
    + *     <array>
    + *       <util:constant static-field="com.fasterxml.jackson.databind.MapperFeature.USE_ANNOTATIONS"/>
    + *     </array>
    + *   </property>
    + * </bean>
    * *

    It also automatically registers the following well-known modules if they are * detected on the classpath: @@ -120,8 +117,6 @@ * support for other Java 8 types like {@link java.util.Optional}

  • *
  • jackson-datatype-jsr310: * support for Java 8 Date & Time API types
  • - *
  • jackson-datatype-joda: - * support for Joda-Time types
  • *
  • jackson-module-kotlin: * support for Kotlin classes and data classes
  • * @@ -129,11 +124,10 @@ *

    In case you want to configure Jackson's {@link ObjectMapper} with a custom {@link Module}, * you can register one or more such Modules by class name via {@link #setModulesToInstall}: * - *

    {@code
    - * 
    - *   
    - * 
    + * 
    + * <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
    + *   <property name="modulesToInstall" value="myapp.jackson.MySampleModule,myapp.jackson.MyOtherModule"/>
    + * </bean>
    * *

    Compatible with Jackson 2.9 to 2.12, as of Spring 5.3. * From 08bce08018596d4e46ba01d1899062428d7b2c7e Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 28 Sep 2021 14:20:31 +0200 Subject: [PATCH 161/735] Use text blocks with JUnit Jupiter 5.8.1 See gh-27450 --- ...duledAnnotationBeanPostProcessorTests.java | 94 +++++++++---------- .../springframework/util/ClassUtilsTests.java | 36 +++---- .../IntegerToEnumConverterFactoryTests.java | 10 +- .../sockjs/client/SockJsUrlInfoTests.java | 32 +++---- 4 files changed, 86 insertions(+), 86 deletions(-) diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java index 04a08b00e64c..9aaf52c881f3 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java @@ -90,11 +90,11 @@ void closeContextAfterTest() { } @ParameterizedTest - @CsvSource({ - "FixedDelay, 5000", - "FixedDelayInSeconds, 5000", - "FixedDelayInMinutes, 180000" - }) + @CsvSource(textBlock = """ + FixedDelay, 5_000 + FixedDelayInSeconds, 5_000 + FixedDelayInMinutes, 180_000 + """) void fixedDelayTask(@NameToClass Class beanClass, long expectedInterval) { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(beanClass); @@ -123,11 +123,11 @@ void fixedDelayTask(@NameToClass Class beanClass, long expectedInterval) { } @ParameterizedTest - @CsvSource({ - "FixedRate, 3000", - "FixedRateInSeconds, 5000", - "FixedRateInMinutes, 180000" - }) + @CsvSource(textBlock = """ + FixedRate, 3_000 + FixedRateInSeconds, 5_000 + FixedRateInMinutes, 180_000 + """) void fixedRateTask(@NameToClass Class beanClass, long expectedInterval) { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(beanClass); @@ -158,11 +158,11 @@ void fixedRateTask(@NameToClass Class beanClass, long expectedInterval) { } @ParameterizedTest - @CsvSource({ - "FixedRateWithInitialDelay, 1000, 3000", - "FixedRateWithInitialDelayInSeconds, 5000, 3000", - "FixedRateWithInitialDelayInMinutes, 60000, 180000" - }) + @CsvSource(textBlock = """ + FixedRateWithInitialDelay, 1_000, 3_000 + FixedRateWithInitialDelayInSeconds, 5_000, 3_000 + FixedRateWithInitialDelayInMinutes, 60_000, 180_000 + """) void fixedRateTaskWithInitialDelay(@NameToClass Class beanClass, long expectedInitialDelay, long expectedInterval) { BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); BeanDefinition targetDefinition = new RootBeanDefinition(beanClass); @@ -252,15 +252,15 @@ private void severalFixedRates(StaticApplicationContext context, assertThat(targetObject).isEqualTo(target); assertThat(targetMethod.getName()).isEqualTo("fixedRate"); assertThat(task1.getInitialDelay()).isEqualTo(0); - assertThat(task1.getInterval()).isEqualTo(4000L); + assertThat(task1.getInterval()).isEqualTo(4_000L); IntervalTask task2 = fixedRateTasks.get(1); ScheduledMethodRunnable runnable2 = (ScheduledMethodRunnable) task2.getRunnable(); targetObject = runnable2.getTarget(); targetMethod = runnable2.getMethod(); assertThat(targetObject).isEqualTo(target); assertThat(targetMethod.getName()).isEqualTo("fixedRate"); - assertThat(task2.getInitialDelay()).isEqualTo(2000L); - assertThat(task2.getInterval()).isEqualTo(4000L); + assertThat(task2.getInitialDelay()).isEqualTo(2_000L); + assertThat(task2.getInterval()).isEqualTo(4_000L); } @Test @@ -407,7 +407,7 @@ void metaAnnotationWithFixedRate() { Method targetMethod = runnable.getMethod(); assertThat(targetObject).isEqualTo(target); assertThat(targetMethod.getName()).isEqualTo("checkForUpdates"); - assertThat(task.getInterval()).isEqualTo(5000L); + assertThat(task.getInterval()).isEqualTo(5_000L); } @Test @@ -434,8 +434,8 @@ void composedAnnotationWithInitialDelayAndFixedRate() { Method targetMethod = runnable.getMethod(); assertThat(targetObject).isEqualTo(target); assertThat(targetMethod.getName()).isEqualTo("checkForUpdates"); - assertThat(task.getInterval()).isEqualTo(5000L); - assertThat(task.getInitialDelay()).isEqualTo(1000L); + assertThat(task.getInterval()).isEqualTo(5_000L); + assertThat(task.getInitialDelay()).isEqualTo(1_000L); } @Test @@ -517,12 +517,12 @@ void propertyPlaceholderWithInactiveCron() { } @ParameterizedTest - @CsvSource({ - "PropertyPlaceholderWithFixedDelay, 5000, 1000, 5000, 1000", - "PropertyPlaceholderWithFixedDelay, PT5S, PT1S, 5000, 1000", - "PropertyPlaceholderWithFixedDelayInSeconds, 5000, 1000, 5000000, 1000000", - "PropertyPlaceholderWithFixedDelayInSeconds, PT5S, PT1S, 5000, 1000" - }) + @CsvSource(textBlock = """ + PropertyPlaceholderWithFixedDelay, 5000, 1000, 5_000, 1_000 + PropertyPlaceholderWithFixedDelay, PT5S, PT1S, 5_000, 1_000 + PropertyPlaceholderWithFixedDelayInSeconds, 5000, 1000, 5_000_000, 1_000_000 + PropertyPlaceholderWithFixedDelayInSeconds, PT5S, PT1S, 5_000, 1_000 + """) void propertyPlaceholderWithFixedDelay(@NameToClass Class beanClass, String fixedDelay, String initialDelay, long expectedInterval, long expectedInitialDelay) { @@ -561,12 +561,12 @@ void propertyPlaceholderWithFixedDelay(@NameToClass Class beanClass, String f } @ParameterizedTest - @CsvSource({ - "PropertyPlaceholderWithFixedRate, 3000, 1000, 3000, 1000", - "PropertyPlaceholderWithFixedRate, PT3S, PT1S, 3000, 1000", - "PropertyPlaceholderWithFixedRateInSeconds, 3000, 1000, 3000000, 1000000", - "PropertyPlaceholderWithFixedRateInSeconds, PT3S, PT1S, 3000, 1000" - }) + @CsvSource(textBlock = """ + PropertyPlaceholderWithFixedRate, 3000, 1000, 3_000, 1_000 + PropertyPlaceholderWithFixedRate, PT3S, PT1S, 3_000, 1_000 + PropertyPlaceholderWithFixedRateInSeconds, 3000, 1000, 3_000_000, 1_000_000 + PropertyPlaceholderWithFixedRateInSeconds, PT3S, PT1S, 3_000, 1_000 + """) void propertyPlaceholderWithFixedRate(@NameToClass Class beanClass, String fixedRate, String initialDelay, long expectedInterval, long expectedInitialDelay) { @@ -728,7 +728,7 @@ void nonEmptyParamList() { static class FixedDelay { - @Scheduled(fixedDelay = 5000) + @Scheduled(fixedDelay = 5_000) void fixedDelay() { } } @@ -750,7 +750,7 @@ void fixedDelay() { static class FixedRate { - @Scheduled(fixedRate = 3000) + @Scheduled(fixedRate = 3_000) void fixedRate() { } } @@ -772,7 +772,7 @@ void fixedRate() { static class FixedRateWithInitialDelay { - @Scheduled(fixedRate = 3000, initialDelay = 1000) + @Scheduled(fixedRate = 3_000, initialDelay = 1_000) void fixedRate() { } } @@ -794,7 +794,7 @@ void fixedRate() { static class SeveralFixedRatesWithSchedulesContainerAnnotationTestBean { - @Schedules({@Scheduled(fixedRate = 4000), @Scheduled(fixedRate = 4000, initialDelay = 2000)}) + @Schedules({@Scheduled(fixedRate = 4_000), @Scheduled(fixedRate = 4_000, initialDelay = 2_000)}) void fixedRate() { } } @@ -802,8 +802,8 @@ void fixedRate() { static class SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean { - @Scheduled(fixedRate = 4000) - @Scheduled(fixedRate = 4000, initialDelay = 2000) + @Scheduled(fixedRate = 4_000) + @Scheduled(fixedRate = 4_000, initialDelay = 2_000) void fixedRate() { } @@ -819,8 +819,8 @@ static SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean nestedProxy() { static class FixedRatesBaseBean { - @Scheduled(fixedRate = 4000) - @Scheduled(fixedRate = 4000, initialDelay = 2000) + @Scheduled(fixedRate = 4_000) + @Scheduled(fixedRate = 4_000, initialDelay = 2_000) void fixedRate() { } } @@ -832,8 +832,8 @@ static class FixedRatesSubBean extends FixedRatesBaseBean { interface FixedRatesDefaultMethod { - @Scheduled(fixedRate = 4000) - @Scheduled(fixedRate = 4000, initialDelay = 2000) + @Scheduled(fixedRate = 4_000) + @Scheduled(fixedRate = 4_000, initialDelay = 2_000) default void fixedRate() { } } @@ -916,13 +916,13 @@ void invalid() { static class NonEmptyParamListTestBean { - @Scheduled(fixedRate = 3000) + @Scheduled(fixedRate = 3_000) void invalid(String oops) { } } - @Scheduled(fixedRate = 5000) + @Scheduled(fixedRate = 5_000) @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) private @interface EveryFiveSeconds { @@ -934,7 +934,7 @@ void invalid(String oops) { private @interface Hourly { } - @Scheduled(initialDelay = 1000) + @Scheduled(initialDelay = 1_000) @Retention(RetentionPolicy.RUNTIME) private @interface WaitASec { @@ -956,7 +956,7 @@ void checkForUpdates() { static class ComposedAnnotationFixedRateTestBean { - @WaitASec(fixedRate = 5000) + @WaitASec(fixedRate = 5_000) void checkForUpdates() { } } diff --git a/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java index b8ddd8c4ca75..1719e2effdf4 100644 --- a/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java @@ -155,24 +155,24 @@ public Class loadClass(String name) throws ClassNotFoundException { } @ParameterizedTest - @CsvSource({ - "boolean, boolean", - "byte, byte", - "char, char", - "short, short", - "int, int", - "long, long", - "float, float", - "double, double", - "[Z, boolean[]", - "[B, byte[]", - "[C, char[]", - "[S, short[]", - "[I, int[]", - "[J, long[]", - "[F, float[]", - "[D, double[]" - }) + @CsvSource(textBlock = """ + boolean, boolean + byte, byte + char, char + short, short + int, int + long, long + float, float + double, double + [Z, boolean[] + [B, byte[] + [C, char[] + [S, short[] + [I, int[] + [J, long[] + [F, float[] + [D, double[] + """) void resolvePrimitiveClassName(String input, Class output) { assertThat(ClassUtils.resolvePrimitiveClassName(input)).isEqualTo(output); } diff --git a/spring-web/src/test/java/org/springframework/core/convert/support/IntegerToEnumConverterFactoryTests.java b/spring-web/src/test/java/org/springframework/core/convert/support/IntegerToEnumConverterFactoryTests.java index b9f48251e95b..3e470ea32bc7 100644 --- a/spring-web/src/test/java/org/springframework/core/convert/support/IntegerToEnumConverterFactoryTests.java +++ b/spring-web/src/test/java/org/springframework/core/convert/support/IntegerToEnumConverterFactoryTests.java @@ -37,11 +37,11 @@ class IntegerToEnumConverterFactoryTests { @ParameterizedTest - @CsvSource({ - "0, RED", - "1, BLUE", - "2, GREEN" - }) + @CsvSource(textBlock = """ + 0, RED + 1, BLUE + 2, GREEN + """) void convertsIntegerToEnum(int index, Color color) { assertThat(converter.convert(index)).isEqualTo(color); } diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/client/SockJsUrlInfoTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/client/SockJsUrlInfoTests.java index 4e63e808cbf8..49fd50b027e9 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/client/SockJsUrlInfoTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/client/SockJsUrlInfoTests.java @@ -48,28 +48,28 @@ void sessionId() throws Exception { } @ParameterizedTest - @CsvSource( { - "http, http", - "https, https", - "ws, http", - "wss, https", - }) + @CsvSource(textBlock = """ + http, http + https, https + ws, http + wss, https + """) void infoUrl(String scheme, String expectedScheme) throws Exception { SockJsUrlInfo info = new SockJsUrlInfo(new URI(scheme + "://example.com")); assertThat(info.getInfoUrl()).isEqualTo(new URI(expectedScheme + "://example.com/info")); } @ParameterizedTest - @CsvSource( { - "http, http, XHR_STREAMING", - "http, ws, WEBSOCKET", - "https, https, XHR_STREAMING", - "https, wss, WEBSOCKET", - "ws, http, XHR_STREAMING", - "ws, ws, WEBSOCKET", - "wss, https, XHR_STREAMING", - "wss, wss, WEBSOCKET" - }) + @CsvSource(textBlock = """ + http, http, XHR_STREAMING + http, ws, WEBSOCKET + https, https, XHR_STREAMING + https, wss, WEBSOCKET + ws, http, XHR_STREAMING + ws, ws, WEBSOCKET + wss, https, XHR_STREAMING + wss, wss, WEBSOCKET + """) void transportUrl(String scheme, String expectedScheme, TransportType transportType) throws Exception { SockJsUrlInfo info = new SockJsUrlInfo(new URI(scheme + "://example.com")); String serverId = info.getServerId(); From 3be2b32e21ad91b94346a1b9f8cf58fb3ea48ced Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 28 Sep 2021 14:56:39 +0200 Subject: [PATCH 162/735] Remove only leading space for SSE data Prior to this commit, all white space was trimmed from Server Sent Event data. After this commit, only a leading space is removed (if present). Closes gh-27473 --- .../codec/ServerSentEventHttpMessageReader.java | 8 +++++++- .../ServerSentEventHttpMessageReaderTests.java | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java index 035d8b4c73e9..d21ec4fe6196 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java +++ b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java @@ -147,7 +147,13 @@ private Object buildEvent(List lines, ResolvableType valueType, boolean for (String line : lines) { if (line.startsWith("data:")) { data = (data != null ? data : new StringBuilder()); - data.append(line.substring(5).trim()).append('\n'); + if (line.charAt(5) != ' ') { + data.append(line, 5, line.length()); + } + else { + data.append(line, 6, line.length()); + } + data.append('\n'); } if (shouldWrap) { if (line.startsWith("id:")) { diff --git a/spring-web/src/test/java/org/springframework/http/codec/ServerSentEventHttpMessageReaderTests.java b/spring-web/src/test/java/org/springframework/http/codec/ServerSentEventHttpMessageReaderTests.java index 22b77fd693de..82602a526ebd 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/ServerSentEventHttpMessageReaderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/ServerSentEventHttpMessageReaderTests.java @@ -138,6 +138,20 @@ public void readString() { .verify(); } + @Test + public void trimWhitespace() { + MockServerHttpRequest request = MockServerHttpRequest.post("/") + .body(Mono.just(stringBuffer("data: \tfoo \ndata:bar\t\n\n"))); + + Flux data = reader.read(ResolvableType.forClass(String.class), + request, Collections.emptyMap()).cast(String.class); + + StepVerifier.create(data) + .expectNext("\tfoo \nbar\t") + .expectComplete() + .verify(); + } + @Test public void readPojo() { MockServerHttpRequest request = MockServerHttpRequest.post("/") From 2feedb98ccaad01d9c75073604a9c90956a33afb Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 28 Sep 2021 18:15:00 +0200 Subject: [PATCH 163/735] Remove lineSeparator LF requirement (accept LF/CR/CRLF by default) See gh-27481 --- src/checkstyle/checkstyle.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/checkstyle/checkstyle.xml b/src/checkstyle/checkstyle.xml index 6358bc47e753..2d8a043623c0 100644 --- a/src/checkstyle/checkstyle.xml +++ b/src/checkstyle/checkstyle.xml @@ -13,9 +13,7 @@ - - - + From 86b010a6b2270d0fb3ff4017ca3e52eb100534d5 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 28 Sep 2021 18:15:22 +0200 Subject: [PATCH 164/735] Defensive reference to JNDI API for JDK 9+ (optional `java.naming` module) Closes gh-27483 --- .../CommonAnnotationBeanPostProcessor.java | 43 ++++++++++++++----- .../support/StandardServletEnvironment.java | 9 +++- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java index d9acb722b08d..8a3ca5a9f889 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -146,22 +146,27 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable { + // Defensive reference to JNDI API for JDK 9+ (optional java.naming module) + private static final boolean jndiPresent = ClassUtils.isPresent( + "javax.naming.InitialContext", CommonAnnotationBeanPostProcessor.class.getClassLoader()); + + private static final Set> resourceAnnotationTypes = new LinkedHashSet<>(4); + @Nullable private static final Class webServiceRefClass; @Nullable private static final Class ejbClass; - private static final Set> resourceAnnotationTypes = new LinkedHashSet<>(4); - static { - webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef"); - ejbClass = loadAnnotationType("javax.ejb.EJB"); - resourceAnnotationTypes.add(Resource.class); + + webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef"); if (webServiceRefClass != null) { resourceAnnotationTypes.add(webServiceRefClass); } + + ejbClass = loadAnnotationType("javax.ejb.EJB"); if (ejbClass != null) { resourceAnnotationTypes.add(ejbClass); } @@ -174,7 +179,8 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean private boolean alwaysUseJndiLookup = false; - private transient BeanFactory jndiFactory = new SimpleJndiBeanFactory(); + @Nullable + private transient BeanFactory jndiFactory; @Nullable private transient BeanFactory resourceFactory; @@ -199,6 +205,11 @@ public CommonAnnotationBeanPostProcessor() { setInitAnnotationType(PostConstruct.class); setDestroyAnnotationType(PreDestroy.class); ignoreResourceType("javax.xml.ws.WebServiceContext"); + + // java.naming module present on JDK 9+? + if (jndiPresent) { + this.jndiFactory = new SimpleJndiBeanFactory(); + } } @@ -464,6 +475,7 @@ public Object getTarget() { public void releaseTarget(Object target) { } }; + ProxyFactory pf = new ProxyFactory(); pf.setTargetSource(ts); if (element.lookupType.isInterface()) { @@ -484,12 +496,23 @@ public void releaseTarget(Object target) { protected Object getResource(LookupElement element, @Nullable String requestingBeanName) throws NoSuchBeanDefinitionException { + // JNDI lookup to perform? + String jndiName = null; if (StringUtils.hasLength(element.mappedName)) { - return this.jndiFactory.getBean(element.mappedName, element.lookupType); + jndiName = element.mappedName; + } + else if (this.alwaysUseJndiLookup) { + jndiName = element.name; } - if (this.alwaysUseJndiLookup) { - return this.jndiFactory.getBean(element.name, element.lookupType); + if (jndiName != null) { + if (this.jndiFactory == null) { + throw new NoSuchBeanDefinitionException(element.lookupType, + "No JNDI factory configured - specify the 'jndiFactory' property"); + } + return this.jndiFactory.getBean(jndiName, element.lookupType); } + + // Regular resource autowiring if (this.resourceFactory == null) { throw new NoSuchBeanDefinitionException(element.lookupType, "No resource factory configured - specify the 'resourceFactory' property"); diff --git a/spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java b/spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java index 3ec9b92be64a..4d49afb974af 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/StandardServletEnvironment.java @@ -27,6 +27,7 @@ import org.springframework.jndi.JndiLocatorDelegate; import org.springframework.jndi.JndiPropertySource; import org.springframework.lang.Nullable; +import org.springframework.util.ClassUtils; import org.springframework.web.context.ConfigurableWebEnvironment; /** @@ -39,6 +40,7 @@ * documentation for details. * * @author Chris Beams + * @author Juergen Hoeller * @since 3.1 * @see StandardEnvironment */ @@ -54,6 +56,11 @@ public class StandardServletEnvironment extends StandardEnvironment implements C public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiProperties"; + // Defensive reference to JNDI API for JDK 9+ (optional java.naming module) + private static final boolean jndiPresent = ClassUtils.isPresent( + "javax.naming.InitialContext", StandardServletEnvironment.class.getClassLoader()); + + /** * Create a new {@code StandardServletEnvironment} instance. */ @@ -100,7 +107,7 @@ protected StandardServletEnvironment(MutablePropertySources propertySources) { protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME)); propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)); - if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) { + if (jndiPresent && JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) { propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME)); } super.customizePropertySources(propertySources); From 040445612f157827e7ee199c2d6af55cbd2497bc Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 28 Sep 2021 18:15:56 +0200 Subject: [PATCH 165/735] Polishing --- .../org/springframework/core/env/AbstractEnvironment.java | 3 +++ .../org/springframework/core/env/StandardEnvironment.java | 7 +++++-- .../main/java/org/apache/commons/logging/LogAdapter.java | 8 ++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java index d4027e16f367..85968d699a89 100644 --- a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java +++ b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java @@ -48,6 +48,7 @@ * * @author Chris Beams * @author Juergen Hoeller + * @author Phillip Webb * @since 3.1 * @see ConfigurableEnvironment * @see StandardEnvironment @@ -129,6 +130,7 @@ public AbstractEnvironment() { * {@link #customizePropertySources(MutablePropertySources)} during * construction to allow subclasses to contribute or manipulate * {@link PropertySource} instances as appropriate. + * @param propertySources property sources to use * @since 5.3.4 * @see #customizePropertySources(MutablePropertySources) */ @@ -138,6 +140,7 @@ protected AbstractEnvironment(MutablePropertySources propertySources) { customizePropertySources(propertySources); } + /** * Factory method used to create the {@link ConfigurablePropertyResolver} * instance used by the Environment. diff --git a/spring-core/src/main/java/org/springframework/core/env/StandardEnvironment.java b/spring-core/src/main/java/org/springframework/core/env/StandardEnvironment.java index b228de56bb2c..9d2a2eb6b886 100644 --- a/spring-core/src/main/java/org/springframework/core/env/StandardEnvironment.java +++ b/spring-core/src/main/java/org/springframework/core/env/StandardEnvironment.java @@ -46,6 +46,7 @@ * variable names. * * @author Chris Beams + * @author Phillip Webb * @since 3.1 * @see ConfigurableEnvironment * @see SystemEnvironmentPropertySource @@ -61,13 +62,15 @@ public class StandardEnvironment extends AbstractEnvironment { /** - * Create a new {@code StandardEnvironment} instance. + * Create a new {@code StandardEnvironment} instance with a default + * {@link MutablePropertySources} instance. */ public StandardEnvironment() { } /** - * Create a new {@code StandardEnvironment} instance with a specific {@link MutablePropertySources} instance. + * Create a new {@code StandardEnvironment} instance with a specific + * {@link MutablePropertySources} instance. * @param propertySources property sources to use * @since 5.3.4 */ diff --git a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java index c918ee7c2df0..cc5bed06ea93 100644 --- a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java +++ b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -278,7 +278,7 @@ private static class Slf4jLog implements Log, Serializable { protected final String name; - protected transient T logger; + protected final transient T logger; public Slf4jLog(T logger) { this.name = logger.getName(); @@ -500,9 +500,9 @@ protected Object readResolve() { @SuppressWarnings("serial") private static class JavaUtilLog implements Log, Serializable { - private String name; + private final String name; - private transient java.util.logging.Logger logger; + private final transient java.util.logging.Logger logger; public JavaUtilLog(String name) { this.name = name; From f32f04d841012b04ed34923f62f783f095284402 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 28 Sep 2021 19:02:44 +0200 Subject: [PATCH 166/735] Code cleanup on new baseline --- .../ParameterResolutionDelegate.java | 46 ++----------------- .../CommonAnnotationBeanPostProcessor.java | 4 +- .../apache/commons/logging/LogAdapter.java | 5 +- 3 files changed, 9 insertions(+), 46 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/ParameterResolutionDelegate.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/ParameterResolutionDelegate.java index fc212da6c6b3..5f5d1a9d82fc 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/ParameterResolutionDelegate.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/ParameterResolutionDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Constructor; import java.lang.reflect.Executable; import java.lang.reflect.Parameter; @@ -30,7 +29,6 @@ import org.springframework.core.annotation.SynthesizingMethodParameter; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; /** * Public delegate for resolving autowirable parameters on externally managed @@ -81,10 +79,9 @@ private ParameterResolutionDelegate() { */ public static boolean isAutowirable(Parameter parameter, int parameterIndex) { Assert.notNull(parameter, "Parameter must not be null"); - AnnotatedElement annotatedParameter = getEffectiveAnnotatedParameter(parameter, parameterIndex); - return (AnnotatedElementUtils.hasAnnotation(annotatedParameter, Autowired.class) || - AnnotatedElementUtils.hasAnnotation(annotatedParameter, Qualifier.class) || - AnnotatedElementUtils.hasAnnotation(annotatedParameter, Value.class)); + return (AnnotatedElementUtils.hasAnnotation(parameter, Autowired.class) || + AnnotatedElementUtils.hasAnnotation(parameter, Qualifier.class) || + AnnotatedElementUtils.hasAnnotation(parameter, Value.class)); } /** @@ -125,8 +122,7 @@ public static Object resolveDependency( Assert.notNull(containingClass, "Containing class must not be null"); Assert.notNull(beanFactory, "AutowireCapableBeanFactory must not be null"); - AnnotatedElement annotatedParameter = getEffectiveAnnotatedParameter(parameter, parameterIndex); - Autowired autowired = AnnotatedElementUtils.findMergedAnnotation(annotatedParameter, Autowired.class); + Autowired autowired = AnnotatedElementUtils.findMergedAnnotation(parameter, Autowired.class); boolean required = (autowired == null || autowired.required()); MethodParameter methodParameter = SynthesizingMethodParameter.forExecutable( @@ -136,36 +132,4 @@ public static Object resolveDependency( return beanFactory.resolveDependency(descriptor, null); } - /** - * Due to a bug in {@code javac} on JDK versions prior to JDK 9, looking up - * annotations directly on a {@link Parameter} will fail for inner class - * constructors. - *

    Bug in javac in JDK < 9

    - *

    The parameter annotations array in the compiled byte code excludes an entry - * for the implicit enclosing instance parameter for an inner class - * constructor. - *

    Workaround

    - *

    This method provides a workaround for this off-by-one error by allowing the - * caller to access annotations on the preceding {@link Parameter} object (i.e., - * {@code index - 1}). If the supplied {@code index} is zero, this method returns - * an empty {@code AnnotatedElement}. - *

    WARNING

    - *

    The {@code AnnotatedElement} returned by this method should never be cast and - * treated as a {@code Parameter} since the metadata (e.g., {@link Parameter#getName()}, - * {@link Parameter#getType()}, etc.) will not match those for the declared parameter - * at the given index in an inner class constructor. - * @return the supplied {@code parameter} or the effective {@code Parameter} - * if the aforementioned bug is in effect - */ - private static AnnotatedElement getEffectiveAnnotatedParameter(Parameter parameter, int index) { - Executable executable = parameter.getDeclaringExecutable(); - if (executable instanceof Constructor && ClassUtils.isInnerClass(executable.getDeclaringClass()) && - executable.getParameterAnnotations().length == executable.getParameterCount() - 1) { - // Bug in javac in JDK <9: annotation array excludes enclosing instance parameter - // for inner classes, so access it with the actual parameter index lowered by 1 - return (index == 0 ? EMPTY_ANNOTATED_ELEMENT : executable.getParameters()[index - 1]); - } - return parameter; - } - } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java index c3ded8c56fa6..c3efdfbed261 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java @@ -227,7 +227,7 @@ public void setAlwaysUseJndiLookup(boolean alwaysUseJndiLookup) { /** * Specify the factory for objects to be injected into {@code @Resource} / - * {@code @WebServiceRef} / {@code @EJB} annotated fields and setter methods, + * {@code @EJB} annotated fields and setter methods, * for {@code mappedName} attributes that point directly into JNDI. * This factory will also be used if "alwaysUseJndiLookup" is set to "true" in order * to enforce JNDI lookups even for {@code name} attributes and default names. @@ -243,7 +243,7 @@ public void setJndiFactory(BeanFactory jndiFactory) { /** * Specify the factory for objects to be injected into {@code @Resource} / - * {@code @WebServiceRef} / {@code @EJB} annotated fields and setter methods, + * {@code @EJB} annotated fields and setter methods, * for {@code name} attributes and default names. *

    The default is the BeanFactory that this post-processor is defined in, * if any, looking up resource names as Spring bean names. Specify the resource diff --git a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java index 5639cc0f6d06..09ae22efe052 100644 --- a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java +++ b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java @@ -681,7 +681,6 @@ else if (found) { setSourceMethodName(sourceMethodName); } - @SuppressWarnings("deprecation") protected Object writeReplace() { LogRecord serialized = new LogRecord(getLevel(), getMessage()); serialized.setLoggerName(getLoggerName()); @@ -691,8 +690,8 @@ protected Object writeReplace() { serialized.setSourceMethodName(getSourceMethodName()); serialized.setSequenceNumber(getSequenceNumber()); serialized.setParameters(getParameters()); - serialized.setThreadID(getThreadID()); - serialized.setMillis(getMillis()); + serialized.setLongThreadID(getLongThreadID()); + serialized.setInstant(getInstant()); serialized.setThrown(getThrown()); return serialized; } From ac5dc698e2f0f6f758983f1af3039eea627ef54d Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 28 Sep 2021 19:10:09 +0200 Subject: [PATCH 167/735] Update/remove outdated JPA and Hibernate version references Closes gh-27487 --- .../hibernate5/LocalSessionFactoryBean.java | 24 ++++++++----------- .../LocalSessionFactoryBuilder.java | 9 ++++--- .../orm/hibernate5/SpringBeanContainer.java | 12 +++++----- .../orm/jpa/DefaultJpaDialect.java | 4 +--- .../orm/jpa/EntityManagerFactoryUtils.java | 4 ++-- .../springframework/orm/jpa/JpaDialect.java | 4 ++-- ...ocalContainerEntityManagerFactoryBean.java | 6 +---- .../jpa/LocalEntityManagerFactoryBean.java | 6 +---- .../DefaultPersistenceUnitManager.java | 4 +--- .../jpa/vendor/AbstractJpaVendorAdapter.java | 4 ++-- .../orm/jpa/vendor/HibernateJpaDialect.java | 4 ++-- .../jpa/vendor/HibernateJpaVendorAdapter.java | 5 ++-- 12 files changed, 34 insertions(+), 52 deletions(-) diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java index eb8fc4acfebf..7dc063b2a52e 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,21 +51,20 @@ import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.type.filter.TypeFilter; import org.springframework.lang.Nullable; -import org.springframework.util.ClassUtils; /** * {@link FactoryBean} that creates a Hibernate {@link SessionFactory}. This is the usual * way to set up a shared Hibernate SessionFactory in a Spring application context; the * SessionFactory can then be passed to data access objects via dependency injection. * - *

    Compatible with Hibernate 5.2/5.3/5.4, as of Spring 5.3. + *

    Compatible with Hibernate 5.5/5.6, as of Spring 6.0. * This Hibernate-specific {@code LocalSessionFactoryBean} can be an immediate alternative - * to {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean} for common - * JPA purposes: In particular with Hibernate 5.3/5.4, the Hibernate {@code SessionFactory} - * will natively expose the JPA {@code EntityManagerFactory} interface as well, and - * Hibernate {@code BeanContainer} integration will be registered out of the box. - * In combination with {@link HibernateTransactionManager}, this naturally allows for - * mixing JPA access code with native Hibernate access code within the same transaction. + * to {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean} for + * common JPA purposes: The Hibernate {@code SessionFactory} will natively expose the JPA + * {@code EntityManagerFactory} interface as well, and Hibernate {@code BeanContainer} + * integration will be registered out of the box. In combination with + * {@link HibernateTransactionManager}, this naturally allows for mixing JPA access code + * with native Hibernate access code within the same transaction. * * @author Juergen Hoeller * @since 4.2 @@ -469,17 +468,14 @@ public ResourceLoader getResourceLoader() { /** * Accept the containing {@link BeanFactory}, registering corresponding Hibernate * {@link org.hibernate.resource.beans.container.spi.BeanContainer} integration for - * it if possible. This requires a Spring {@link ConfigurableListableBeanFactory} - * and Hibernate 5.3 or higher on the classpath. + * it if possible. This requires a Spring {@link ConfigurableListableBeanFactory}. * @since 5.1 * @see SpringBeanContainer * @see LocalSessionFactoryBuilder#setBeanContainer */ @Override public void setBeanFactory(BeanFactory beanFactory) { - if (beanFactory instanceof ConfigurableListableBeanFactory && - ClassUtils.isPresent("org.hibernate.resource.beans.container.spi.BeanContainer", - getClass().getClassLoader())) { + if (beanFactory instanceof ConfigurableListableBeanFactory) { this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; } } diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java index 5fac7741cd22..0ddf08bb8683 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,12 +77,12 @@ * Typically combined with {@link HibernateTransactionManager} for declarative * transactions against the {@code SessionFactory} and its JDBC {@code DataSource}. * - *

    Compatible with Hibernate 5.2/5.3/5.4, as of Spring 5.3. + *

    Compatible with Hibernate 5.5/5.6, as of Spring 6.0. * This Hibernate-specific factory builder can also be a convenient way to set up * a JPA {@code EntityManagerFactory} since the Hibernate {@code SessionFactory} * natively exposes the JPA {@code EntityManagerFactory} interface as well now. * - *

    This builder supports Hibernate 5.3/5.4 {@code BeanContainer} integration, + *

    This builder supports Hibernate {@code BeanContainer} integration, * {@link MetadataSources} from custom {@link BootstrapServiceRegistryBuilder} * setup, as well as other advanced Hibernate configuration options beyond the * standard JPA bootstrap contract. @@ -221,8 +221,7 @@ else if (jtaTransactionManager instanceof TransactionManager) { /** * Set a Hibernate {@link org.hibernate.resource.beans.container.spi.BeanContainer} * for the given Spring {@link ConfigurableListableBeanFactory}. - *

    Note: Bean container integration requires Hibernate 5.3 or higher. - * It enables autowiring of Hibernate attribute converters and entity listeners. + *

    This enables autowiring of Hibernate attribute converters and entity listeners. * @since 5.1 * @see SpringBeanContainer * @see AvailableSettings#BEAN_CONTAINER diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringBeanContainer.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringBeanContainer.java index 92064f2a4cb6..6f0d4c8b5f4e 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringBeanContainer.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringBeanContainer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,7 @@ import org.springframework.util.ConcurrentReferenceHashMap; /** - * Spring's implementation of Hibernate 5.3's {@link BeanContainer} SPI, + * Spring's implementation of Hibernate's {@link BeanContainer} SPI, * delegating to a Spring {@link ConfigurableListableBeanFactory}. * *

    Auto-configured by {@link LocalSessionFactoryBean#setBeanFactory}, @@ -62,10 +62,10 @@ *

    * * Please note that Spring's {@link LocalSessionFactoryBean} is an immediate alternative - * to {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean} for common - * JPA purposes: In particular with Hibernate 5.3/5.4, the Hibernate {@code SessionFactory} - * will natively expose the JPA {@code EntityManagerFactory} interface as well, and - * Hibernate {@code BeanContainer} integration will be registered out of the box. + * to {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean} for + * common JPA purposes: The Hibernate {@code SessionFactory} will natively expose the JPA + * {@code EntityManagerFactory} interface as well, and Hibernate {@code BeanContainer} + * integration will be registered out of the box. * * @author Juergen Hoeller * @since 5.1 diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/DefaultJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/DefaultJpaDialect.java index d78a2f79948b..f562fa03e249 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/DefaultJpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/DefaultJpaDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,8 +36,6 @@ *

    Simply begins a standard JPA transaction in {@link #beginTransaction} and * performs standard exception translation through {@link EntityManagerFactoryUtils}. * - *

    NOTE: Spring's JPA support requires JPA 2.1 or higher, as of Spring 5.0. - * * @author Juergen Hoeller * @since 2.0 * @see JpaTransactionManager#setJpaDialect diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java index 2bf679271249..ceb470a9ea04 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -333,7 +333,7 @@ private static void cleanupTransaction(@Nullable Object transactionData, EntityM /** * Apply the current transaction timeout, if any, to the given JPA Query object. - *

    This method sets the JPA 2.0 query hint "jakarta.persistence.query.timeout" accordingly. + *

    This method sets the JPA query hint "jakarta.persistence.query.timeout" accordingly. * @param query the JPA Query object * @param emf the JPA EntityManagerFactory that the Query was created for */ diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaDialect.java index b2c172b453f2..9d519dfbfde7 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import org.springframework.transaction.TransactionException; /** - * SPI strategy that encapsulates certain functionality that standard JPA 2.1 does + * SPI strategy that encapsulates certain functionality that standard JPA 3.0 does * not offer, such as access to the underlying JDBC Connection. This strategy is * mainly intended for standalone usage of a JPA provider; most of its functionality * is not relevant when running with JTA transactions. diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java index 3ec01ff8d847..a77d4f0b1a59 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,10 +70,6 @@ * plus the {@link EntityManagerFactoryInfo} interface which exposes additional * metadata as assembled by this FactoryBean. * - *

    NOTE: Spring's JPA support requires JPA 2.1 or higher, as of Spring 5.0. - * JPA 1.0/2.0 based applications are still supported; however, a JPA 2.1 compliant - * persistence provider is needed at runtime. - * * @author Juergen Hoeller * @author Rod Johnson * @since 2.0 diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java index 10e528cee583..68e740057854 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,10 +52,6 @@ * to the JPA provider, consider using Spring's more powerful * {@link LocalContainerEntityManagerFactoryBean} instead. * - *

    NOTE: Spring's JPA support requires JPA 2.1 or higher, as of Spring 5.0. - * JPA 1.0/2.0 based applications are still supported; however, a JPA 2.1 compliant - * persistence provider is needed at runtime. - * * @author Juergen Hoeller * @author Rod Johnson * @since 2.0 diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java index c16527b6153d..7d51f1bfa293 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,8 +77,6 @@ * DataSource names are by default interpreted as JNDI names, and no load time weaving * is available (which requires weaving to be turned off in the persistence provider). * - *

    NOTE: Spring's JPA support requires JPA 2.1 or higher, as of Spring 5.0. - * * @author Juergen Hoeller * @author Stephane Nicoll * @since 2.0 diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/AbstractJpaVendorAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/AbstractJpaVendorAdapter.java index 8e6d0101f564..baa3a34b255d 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/AbstractJpaVendorAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/AbstractJpaVendorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,7 +88,7 @@ protected String getDatabasePlatform() { *

    Note that the exact semantics of this flag depend on the underlying * persistence provider. For any more advanced needs, specify the appropriate * vendor-specific settings as "jpaProperties". - *

    NOTE: Do not set this flag to 'true' while also setting JPA 2.1's + *

    NOTE: Do not set this flag to 'true' while also setting JPA's * {@code jakarta.persistence.schema-generation.database.action} property. * These two schema generation mechanisms - standard JPA versus provider-native - * are mutually exclusive, e.g. with Hibernate 5. diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java index 327f887f08ff..a87bf44b6519 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,7 +73,7 @@ /** * {@link org.springframework.orm.jpa.JpaDialect} implementation for - * Hibernate EntityManager. Developed against Hibernate 5.2/5.3/5.4. + * Hibernate EntityManager. * * @author Juergen Hoeller * @author Costin Leau diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java index 5807200a9c2a..67d86d87e0bb 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,8 +44,7 @@ /** * {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Hibernate - * EntityManager. Developed and tested against Hibernate 5.3 and 5.4; - * backwards-compatible with Hibernate 5.2 at runtime on a best-effort basis. + * EntityManager. * *

    Exposes Hibernate's persistence provider and Hibernate's Session as extended * EntityManager interface, and adapts {@link AbstractJpaVendorAdapter}'s common From 3ad796e91374f5b0475bdbe93f444c975cb30cab Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 29 Sep 2021 09:56:29 +0200 Subject: [PATCH 168/735] Keep getEffectiveAnnotatedParameter for user code compiled with javac 8 --- .../ParameterResolutionDelegate.java | 46 +++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/ParameterResolutionDelegate.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/ParameterResolutionDelegate.java index 5f5d1a9d82fc..f8f7b0dce6f4 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/ParameterResolutionDelegate.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/ParameterResolutionDelegate.java @@ -18,6 +18,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Constructor; import java.lang.reflect.Executable; import java.lang.reflect.Parameter; @@ -29,6 +30,7 @@ import org.springframework.core.annotation.SynthesizingMethodParameter; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; /** * Public delegate for resolving autowirable parameters on externally managed @@ -79,9 +81,10 @@ private ParameterResolutionDelegate() { */ public static boolean isAutowirable(Parameter parameter, int parameterIndex) { Assert.notNull(parameter, "Parameter must not be null"); - return (AnnotatedElementUtils.hasAnnotation(parameter, Autowired.class) || - AnnotatedElementUtils.hasAnnotation(parameter, Qualifier.class) || - AnnotatedElementUtils.hasAnnotation(parameter, Value.class)); + AnnotatedElement annotatedParameter = getEffectiveAnnotatedParameter(parameter, parameterIndex); + return (AnnotatedElementUtils.hasAnnotation(annotatedParameter, Autowired.class) || + AnnotatedElementUtils.hasAnnotation(annotatedParameter, Qualifier.class) || + AnnotatedElementUtils.hasAnnotation(annotatedParameter, Value.class)); } /** @@ -122,7 +125,8 @@ public static Object resolveDependency( Assert.notNull(containingClass, "Containing class must not be null"); Assert.notNull(beanFactory, "AutowireCapableBeanFactory must not be null"); - Autowired autowired = AnnotatedElementUtils.findMergedAnnotation(parameter, Autowired.class); + AnnotatedElement annotatedParameter = getEffectiveAnnotatedParameter(parameter, parameterIndex); + Autowired autowired = AnnotatedElementUtils.findMergedAnnotation(annotatedParameter, Autowired.class); boolean required = (autowired == null || autowired.required()); MethodParameter methodParameter = SynthesizingMethodParameter.forExecutable( @@ -132,4 +136,38 @@ public static Object resolveDependency( return beanFactory.resolveDependency(descriptor, null); } + /** + * Due to a bug in {@code javac} on JDK versions prior to JDK 9, looking up + * annotations directly on a {@link Parameter} will fail for inner class + * constructors. + *

    Note: Since Spring 6 may still encounter user code compiled with + * {@code javac 8}, this workaround is kept in place for the time being. + *

    Bug in javac in JDK < 9

    + *

    The parameter annotations array in the compiled byte code excludes an entry + * for the implicit enclosing instance parameter for an inner class + * constructor. + *

    Workaround

    + *

    This method provides a workaround for this off-by-one error by allowing the + * caller to access annotations on the preceding {@link Parameter} object (i.e., + * {@code index - 1}). If the supplied {@code index} is zero, this method returns + * an empty {@code AnnotatedElement}. + *

    WARNING

    + *

    The {@code AnnotatedElement} returned by this method should never be cast and + * treated as a {@code Parameter} since the metadata (e.g., {@link Parameter#getName()}, + * {@link Parameter#getType()}, etc.) will not match those for the declared parameter + * at the given index in an inner class constructor. + * @return the supplied {@code parameter} or the effective {@code Parameter} + * if the aforementioned bug is in effect + */ + private static AnnotatedElement getEffectiveAnnotatedParameter(Parameter parameter, int index) { + Executable executable = parameter.getDeclaringExecutable(); + if (executable instanceof Constructor && ClassUtils.isInnerClass(executable.getDeclaringClass()) && + executable.getParameterAnnotations().length == executable.getParameterCount() - 1) { + // Bug in javac in JDK <9: annotation array excludes enclosing instance parameter + // for inner classes, so access it with the actual parameter index lowered by 1 + return (index == 0 ? EMPTY_ANNOTATED_ELEMENT : executable.getParameters()[index - 1]); + } + return parameter; + } + } From 96e4d3a53079f373de16b2754d1a5eee32d9ee2c Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 29 Sep 2021 14:02:37 +0200 Subject: [PATCH 169/735] Fail Gradle build for Javadoc warnings In order to catch Javadoc errors in the build, we now enable the `Xwerror` flag for the `javadoc` tool. In addition, we now use `Xdoclint:syntax` instead of `Xdoclint:none` in order to validate syntax within our Javadoc. This commit fixes all resulting Javadoc errors and warnings. This commit also upgrades to Undertow 2.2.12.Final and fixes the artifact names for exclusions for the Servlet and annotations APIs. The incorrect exclusion of the Servlet API resulted in the Servlet API being on the classpath twice for the javadoc task, which resulted in the following warnings in previous builds. javadoc: warning - Multiple sources of package comments found for package "javax.servlet" javadoc: warning - Multiple sources of package comments found for package "javax.servlet.http" javadoc: warning - Multiple sources of package comments found for package "javax.servlet.descriptor" javadoc: warning - Multiple sources of package comments found for package "javax.servlet.annotation" Closes gh-27480 --- build.gradle | 7 ++- gradle/docs.gradle | 5 ++- .../target/QuickTargetSourceCreator.java | 8 ++-- .../org/springframework/beans/BeanUtils.java | 2 +- .../beans/PropertyAccessorUtils.java | 4 +- .../factory/config/MethodInvokingBean.java | 14 +++--- .../config/MethodInvokingFactoryBean.java | 24 +++++----- .../config/ServiceLocatorFactoryBean.java | 44 +++++++++---------- .../beans/factory/config/YamlProcessor.java | 2 +- .../AbstractAutowireCapableBeanFactory.java | 4 +- .../factory/xml/DefaultDocumentLoader.java | 2 +- .../factory/xml/PluggableSchemaResolver.java | 6 +-- .../mail/javamail/MimeMessageHelper.java | 8 ++-- .../AnnotationBeanNameGenerator.java | 2 +- ...ReloadableResourceBundleMessageSource.java | 2 +- .../rmi/JndiRmiClientInterceptor.java | 2 +- .../remoting/rmi/JndiRmiProxyFactoryBean.java | 2 +- .../remoting/rmi/JndiRmiServiceExporter.java | 2 +- .../support/ResourceBundleThemeSource.java | 2 +- .../springframework/validation/Errors.java | 4 +- .../org/springframework/core/Constants.java | 8 ++-- .../core/SmartClassLoader.java | 1 - .../core/io/FileSystemResource.java | 8 ++-- .../springframework/core/io/PathResource.java | 6 +-- .../springframework/util/AntPathMatcher.java | 16 +++---- .../java/org/springframework/util/Assert.java | 2 +- .../springframework/util/MethodInvoker.java | 2 +- .../org/springframework/util/PathMatcher.java | 2 +- .../org/springframework/util/StringUtils.java | 6 +-- .../util/comparator/InvertibleComparator.java | 4 +- .../LazyConnectionDataSourceProxy.java | 4 +- .../UserCredentialsDataSourceAdapter.java | 2 +- ...erCredentialsConnectionFactoryAdapter.java | 2 +- .../DefaultJmsActivationSpecFactory.java | 4 +- .../endpoint/JmsMessageEndpointManager.java | 2 +- .../MessageMappingMessageHandler.java | 2 +- .../support/RSocketMessageHandler.java | 2 +- .../orm/hibernate5/SpringBeanContainer.java | 2 +- .../r2dbc/core/DatabaseClient.java | 10 ++--- .../r2dbc/core/ExecuteFunction.java | 2 +- .../AbstractRequestExpectationManager.java | 2 +- .../reactive/server/FluxExchangeResult.java | 2 +- .../web/reactive/server/WebTestClient.java | 10 ++--- ...onnectionSpecConnectionFactoryAdapter.java | 2 +- .../TransactionProxyFactoryBean.java | 2 +- .../http/ContentDisposition.java | 11 +++-- .../org/springframework/http/HttpStatus.java | 6 +-- .../client/ClientHttpRequestInterceptor.java | 6 +-- .../http/codec/xml/XmlEventDecoder.java | 2 +- .../ObjectToStringHttpMessageConverter.java | 10 ++--- .../feed/AtomFeedHttpMessageConverter.java | 2 +- .../feed/RssChannelHttpMessageConverter.java | 2 +- .../SimpleHttpServerJaxWsServiceExporter.java | 2 +- .../jaxws/SimpleJaxWsServiceExporter.java | 2 +- .../SpringServletContainerInitializer.java | 4 +- .../web/WebApplicationInitializer.java | 10 ++--- .../web/jsf/el/SpringBeanFacesELResolver.java | 28 ++++++------ .../WebApplicationContextFacesELResolver.java | 6 +-- .../web/server/ServerWebExchange.java | 2 +- .../web/util/UrlPathHelper.java | 10 ++--- .../function/client/ExchangeFunction.java | 2 +- .../reactive/function/client/WebClient.java | 8 ++-- .../function/server/RouterFunctions.java | 18 ++++---- .../function/server/ServerRequest.java | 6 +-- .../result/view/UrlBasedViewResolver.java | 2 +- .../web/reactive/socket/WebSocketHandler.java | 10 ++--- .../web/servlet/DispatcherServlet.java | 2 +- .../web/servlet/ModelAndView.java | 2 +- .../web/servlet/function/RouterFunctions.java | 18 ++++---- .../web/servlet/function/ServerRequest.java | 6 +-- .../web/servlet/function/ServerResponse.java | 8 ++-- .../DefaultHandlerExceptionResolver.java | 1 - .../servlet/support/WebContentGenerator.java | 2 +- .../servlet/view/InternalResourceView.java | 2 +- .../web/servlet/view/JstlView.java | 2 +- .../servlet/view/UrlBasedViewResolver.java | 12 ++--- .../view/feed/AbstractAtomFeedView.java | 2 +- .../servlet/view/feed/AbstractFeedView.java | 2 +- .../view/feed/AbstractRssFeedView.java | 2 +- .../view/freemarker/FreeMarkerConfigurer.java | 2 +- .../servlet/view/tiles3/TilesConfigurer.java | 38 ++++++++-------- 81 files changed, 251 insertions(+), 250 deletions(-) diff --git a/build.gradle b/build.gradle index ba209903d9b2..86379dd04b7f 100644 --- a/build.gradle +++ b/build.gradle @@ -139,14 +139,14 @@ configure(allprojects) { project -> entry 'tomcat-embed-core' entry 'tomcat-embed-websocket' } - dependencySet(group: 'io.undertow', version: '2.2.10.Final') { + dependencySet(group: 'io.undertow', version: '2.2.12.Final') { entry 'undertow-core' entry('undertow-websockets-jsr') { exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec" } entry('undertow-servlet') { - exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_3.1_spec" - exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.2_spec" + exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_4.0_spec" + exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.3_spec" } } @@ -371,7 +371,6 @@ configure([rootProject] + javaProjects) { project -> "https://docs.oracle.com/javaee/7/api/", "https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ "https://www.ibm.com/docs/api/v1/content/SSEQTP_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/", - "https://glassfish.java.net/nonav/docs/v3/api/", "https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/", "https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/", "https://tiles.apache.org/tiles-request/apidocs/", diff --git a/gradle/docs.gradle b/gradle/docs.gradle index bfb26d152b9c..b0a356be9207 100644 --- a/gradle/docs.gradle +++ b/gradle/docs.gradle @@ -46,8 +46,9 @@ task api(type: Javadoc) { stylesheetFile = file("src/docs/api/stylesheet.css") splitIndex = true links(project.ext.javadocLinks) - addStringOption('Xdoclint:none', '-quiet') - if(JavaVersion.current().isJava9Compatible()) { + addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint + addBooleanOption('Xwerror', true) // fail build on Javadoc warnings + if (JavaVersion.current().isJava9Compatible()) { addBooleanOption('html5', true) } } diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/target/QuickTargetSourceCreator.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/target/QuickTargetSourceCreator.java index a6a741e0f879..f7df6c30249b 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/target/QuickTargetSourceCreator.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/target/QuickTargetSourceCreator.java @@ -25,9 +25,11 @@ /** * Convenient TargetSourceCreator using bean name prefixes to create one of three * well-known TargetSource types: - *

  • : CommonsPool2TargetSource - *
  • % ThreadLocalTargetSource - *
  • ! PrototypeTargetSource + *
      + *
    • : CommonsPool2TargetSource
    • + *
    • % ThreadLocalTargetSource
    • + *
    • ! PrototypeTargetSource
    • + *
    * * @author Rod Johnson * @author Stephane Nicoll diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index 9483d18871f5..3a2b3f0b03ae 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -540,7 +540,7 @@ public static PropertyDescriptor findPropertyForMethod(Method method, Class c /** * Find a JavaBeans PropertyEditor following the 'Editor' suffix convention - * (e.g. "mypackage.MyDomainClass" -> "mypackage.MyDomainClassEditor"). + * (e.g. "mypackage.MyDomainClass" → "mypackage.MyDomainClassEditor"). *

    Compatible to the standard JavaBeans convention as implemented by * {@link java.beans.PropertyEditorManager} but isolated from the latter's * registered default editors for primitive types. diff --git a/spring-beans/src/main/java/org/springframework/beans/PropertyAccessorUtils.java b/spring-beans/src/main/java/org/springframework/beans/PropertyAccessorUtils.java index 55f50e5a275c..564194e2f0aa 100644 --- a/spring-beans/src/main/java/org/springframework/beans/PropertyAccessorUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/PropertyAccessorUtils.java @@ -134,8 +134,8 @@ public static boolean matchesProperty(String registeredPath, String propertyPath /** * Determine the canonical name for the given property path. * Removes surrounding quotes from map keys:
    - * {@code map['key']} -> {@code map[key]}
    - * {@code map["key"]} -> {@code map[key]} + * {@code map['key']} → {@code map[key]}
    + * {@code map["key"]} → {@code map[key]} * @param propertyName the bean property path * @return the canonical representation of the property path */ diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/MethodInvokingBean.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/MethodInvokingBean.java index 1374c4105e98..57fa7ab222c0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/MethodInvokingBean.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/MethodInvokingBean.java @@ -47,17 +47,17 @@ * which uses this class to call a static initialization method: * *

    - * <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingBean">
    - *   <property name="staticMethod" value="com.whatever.MyClass.init"/>
    - * </bean>
    + * <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingBean"> + * <property name="staticMethod" value="com.whatever.MyClass.init"/> + * </bean> * *

    An example of calling an instance method to start some server bean: * *

    - * <bean id="myStarter" class="org.springframework.beans.factory.config.MethodInvokingBean">
    - *   <property name="targetObject" ref="myServer"/>
    - *   <property name="targetMethod" value="start"/>
    - * </bean>
    + * <bean id="myStarter" class="org.springframework.beans.factory.config.MethodInvokingBean"> + * <property name="targetObject" ref="myServer"/> + * <property name="targetMethod" value="start"/> + * </bean> * * @author Juergen Hoeller * @since 4.0.3 diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/MethodInvokingFactoryBean.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/MethodInvokingFactoryBean.java index 86a6be985645..3ff39d81e5e3 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/MethodInvokingFactoryBean.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/MethodInvokingFactoryBean.java @@ -56,24 +56,24 @@ * which uses this class to call a static factory method: * *
    - * <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    - *   <property name="staticMethod" value="com.whatever.MyClassFactory.getInstance"/>
    - * </bean>
    + * <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> + * <property name="staticMethod" value="com.whatever.MyClassFactory.getInstance"/> + * </bean> * *

    An example of calling a static method then an instance method to get at a * Java system property. Somewhat verbose, but it works. * *

    - * <bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    - *   <property name="targetClass" value="java.lang.System"/>
    - *   <property name="targetMethod" value="getProperties"/>
    - * </bean>
    + * <bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    + *   <property name="targetClass" value="java.lang.System"/>
    + *   <property name="targetMethod" value="getProperties"/>
    + * </bean>
      *
    - * <bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    - *   <property name="targetObject" ref="sysProps"/>
    - *   <property name="targetMethod" value="getProperty"/>
    - *   <property name="arguments" value="java.version"/>
    - * </bean>
    + * <bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> + * <property name="targetObject" ref="sysProps"/> + * <property name="targetMethod" value="getProperty"/> + * <property name="arguments" value="java.version"/> + * </bean> * * @author Colin Sampaleanu * @author Juergen Hoeller diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java index e0ee01e6e3d7..272e97f5b74f 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java @@ -83,22 +83,22 @@ *

    A sample config in an XML-based * {@link org.springframework.beans.factory.BeanFactory} might look as follows: * - *

    <beans>
    + * 
    <beans>
      *
    - *   <!-- Prototype bean since we have state -->
    - *   <bean id="myService" class="a.b.c.MyService" singleton="false"/>
    + *   <!-- Prototype bean since we have state -->
    + *   <bean id="myService" class="a.b.c.MyService" singleton="false"/>
      *
    - *   <!-- will lookup the above 'myService' bean by *TYPE* -->
    + *   <!-- will lookup the above 'myService' bean by *TYPE* -->
      *   <bean id="myServiceFactory"
    - *            class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
    - *     <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
    - *   </bean>
    + *            class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
    + *     <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
    + *   </bean>
      *
    - *   <bean id="clientBean" class="a.b.c.MyClientBean">
    - *     <property name="myServiceFactory" ref="myServiceFactory"/>
    - *   </bean>
    + *   <bean id="clientBean" class="a.b.c.MyClientBean">
    + *     <property name="myServiceFactory" ref="myServiceFactory"/>
    + *   </bean>
      *
    - *</beans>
    + *</beans>
    * *

    The attendant {@code MyClientBean} class implementation might then * look something like this: @@ -135,22 +135,22 @@ *

    A sample config in an XML-based * {@link org.springframework.beans.factory.BeanFactory} might look as follows: * - *

    <beans>
    + * 
    <beans>
      *
    - *   <!-- Prototype beans since we have state (both extend MyService) -->
    - *   <bean id="specialService" class="a.b.c.SpecialService" singleton="false"/>
    - *   <bean id="anotherService" class="a.b.c.AnotherService" singleton="false"/>
    + *   <!-- Prototype beans since we have state (both extend MyService) -->
    + *   <bean id="specialService" class="a.b.c.SpecialService" singleton="false"/>
    + *   <bean id="anotherService" class="a.b.c.AnotherService" singleton="false"/>
      *
      *   <bean id="myServiceFactory"
    - *            class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
    - *     <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
    - *   </bean>
    + *            class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
    + *     <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
    + *   </bean>
      *
    - *   <bean id="clientBean" class="a.b.c.MyClientBean">
    - *     <property name="myServiceFactory" ref="myServiceFactory"/>
    - *   </bean>
    + *   <bean id="clientBean" class="a.b.c.MyClientBean">
    + *     <property name="myServiceFactory" ref="myServiceFactory"/>
    + *   </bean>
      *
    - *</beans>
    + *</beans>
    * *

    The attendant {@code MyClientBean} class implementation might then * look something like this: diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java index e34d7c25ce83..7949003c68bd 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java @@ -86,7 +86,7 @@ public abstract class YamlProcessor { * * when mapped with *

    -	 * setDocumentMatchers(properties ->
    +	 * setDocumentMatchers(properties ->
     	 *     ("prod".equals(properties.getProperty("environment")) ? MatchStatus.FOUND : MatchStatus.NOT_FOUND));
     	 * 
    * would end up as diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 02b27fe30443..e3908a2a7c30 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -1342,7 +1342,7 @@ protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) { * @param beanName the name of the bean * @param mbd the bean definition for the bean * @param explicitArgs argument values passed in programmatically via the getBean method, - * or {@code null} if none (-> use constructor argument values from bean definition) + * or {@code null} if none (implying the use of constructor argument values from bean definition) * @return a BeanWrapper for the new instance * @see #getBean(String, Object[]) */ @@ -1363,7 +1363,7 @@ protected BeanWrapper instantiateUsingFactoryMethod( * @param mbd the bean definition for the bean * @param ctors the chosen candidate constructors * @param explicitArgs argument values passed in programmatically via the getBean method, - * or {@code null} if none (-> use constructor argument values from bean definition) + * or {@code null} if none (implying the use of constructor argument values from bean definition) * @return a BeanWrapper for the new instance */ protected BeanWrapper autowireConstructor( diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultDocumentLoader.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultDocumentLoader.java index a443e7b1d669..08b1d16f2778 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultDocumentLoader.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultDocumentLoader.java @@ -39,7 +39,7 @@ * when starting your JVM. For example, to use the Oracle {@link DocumentBuilder}, * you might start your application like as follows: * - *
    java -Djavax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory MyMainClass
    + *
    java -Djavax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory MyMainClass
    * * @author Rob Harrop * @author Juergen Hoeller diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java index 3b1bff1febc3..82d632302d52 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java @@ -71,13 +71,13 @@ public class PluggableSchemaResolver implements EntityResolver { private final String schemaMappingsLocation; - /** Stores the mapping of schema URL -> local schema path. */ + /** Stores the mapping of schema URL → local schema path. */ @Nullable private volatile Map schemaMappings; /** - * Loads the schema URL -> schema file location mappings using the default + * Loads the schema URL → schema file location mappings using the default * mapping file pattern "META-INF/spring.schemas". * @param classLoader the ClassLoader to use for loading * (can be {@code null}) to use the default ClassLoader) @@ -89,7 +89,7 @@ public PluggableSchemaResolver(@Nullable ClassLoader classLoader) { } /** - * Loads the schema URL -> schema file location mappings using the given + * Loads the schema URL → schema file location mappings using the given * mapping file pattern. * @param classLoader the ClassLoader to use for loading * (can be {@code null}) to use the default ClassLoader) diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java index f795390fa24d..1eff5cebfaa9 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java @@ -896,7 +896,7 @@ private void setHtmlTextToMimePart(MimePart mimePart, String text) throws Messag *

    NOTE: Invoke {@code addInline} after {@link #setText}; * else, mail readers might not be able to resolve inline references correctly. * @param contentId the content ID to use. Will end up as "Content-ID" header - * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>". + * in the body part, surrounded by angle brackets: e.g. "myId" → "<myId>". * Can be referenced in HTML source via src="cid:myId" expressions. * @param dataSource the {@code javax.activation.DataSource} to take * the content from, determining the InputStream and the content type @@ -923,7 +923,7 @@ public void addInline(String contentId, DataSource dataSource) throws MessagingE *

    NOTE: Invoke {@code addInline} after {@link #setText}; * else, mail readers might not be able to resolve inline references correctly. * @param contentId the content ID to use. Will end up as "Content-ID" header - * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>". + * in the body part, surrounded by angle brackets: e.g. "myId" → "<myId>". * Can be referenced in HTML source via src="cid:myId" expressions. * @param file the File resource to take the content from * @throws MessagingException in case of errors @@ -950,7 +950,7 @@ public void addInline(String contentId, File file) throws MessagingException { *

    NOTE: Invoke {@code addInline} after {@link #setText}; * else, mail readers might not be able to resolve inline references correctly. * @param contentId the content ID to use. Will end up as "Content-ID" header - * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>". + * in the body part, surrounded by angle brackets: e.g. "myId" → "<myId>". * Can be referenced in HTML source via src="cid:myId" expressions. * @param resource the resource to take the content from * @throws MessagingException in case of errors @@ -976,7 +976,7 @@ public void addInline(String contentId, Resource resource) throws MessagingExcep *

    NOTE: Invoke {@code addInline} after {@code setText}; * else, mail readers might not be able to resolve inline references correctly. * @param contentId the content ID to use. Will end up as "Content-ID" header - * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>". + * in the body part, surrounded by angle brackets: e.g. "myId" → "<myId>". * Can be referenced in HTML source via src="cid:myId" expressions. * @param inputStreamSource the resource to take the content from * @param contentType the content type to use for the element diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java index a589a92335ac..4beee8680642 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java @@ -156,7 +156,7 @@ protected String buildDefaultBeanName(BeanDefinition definition, BeanDefinitionR /** * Derive a default bean name from the given bean definition. *

    The default implementation simply builds a decapitalized version - * of the short class name: e.g. "mypackage.MyJdbcDao" -> "myJdbcDao". + * of the short class name: e.g. "mypackage.MyJdbcDao" → "myJdbcDao". *

    Note that inner classes will thus have names of the form * "outerClassName.InnerClassName", which because of the period in the * name may be an issue if you are autowiring by name. diff --git a/spring-context/src/main/java/org/springframework/context/support/ReloadableResourceBundleMessageSource.java b/spring-context/src/main/java/org/springframework/context/support/ReloadableResourceBundleMessageSource.java index 6b6ff96af18e..1a93dd38d087 100644 --- a/spring-context/src/main/java/org/springframework/context/support/ReloadableResourceBundleMessageSource.java +++ b/spring-context/src/main/java/org/springframework/context/support/ReloadableResourceBundleMessageSource.java @@ -315,7 +315,7 @@ protected List calculateAllFilenames(String basename, Locale locale) { /** * Calculate the filenames for the given bundle basename and Locale, * appending language code, country code, and variant code. - * E.g.: basename "messages", Locale "de_AT_oo" -> "messages_de_AT_OO", + *

    For example, basename "messages", Locale "de_AT_oo" → "messages_de_AT_OO", * "messages_de_AT", "messages_de". *

    Follows the rules defined by {@link java.util.Locale#toString()}. * @param basename the basename of the bundle diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiClientInterceptor.java b/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiClientInterceptor.java index d90dd6a1a347..e883ff294954 100644 --- a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiClientInterceptor.java +++ b/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiClientInterceptor.java @@ -56,7 +56,7 @@ * For example: * *

    <property name="jndiEnvironment">
    - * 	 <props>
    + * 	 <props>
      *		 <prop key="java.naming.factory.initial">com.sun.jndi.cosnaming.CNCtxFactory</prop>
      *		 <prop key="java.naming.provider.url">iiop://localhost:1050</prop>
      *	 </props>
    diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiProxyFactoryBean.java b/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiProxyFactoryBean.java
    index a9d33d8973b6..48feb108a00f 100644
    --- a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiProxyFactoryBean.java
    +++ b/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiProxyFactoryBean.java
    @@ -43,7 +43,7 @@
      * For example:
      *
      * 
    <property name="jndiEnvironment">
    - * 	 <props>
    + * 	 <props>
      *		 <prop key="java.naming.factory.initial">com.sun.jndi.cosnaming.CNCtxFactory</prop>
      *		 <prop key="java.naming.provider.url">iiop://localhost:1050</prop>
      *	 </props>
    diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiServiceExporter.java b/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiServiceExporter.java
    index 49b2db295ae8..60543f6b1873 100644
    --- a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiServiceExporter.java
    +++ b/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiServiceExporter.java
    @@ -52,7 +52,7 @@
      * For example:
      *
      * 
    <property name="jndiEnvironment">
    - * 	 <props>
    + * 	 <props>
      *		 <prop key="java.naming.factory.initial">com.sun.jndi.cosnaming.CNCtxFactory</prop>
      *		 <prop key="java.naming.provider.url">iiop://localhost:1050</prop>
      *	 </props>
    diff --git a/spring-context/src/main/java/org/springframework/ui/context/support/ResourceBundleThemeSource.java b/spring-context/src/main/java/org/springframework/ui/context/support/ResourceBundleThemeSource.java
    index 0e5ba7e9a85b..fe68fc0fc8cd 100644
    --- a/spring-context/src/main/java/org/springframework/ui/context/support/ResourceBundleThemeSource.java
    +++ b/spring-context/src/main/java/org/springframework/ui/context/support/ResourceBundleThemeSource.java
    @@ -87,7 +87,7 @@ public ThemeSource getParentThemeSource() {
     	/**
     	 * Set the prefix that gets applied to the ResourceBundle basenames,
     	 * i.e. the theme names.
    -	 * E.g.: basenamePrefix="test.", themeName="theme" -> basename="test.theme".
    +	 * E.g.: basenamePrefix="test.", themeName="theme" → basename="test.theme".
     	 * 

    Note that ResourceBundle names are effectively classpath locations: As a * consequence, the JDK's standard ResourceBundle treats dots as package separators. * This means that "test.theme" is effectively equivalent to "test/theme", diff --git a/spring-context/src/main/java/org/springframework/validation/Errors.java b/spring-context/src/main/java/org/springframework/validation/Errors.java index ebaa9460bf12..45ae5d7b57af 100644 --- a/spring-context/src/main/java/org/springframework/validation/Errors.java +++ b/spring-context/src/main/java/org/springframework/validation/Errors.java @@ -83,8 +83,8 @@ public interface Errors { * {@code pushNestedPath(String)} call. *

    Using the nested path stack allows to set temporary nested paths * for subobjects without having to worry about a temporary path holder. - *

    For example: current path "spouse.", pushNestedPath("child") -> - * result path "spouse.child."; popNestedPath() -> "spouse." again. + *

    For example: current path "spouse.", pushNestedPath("child") → + * result path "spouse.child."; popNestedPath() → "spouse." again. * @param subPath the sub path to push onto the nested path stack * @see #popNestedPath */ diff --git a/spring-core/src/main/java/org/springframework/core/Constants.java b/spring-core/src/main/java/org/springframework/core/Constants.java index 8e91d511c10c..f94b1842bb68 100644 --- a/spring-core/src/main/java/org/springframework/core/Constants.java +++ b/spring-core/src/main/java/org/springframework/core/Constants.java @@ -310,10 +310,10 @@ public String toCodeForSuffix(Object value, @Nullable String nameSuffix) throws * Convert the given bean property name to a constant name prefix. *

    Uses a common naming idiom: turning all lower case characters to * upper case, and prepending upper case characters with an underscore. - *

    Example: "imageSize" -> "IMAGE_SIZE"
    - * Example: "imagesize" -> "IMAGESIZE".
    - * Example: "ImageSize" -> "_IMAGE_SIZE".
    - * Example: "IMAGESIZE" -> "_I_M_A_G_E_S_I_Z_E" + *

    Example: "imageSize" → "IMAGE_SIZE"
    + * Example: "imagesize" → "IMAGESIZE".
    + * Example: "ImageSize" → "_IMAGE_SIZE".
    + * Example: "IMAGESIZE" → "_I_M_A_G_E_S_I_Z_E" * @param propertyName the name of the bean property * @return the corresponding constant name prefix * @see #getValuesForProperty diff --git a/spring-core/src/main/java/org/springframework/core/SmartClassLoader.java b/spring-core/src/main/java/org/springframework/core/SmartClassLoader.java index e6a39c149ec4..964c791a8e00 100644 --- a/spring-core/src/main/java/org/springframework/core/SmartClassLoader.java +++ b/spring-core/src/main/java/org/springframework/core/SmartClassLoader.java @@ -91,7 +91,6 @@ default ClassLoader getOriginalClassLoader() { * not being possible (thrown by the default implementation in this interface) * @since 5.3.4 * @see ClassLoader#defineClass(String, byte[], int, int, ProtectionDomain) - * @see java.lang.invoke.MethodHandles.Lookup#defineClass(byte[]) */ default Class publicDefineClass(String name, byte[] b, @Nullable ProtectionDomain protectionDomain) { throw new UnsupportedOperationException(); diff --git a/spring-core/src/main/java/org/springframework/core/io/FileSystemResource.java b/spring-core/src/main/java/org/springframework/core/io/FileSystemResource.java index d0f7d392e802..feb2f9067da3 100644 --- a/spring-core/src/main/java/org/springframework/core/io/FileSystemResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/FileSystemResource.java @@ -70,9 +70,9 @@ public class FileSystemResource extends AbstractResource implements WritableReso *

    Note: When building relative resources via {@link #createRelative}, * it makes a difference whether the specified resource base path here * ends with a slash or not. In the case of "C:/dir1/", relative paths - * will be built underneath that root: e.g. relative path "dir2" -> + * will be built underneath that root: e.g. relative path "dir2" → * "C:/dir1/dir2". In the case of "C:/dir1", relative paths will apply - * at the same directory level: relative path "dir2" -> "C:/dir2". + * at the same directory level: relative path "dir2" → "C:/dir2". * @param path a file path * @see #FileSystemResource(Path) */ @@ -87,7 +87,7 @@ public FileSystemResource(String path) { * Create a new {@code FileSystemResource} from a {@link File} handle. *

    Note: When building relative resources via {@link #createRelative}, * the relative path will apply at the same directory level: - * e.g. new File("C:/dir1"), relative path "dir2" -> "C:/dir2"! + * e.g. new File("C:/dir1"), relative path "dir2" → "C:/dir2"! * If you prefer to have relative paths built underneath the given root directory, * use the {@link #FileSystemResource(String) constructor with a file path} * to append a trailing slash to the root path: "C:/dir1/", which indicates @@ -111,7 +111,7 @@ public FileSystemResource(File file) { * path cleaning and {@link #createRelative(String)} handling. *

    Note: When building relative resources via {@link #createRelative}, * the relative path will apply at the same directory level: - * e.g. Paths.get("C:/dir1"), relative path "dir2" -> "C:/dir2"! + * e.g. Paths.get("C:/dir1"), relative path "dir2" → "C:/dir2"! * If you prefer to have relative paths built underneath the given root directory, * use the {@link #FileSystemResource(String) constructor with a file path} * to append a trailing slash to the root path: "C:/dir1/", which indicates diff --git a/spring-core/src/main/java/org/springframework/core/io/PathResource.java b/spring-core/src/main/java/org/springframework/core/io/PathResource.java index bd334cc51856..6412f001a2b4 100644 --- a/spring-core/src/main/java/org/springframework/core/io/PathResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/PathResource.java @@ -64,7 +64,7 @@ public class PathResource extends AbstractResource implements WritableResource { * Create a new PathResource from a Path handle. *

    Note: Unlike {@link FileSystemResource}, when building relative resources * via {@link #createRelative}, the relative path will be built underneath - * the given root: e.g. Paths.get("C:/dir1/"), relative path "dir2" -> "C:/dir1/dir2"! + * the given root: e.g. Paths.get("C:/dir1/"), relative path "dir2" → "C:/dir1/dir2"! * @param path a Path handle */ public PathResource(Path path) { @@ -76,7 +76,7 @@ public PathResource(Path path) { * Create a new PathResource from a Path handle. *

    Note: Unlike {@link FileSystemResource}, when building relative resources * via {@link #createRelative}, the relative path will be built underneath - * the given root: e.g. Paths.get("C:/dir1/"), relative path "dir2" -> "C:/dir1/dir2"! + * the given root: e.g. Paths.get("C:/dir1/"), relative path "dir2" → "C:/dir1/dir2"! * @param path a path * @see java.nio.file.Paths#get(String, String...) */ @@ -89,7 +89,7 @@ public PathResource(String path) { * Create a new PathResource from a Path handle. *

    Note: Unlike {@link FileSystemResource}, when building relative resources * via {@link #createRelative}, the relative path will be built underneath - * the given root: e.g. Paths.get("C:/dir1/"), relative path "dir2" -> "C:/dir1/dir2"! + * the given root: e.g. Paths.get("C:/dir1/"), relative path "dir2" → "C:/dir1/dir2"! * @param uri a path URI * @see java.nio.file.Paths#get(URI) */ 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 59087313ea58..997925613649 100644 --- a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java @@ -475,14 +475,14 @@ protected AntPathStringMatcher getStringMatcher(String pattern) { /** * Given a pattern and a full path, determine the pattern-mapped part.

    For example:

      - *
    • '{@code /docs/cvs/commit.html}' and '{@code /docs/cvs/commit.html} -> ''
    • - *
    • '{@code /docs/*}' and '{@code /docs/cvs/commit} -> '{@code cvs/commit}'
    • - *
    • '{@code /docs/cvs/*.html}' and '{@code /docs/cvs/commit.html} -> '{@code commit.html}'
    • - *
    • '{@code /docs/**}' and '{@code /docs/cvs/commit} -> '{@code cvs/commit}'
    • - *
    • '{@code /docs/**\/*.html}' and '{@code /docs/cvs/commit.html} -> '{@code cvs/commit.html}'
    • - *
    • '{@code /*.html}' and '{@code /docs/cvs/commit.html} -> '{@code docs/cvs/commit.html}'
    • - *
    • '{@code *.html}' and '{@code /docs/cvs/commit.html} -> '{@code /docs/cvs/commit.html}'
    • - *
    • '{@code *}' and '{@code /docs/cvs/commit.html} -> '{@code /docs/cvs/commit.html}'
    + *
  • '{@code /docs/cvs/commit.html}' and '{@code /docs/cvs/commit.html} → ''
  • + *
  • '{@code /docs/*}' and '{@code /docs/cvs/commit} → '{@code cvs/commit}'
  • + *
  • '{@code /docs/cvs/*.html}' and '{@code /docs/cvs/commit.html} → '{@code commit.html}'
  • + *
  • '{@code /docs/**}' and '{@code /docs/cvs/commit} → '{@code cvs/commit}'
  • + *
  • '{@code /docs/**\/*.html}' and '{@code /docs/cvs/commit.html} → '{@code cvs/commit.html}'
  • + *
  • '{@code /*.html}' and '{@code /docs/cvs/commit.html} → '{@code docs/cvs/commit.html}'
  • + *
  • '{@code *.html}' and '{@code /docs/cvs/commit.html} → '{@code /docs/cvs/commit.html}'
  • + *
  • '{@code *}' and '{@code /docs/cvs/commit.html} → '{@code /docs/cvs/commit.html}'
  • *

    Assumes that {@link #match} returns {@code true} for '{@code pattern}' and '{@code path}', but * does not enforce this. */ diff --git a/spring-core/src/main/java/org/springframework/util/Assert.java b/spring-core/src/main/java/org/springframework/util/Assert.java index fbba65fbc460..fd841793936d 100644 --- a/spring-core/src/main/java/org/springframework/util/Assert.java +++ b/spring-core/src/main/java/org/springframework/util/Assert.java @@ -43,7 +43,7 @@ * *

      * Assert.notNull(clazz, "The class must not be null");
    - * Assert.isTrue(i > 0, "The value must be greater than zero");
    + * Assert.isTrue(i > 0, "The value must be greater than zero");
    * *

    Mainly for internal use within the framework; for a more comprehensive suite * of assertion utilities consider {@code org.apache.commons.lang3.Validate} from diff --git a/spring-core/src/main/java/org/springframework/util/MethodInvoker.java b/spring-core/src/main/java/org/springframework/util/MethodInvoker.java index 8672b0197a60..b3e0c5554806 100644 --- a/spring-core/src/main/java/org/springframework/util/MethodInvoker.java +++ b/spring-core/src/main/java/org/springframework/util/MethodInvoker.java @@ -288,7 +288,7 @@ public Object invoke() throws InvocationTargetException, IllegalAccessException * Algorithm that judges the match between the declared parameter types of a candidate method * and a specific list of arguments that this method is supposed to be invoked with. *

    Determines a weight that represents the class hierarchy difference between types and - * arguments. A direct match, i.e. type Integer -> arg of class Integer, does not increase + * arguments. A direct match, i.e. type Integer → arg of class Integer, does not increase * the result - all direct matches means weight 0. A match between type Object and arg of * class Integer would increase the weight by 2, due to the superclass 2 steps up in the * hierarchy (i.e. Object) being the last one that still matches the required type Object. diff --git a/spring-core/src/main/java/org/springframework/util/PathMatcher.java b/spring-core/src/main/java/org/springframework/util/PathMatcher.java index 5d711d00b222..7268e7ba5b75 100644 --- a/spring-core/src/main/java/org/springframework/util/PathMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/PathMatcher.java @@ -94,7 +94,7 @@ public interface PathMatcher { * Given a pattern and a full path, extract the URI template variables. URI template * variables are expressed through curly brackets ('{' and '}'). *

    For example: For pattern "/hotels/{hotel}" and path "/hotels/1", this method will - * return a map containing "hotel"->"1". + * return a map containing "hotel" → "1". * @param pattern the path pattern, possibly containing URI templates * @param path the full path to extract template variables from * @return a map, containing variable names as keys; variables values as values 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 269257fd6024..5b5c762408fd 100644 --- a/spring-core/src/main/java/org/springframework/util/StringUtils.java +++ b/spring-core/src/main/java/org/springframework/util/StringUtils.java @@ -571,7 +571,7 @@ private static String changeFirstCharacterCase(String str, boolean capitalize) { /** * Extract the filename from the given Java resource path, - * e.g. {@code "mypath/myfile.txt" -> "myfile.txt"}. + * e.g. {@code "mypath/myfile.txt" → "myfile.txt"}. * @param path the file path (may be {@code null}) * @return the extracted filename, or {@code null} if none */ @@ -587,7 +587,7 @@ public static String getFilename(@Nullable String path) { /** * Extract the filename extension from the given Java resource path, - * e.g. "mypath/myfile.txt" -> "txt". + * e.g. "mypath/myfile.txt" → "txt". * @param path the file path (may be {@code null}) * @return the extracted filename extension, or {@code null} if none */ @@ -612,7 +612,7 @@ public static String getFilenameExtension(@Nullable String path) { /** * Strip the filename extension from the given Java resource path, - * e.g. "mypath/myfile.txt" -> "mypath/myfile". + * e.g. "mypath/myfile.txt" → "mypath/myfile". * @param path the file path * @return the path with stripped filename extension */ diff --git a/spring-core/src/main/java/org/springframework/util/comparator/InvertibleComparator.java b/spring-core/src/main/java/org/springframework/util/comparator/InvertibleComparator.java index fbb17f687c5c..7da876615b9d 100644 --- a/spring-core/src/main/java/org/springframework/util/comparator/InvertibleComparator.java +++ b/spring-core/src/main/java/org/springframework/util/comparator/InvertibleComparator.java @@ -81,8 +81,8 @@ public boolean isAscending() { } /** - * Invert the sort order: ascending -> descending or - * descending -> ascending. + * Invert the sort order: ascending → descending or + * descending → ascending. */ public void invertOrder() { this.ascending = !this.ascending; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java index e22d47de3723..680e5feb746d 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java @@ -111,7 +111,7 @@ public LazyConnectionDataSourceProxy(DataSource targetDataSource) { /** * Set the default auto-commit mode to expose when no target Connection - * has been fetched yet (-> actual JDBC Connection default not known yet). + * has been fetched yet (when the actual JDBC Connection default is not known yet). *

    If not specified, the default gets determined by checking a target * Connection on startup. If that check fails, the default will be determined * lazily on first access of a Connection. @@ -123,7 +123,7 @@ public void setDefaultAutoCommit(boolean defaultAutoCommit) { /** * Set the default transaction isolation level to expose when no target Connection - * has been fetched yet (-> actual JDBC Connection default not known yet). + * has been fetched yet (when the actual JDBC Connection default is not known yet). *

    This property accepts the int constant value (e.g. 8) as defined in the * {@link java.sql.Connection} interface; it is mainly intended for programmatic * use. Consider using the "defaultTransactionIsolationName" property for setting diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapter.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapter.java index 8d0957502353..659c11fae8d3 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapter.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapter.java @@ -48,7 +48,7 @@ * <property name="targetDataSource" ref="myTargetDataSource"/> * <property name="username" value="myusername"/> * <property name="password" value="mypassword"/> - * </bean>

    + * </bean>
    * *

    If the "username" is empty, this proxy will simply delegate to the * standard {@code getConnection()} method of the target DataSource. diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java b/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java index f8d2e4b9b42e..1943d753c49d 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java @@ -55,7 +55,7 @@ * <property name="targetConnectionFactory" ref="myTargetConnectionFactory"/> * <property name="username" value="myusername"/> * <property name="password" value="mypassword"/> - * </bean> + * </bean> * *

    If the "username" is empty, this proxy will simply delegate to the standard * {@code createConnection()} method of the target ConnectionFactory. diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/DefaultJmsActivationSpecFactory.java b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/DefaultJmsActivationSpecFactory.java index 1702070063b0..d85d89211fa9 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/DefaultJmsActivationSpecFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/DefaultJmsActivationSpecFactory.java @@ -33,7 +33,7 @@ *

    An ActivationSpec factory is effectively dependent on the concrete * JMS provider, e.g. on ActiveMQ. This default implementation simply * guesses the ActivationSpec class name from the provider's class name - * ("ActiveMQResourceAdapter" -> "ActiveMQActivationSpec" in the same package, + * ("ActiveMQResourceAdapter" → "ActiveMQActivationSpec" in the same package, * or "ActivationSpecImpl" in the same package as the ResourceAdapter class), * and populates the ActivationSpec properties as suggested by the * JCA 1.5 specification (Appendix B). Specify the 'activationSpecClass' @@ -68,7 +68,7 @@ public class DefaultJmsActivationSpecFactory extends StandardJmsActivationSpecFa /** * This implementation guesses the ActivationSpec class name from the - * provider's class name: e.g. "ActiveMQResourceAdapter" -> + * provider's class name: e.g. "ActiveMQResourceAdapter" → * "ActiveMQActivationSpec" in the same package, or a class named * "ActivationSpecImpl" in the same package as the ResourceAdapter class. */ diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointManager.java b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointManager.java index 518736f59e20..c6820c66eb1f 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointManager.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointManager.java @@ -104,7 +104,7 @@ public void setTransactionManager(Object transactionManager) { * {@link #setActivationSpecConfig JmsActivationSpecConfig} objects. *

    This factory is dependent on the concrete JMS provider, e.g. on ActiveMQ. * The default implementation simply guesses the ActivationSpec class name - * from the provider's class name (e.g. "ActiveMQResourceAdapter" -> + * from the provider's class name (e.g. "ActiveMQResourceAdapter" → * "ActiveMQActivationSpec" in the same package), and populates the * ActivationSpec properties as suggested by the JCA 1.5 specification * (plus a couple of autodetected vendor-specific properties). diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandler.java index 0804bff2d0a1..86bd27208508 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandler.java @@ -200,7 +200,7 @@ public void setEmbeddedValueResolver(StringValueResolver resolver) { * {@code @ControllerAdvice} bean. You can use the following adapter code * to register {@code @ControllerAdvice} beans here: *

    -	 * ControllerAdviceBean.findAnnotatedBeans(context).forEach(bean ->
    +	 * ControllerAdviceBean.findAnnotatedBeans(context).forEach(bean ->
     	 *         messageHandler.registerMessagingAdvice(new ControllerAdviceWrapper(bean));
     	 *
     	 * public class ControllerAdviceWrapper implements MessagingAdviceBean {
    diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandler.java
    index 4bcd5c0f4ef5..a779b3272625 100644
    --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandler.java
    +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandler.java
    @@ -461,7 +461,7 @@ private boolean isDataMimeTypeSupported(MimeType dataMimeType) {
     	 *         RSocketMessageHandler.responder(strategies, new ClientHandler());
     	 *
     	 * RSocketRequester.builder()
    -	 *         .rsocketConnector(connector -> connector.acceptor(responder))
    +	 *         .rsocketConnector(connector -> connector.acceptor(responder))
     	 *         .connectTcp("localhost", server.address().getPort());
     	 * 
    * diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringBeanContainer.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringBeanContainer.java index 92064f2a4cb6..b96d9df89b6b 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringBeanContainer.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringBeanContainer.java @@ -46,7 +46,7 @@ * <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> * ... * <property name="jpaPropertyMap"> - * <map> + * <map> * <entry key="hibernate.resource.beans.container"> * <bean class="org.springframework.orm.hibernate5.SpringBeanContainer"/> * </entry> diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DatabaseClient.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DatabaseClient.java index 324e419ce000..7b0c7ddd590d 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DatabaseClient.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DatabaseClient.java @@ -44,9 +44,9 @@ * ConnectionFactory factory = … * * DatabaseClient client = DatabaseClient.create(factory); - * Mono>Actor;lt actor = client.sql("select first_name, last_name from t_actor") - * .map(row -> new Actor(row.get("first_name, String.class"), - * row.get("last_name, String.class"))) + * Mono<Actor> actor = client.sql("select first_name, last_name from t_actor") + * .map(row -> new Actor(row.get("first_name, String.class"), + * row.get("last_name, String.class"))) * .first(); * * @@ -190,7 +190,7 @@ interface GenericExecuteSpec { * before it is executed. For example: *
     		 * DatabaseClient client = …;
    -		 * client.sql("SELECT book_id FROM book").filter(statement -> statement.fetchSize(100))
    +		 * client.sql("SELECT book_id FROM book").filter(statement -> statement.fetchSize(100))
     		 * 
    * @param filterFunction the filter to be added to the chain */ @@ -205,7 +205,7 @@ default GenericExecuteSpec filter(Function * DatabaseClient client = …; - * client.sql("SELECT book_id FROM book").filter((statement, next) -> next.execute(statement.fetchSize(100))) + * client.sql("SELECT book_id FROM book").filter((statement, next) -> next.execute(statement.fetchSize(100))) * * @param filter the filter to be added to the chain */ diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ExecuteFunction.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ExecuteFunction.java index c60888f6ebff..a0bfb22d8a2d 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ExecuteFunction.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ExecuteFunction.java @@ -36,7 +36,7 @@ * For example: *

      * DatabaseClient.builder()
    - *		.executeFunction(statement -> statement.execute())
    + *		.executeFunction(statement -> statement.execute())
      * 		.build();
      * 
    * diff --git a/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java b/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java index 10e1f39b3a55..bd57ec72fcd0 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java @@ -256,7 +256,7 @@ public RequestExpectation findExpectation(ClientHttpRequest request) throws IOEx /** * Invoke this for an expectation that has been matched. *

    The count of the given expectation is incremented, then it is - * either stored if remainingCount > 0 or removed otherwise. + * either stored if remainingCount > 0 or removed otherwise. */ public void update(RequestExpectation expectation) { expectation.incrementAndValidate(); diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/FluxExchangeResult.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/FluxExchangeResult.java index a8d48e9e9d14..f15528a10246 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/FluxExchangeResult.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/FluxExchangeResult.java @@ -80,7 +80,7 @@ public Flux getResponseBody() { * .exchange() * .expectStatus().isOk() * .returnResult() - * .consumeWith(result -> assertThat(...); + * .consumeWith(result -> assertThat(...); * * @param consumer the consumer for {@code "this"} instance */ diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java index 878a901c2267..141428f171ab 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java @@ -448,15 +448,15 @@ interface Builder { *

     		 * client.get().uri("/accounts/1")
     		 *         .exchange()
    -		 *         .expectBody(Person.class).consumeWith(exchangeResult -> ... ));
    +		 *         .expectBody(Person.class).consumeWith(exchangeResult -> ... ));
     		 *
     		 * client.get().uri("/accounts")
     		 *         .exchange()
    -		 *         .expectBodyList(Person.class).consumeWith(exchangeResult -> ... ));
    +		 *         .expectBodyList(Person.class).consumeWith(exchangeResult -> ... ));
     		 *
     		 * client.get().uri("/accounts/1")
     		 *         .exchange()
    -		 *         .expectBody().consumeWith(exchangeResult -> ... ));
    +		 *         .expectBody().consumeWith(exchangeResult -> ... ));
     		 * 
    *

    Note that the configured consumer does not apply to responses * decoded to {@code Flux} which can be consumed outside the workflow @@ -802,8 +802,8 @@ interface ResponseSpec { *

     		 * webTestClient.get().uri("/hello").exchange()
     		 *     .expectAll(
    -		 *         responseSpec -> responseSpec.expectStatus().isOk(),
    -		 *         responseSpec -> responseSpec.expectBody(String.class).isEqualTo("Hello, World!")
    +		 *         responseSpec -> responseSpec.expectStatus().isOk(),
    +		 *         responseSpec -> responseSpec.expectBody(String.class).isEqualTo("Hello, World!")
     		 *     );
     		 * 
    * @param consumers the list of {@code ResponseSpec} consumers diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java index 2f80f0cefe57..2e6f56756448 100644 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java +++ b/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java @@ -43,7 +43,7 @@ *
      * <bean id="myTargetConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
      *   <property name="jndiName" value="java:comp/env/cci/mycf"/>
    - * </bean>
    + * </bean>
      *
      * <bean id="myConnectionFactory" class="org.springframework.jca.cci.connection.ConnectionSpecConnectionFactoryAdapter">
      *   <property name="targetConnectionFactory" ref="myTargetConnectionFactory"/>
    diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionProxyFactoryBean.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionProxyFactoryBean.java
    index 56e5cef3d819..774107b46ff1 100644
    --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionProxyFactoryBean.java
    +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionProxyFactoryBean.java
    @@ -79,7 +79,7 @@
      * deriving concrete child bean definitions for specific target objects.
      * This reduces the per-bean definition effort to a minimum.
      *
    - * 
    + * 
      * <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
      *     abstract="true">
      *   <property name="transactionManager" ref="transactionManager"/>
    diff --git a/spring-web/src/main/java/org/springframework/http/ContentDisposition.java b/spring-web/src/main/java/org/springframework/http/ContentDisposition.java
    index 32c718814b2c..1d5254e336a8 100644
    --- a/spring-web/src/main/java/org/springframework/http/ContentDisposition.java
    +++ b/spring-web/src/main/java/org/springframework/http/ContentDisposition.java
    @@ -576,14 +576,13 @@ public interface Builder {
     		Builder filename(String filename);
     
     		/**
    -		 * Set the value of the {@literal filename*} that will be encoded as
    -		 * defined in the RFC 5987. Only the US-ASCII, UTF-8 and ISO-8859-1
    +		 * Set the value of the {@code filename} that will be encoded as
    +		 * defined in RFC 5987. Only the US-ASCII, UTF-8, and ISO-8859-1
     		 * charsets are supported.
     		 * 

    Note: Do not use this for a - * {@code "multipart/form-data"} requests as per - * RFC 7578, Section 4.2 - * and also RFC 5987 itself mentions it does not apply to multipart - * requests. + * {@code "multipart/form-data"} request since + * RFC 7578, Section 4.2 + * and also RFC 5987 mention it does not apply to multipart requests. */ Builder filename(String filename, Charset charset); diff --git a/spring-web/src/main/java/org/springframework/http/HttpStatus.java b/spring-web/src/main/java/org/springframework/http/HttpStatus.java index f6a9911d1ab5..486b524df91b 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpStatus.java +++ b/spring-web/src/main/java/org/springframework/http/HttpStatus.java @@ -285,21 +285,21 @@ public enum HttpStatus { I_AM_A_TEAPOT(418, Series.CLIENT_ERROR, "I'm a teapot"), /** * @deprecated See - * + * * WebDAV Draft Changes */ @Deprecated INSUFFICIENT_SPACE_ON_RESOURCE(419, Series.CLIENT_ERROR, "Insufficient Space On Resource"), /** * @deprecated See - * + * * WebDAV Draft Changes */ @Deprecated METHOD_FAILURE(420, Series.CLIENT_ERROR, "Method Failure"), /** * @deprecated - * See + * See * WebDAV Draft Changes */ @Deprecated diff --git a/spring-web/src/main/java/org/springframework/http/client/ClientHttpRequestInterceptor.java b/spring-web/src/main/java/org/springframework/http/client/ClientHttpRequestInterceptor.java index 966869878643..82e6f7be71c3 100644 --- a/spring-web/src/main/java/org/springframework/http/client/ClientHttpRequestInterceptor.java +++ b/spring-web/src/main/java/org/springframework/http/client/ClientHttpRequestInterceptor.java @@ -42,15 +42,15 @@ public interface ClientHttpRequestInterceptor { * request and response to the next entity in the chain. *

    A typical implementation of this method would follow the following pattern: *

      - *
    1. Examine the {@linkplain HttpRequest request} and body
    2. + *
    3. Examine the {@linkplain HttpRequest request} and body.
    4. *
    5. Optionally {@linkplain org.springframework.http.client.support.HttpRequestWrapper * wrap} the request to filter HTTP attributes.
    6. *
    7. Optionally modify the body of the request.
    8. - *
    9. Either *
        + *
      • Either *
      • execute the request using * {@link ClientHttpRequestExecution#execute(org.springframework.http.HttpRequest, byte[])},
      • - * or + *
      • or
      • *
      • do not execute the request to block the execution altogether.
      • *
      *
    10. Optionally wrap the response to filter HTTP attributes.
    11. diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java index dac546303944..ccd692808702 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java @@ -55,7 +55,7 @@ *

      Given the following XML: * *

      - * <root>
      + * <root>
        *     <child>foo</child>
        *     <child>bar</child>
        * </root>
      diff --git a/spring-web/src/main/java/org/springframework/http/converter/ObjectToStringHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/ObjectToStringHttpMessageConverter.java
      index d35f7f4d26d4..6f6ac69bd450 100644
      --- a/spring-web/src/main/java/org/springframework/http/converter/ObjectToStringHttpMessageConverter.java
      +++ b/spring-web/src/main/java/org/springframework/http/converter/ObjectToStringHttpMessageConverter.java
      @@ -38,11 +38,11 @@
        * 

      A usage example: * *

      - * <bean class="org.springframework.http.converter.ObjectToStringHttpMessageConverter">
      - *   <constructor-arg>
      - *     <bean class="org.springframework.context.support.ConversionServiceFactoryBean"/>
      - *   </constructor-arg>
      - * </bean>
      + * <bean class="org.springframework.http.converter.ObjectToStringHttpMessageConverter">
      + *   <constructor-arg>
      + *     <bean class="org.springframework.context.support.ConversionServiceFactoryBean"/>
      + *   </constructor-arg>
      + * </bean>
        * 
      * * @author Dmitry Katsubo diff --git a/spring-web/src/main/java/org/springframework/http/converter/feed/AtomFeedHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/feed/AtomFeedHttpMessageConverter.java index 88a074752a4e..ae0a5fdb0bda 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/feed/AtomFeedHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/feed/AtomFeedHttpMessageConverter.java @@ -25,7 +25,7 @@ * that can read and write Atom feeds. Specifically, this converter can handle {@link Feed} * objects from the ROME project. * - *

      >NOTE: As of Spring 4.1, this is based on the {@code com.rometools} + *

      NOTE: As of Spring 4.1, this is based on the {@code com.rometools} * variant of ROME, version 1.5. Please upgrade your build dependency. * *

      By default, this converter reads and writes the media type ({@code application/atom+xml}). diff --git a/spring-web/src/main/java/org/springframework/http/converter/feed/RssChannelHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/feed/RssChannelHttpMessageConverter.java index 0ecf87a703ea..28a5f19e7881 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/feed/RssChannelHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/feed/RssChannelHttpMessageConverter.java @@ -25,7 +25,7 @@ * that can read and write RSS feeds. Specifically, this converter can handle {@link Channel} * objects from the ROME project. * - *

      >NOTE: As of Spring 4.1, this is based on the {@code com.rometools} + *

      NOTE: As of Spring 4.1, this is based on the {@code com.rometools} * variant of ROME, version 1.5. Please upgrade your build dependency. * *

      By default, this converter reads and writes the media type ({@code application/rss+xml}). diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleHttpServerJaxWsServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleHttpServerJaxWsServiceExporter.java index 54382b30d6e7..8b5ff40dc2c6 100644 --- a/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleHttpServerJaxWsServiceExporter.java +++ b/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleHttpServerJaxWsServiceExporter.java @@ -135,7 +135,7 @@ public void setShutdownDelay(int shutdownDelay) { * Set the base path for context publication. Default is "/". *

      For each context publication path, the service name will be * appended to this base address. E.g. service name "OrderService" - * -> "/OrderService". + * → "/OrderService". * @see javax.xml.ws.Endpoint#publish(Object) * @see javax.jws.WebService#serviceName() */ diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleJaxWsServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleJaxWsServiceExporter.java index 06786578f9c0..33441765a8a2 100644 --- a/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleJaxWsServiceExporter.java +++ b/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleJaxWsServiceExporter.java @@ -52,7 +52,7 @@ public class SimpleJaxWsServiceExporter extends AbstractJaxWsServiceExporter { * Default is "http://localhost:8080/". *

      For each actual publication address, the service name will be * appended to this base address. E.g. service name "OrderService" - * -> "http://localhost:8080/OrderService". + * → "http://localhost:8080/OrderService". * @see javax.xml.ws.Endpoint#publish(String) * @see javax.jws.WebService#serviceName() */ diff --git a/spring-web/src/main/java/org/springframework/web/SpringServletContainerInitializer.java b/spring-web/src/main/java/org/springframework/web/SpringServletContainerInitializer.java index da3cd91c3d8c..c5ab1e70d114 100644 --- a/spring-web/src/main/java/org/springframework/web/SpringServletContainerInitializer.java +++ b/spring-web/src/main/java/org/springframework/web/SpringServletContainerInitializer.java @@ -61,8 +61,8 @@ * *

        * <absolute-ordering>
      - *   <name>some_web_fragment</name>
      - *   <name>spring_web</name>
      + *   <name>some_web_fragment</name>
      + *   <name>spring_web</name>
        * </absolute-ordering>
        * 
      * diff --git a/spring-web/src/main/java/org/springframework/web/WebApplicationInitializer.java b/spring-web/src/main/java/org/springframework/web/WebApplicationInitializer.java index 337f53291e7a..955fc624b984 100644 --- a/spring-web/src/main/java/org/springframework/web/WebApplicationInitializer.java +++ b/spring-web/src/main/java/org/springframework/web/WebApplicationInitializer.java @@ -36,15 +36,15 @@ * follows: *
        * <servlet>
      - *   <servlet-name>dispatcher</servlet-name>
      + *   <servlet-name>dispatcher</servlet-name>
        *   <servlet-class>
        *     org.springframework.web.servlet.DispatcherServlet
        *   </servlet-class>
      - *   <init-param>
      - *     <param-name>contextConfigLocation</param-name>
      - *     <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
      + *   <init-param>
      + *     <param-name>contextConfigLocation</param-name>
      + *     <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
        *   </init-param>
      - *   <load-on-startup>1</load-on-startup>
      + *   <load-on-startup>1</load-on-startup>
        * </servlet>
        *
        * <servlet-mapping>
      diff --git a/spring-web/src/main/java/org/springframework/web/jsf/el/SpringBeanFacesELResolver.java b/spring-web/src/main/java/org/springframework/web/jsf/el/SpringBeanFacesELResolver.java
      index 922174d830d0..ab16c0baa5c6 100644
      --- a/spring-web/src/main/java/org/springframework/web/jsf/el/SpringBeanFacesELResolver.java
      +++ b/spring-web/src/main/java/org/springframework/web/jsf/el/SpringBeanFacesELResolver.java
      @@ -36,33 +36,33 @@
        * 

      Configure this resolver in your {@code faces-config.xml} file as follows: * *

      - * <application>
      + * <application>
        *   ...
      - *   <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
      - * </application>
      + * <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> + * </application>
      * * All your JSF expressions can then implicitly refer to the names of * Spring-managed service layer beans, for example in property values of * JSF-managed beans: * *
      - * <managed-bean>
      - *   <managed-bean-name>myJsfManagedBean</managed-bean-name>
      - *   <managed-bean-class>example.MyJsfManagedBean</managed-bean-class>
      - *   <managed-bean-scope>session</managed-bean-scope>
      - *   <managed-property>
      - *     <property-name>mySpringManagedBusinessObject</property-name>
      - *     <value>#{mySpringManagedBusinessObject}</value>
      - *   </managed-property>
      - * </managed-bean>
      + * <managed-bean> + * <managed-bean-name>myJsfManagedBean</managed-bean-name> + * <managed-bean-class>example.MyJsfManagedBean</managed-bean-class> + * <managed-bean-scope>session</managed-bean-scope> + * <managed-property> + * <property-name>mySpringManagedBusinessObject</property-name> + * <value>#{mySpringManagedBusinessObject}</value> + * </managed-property> + * </managed-bean>
      * * with "mySpringManagedBusinessObject" defined as Spring bean in * applicationContext.xml: * *
      - * <bean id="mySpringManagedBusinessObject" class="example.MySpringManagedBusinessObject">
      + * <bean id="mySpringManagedBusinessObject" class="example.MySpringManagedBusinessObject">
        *   ...
      - * </bean>
      + * </bean>
    * * @author Juergen Hoeller * @since 2.5 diff --git a/spring-web/src/main/java/org/springframework/web/jsf/el/WebApplicationContextFacesELResolver.java b/spring-web/src/main/java/org/springframework/web/jsf/el/WebApplicationContextFacesELResolver.java index d729187464d3..fd8d4a132bc2 100644 --- a/spring-web/src/main/java/org/springframework/web/jsf/el/WebApplicationContextFacesELResolver.java +++ b/spring-web/src/main/java/org/springframework/web/jsf/el/WebApplicationContextFacesELResolver.java @@ -45,10 +45,10 @@ *

    Configure this resolver in your {@code faces-config.xml} file as follows: * *

    - * <application>
    + * <application>
      *   ...
    - *   <el-resolver>org.springframework.web.jsf.el.WebApplicationContextFacesELResolver</el-resolver>
    - * </application>
    + * <el-resolver>org.springframework.web.jsf.el.WebApplicationContextFacesELResolver</el-resolver> + * </application>
    * * @author Juergen Hoeller * @since 2.5 diff --git a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java index d8cef567578e..0062325b64e8 100644 --- a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java +++ b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java @@ -248,7 +248,7 @@ interface Builder { * Configure a consumer to modify the current request using a builder. *

    Effectively this: *

    -		 * exchange.mutate().request(builder-> builder.method(HttpMethod.PUT));
    +		 * exchange.mutate().request(builder -> builder.method(HttpMethod.PUT));
     		 *
     		 * // vs...
     		 *
    diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
    index 663dbb7566c4..e38fdff9b53c 100644
    --- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
    +++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
    @@ -290,11 +290,11 @@ public String getPathWithinServletMapping(HttpServletRequest request) {
     	 * i.e. the part of the request's URL beyond the part that called the servlet,
     	 * or "" if the whole URL has been used to identify the servlet.
     	 * 

    Detects include request URL if called within a RequestDispatcher include. - *

    E.g.: servlet mapping = "/*"; request URI = "/test/a" -> "/test/a". - *

    E.g.: servlet mapping = "/"; request URI = "/test/a" -> "/test/a". - *

    E.g.: servlet mapping = "/test/*"; request URI = "/test/a" -> "/a". - *

    E.g.: servlet mapping = "/test"; request URI = "/test" -> "". - *

    E.g.: servlet mapping = "/*.test"; request URI = "/a.test" -> "". + *

    E.g.: servlet mapping = "/*"; request URI = "/test/a" → "/test/a". + *

    E.g.: servlet mapping = "/"; request URI = "/test/a" → "/test/a". + *

    E.g.: servlet mapping = "/test/*"; request URI = "/test/a" → "/a". + *

    E.g.: servlet mapping = "/test"; request URI = "/test" → "". + *

    E.g.: servlet mapping = "/*.test"; request URI = "/a.test" → "". * @param request current HTTP request * @param pathWithinApp a precomputed path within the application * @return the path within the servlet mapping, or "" diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFunction.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFunction.java index fddb3389c56a..c5325284a64d 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFunction.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFunction.java @@ -32,7 +32,7 @@ * * Mono<String> bodyMono = exchangeFunction * .exchange(request) - * .flatMap(response -> response.bodyToMono(String.class)); + * .flatMap(response -> response.bodyToMono(String.class)); *

    * * @author Arjen Poutsma diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java index 801609d68fbd..4d929888bde8 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java @@ -522,7 +522,7 @@ interface RequestHeadersSpec> { * Mono<Object> entityMono = client.get() * .uri("/persons/1") * .accept(MediaType.APPLICATION_JSON) - * .exchangeToMono(response -> { + * .exchangeToMono(response -> { * if (response.statusCode().equals(HttpStatus.OK)) { * return response.bodyToMono(Person.class); * } @@ -554,7 +554,7 @@ interface RequestHeadersSpec> { * Mono<Object> entityMono = client.get() * .uri("/persons") * .accept(MediaType.APPLICATION_JSON) - * .exchangeToFlux(response -> { + * .exchangeToFlux(response -> { * if (response.statusCode().equals(HttpStatus.OK)) { * return response.bodyToFlux(Person.class); * } @@ -751,7 +751,7 @@ interface ResponseSpec { * Provide a function to map specific error status codes to an error * signal to be propagated downstream instead of the response. *

    By default, if there are no matching status handlers, responses - * with status codes >= 400 are mapped to + * with status codes >= 400 are mapped to * {@link WebClientResponseException} which is created with * {@link ClientResponse#createException()}. *

    To suppress the treatment of a status code as an error and process @@ -766,7 +766,7 @@ interface ResponseSpec { * .retrieve() * .bodyToMono(Account.class) * .onErrorResume(WebClientResponseException.class, - * ex -> ex.getRawStatusCode() == 404 ? Mono.empty() : Mono.error(ex)); + * ex -> ex.getRawStatusCode() == 404 ? Mono.empty() : Mono.error(ex)); *

    * @param statusPredicate to match responses with * @param exceptionFunction to map the response to an error signal diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java index 64d1e3ed9b61..30157153d4ae 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java @@ -670,7 +670,7 @@ public interface Builder { *
     		 * RouterFunction<ServerResponse> nestedRoute =
     		 *   RouterFunctions.route()
    -		 *     .nest(RequestPredicates.path("/user"), () ->
    +		 *     .nest(RequestPredicates.path("/user"), () ->
     		 *       RouterFunctions.route()
     		 *         .GET(this::listUsers)
     		 *         .POST(this::createUser)
    @@ -695,7 +695,7 @@ public interface Builder {
     		 * 
     		 * RouterFunction<ServerResponse> nestedRoute =
     		 *   RouterFunctions.route()
    -		 *     .nest(RequestPredicates.path("/user"), builder ->
    +		 *     .nest(RequestPredicates.path("/user"), builder ->
     		 *       builder.GET(this::listUsers)
     		 *              .POST(this::createUser))
     		 *     .build();
    @@ -740,7 +740,7 @@ public interface Builder {
     		 * 
     		 * RouterFunction<ServerResponse> nestedRoute =
     		 *   RouterFunctions.route()
    -		 *     .path("/user", builder ->
    +		 *     .path("/user", builder ->
     		 *       builder.GET(this::listUsers)
     		 *              .POST(this::createUser))
     		 *     .build();
    @@ -762,7 +762,7 @@ public interface Builder {
     		 * RouterFunction<ServerResponse> filteredRoute =
     		 *   RouterFunctions.route()
     		 *     .GET("/user", this::listUsers)
    -		 *     .filter((request, next) -> {
    +		 *     .filter((request, next) -> {
     		 *       // check for authentication headers
     		 *       if (isAuthenticated(request)) {
     		 *         return next.handle(request);
    @@ -788,7 +788,7 @@ public interface Builder {
     		 * RouterFunction<ServerResponse> filteredRoute =
     		 *   RouterFunctions.route()
     		 *     .GET("/user", this::listUsers)
    -		 *     .before(request -> {
    +		 *     .before(request -> {
     		 *       log(request);
     		 *       return request;
     		 *     })
    @@ -809,7 +809,7 @@ public interface Builder {
     		 * RouterFunction<ServerResponse> filteredRoute =
     		 *   RouterFunctions.route()
     		 *     .GET("/user", this::listUsers)
    -		 *     .after((request, response) -> {
    +		 *     .after((request, response) -> {
     		 *       log(response);
     		 *       return response;
     		 *     })
    @@ -829,8 +829,8 @@ public interface Builder {
     		 * RouterFunction<ServerResponse> filteredRoute =
     		 *   RouterFunctions.route()
     		 *     .GET("/user", this::listUsers)
    -		 *     .onError(e -> e instanceof IllegalStateException,
    -		 *       (e, request) -> ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).build())
    +		 *     .onError(e -> e instanceof IllegalStateException,
    +		 *       (e, request) -> ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).build())
     		 *     .build();
     		 * 
    * @param predicate the type of exception to filter @@ -850,7 +850,7 @@ Builder onError(Predicate predicate, * RouterFunctions.route() * .GET("/user", this::listUsers) * .onError(IllegalStateException.class, - * (e, request) -> ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).build()) + * (e, request) -> ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).build()) * .build(); *
    * @param exceptionType the type of exception to filter diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java index 5376269f2417..5b44e5a45647 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java @@ -310,7 +310,7 @@ default String pathVariable(String name) { * public Mono<ServerResponse> myHandleMethod(ServerRequest request) { * Instant lastModified = // application-specific calculation * return request.checkNotModified(lastModified) - * .switchIfEmpty(Mono.defer(() -> { + * .switchIfEmpty(Mono.defer(() -> { * // further request processing, actually building content * return ServerResponse.ok().body(...); * })); @@ -344,7 +344,7 @@ default Mono checkNotModified(Instant lastModified) { * public Mono<ServerResponse> myHandleMethod(ServerRequest request) { * String eTag = // application-specific calculation * return request.checkNotModified(eTag) - * .switchIfEmpty(Mono.defer(() -> { + * .switchIfEmpty(Mono.defer(() -> { * // further request processing, actually building content * return ServerResponse.ok().body(...); * })); @@ -381,7 +381,7 @@ default Mono checkNotModified(String etag) { * Instant lastModified = // application-specific calculation * String eTag = // application-specific calculation * return request.checkNotModified(lastModified, eTag) - * .switchIfEmpty(Mono.defer(() -> { + * .switchIfEmpty(Mono.defer(() -> { * // further request processing, actually building content * return ServerResponse.ok().body(...); * })); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/UrlBasedViewResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/UrlBasedViewResolver.java index 0a31cb5aaf39..fd46f78331fa 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/UrlBasedViewResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/UrlBasedViewResolver.java @@ -45,7 +45,7 @@ * specified prefix and/or suffix. Exporting an attribute that holds the * RequestContext to all views is explicitly supported. * - *

    Example: prefix="templates/", suffix=".ftl", viewname="test" -> + *

    Example: prefix="templates/", suffix=".ftl", viewname="test" → * "templates/test.ftl" * *

    As a special feature, redirect URLs can be specified via the "redirect:" diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketHandler.java index 616931ebda3d..0703dae330d4 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketHandler.java @@ -45,13 +45,13 @@ * public Mono<Void> handle(WebSocketSession session) { * * Flux<WebSocketMessage> output = session.receive() - * .doOnNext(message -> { + * .doOnNext(message -> { * // ... * }) - * .concatMap(message -> { + * .concatMap(message -> { * // ... * }) - * .map(value -> session.textMessage("Echo " + value)); + * .map(value -> session.textMessage("Echo " + value)); * * return session.send(output); * } @@ -68,10 +68,10 @@ * public Mono<Void> handle(WebSocketSession session) { * * Mono<Void> input = session.receive() - * .doOnNext(message -> { + * .doOnNext(message -> { * // ... * }) - * .concatMap(message -> { + * .concatMap(message -> { * // ... * }) * .then(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java index 5be28f3e13e0..869b4c6979c5 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java @@ -1268,7 +1268,7 @@ protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Ex } /** - * No handler found -> set appropriate HTTP response status. + * No handler found → set appropriate HTTP response status. * @param request current HTTP request * @param response current HTTP response * @throws Exception if preparing the response failed diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/ModelAndView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/ModelAndView.java index 9dbb3af4aafb..b10775cf81c7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/ModelAndView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/ModelAndView.java @@ -303,7 +303,7 @@ public ModelAndView addObject(Object attributeValue) { /** * Add all attributes contained in the provided Map to the model. - * @param modelMap a Map of attributeName -> attributeValue pairs + * @param modelMap a Map of attributeName → attributeValue pairs * @see ModelMap#addAllAttributes(Map) * @see #getModelMap() */ diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java index 745bce13ae41..95a59373f4b4 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java @@ -582,7 +582,7 @@ public interface Builder { *

     		 * RouterFunction<ServerResponse> nestedRoute =
     		 *   RouterFunctions.route()
    -		 *     .nest(RequestPredicates.path("/user"), () ->
    +		 *     .nest(RequestPredicates.path("/user"), () ->
     		 *       RouterFunctions.route()
     		 *         .GET(this::listUsers)
     		 *         .POST(this::createUser)
    @@ -607,7 +607,7 @@ public interface Builder {
     		 * 
     		 * RouterFunction<ServerResponse> nestedRoute =
     		 *   RouterFunctions.route()
    -		 *     .nest(RequestPredicates.path("/user"), builder ->
    +		 *     .nest(RequestPredicates.path("/user"), builder ->
     		 *       builder.GET(this::listUsers)
     		 *              .POST(this::createUser))
     		 *     .build();
    @@ -652,7 +652,7 @@ public interface Builder {
     		 * 
     		 * RouterFunction<ServerResponse> nestedRoute =
     		 *   RouterFunctions.route()
    -		 *     .path("/user", builder ->
    +		 *     .path("/user", builder ->
     		 *       builder.GET(this::listUsers)
     		 *              .POST(this::createUser))
     		 *     .build();
    @@ -674,7 +674,7 @@ public interface Builder {
     		 * RouterFunction<ServerResponse> filteredRoute =
     		 *   RouterFunctions.route()
     		 *     .GET("/user", this::listUsers)
    -		 *     .filter((request, next) -> {
    +		 *     .filter((request, next) -> {
     		 *       // check for authentication headers
     		 *       if (isAuthenticated(request)) {
     		 *         return next.handle(request);
    @@ -700,7 +700,7 @@ public interface Builder {
     		 * RouterFunction<ServerResponse> filteredRoute =
     		 *   RouterFunctions.route()
     		 *     .GET("/user", this::listUsers)
    -		 *     .before(request -> {
    +		 *     .before(request -> {
     		 *       log(request);
     		 *       return request;
     		 *     })
    @@ -721,7 +721,7 @@ public interface Builder {
     		 * RouterFunction<ServerResponse> filteredRoute =
     		 *   RouterFunctions.route()
     		 *     .GET("/user", this::listUsers)
    -		 *     .after((request, response) -> {
    +		 *     .after((request, response) -> {
     		 *       log(response);
     		 *       return response;
     		 *     })
    @@ -741,8 +741,8 @@ public interface Builder {
     		 * RouterFunction<ServerResponse> filteredRoute =
     		 *   RouterFunctions.route()
     		 *     .GET("/user", this::listUsers)
    -		 *     .onError(e -> e instanceof IllegalStateException,
    -		 *       (e, request) -> ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).build())
    +		 *     .onError(e -> e instanceof IllegalStateException,
    +		 *       (e, request) -> ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).build())
     		 *     .build();
     		 * 
    * @param predicate the type of exception to filter @@ -762,7 +762,7 @@ Builder onError(Predicate predicate, * RouterFunctions.route() * .GET("/user", this::listUsers) * .onError(IllegalStateException.class, - * (e, request) -> ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).build()) + * (e, request) -> ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).build()) * .build(); *
    * @param exceptionType the type of exception to filter diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java index d8f2f2d013c1..ce50a2466b93 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java @@ -259,7 +259,7 @@ default String pathVariable(String name) { * public ServerResponse myHandleMethod(ServerRequest request) { * Instant lastModified = // application-specific calculation * return request.checkNotModified(lastModified) - * .orElseGet(() -> { + * .orElseGet(() -> { * // further request processing, actually building content * return ServerResponse.ok().body(...); * }); @@ -293,7 +293,7 @@ default Optional checkNotModified(Instant lastModified) { * public ServerResponse myHandleMethod(ServerRequest request) { * String eTag = // application-specific calculation * return request.checkNotModified(eTag) - * .orElseGet(() -> { + * .orElseGet(() -> { * // further request processing, actually building content * return ServerResponse.ok().body(...); * }); @@ -330,7 +330,7 @@ default Optional checkNotModified(String etag) { * Instant lastModified = // application-specific calculation * String eTag = // application-specific calculation * return request.checkNotModified(lastModified, eTag) - * .orElseGet(() -> { + * .orElseGet(() -> { * // further request processing, actually building content * return ServerResponse.ok().body(...); * }); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java index 2c1479ca70f3..0923087483bb 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerResponse.java @@ -267,14 +267,14 @@ static ServerResponse async(Object asyncResponse, Duration timeout) { *

    For example: *

     	 * public ServerResponse handleSse(ServerRequest request) {
    -	 *     return ServerResponse.sse(sse -> sse.send("Hello World!"));
    +	 *     return ServerResponse.sse(sse -> sse.send("Hello World!"));
     	 * }
     	 * 
    * *

    or, to set both the id and event type: *

     	 * public ServerResponse handleSse(ServerRequest request) {
    -	 *     return ServerResponse.sse(sse -> sse
    +	 *     return ServerResponse.sse(sse -> sse
     	 *         .id("42)
     	 *         .event("event")
     	 *         .send("Hello World!"));
    @@ -296,14 +296,14 @@ static ServerResponse sse(Consumer consumer) {
     	 * 

    For example: *

     	 * public ServerResponse handleSse(ServerRequest request) {
    -	 *     return ServerResponse.sse(sse -> sse.send("Hello World!"));
    +	 *     return ServerResponse.sse(sse -> sse.send("Hello World!"));
     	 * }
     	 * 
    * *

    or, to set both the id and event type: *

     	 * public ServerResponse handleSse(ServerRequest request) {
    -	 *     return ServerResponse.sse(sse -> sse
    +	 *     return ServerResponse.sse(sse -> sse
     	 *         .id("42)
     	 *         .event("event")
     	 *         .send("Hello World!"));
    diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java
    index 542f0ae8f87d..acb57f665210 100644
    --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java
    +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java
    @@ -61,7 +61,6 @@
      * 

    This exception resolver is enabled by default in the common Spring * {@link org.springframework.web.servlet.DispatcherServlet}. * - *

    * * * diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java index e6bb3a73a592..2dd0aa5180d3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java @@ -244,7 +244,7 @@ public final CacheControl getCacheControl() { *
      *
    • seconds == -1 (default value): no generation cache-related headers
    • *
    • seconds == 0: "Cache-Control: no-store" will prevent caching
    • - *
    • seconds > 0: "Cache-Control: max-age=seconds" will ask to cache content
    • + *
    • seconds > 0: "Cache-Control: max-age=seconds" will ask to cache content
    • *
    *

    For more specific needs, a custom {@link org.springframework.http.CacheControl} * should be used. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/InternalResourceView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/InternalResourceView.java index 6deab1ca3b48..192aa5681237 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/InternalResourceView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/InternalResourceView.java @@ -51,7 +51,7 @@ * </bean> * * Every view name returned from a handler will be translated to a JSP - * resource (for example: "myView" -> "/WEB-INF/jsp/myView.jsp"), using + * resource (for example: "myView" → "/WEB-INF/jsp/myView.jsp"), using * this view class by default. * * @author Rod Johnson diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/JstlView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/JstlView.java index c11eb4e6c94d..8b36835d254e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/JstlView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/JstlView.java @@ -47,7 +47,7 @@ * </bean> * * Every view name returned from a handler will be translated to a JSP - * resource (for example: "myView" -> "/WEB-INF/jsp/myView.jsp"), using + * resource (for example: "myView" → "/WEB-INF/jsp/myView.jsp"), using * this view class to enable explicit JSTL support. * *

    The specified MessageSource loads messages from "messages.properties" etc diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/UrlBasedViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/UrlBasedViewResolver.java index d25f426d9e4e..323f1ec93b15 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/UrlBasedViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/UrlBasedViewResolver.java @@ -49,7 +49,7 @@ * specified prefix and/or suffix. Exporting an attribute that holds the * RequestContext to all views is explicitly supported. * - *

    Example: prefix="/WEB-INF/jsp/", suffix=".jsp", viewname="test" -> + *

    Example: prefix="/WEB-INF/jsp/", suffix=".jsp", viewname="test" → * "/WEB-INF/jsp/test.jsp" * *

    As a special feature, redirect URLs can be specified via the "redirect:" @@ -342,14 +342,16 @@ public Map getAttributesMap() { } /** - * Specify whether views resolved by this resolver should add path variables to the model or not. - *

    >The default setting is to let each View decide (see {@link AbstractView#setExposePathVariables}. - * However, you can use this property to override that. + * Specify whether views resolved by this resolver should add path + * variables to the model or not. + *

    The default setting is to let each View decide + * (see {@link AbstractView#setExposePathVariables}). However, you + * can use this property to override that. * @param exposePathVariables *

      *
    • {@code true} - all Views resolved by this resolver will expose path variables *
    • {@code false} - no Views resolved by this resolver will expose path variables - *
    • {@code null} - individual Views can decide for themselves (this is used by the default) + *
    • {@code null} - individual Views can decide for themselves (this is used by default) *
    * @see AbstractView#setExposePathVariables */ diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractAtomFeedView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractAtomFeedView.java index 58e0893cd272..1e17ce42aaad 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractAtomFeedView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractAtomFeedView.java @@ -29,7 +29,7 @@ * Abstract superclass for Atom Feed views, using the * ROME package. * - *

    >NOTE: As of Spring 4.1, this is based on the {@code com.rometools} + *

    NOTE: As of Spring 4.1, this is based on the {@code com.rometools} * variant of ROME, version 1.5. Please upgrade your build dependency. * *

    Application-specific view classes will extend this class. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractFeedView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractFeedView.java index 6ea756645817..0e34fe189d81 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractFeedView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractFeedView.java @@ -33,7 +33,7 @@ * Abstract base class for Atom and RSS Feed views, using the * ROME package. * - *

    >NOTE: As of Spring 4.1, this is based on the {@code com.rometools} + *

    NOTE: As of Spring 4.1, this is based on the {@code com.rometools} * variant of ROME, version 1.5. Please upgrade your build dependency. * *

    Application-specific view classes will typically extend from either diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractRssFeedView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractRssFeedView.java index aef278f791ba..769fbd37ad85 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractRssFeedView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/feed/AbstractRssFeedView.java @@ -31,7 +31,7 @@ * Abstract superclass for RSS Feed views, using the * ROME package. * - *

    >NOTE: As of Spring 4.1, this is based on the {@code com.rometools} + *

    NOTE: As of Spring 4.1, this is based on the {@code com.rometools} * variant of ROME, version 1.5. Please upgrade your build dependency. * *

    Application-specific view classes will extend this class. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java index 0eb2e30f3bc7..577b1025d05b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java @@ -42,7 +42,7 @@ * *

      * <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
    - *   <property name="templateLoaderPath"><value>/WEB-INF/freemarker/</value></property>
    + *   <property name="templateLoaderPath"><value>/WEB-INF/freemarker/</value></property>
      * </bean>
    * * This bean must be included in the application context of any application diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesConfigurer.java index dbbdf0f22e91..8567055fc020 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesConfigurer.java @@ -88,17 +88,17 @@ *

    A typical TilesConfigurer bean definition looks as follows: * *

    - * <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
    - *   <property name="definitions">
    - *     <list>
    - *       <value>/WEB-INF/defs/general.xml</value>
    - *       <value>/WEB-INF/defs/widgets.xml</value>
    - *       <value>/WEB-INF/defs/administrator.xml</value>
    - *       <value>/WEB-INF/defs/customer.xml</value>
    - *       <value>/WEB-INF/defs/templates.xml</value>
    - *     </list>
    - *   </property>
    - * </bean>
    + * <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
    + *   <property name="definitions">
    + *     <list>
    + *       <value>/WEB-INF/defs/general.xml</value>
    + *       <value>/WEB-INF/defs/widgets.xml</value>
    + *       <value>/WEB-INF/defs/administrator.xml</value>
    + *       <value>/WEB-INF/defs/customer.xml</value>
    + *       <value>/WEB-INF/defs/templates.xml</value>
    + *     </list>
    + *   </property>
    + * </bean>
      * 
    * * The values in the list are the actual Tiles XML files containing the definitions. @@ -108,14 +108,14 @@ * definitions is used to indicate locale information, for example: * *
    - * <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
    - *   <property name="definitions">
    - *     <list>
    - *       <value>/WEB-INF/defs/tiles.xml</value>
    - *       <value>/WEB-INF/defs/tiles_fr_FR.xml</value>
    - *     </list>
    - *   </property>
    - * </bean>
    + * <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
    + *   <property name="definitions">
    + *     <list>
    + *       <value>/WEB-INF/defs/tiles.xml</value>
    + *       <value>/WEB-INF/defs/tiles_fr_FR.xml</value>
    + *     </list>
    + *   </property>
    + * </bean>
      * 
    * * @author mick semb wever From 3e53e54b80ead7fb22c05852987b11bbf4cd8bc2 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 29 Sep 2021 17:17:13 +0200 Subject: [PATCH 170/735] Remove external Javadoc links to Tiles and Ehcache Support code for Apache Tiles and Ehcache has already been removed from Spring Framework 6.0. This commit therefore removes the configuration for external links to these projects. --- build.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/build.gradle b/build.gradle index d005cc2588a5..6a9eb152bada 100644 --- a/build.gradle +++ b/build.gradle @@ -336,10 +336,7 @@ configure([rootProject] + javaProjects) { project -> "https://www.ibm.com/docs/api/v1/content/SSEQTP_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/", "https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/", "https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/", - "https://tiles.apache.org/tiles-request/apidocs/", - "https://tiles.apache.org/framework/apidocs/", "https://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/", - "https://www.ehcache.org/apidocs/2.10.4/", "https://www.quartz-scheduler.org/api/2.3.0/", "https://fasterxml.github.io/jackson-core/javadoc/2.10/", "https://fasterxml.github.io/jackson-databind/javadoc/2.10/", From 167e538dd13535c4b7a7cff171cd7a0ae22c9b81 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 29 Sep 2021 17:19:19 +0200 Subject: [PATCH 171/735] Link to Jakarta EE APIs instead of Java EE APIs --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6a9eb152bada..4328886a06f6 100644 --- a/build.gradle +++ b/build.gradle @@ -331,7 +331,7 @@ configure([rootProject] + javaProjects) { project -> ext.javadocLinks = [ "https://docs.oracle.com/en/java/javase/17/docs/api/", - "https://javaee.github.io/javaee-spec/javadocs/", + "https://jakarta.ee/specifications/platform/9/apidocs/", "https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ "https://www.ibm.com/docs/api/v1/content/SSEQTP_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/", "https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/", From 388c8e4aa508798e2fcc170a67fc47c7932dc307 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Thu, 30 Sep 2021 16:15:38 +0200 Subject: [PATCH 172/735] Make sure that MediaType comparators are transitive Previous to this commit, the specificity and quality comparators (used by MediaType::sortByQualityValue and MediaType::sortBySpecificity) could result in IllegalArgumentExceptions when used for sorting. The underlying reason was that the comparators were not transitive, and both media types with the same type, and types with the same amount of parameters, would be considered identical by the comparator (result 0). This commit ensures that the comparators are transitive. Closes gh-27488 --- .../src/main/java/org/springframework/util/MimeType.java | 6 ------ .../src/main/java/org/springframework/http/MediaType.java | 6 ------ 2 files changed, 12 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/MimeType.java b/spring-core/src/main/java/org/springframework/util/MimeType.java index de29040b07f6..b6e1ff2ff3de 100644 --- a/spring-core/src/main/java/org/springframework/util/MimeType.java +++ b/spring-core/src/main/java/org/springframework/util/MimeType.java @@ -637,9 +637,6 @@ public int compare(T mimeType1, T mimeType2) { else if (mimeType2.isWildcardType() && !mimeType1.isWildcardType()) { // audio/* > */* return -1; } - else if (!mimeType1.getType().equals(mimeType2.getType())) { // audio/basic == text/html - return 0; - } else { // mediaType1.getType().equals(mediaType2.getType()) if (mimeType1.isWildcardSubtype() && !mimeType2.isWildcardSubtype()) { // audio/* < audio/basic return 1; @@ -647,9 +644,6 @@ else if (!mimeType1.getType().equals(mimeType2.getType())) { // audio/basic == else if (mimeType2.isWildcardSubtype() && !mimeType1.isWildcardSubtype()) { // audio/basic > audio/* return -1; } - else if (!mimeType1.getSubtype().equals(mimeType2.getSubtype())) { // audio/basic == audio/wave - return 0; - } else { // mediaType2.getSubtype().equals(mediaType2.getSubtype()) return compareParameters(mimeType1, mimeType2); } diff --git a/spring-web/src/main/java/org/springframework/http/MediaType.java b/spring-web/src/main/java/org/springframework/http/MediaType.java index f4af4c01a507..dfdee9740aed 100644 --- a/spring-web/src/main/java/org/springframework/http/MediaType.java +++ b/spring-web/src/main/java/org/springframework/http/MediaType.java @@ -798,9 +798,6 @@ else if (mediaType1.isWildcardType() && !mediaType2.isWildcardType()) { // */* else if (mediaType2.isWildcardType() && !mediaType1.isWildcardType()) { // audio/* > */* return -1; } - else if (!mediaType1.getType().equals(mediaType2.getType())) { // audio/basic == text/html - return 0; - } else { // mediaType1.getType().equals(mediaType2.getType()) if (mediaType1.isWildcardSubtype() && !mediaType2.isWildcardSubtype()) { // audio/* < audio/basic return 1; @@ -808,9 +805,6 @@ else if (!mediaType1.getType().equals(mediaType2.getType())) { // audio/basic = else if (mediaType2.isWildcardSubtype() && !mediaType1.isWildcardSubtype()) { // audio/basic > audio/* return -1; } - else if (!mediaType1.getSubtype().equals(mediaType2.getSubtype())) { // audio/basic == audio/wave - return 0; - } else { int paramsSize1 = mediaType1.getParameters().size(); int paramsSize2 = mediaType2.getParameters().size(); From bfa01b35df42c526253866a4b601e8be83746a4b Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Thu, 30 Sep 2021 17:09:03 +0200 Subject: [PATCH 173/735] Polishing See gh-27488 --- .../src/main/java/org/springframework/util/MimeType.java | 4 ++-- .../src/main/java/org/springframework/http/MediaType.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/MimeType.java b/spring-core/src/main/java/org/springframework/util/MimeType.java index b6e1ff2ff3de..aa4ef6f53a31 100644 --- a/spring-core/src/main/java/org/springframework/util/MimeType.java +++ b/spring-core/src/main/java/org/springframework/util/MimeType.java @@ -637,14 +637,14 @@ public int compare(T mimeType1, T mimeType2) { else if (mimeType2.isWildcardType() && !mimeType1.isWildcardType()) { // audio/* > */* return -1; } - else { // mediaType1.getType().equals(mediaType2.getType()) + else { if (mimeType1.isWildcardSubtype() && !mimeType2.isWildcardSubtype()) { // audio/* < audio/basic return 1; } else if (mimeType2.isWildcardSubtype() && !mimeType1.isWildcardSubtype()) { // audio/basic > audio/* return -1; } - else { // mediaType2.getSubtype().equals(mediaType2.getSubtype()) + else { return compareParameters(mimeType1, mimeType2); } } diff --git a/spring-web/src/main/java/org/springframework/http/MediaType.java b/spring-web/src/main/java/org/springframework/http/MediaType.java index dfdee9740aed..6b51e1783df8 100644 --- a/spring-web/src/main/java/org/springframework/http/MediaType.java +++ b/spring-web/src/main/java/org/springframework/http/MediaType.java @@ -798,7 +798,7 @@ else if (mediaType1.isWildcardType() && !mediaType2.isWildcardType()) { // */* else if (mediaType2.isWildcardType() && !mediaType1.isWildcardType()) { // audio/* > */* return -1; } - else { // mediaType1.getType().equals(mediaType2.getType()) + else { if (mediaType1.isWildcardSubtype() && !mediaType2.isWildcardSubtype()) { // audio/* < audio/basic return 1; } From a295a28e4be9dbace211f278ffec309e91a96f86 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 30 Sep 2021 17:33:58 +0200 Subject: [PATCH 174/735] Defensively handle fast class generation failure for individual methods Includes rethrowing of last actual defineClass exception encountered. Closes gh-27490 --- .../aop/framework/CglibAopProxy.java | 36 ++++++++++---- .../cglib/core/ReflectUtils.java | 48 ++++++++++--------- 2 files changed, 52 insertions(+), 32 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java index 43d747f90cee..022cc0fddf24 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java @@ -679,13 +679,19 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy Object retVal; // Check whether we only have one InvokerInterceptor: that is, // no real advice, but just reflective invocation of the target. - if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { + if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) { // We can skip creating a MethodInvocation: just invoke the target directly. // Note that the final invoker must be an InvokerInterceptor, so we know // it does nothing but a reflective operation on the target, and no hot // swapping or fancy proxying. Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); - retVal = methodProxy.invoke(target, argsToUse); + try { + retVal = methodProxy.invoke(target, argsToUse); + } + catch (CodeGenerationException ex) { + CglibMethodInvocation.logFastClassGenerationFailure(method); + retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); + } } else { // We need to create a method invocation... @@ -737,10 +743,7 @@ public CglibMethodInvocation(Object proxy, @Nullable Object target, Method metho super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers); // Only use method proxy for public methods not derived from java.lang.Object - this.methodProxy = (Modifier.isPublic(method.getModifiers()) && - method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) && - !AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ? - methodProxy : null); + this.methodProxy = (isMethodProxyCompatible(method) ? methodProxy : null); } @Override @@ -776,10 +779,25 @@ public Object proceed() throws Throwable { @Override protected Object invokeJoinpoint() throws Throwable { if (this.methodProxy != null) { - return this.methodProxy.invoke(this.target, this.arguments); + try { + return this.methodProxy.invoke(this.target, this.arguments); + } + catch (CodeGenerationException ex) { + logFastClassGenerationFailure(this.method); + } } - else { - return super.invokeJoinpoint(); + return super.invokeJoinpoint(); + } + + static boolean isMethodProxyCompatible(Method method) { + return (Modifier.isPublic(method.getModifiers()) && + method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) && + !AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method)); + } + + static void logFastClassGenerationFailure(Method method) { + if (logger.isDebugEnabled()) { + logger.debug("Failed to generate CGLIB fast class for method: " + method); } } } diff --git a/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java b/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java index 4420c50c9ee1..2f3ac37e6516 100644 --- a/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java +++ b/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java @@ -63,17 +63,16 @@ private ReflectUtils() { private static final Method classLoaderDefineClassMethod; - private static final ProtectionDomain PROTECTION_DOMAIN; - private static final Throwable THROWABLE; + private static final ProtectionDomain PROTECTION_DOMAIN; + private static final List OBJECT_METHODS = new ArrayList(); static { Method privateLookupIn; Method lookupDefineClass; Method classLoaderDefineClass; - ProtectionDomain protectionDomain; Throwable throwable = null; try { privateLookupIn = (Method) AccessController.doPrivileged(new PrivilegedExceptionAction() { @@ -102,39 +101,37 @@ public Object run() throws Exception { String.class, byte[].class, Integer.TYPE, Integer.TYPE, ProtectionDomain.class); } }); - protectionDomain = getProtectionDomain(ReflectUtils.class); - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - Method[] methods = Object.class.getDeclaredMethods(); - for (Method method : methods) { - if ("finalize".equals(method.getName()) - || (method.getModifiers() & (Modifier.FINAL | Modifier.STATIC)) > 0) { - continue; - } - OBJECT_METHODS.add(method); - } - return null; - } - }); } catch (Throwable t) { privateLookupIn = null; lookupDefineClass = null; classLoaderDefineClass = null; - protectionDomain = null; throwable = t; } + privateLookupInMethod = privateLookupIn; lookupDefineClassMethod = lookupDefineClass; classLoaderDefineClassMethod = classLoaderDefineClass; - PROTECTION_DOMAIN = protectionDomain; THROWABLE = throwable; + PROTECTION_DOMAIN = getProtectionDomain(ReflectUtils.class); + + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + Method[] methods = Object.class.getDeclaredMethods(); + for (Method method : methods) { + if ("finalize".equals(method.getName()) + || (method.getModifiers() & (Modifier.FINAL | Modifier.STATIC)) > 0) { + continue; + } + OBJECT_METHODS.add(method); + } + return null; + } + }); } // SPRING PATCH END - private static final String[] CGLIB_PACKAGES = { - "java.lang", - }; + private static final String[] CGLIB_PACKAGES = {"java.lang"}; static { primitives.put("byte", Byte.TYPE); @@ -499,6 +496,7 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader, ProtectionDomain protectionDomain, Class contextClass) throws Exception { Class c = null; + Throwable t = THROWABLE; // Preferred option: JDK 9+ Lookup.defineClass API if ClassLoader matches if (contextClass != null && contextClass.getClassLoader() == loader && @@ -516,6 +514,7 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader, // in case of plain LinkageError (class already defined) // or IllegalArgumentException (class in different package): // fall through to traditional ClassLoader.defineClass below + t = ex; } catch (Throwable ex) { throw new CodeGenerationException(ex); @@ -539,9 +538,11 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader, throw new CodeGenerationException(ex.getTargetException()); } // in case of UnsupportedOperationException, fall through + t = ex.getTargetException(); } catch (Throwable ex) { // publicDefineClass method not available -> fall through + t = ex; } // Classic option: protected ClassLoader.defineClass method @@ -562,6 +563,7 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader, if (!ex.getClass().getName().endsWith("InaccessibleObjectException")) { throw new CodeGenerationException(ex); } + t = ex; } } } @@ -584,7 +586,7 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader, // No defineClass variant available at all? if (c == null) { - throw new CodeGenerationException(THROWABLE); + throw new CodeGenerationException(t); } // Force static initializers to run. From 4f44ae3f282b72d7051a2ac67ec5b001ebd9e884 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 30 Sep 2021 17:34:22 +0200 Subject: [PATCH 175/735] Polishing --- .../junit/jupiter/SpringExtension.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java index dfd7aaaa28cd..8861c5e3621f 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java @@ -89,8 +89,8 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes * {@link Namespace} in which {@code @Autowired} validation error messages * are stored, keyed by test class. */ - private static final Namespace AUTOWIRED_VALIDATION_NAMESPACE = Namespace.create(SpringExtension.class.getName() + - "#autowired.validation"); + private static final Namespace AUTOWIRED_VALIDATION_NAMESPACE = + Namespace.create(SpringExtension.class.getName() + "#autowired.validation"); private static final String NO_AUTOWIRED_VIOLATIONS_DETECTED = "NO AUTOWIRED VIOLATIONS DETECTED"; @@ -101,8 +101,8 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes private static final MethodFilter autowiredTestOrLifecycleMethodFilter = ReflectionUtils.USER_DECLARED_METHODS - .and(method -> !Modifier.isPrivate(method.getModifiers())) - .and(SpringExtension::isAutowiredTestOrLifecycleMethod); + .and(method -> !Modifier.isPrivate(method.getModifiers())) + .and(SpringExtension::isAutowiredTestOrLifecycleMethod); /** @@ -147,16 +147,16 @@ private void validateAutowiredConfig(ExtensionContext context) { // We save the result in the ExtensionContext.Store so that we don't // re-validate all methods for the same test class multiple times. Store store = context.getStore(AUTOWIRED_VALIDATION_NAMESPACE); - String errorMessage = store.getOrComputeIfAbsent(context.getRequiredTestClass(), - testClass -> { + + String errorMessage = store.getOrComputeIfAbsent(context.getRequiredTestClass(), testClass -> { Method[] methodsWithErrors = ReflectionUtils.getUniqueDeclaredMethods(testClass, autowiredTestOrLifecycleMethodFilter); return (methodsWithErrors.length == 0 ? NO_AUTOWIRED_VIOLATIONS_DETECTED : String.format( - "Test methods and test lifecycle methods must not be annotated with @Autowired. " + - "You should instead annotate individual method parameters with @Autowired, " + - "@Qualifier, or @Value. Offending methods in test class %s: %s", - testClass.getName(), Arrays.toString(methodsWithErrors))); + "Test methods and test lifecycle methods must not be annotated with @Autowired. " + + "You should instead annotate individual method parameters with @Autowired, " + + "@Qualifier, or @Value. Offending methods in test class %s: %s", + testClass.getName(), Arrays.toString(methodsWithErrors))); }, String.class); if (errorMessage != NO_AUTOWIRED_VIOLATIONS_DETECTED) { @@ -247,7 +247,7 @@ public boolean supportsParameter(ParameterContext parameterContext, ExtensionCon private boolean supportsApplicationEvents(ParameterContext parameterContext) { if (ApplicationEvents.class.isAssignableFrom(parameterContext.getParameter().getType())) { Assert.isTrue(parameterContext.getDeclaringExecutable() instanceof Method, - "ApplicationEvents can only be injected into test and lifecycle methods"); + "ApplicationEvents can only be injected into test and lifecycle methods"); return true; } return false; From 24bcb52b2f08aae987cb1d2da14d2436a56a29e6 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 30 Sep 2021 18:09:07 +0200 Subject: [PATCH 176/735] Polishing --- .../main/java/org/springframework/cglib/core/ReflectUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java b/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java index 2f3ac37e6516..f11a75fc064d 100644 --- a/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java +++ b/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java @@ -514,7 +514,7 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader, // in case of plain LinkageError (class already defined) // or IllegalArgumentException (class in different package): // fall through to traditional ClassLoader.defineClass below - t = ex; + t = target; } catch (Throwable ex) { throw new CodeGenerationException(ex); From f64f07049d4427909251b016c4ed6c152f3368a4 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 30 Sep 2021 18:12:10 +0200 Subject: [PATCH 177/735] Upgrade to SLF4J 1.7.32 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 86379dd04b7f..f2346de7918b 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ configure(allprojects) { project -> entry 'log4j-jul' entry 'log4j-slf4j-impl' } - dependency "org.slf4j:slf4j-api:1.7.30" + dependency "org.slf4j:slf4j-api:1.7.32" dependency("com.google.code.findbugs:findbugs:3.0.1") { exclude group: "dom4j", name: "dom4j" } From ad873617d2eb18bb61bd471ce83fcbaeacc6d6d3 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 30 Sep 2021 18:26:01 +0200 Subject: [PATCH 178/735] Note on ClassLoader.defineClass being used as a fallback only --- .../java/org/springframework/cglib/core/ReflectUtils.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java b/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java index 3d5e1f087ee2..5fe0cef8f26c 100644 --- a/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java +++ b/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java @@ -63,6 +63,8 @@ private ReflectUtils() { // SPRING PATCH BEGIN static { + // Resolve protected ClassLoader.defineClass method for fallback use + // (even if JDK 9+ Lookup.defineClass is preferably used below) Method classLoaderDefineClass; Throwable throwable = null; try { @@ -453,7 +455,7 @@ public static Class defineClass(String className, byte[] b, ClassLoader loader, // in case of plain LinkageError (class already defined) // or IllegalArgumentException (class in different package): // fall through to traditional ClassLoader.defineClass below - t = target; + t = ex; } catch (Throwable ex) { throw new CodeGenerationException(ex); From f0aa4f4857fbe197c162c9639d24d5bb460eb8f7 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 1 Oct 2021 10:35:28 +0200 Subject: [PATCH 179/735] Escape closing curly braces in regular expressions for Android support PR gh-24470 introduced a regression for Android users by no longer escaping closing curly braces in regular expressions. This commit therefore partially reverts the changes made in 273812f9c5 for closing curly braces (`}`). Closes gh27467 --- .../main/java/org/springframework/util/AntPathMatcher.java | 6 +++--- .../test/context/util/TestContextResourceUtils.java | 4 ++-- .../java/org/springframework/web/util/UriComponents.java | 2 +- .../org/springframework/web/util/UriComponentsBuilder.java | 2 +- .../springframework/web/util/pattern/RegexPathElement.java | 4 ++-- .../web/reactive/result/view/RedirectView.java | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) 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 997925613649..d304f08d2c00 100644 --- a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,7 +78,7 @@ public class AntPathMatcher implements PathMatcher { private static final int CACHE_TURNOFF_THRESHOLD = 65536; - private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\{[^/]+?}"); + private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\{[^/]+?\\}"); private static final char[] WILDCARD_CHARS = {'*', '?', '{'}; @@ -642,7 +642,7 @@ public Comparator getPatternComparator(String path) { */ protected static class AntPathStringMatcher { - private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?}|[^/{}]|\\\\[{}])+?)}"); + private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}"); private static final String DEFAULT_VARIABLE_PATTERN = "((?s).*)"; diff --git a/spring-test/src/main/java/org/springframework/test/context/util/TestContextResourceUtils.java b/spring-test/src/main/java/org/springframework/test/context/util/TestContextResourceUtils.java index 632e7a90432f..b931d987cf7b 100644 --- a/spring-test/src/main/java/org/springframework/test/context/util/TestContextResourceUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/util/TestContextResourceUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,7 +47,7 @@ public abstract class TestContextResourceUtils { private static final String SLASH = "/"; - private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile(".*\\$\\{[^}]+}.*"); + private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile(".*\\$\\{[^}]+\\}.*"); /** diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponents.java b/spring-web/src/main/java/org/springframework/web/util/UriComponents.java index fd3a667cef2f..7ff83bdf76da 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponents.java @@ -48,7 +48,7 @@ public abstract class UriComponents implements Serializable { /** Captures URI template variable names. */ - private static final Pattern NAMES_PATTERN = Pattern.compile("\\{([^/]+?)}"); + private static final Pattern NAMES_PATTERN = Pattern.compile("\\{([^/]+?)\\}"); @Nullable diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index d378a36840a0..68c98562a280 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -85,7 +85,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable { private static final String HOST_PATTERN = "(" + HOST_IPV6_PATTERN + "|" + HOST_IPV4_PATTERN + ")"; - private static final String PORT_PATTERN = "(\\{[^}]+}?|[^/?#]*)"; + private static final String PORT_PATTERN = "(\\{[^}]+\\}?|[^/?#]*)"; private static final String PATH_PATTERN = "([^?#]*)"; diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java index f326a87e134e..cdbad924bb4f 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ */ class RegexPathElement extends PathElement { - private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?}|[^/{}]|\\\\[{}])+?)}"); + private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}"); private static final String DEFAULT_VARIABLE_PATTERN = "(.*)"; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java index 4ec3f0ecec3c..50aa95ecb0c3 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ */ public class RedirectView extends AbstractUrlBasedView { - private static final Pattern URI_TEMPLATE_VARIABLE_PATTERN = Pattern.compile("\\{([^/]+?)}"); + private static final Pattern URI_TEMPLATE_VARIABLE_PATTERN = Pattern.compile("\\{([^/]+?)\\}"); private HttpStatus statusCode = HttpStatus.SEE_OTHER; From 7311ae19be835816534a5c18bd8a948d26143ded Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 1 Oct 2021 11:09:59 +0200 Subject: [PATCH 180/735] Fix build by disabling linking to JUnit 5.8.1 Javadoc The `package-list` file no longer exists at https://junit.org/junit5/docs/5.8.1/api/, due to the following commit. https://github.com/junit-team/junit5/commit/67ad4e545518b0ce2b0e7c96df31a669866d5003 --- build.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f2346de7918b..c6545c8abf21 100644 --- a/build.gradle +++ b/build.gradle @@ -384,7 +384,9 @@ configure([rootProject] + javaProjects) { project -> "https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/", "https://projectreactor.io/docs/test/release/api/", "https://junit.org/junit4/javadoc/4.13.2/", - "https://junit.org/junit5/docs/5.8.1/api/", + // Disabling linking to JUnit 5.8.1, since the `package-list` file no longer exists due to + // https://github.com/junit-team/junit5/commit/67ad4e545518b0ce2b0e7c96df31a669866d5003. + // "https://junit.org/junit5/docs/5.8.1/api/", "https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/", "https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/", "https://r2dbc.io/spec/0.8.5.RELEASE/api/" From d6ec6f0fe9f50ff2241229a9972a8649ad2dead5 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Fri, 1 Oct 2021 09:33:17 +0200 Subject: [PATCH 181/735] Remove remark about missing caching API. --- src/docs/asciidoc/integration.adoc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index 883acc17867a..41d5a0dba8ec 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -6653,15 +6653,13 @@ invoked every time. === Plugging-in Different Back-end Caches Clearly, there are plenty of caching products out there that you can use as a backing -store. To plug them in, you need to provide a `CacheManager` and a `Cache` implementation, -since, unfortunately, there is no available standard that we can use instead. +store. For those that do not support JSR-107 you need to provide a `CacheManager` and a `Cache` implementation. This may sound harder than it is, since, in practice, the classes tend to be simple https://en.wikipedia.org/wiki/Adapter_pattern[adapters] that map the caching abstraction framework on top of the storage API, as the `ehcache` classes do. Most `CacheManager` classes can use the classes in the `org.springframework.cache.support` package (such as `AbstractCacheManager` which takes care of the boiler-plate code, -leaving only the actual mapping to be completed). We hope that, in time, the libraries -that provide integration with Spring can fill in this small configuration gap. +leaving only the actual mapping to be completed). We hope that, in time, all relevant caches will offer JSR-107 support. From fd11789db90de09e0edd906d6ad78189df895e22 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 1 Oct 2021 12:51:52 +0200 Subject: [PATCH 182/735] Polish JSR-107 caching ref docs --- src/docs/asciidoc/integration.adoc | 42 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index 41d5a0dba8ec..6f010159947d 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -5587,8 +5587,8 @@ an existing Spring application. Similar to the <> and more customization options. +In Spring Framework 4.1, the cache abstraction was significantly extended with support +for <> and more customization options. @@ -6313,7 +6313,7 @@ up its declaration at runtime and understands its meaning. Note that, as mention === JCache (JSR-107) Annotations Since version 4.1, Spring's caching abstraction fully supports the JCache standard -annotations: `@CacheResult`, `@CachePut`, `@CacheRemove`, and `@CacheRemoveAll` +(JSR-107) annotations: `@CacheResult`, `@CachePut`, `@CacheRemove`, and `@CacheRemoveAll` as well as the `@CacheDefaults`, `@CacheKey`, and `@CacheValue` companions. You can use these annotations even without migrating your cache store to JSR-107. The internal implementation uses Spring's caching abstraction and provides default @@ -6327,8 +6327,8 @@ you can switch to these standard annotations without changing your cache storage ==== Feature Summary For those who are familiar with Spring's caching annotations, the following table -describes the main differences between the Spring annotations and the JSR-107 -counterpart: +describes the main differences between the Spring annotations and their JSR-107 +counterparts: .Spring vs. JSR-107 caching annotations [cols="1,1,3"] @@ -6420,16 +6420,15 @@ invoking the method again: ==== Enabling JSR-107 Support -You need do nothing specific to enable the JSR-107 support alongside Spring's -declarative annotation support. Both `@EnableCaching` and the -`cache:annotation-driven` element automatically enable the JCache support -if both the JSR-107 API and the `spring-context-support` module are present -in the classpath. +You do not need to do anything specific to enable the JSR-107 support alongside Spring's +declarative annotation support. Both `@EnableCaching` and the `cache:annotation-driven` +XML element automatically enable the JCache support if both the JSR-107 API and the +`spring-context-support` module are present in the classpath. -NOTE: Depending on your use case, the choice is basically yours. You can even -mix and match services by using the JSR-107 API on some and using Spring's own -annotations on others. However, if these services impact the same caches, -you should use a consistent and identical key generation implementation. +NOTE: Depending on your use case, the choice is basically yours. You can even mix and +match services by using the JSR-107 API on some and using Spring's own annotations on +others. However, if these services impact the same caches, you should use a consistent +and identical key generation implementation. @@ -6653,13 +6652,14 @@ invoked every time. === Plugging-in Different Back-end Caches Clearly, there are plenty of caching products out there that you can use as a backing -store. For those that do not support JSR-107 you need to provide a `CacheManager` and a `Cache` implementation. -This may sound harder than it is, since, in practice, the classes tend to be simple -https://en.wikipedia.org/wiki/Adapter_pattern[adapters] that map the caching abstraction -framework on top of the storage API, as the `ehcache` classes do. Most `CacheManager` -classes can use the classes in the `org.springframework.cache.support` package -(such as `AbstractCacheManager` which takes care of the boiler-plate code, -leaving only the actual mapping to be completed). We hope that, in time, all relevant caches will offer JSR-107 support. +store. For those that do not support JSR-107 you need to provide a `CacheManager` and a +`Cache` implementation. This may sound harder than it is, since, in practice, the classes +tend to be simple https://en.wikipedia.org/wiki/Adapter_pattern[adapters] that map the +caching abstraction framework on top of the storage API, as the `ehcache` classes do. +Most `CacheManager` classes can use the classes in the +`org.springframework.cache.support` package (such as `AbstractCacheManager` which takes +care of the boiler-plate code, leaving only the actual mapping to be completed). We hope +that, in time, all relevant caches will offer JSR-107 support. From b452d1b41d05e5656d39433ea2649e152fb184b2 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 1 Oct 2021 13:06:57 +0200 Subject: [PATCH 183/735] Remove obsolete references to Ehcache 2.x from ref docs --- src/docs/asciidoc/integration.adoc | 37 ++++++++---------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index 6f010159947d..1fa867c39d86 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -5627,7 +5627,7 @@ invoke the method again. The caching logic is applied transparently without any interference to the invoker. IMPORTANT: This approach works only for methods that are guaranteed to return the same -output (result) for a given input (or arguments) no matter how many times it is invoked. +output (result) for a given input (or arguments) no matter how many times they are invoked. The caching abstraction provides other cache-related operations, such as the ability to update the content of the cache or to remove one or all entries. These are useful if @@ -5640,10 +5640,10 @@ provide the actual data store. This abstraction is materialized by the `org.springframework.cache.Cache` and `org.springframework.cache.CacheManager` interfaces. Spring provides <> of that abstraction: -JDK `java.util.concurrent.ConcurrentMap` based caches, https://www.ehcache.org/[Ehcache 2.x], -Gemfire cache, https://github.com/ben-manes/caffeine/wiki[Caffeine], and JSR-107 -compliant caches (such as Ehcache 3.x). See <> for more information on -plugging in other cache stores and providers. +JDK `java.util.concurrent.ConcurrentMap` based caches, Gemfire cache, +https://github.com/ben-manes/caffeine/wiki[Caffeine], and JSR-107 compliant caches (such +as Ehcache 3.x). See <> for more information on plugging in other cache +stores and providers. IMPORTANT: The caching abstraction has no special handling for multi-threaded and multi-process environments, as such features are handled by the cache implementation. @@ -5663,7 +5663,7 @@ in that area. See the documentation of your cache provider for more details. To use the cache abstraction, you need to take care of two aspects: -* Caching declaration: Identify the methods that need to be cached and their policy. +* Caching declaration: Identify the methods that need to be cached and their policies. * Cache configuration: The backing cache where the data is stored and from which it is read. @@ -6526,28 +6526,11 @@ and is very fast, but it does not provide any management, persistence capabiliti or eviction contracts. -[[cache-store-configuration-ehcache]] +[[cache-store-configuration-eviction]] ==== Ehcache-based Cache -NOTE: Ehcache 3.x is fully JSR-107 compliant and no dedicated support is required for it. - -The Ehcache 2.x implementation is located in the `org.springframework.cache.ehcache` -package. Again, to use it, you need to declare the appropriate `CacheManager`. -The following example shows how to do so: - -[source,xml,indent=0,subs="verbatim,quotes"] ----- - - - - ----- - -This setup bootstraps the ehcache library inside the Spring IoC (through the `ehcache` -bean), which is then wired into the dedicated `CacheManager` implementation. Note that -the entire Ehcache-specific configuration is read from `ehcache.xml`. +Ehcache 3.x is fully JSR-107 compliant and no dedicated support is required for it. See +<> for details. [[cache-store-configuration-caffeine]] @@ -6655,7 +6638,7 @@ Clearly, there are plenty of caching products out there that you can use as a ba store. For those that do not support JSR-107 you need to provide a `CacheManager` and a `Cache` implementation. This may sound harder than it is, since, in practice, the classes tend to be simple https://en.wikipedia.org/wiki/Adapter_pattern[adapters] that map the -caching abstraction framework on top of the storage API, as the `ehcache` classes do. +caching abstraction framework on top of the storage API, as the _Caffeine_ classes do. Most `CacheManager` classes can use the classes in the `org.springframework.cache.support` package (such as `AbstractCacheManager` which takes care of the boiler-plate code, leaving only the actual mapping to be completed). We hope From f632165dec5df566f2ccac6350d9c67ac63106c4 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 1 Oct 2021 13:26:25 +0200 Subject: [PATCH 184/735] Invoke bean-derived (Auto)Closeable.close() method directly Closes gh-27504 --- .../support/DisposableBeanAdapter.java | 145 +++++++++++------- .../DestroyMethodInferenceTests.java | 45 ++++-- .../DestroyMethodInferenceTests-context.xml | 8 +- 3 files changed, 136 insertions(+), 62 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java index 3e779752a952..e6f90239343d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java @@ -61,6 +61,8 @@ @SuppressWarnings("serial") class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { + private static final String DESTROY_METHOD_NAME = "destroy"; + private static final String CLOSE_METHOD_NAME = "close"; private static final String SHUTDOWN_METHOD_NAME = "shutdown"; @@ -72,12 +74,11 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { private final String beanName; - private final boolean invokeDisposableBean; - private final boolean nonPublicAccessAllowed; - @Nullable - private final AccessControlContext acc; + private final boolean invokeDisposableBean; + + private boolean invokeAutoCloseable; @Nullable private String destroyMethodName; @@ -88,6 +89,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @Nullable private final List beanPostProcessors; + @Nullable + private final AccessControlContext acc; + /** * Create a new DisposableBeanAdapter for the given bean. @@ -103,38 +107,45 @@ public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition be Assert.notNull(bean, "Disposable bean must not be null"); this.bean = bean; this.beanName = beanName; - this.invokeDisposableBean = - (this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy")); this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed(); - this.acc = acc; + this.invokeDisposableBean = (bean instanceof DisposableBean && + !beanDefinition.isExternallyManagedDestroyMethod(DESTROY_METHOD_NAME)); + String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition); - if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) && + if (destroyMethodName != null && + !(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodName)) && !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) { - this.destroyMethodName = destroyMethodName; - Method destroyMethod = determineDestroyMethod(destroyMethodName); - if (destroyMethod == null) { - if (beanDefinition.isEnforceDestroyMethod()) { - throw new BeanDefinitionValidationException("Could not find a destroy method named '" + - destroyMethodName + "' on bean with name '" + beanName + "'"); - } - } - else { - if (destroyMethod.getParameterCount() > 0) { - Class[] paramTypes = destroyMethod.getParameterTypes(); - if (paramTypes.length > 1) { - throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + - beanName + "' has more than one parameter - not supported as destroy method"); + + this.invokeAutoCloseable = (bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodName)); + if (!this.invokeAutoCloseable) { + this.destroyMethodName = destroyMethodName; + Method destroyMethod = determineDestroyMethod(destroyMethodName); + if (destroyMethod == null) { + if (beanDefinition.isEnforceDestroyMethod()) { + throw new BeanDefinitionValidationException("Could not find a destroy method named '" + + destroyMethodName + "' on bean with name '" + beanName + "'"); } - else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) { - throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + - beanName + "' has a non-boolean parameter - not supported as destroy method"); + } + else { + if (destroyMethod.getParameterCount() > 0) { + Class[] paramTypes = destroyMethod.getParameterTypes(); + if (paramTypes.length > 1) { + throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + + beanName + "' has more than one parameter - not supported as destroy method"); + } + else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) { + throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + + beanName + "' has a non-boolean parameter - not supported as destroy method"); + } } + destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod); } - destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod); + this.destroyMethod = destroyMethod; } - this.destroyMethod = destroyMethod; } + this.beanPostProcessors = filterPostProcessors(postProcessors, bean); + this.acc = acc; } /** @@ -149,26 +160,27 @@ public DisposableBeanAdapter( Assert.notNull(bean, "Disposable bean must not be null"); this.bean = bean; this.beanName = bean.getClass().getName(); - this.invokeDisposableBean = (this.bean instanceof DisposableBean); this.nonPublicAccessAllowed = true; - this.acc = acc; + this.invokeDisposableBean = (this.bean instanceof DisposableBean); this.beanPostProcessors = filterPostProcessors(postProcessors, bean); + this.acc = acc; } /** * Create a new DisposableBeanAdapter for the given bean. */ - private DisposableBeanAdapter(Object bean, String beanName, boolean invokeDisposableBean, - boolean nonPublicAccessAllowed, @Nullable String destroyMethodName, + private DisposableBeanAdapter(Object bean, String beanName, boolean nonPublicAccessAllowed, + boolean invokeDisposableBean, boolean invokeAutoCloseable, @Nullable String destroyMethodName, @Nullable List postProcessors) { this.bean = bean; this.beanName = beanName; - this.invokeDisposableBean = invokeDisposableBean; this.nonPublicAccessAllowed = nonPublicAccessAllowed; - this.acc = null; + this.invokeDisposableBean = invokeDisposableBean; + this.invokeAutoCloseable = invokeAutoCloseable; this.destroyMethodName = destroyMethodName; this.beanPostProcessors = postProcessors; + this.acc = null; } @@ -211,7 +223,32 @@ public void destroy() { } } - if (this.destroyMethod != null) { + if (this.invokeAutoCloseable) { + if (logger.isTraceEnabled()) { + logger.trace("Invoking close() on bean with name '" + this.beanName + "'"); + } + try { + if (System.getSecurityManager() != null) { + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + ((AutoCloseable) this.bean).close(); + return null; + }, this.acc); + } + else { + ((AutoCloseable) this.bean).close(); + } + } + catch (Throwable ex) { + String msg = "Invocation of close method failed on bean with name '" + this.beanName + "'"; + if (logger.isDebugEnabled()) { + logger.warn(msg, ex); + } + else { + logger.warn(msg + ": " + ex); + } + } + } + else if (this.destroyMethod != null) { invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName != null) { @@ -259,7 +296,7 @@ private void invokeCustomDestroyMethod(final Method destroyMethod) { args[0] = Boolean.TRUE; } if (logger.isTraceEnabled()) { - logger.trace("Invoking destroy method '" + this.destroyMethodName + + logger.trace("Invoking custom destroy method '" + this.destroyMethodName + "' on bean with name '" + this.beanName + "'"); } try { @@ -282,7 +319,7 @@ private void invokeCustomDestroyMethod(final Method destroyMethod) { } } catch (InvocationTargetException ex) { - String msg = "Destroy method '" + this.destroyMethodName + "' on bean with name '" + + String msg = "Custom destroy method '" + this.destroyMethodName + "' on bean with name '" + this.beanName + "' threw an exception"; if (logger.isDebugEnabled()) { logger.warn(msg, ex.getTargetException()); @@ -292,7 +329,7 @@ private void invokeCustomDestroyMethod(final Method destroyMethod) { } } catch (Throwable ex) { - logger.warn("Failed to invoke destroy method '" + this.destroyMethodName + + logger.warn("Failed to invoke custom destroy method '" + this.destroyMethodName + "' on bean with name '" + this.beanName + "'", ex); } } @@ -312,8 +349,9 @@ protected Object writeReplace() { } } } - return new DisposableBeanAdapter(this.bean, this.beanName, this.invokeDisposableBean, - this.nonPublicAccessAllowed, this.destroyMethodName, serializablePostProcessors); + return new DisposableBeanAdapter( + this.bean, this.beanName, this.nonPublicAccessAllowed, this.invokeDisposableBean, + this.invokeAutoCloseable, this.destroyMethodName, serializablePostProcessors); } @@ -323,10 +361,7 @@ protected Object writeReplace() { * @param beanDefinition the corresponding bean definition */ public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) { - if (bean instanceof DisposableBean || bean instanceof AutoCloseable) { - return true; - } - return inferDestroyMethodIfNecessary(bean, beanDefinition) != null; + return (bean instanceof DisposableBean || inferDestroyMethodIfNecessary(bean, beanDefinition) != null); } @@ -348,21 +383,27 @@ private static String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinit String destroyMethodName = beanDefinition.resolvedDestroyMethodName; if (destroyMethodName == null) { destroyMethodName = beanDefinition.getDestroyMethodName(); + boolean autoCloseable = (bean instanceof AutoCloseable); if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) || - (destroyMethodName == null && bean instanceof AutoCloseable)) { - // Only perform destroy method inference or Closeable detection - // in case of the bean not explicitly implementing DisposableBean + (destroyMethodName == null && autoCloseable)) { + // Only perform destroy method inference in case of the bean + // not explicitly implementing the DisposableBean interface destroyMethodName = null; if (!(bean instanceof DisposableBean)) { - try { - destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName(); + if (autoCloseable) { + destroyMethodName = CLOSE_METHOD_NAME; } - catch (NoSuchMethodException ex) { + else { try { - destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName(); + destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName(); } - catch (NoSuchMethodException ex2) { - // no candidate destroy method found + catch (NoSuchMethodException ex) { + try { + destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName(); + } + catch (NoSuchMethodException ex2) { + // no candidate destroy method found + } } } } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/DestroyMethodInferenceTests.java b/spring-context/src/test/java/org/springframework/context/annotation/DestroyMethodInferenceTests.java index 7da4675bed5e..c15abc241db2 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/DestroyMethodInferenceTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/DestroyMethodInferenceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,6 @@ import static org.assertj.core.api.Assertions.assertThat; - /** * @author Chris Beams * @author Juergen Hoeller @@ -47,6 +46,7 @@ public void beanMethods() { WithLocalShutdownMethod c7 = ctx.getBean("c7", WithLocalShutdownMethod.class); WithInheritedCloseMethod c8 = ctx.getBean("c8", WithInheritedCloseMethod.class); WithDisposableBean c9 = ctx.getBean("c9", WithDisposableBean.class); + WithAutoCloseable c10 = ctx.getBean("c10", WithAutoCloseable.class); assertThat(c0.closed).as("c0").isFalse(); assertThat(c1.closed).as("c1").isFalse(); @@ -58,6 +58,8 @@ public void beanMethods() { assertThat(c7.closed).as("c7").isFalse(); assertThat(c8.closed).as("c8").isFalse(); assertThat(c9.closed).as("c9").isFalse(); + assertThat(c10.closed).as("c10").isFalse(); + ctx.close(); assertThat(c0.closed).as("c0").isTrue(); assertThat(c1.closed).as("c1").isTrue(); @@ -69,6 +71,7 @@ public void beanMethods() { assertThat(c7.closed).as("c7").isTrue(); assertThat(c8.closed).as("c8").isFalse(); assertThat(c9.closed).as("c9").isTrue(); + assertThat(c10.closed).as("c10").isTrue(); } @Test @@ -80,21 +83,29 @@ public void xml() { WithLocalCloseMethod x3 = ctx.getBean("x3", WithLocalCloseMethod.class); WithNoCloseMethod x4 = ctx.getBean("x4", WithNoCloseMethod.class); WithInheritedCloseMethod x8 = ctx.getBean("x8", WithInheritedCloseMethod.class); + WithDisposableBean x9 = ctx.getBean("x9", WithDisposableBean.class); + WithAutoCloseable x10 = ctx.getBean("x10", WithAutoCloseable.class); assertThat(x1.closed).isFalse(); assertThat(x2.closed).isFalse(); assertThat(x3.closed).isFalse(); assertThat(x4.closed).isFalse(); + assertThat(x8.closed).isFalse(); + assertThat(x9.closed).isFalse(); + assertThat(x10.closed).isFalse(); + ctx.close(); assertThat(x1.closed).isFalse(); assertThat(x2.closed).isTrue(); assertThat(x3.closed).isTrue(); assertThat(x4.closed).isFalse(); assertThat(x8.closed).isFalse(); + assertThat(x9.closed).isTrue(); + assertThat(x10.closed).isTrue(); } - @Configuration + @Configuration(proxyBeanMethods = false) static class Config { @Bean(destroyMethod = "explicitClose") @@ -155,6 +166,11 @@ public WithInheritedCloseMethod c8() { public WithDisposableBean c9() { return new WithDisposableBean(); } + + @Bean + public WithAutoCloseable c10() { + return new WithAutoCloseable(); + } } @@ -189,28 +205,39 @@ public void close() { } - static class WithDisposableBean implements DisposableBean { + static class WithNoCloseMethod { boolean closed = false; + } - @Override - public void destroy() { + + static class WithLocalShutdownMethod { + + boolean closed = false; + + public void shutdown() { closed = true; } } - static class WithNoCloseMethod { + static class WithDisposableBean implements DisposableBean { boolean closed = false; + + @Override + public void destroy() { + closed = true; + } } - static class WithLocalShutdownMethod { + static class WithAutoCloseable implements AutoCloseable { boolean closed = false; - public void shutdown() { + @Override + public void close() { closed = true; } } diff --git a/spring-context/src/test/resources/org/springframework/context/annotation/DestroyMethodInferenceTests-context.xml b/spring-context/src/test/resources/org/springframework/context/annotation/DestroyMethodInferenceTests-context.xml index 5c66a6d9e29b..c72bd70db550 100644 --- a/spring-context/src/test/resources/org/springframework/context/annotation/DestroyMethodInferenceTests-context.xml +++ b/spring-context/src/test/resources/org/springframework/context/annotation/DestroyMethodInferenceTests-context.xml @@ -15,10 +15,16 @@ class="org.springframework.context.annotation.DestroyMethodInferenceTests.WithInheritedCloseMethod" destroy-method=""/> + + + + - From 678fd8344ea52702659bf47156a58f7883bd5d0e Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 1 Oct 2021 14:37:07 +0200 Subject: [PATCH 185/735] Polishing --- src/docs/asciidoc/integration.adoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index 6f010159947d..f2ec53ad0aed 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -6658,8 +6658,7 @@ tend to be simple https://en.wikipedia.org/wiki/Adapter_pattern[adapters] that m caching abstraction framework on top of the storage API, as the `ehcache` classes do. Most `CacheManager` classes can use the classes in the `org.springframework.cache.support` package (such as `AbstractCacheManager` which takes -care of the boiler-plate code, leaving only the actual mapping to be completed). We hope -that, in time, all relevant caches will offer JSR-107 support. +care of the boiler-plate code, leaving only the actual mapping to be completed). From 04eed155cdf10dd943818c343c9fd49fb6d8fcf4 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 1 Oct 2021 14:52:27 +0200 Subject: [PATCH 186/735] Upgrade to Hibernate ORM 5.6 CR1, JRuby 9.3, WebJars Locator 0.48, HtmlUnit 2.53 --- build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 1963b42f8292..569569e295e4 100644 --- a/build.gradle +++ b/build.gradle @@ -112,9 +112,9 @@ configure(allprojects) { project -> dependency "org.quartz-scheduler:quartz:2.3.2" dependency "org.ehcache:jcache:1.0.1" dependency "org.ehcache:ehcache:3.4.0" - dependency "org.hibernate:hibernate-core-jakarta:5.5.7.Final" + dependency "org.hibernate:hibernate-core-jakarta:5.6.0.CR1" dependency "org.hibernate:hibernate-validator:7.0.1.Final" - dependency "org.webjars:webjars-locator-core:0.47" + dependency "org.webjars:webjars-locator-core:0.48" dependency "org.webjars:underscorejs:1.8.3" dependencySet(group: 'org.apache.tomcat', version: '10.0.11') { @@ -150,7 +150,7 @@ configure(allprojects) { project -> dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.1' dependency "org.eclipse.jetty:jetty-reactive-httpclient:3.0.4" - dependency "org.jruby:jruby:9.2.19.0" + dependency "org.jruby:jruby:9.3.0.0" dependency "org.python:jython-standalone:2.7.1" dependency "org.mozilla:rhino:1.7.11" @@ -189,10 +189,10 @@ configure(allprojects) { project -> } dependency "io.mockk:mockk:1.12.0" - dependency("net.sourceforge.htmlunit:htmlunit:2.52.0") { + dependency("net.sourceforge.htmlunit:htmlunit:2.53.0") { exclude group: "commons-logging", name: "commons-logging" } - dependency("org.seleniumhq.selenium:htmlunit-driver:2.52.0") { + dependency("org.seleniumhq.selenium:htmlunit-driver:2.53.0") { exclude group: "commons-logging", name: "commons-logging" } dependency("org.seleniumhq.selenium:selenium-java:3.141.59") { From bf373c5065fc5b561b385365cb01a9eb27621e9e Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 2 Oct 2021 12:04:13 +0200 Subject: [PATCH 187/735] Skip all flaky StopWatch time assertions --- .../springframework/util/StopWatchTests.java | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/spring-core/src/test/java/org/springframework/util/StopWatchTests.java b/spring-core/src/test/java/org/springframework/util/StopWatchTests.java index 83eb5adbec63..a3458afb6a1f 100644 --- a/spring-core/src/test/java/org/springframework/util/StopWatchTests.java +++ b/spring-core/src/test/java/org/springframework/util/StopWatchTests.java @@ -20,7 +20,6 @@ import org.springframework.util.StopWatch.TaskInfo; -import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; @@ -78,18 +77,21 @@ void validUsage() throws Exception { assertThat(stopWatch.currentTaskName()).isEqualTo(name1); stopWatch.stop(); assertThat(stopWatch.isRunning()).isFalse(); + + /* Flaky StopWatch time assertions... assertThat(stopWatch.getLastTaskTimeNanos()) - .as("last task time in nanoseconds for task #1") - .isGreaterThanOrEqualTo(millisToNanos(duration1 - fudgeFactor)) - .isLessThanOrEqualTo(millisToNanos(duration1 + fudgeFactor)); + .as("last task time in nanoseconds for task #1") + .isGreaterThanOrEqualTo(TimeUnit.MILLISECONDS.toNanos(duration1 - fudgeFactor)) + .isLessThanOrEqualTo(TimeUnit.MILLISECONDS.toNanos(duration1 + fudgeFactor)); assertThat(stopWatch.getTotalTimeMillis()) - .as("total time in milliseconds for task #1") - .isGreaterThanOrEqualTo(duration1 - fudgeFactor) - .isLessThanOrEqualTo(duration1 + fudgeFactor); + .as("total time in milliseconds for task #1") + .isGreaterThanOrEqualTo(duration1 - fudgeFactor) + .isLessThanOrEqualTo(duration1 + fudgeFactor); assertThat(stopWatch.getTotalTimeSeconds()) - .as("total time in seconds for task #1") - .isGreaterThanOrEqualTo((duration1 - fudgeFactor) / 1000.0) - .isLessThanOrEqualTo((duration1 + fudgeFactor) / 1000.0); + .as("total time in seconds for task #1") + .isGreaterThanOrEqualTo((duration1 - fudgeFactor) / 1000.0) + .isLessThanOrEqualTo((duration1 + fudgeFactor) / 1000.0); + */ stopWatch.start(name2); Thread.sleep(duration2); @@ -100,17 +102,17 @@ void validUsage() throws Exception { /* Flaky StopWatch time assertions... assertThat(stopWatch.getLastTaskTimeNanos()) - .as("last task time in nanoseconds for task #2") - .isGreaterThanOrEqualTo(millisToNanos(duration2)) - .isLessThanOrEqualTo(millisToNanos(duration2 + fudgeFactor)); + .as("last task time in nanoseconds for task #2") + .isGreaterThanOrEqualTo(TimeUnit.MILLISECONDS.toNanos(duration2)) + .isLessThanOrEqualTo(TimeUnit.MILLISECONDS.toNanos(duration2 + fudgeFactor)); assertThat(stopWatch.getTotalTimeMillis()) - .as("total time in milliseconds for tasks #1 and #2") - .isGreaterThanOrEqualTo(duration1 + duration2 - fudgeFactor) - .isLessThanOrEqualTo(duration1 + duration2 + fudgeFactor); + .as("total time in milliseconds for tasks #1 and #2") + .isGreaterThanOrEqualTo(duration1 + duration2 - fudgeFactor) + .isLessThanOrEqualTo(duration1 + duration2 + fudgeFactor); assertThat(stopWatch.getTotalTimeSeconds()) - .as("total time in seconds for task #2") - .isGreaterThanOrEqualTo((duration1 + duration2 - fudgeFactor) / 1000.0) - .isLessThanOrEqualTo((duration1 + duration2 + fudgeFactor) / 1000.0); + .as("total time in seconds for task #2") + .isGreaterThanOrEqualTo((duration1 + duration2 - fudgeFactor) / 1000.0) + .isLessThanOrEqualTo((duration1 + duration2 + fudgeFactor) / 1000.0); */ assertThat(stopWatch.getTaskCount()).isEqualTo(2); @@ -138,12 +140,8 @@ void validUsageDoesNotKeepTaskList() throws Exception { assertThat(stopWatch.prettyPrint()).contains("No task info kept"); assertThat(stopWatch.toString()).doesNotContain(name1, name2); assertThatExceptionOfType(UnsupportedOperationException.class) - .isThrownBy(stopWatch::getTaskInfo) - .withMessage("Task info is not being kept!"); - } - - private static long millisToNanos(long duration) { - return MILLISECONDS.toNanos(duration); + .isThrownBy(stopWatch::getTaskInfo) + .withMessage("Task info is not being kept!"); } } From 49427b0c3c7e0d1329b0fe85514d9807ee2f6001 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 2 Oct 2021 12:08:09 +0200 Subject: [PATCH 188/735] Upgrade to Apache Johnzon 1.2.14, Vavr 0.10.4, WebJars Locator 0.48, HtmlUnit 2.53 --- build.gradle | 12 ++++++------ .../converter/JsonbMessageConverterTests.java | 6 +++--- .../json/JsonbHttpMessageConverterTests.java | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index c6545c8abf21..ec48137948d3 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { id 'org.asciidoctor.jvm.convert' version '3.3.2' id 'org.asciidoctor.jvm.pdf' version '3.3.2' id 'de.undercouch.download' version '4.1.2' - id "io.freefair.aspectj" version '6.1.0' apply false + id "io.freefair.aspectj" version '6.2.0' apply false id "com.github.ben-manes.versions" version '0.39.0' id "com.github.johnrengelman.shadow" version '7.0.0' apply false id "me.champeau.jmh" version "0.6.6" apply false @@ -83,7 +83,7 @@ configure(allprojects) { project -> exclude group: "xpp3", name: "xpp3_min" exclude group: "xmlpull", name: "xmlpull" } - dependency "org.apache.johnzon:johnzon-jsonb:1.2.10" + dependency "org.apache.johnzon:johnzon-jsonb:1.2.14" dependency("org.codehaus.jettison:jettison:1.3.8") { exclude group: "stax", name: "stax-api" } @@ -99,7 +99,7 @@ configure(allprojects) { project -> dependency "com.github.librepdf:openpdf:1.3.26" dependency "com.rometools:rome:1.16.0" dependency "commons-io:commons-io:2.5" - dependency "io.vavr:vavr:0.10.3" + dependency "io.vavr:vavr:0.10.4" dependency "net.sf.jopt-simple:jopt-simple:5.0.4" dependencySet(group: 'org.apache.activemq', version: '5.16.2') { entry 'activemq-broker' @@ -125,7 +125,7 @@ configure(allprojects) { project -> dependency "org.ehcache:ehcache:3.4.0" dependency "org.hibernate:hibernate-core:5.4.32.Final" dependency "org.hibernate:hibernate-validator:6.2.0.Final" - dependency "org.webjars:webjars-locator-core:0.47" + dependency "org.webjars:webjars-locator-core:0.48" dependency "org.webjars:underscorejs:1.8.3" dependencySet(group: 'org.apache.tomcat', version: '9.0.53') { @@ -206,10 +206,10 @@ configure(allprojects) { project -> } dependency "io.mockk:mockk:1.12.0" - dependency("net.sourceforge.htmlunit:htmlunit:2.52.0") { + dependency("net.sourceforge.htmlunit:htmlunit:2.53.0") { exclude group: "commons-logging", name: "commons-logging" } - dependency("org.seleniumhq.selenium:htmlunit-driver:2.52.0") { + dependency("org.seleniumhq.selenium:htmlunit-driver:2.53.0") { exclude group: "commons-logging", name: "commons-logging" } dependency("org.seleniumhq.selenium:selenium-java:3.141.59") { diff --git a/spring-messaging/src/test/java/org/springframework/messaging/converter/JsonbMessageConverterTests.java b/spring-messaging/src/test/java/org/springframework/messaging/converter/JsonbMessageConverterTests.java index 63380ea4ebcf..7b524de480ec 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/converter/JsonbMessageConverterTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/converter/JsonbMessageConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -165,7 +165,7 @@ public void toMessageUtf16() { String payload = "H\u00e9llo W\u00f6rld"; Message message = converter.toMessage(payload, headers); - assertThat(new String((byte[]) message.getPayload(), StandardCharsets.UTF_16BE)).isEqualTo(payload); + assertThat(new String((byte[]) message.getPayload(), StandardCharsets.UTF_16BE)).isEqualTo("\"" + payload + "\""); assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE)).isEqualTo(contentType); } @@ -181,7 +181,7 @@ public void toMessageUtf16String() { String payload = "H\u00e9llo W\u00f6rld"; Message message = converter.toMessage(payload, headers); - assertThat(message.getPayload()).isEqualTo(payload); + assertThat(message.getPayload()).isEqualTo("\"" + payload + "\""); assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE)).isEqualTo(contentType); } diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/JsonbHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/JsonbHttpMessageConverterTests.java index 7649e8415bd5..44e14ac57612 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/json/JsonbHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/json/JsonbHttpMessageConverterTests.java @@ -162,7 +162,7 @@ public void writeUTF16() throws IOException { MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); String body = "H\u00e9llo W\u00f6rld"; this.converter.write(body, contentType, outputMessage); - assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_16BE)).as("Invalid result").isEqualTo(body); + assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_16BE)).as("Invalid result").isEqualTo("\"" + body + "\""); assertThat(outputMessage.getHeaders().getContentType()).as("Invalid content-type").isEqualTo(contentType); } @@ -260,7 +260,7 @@ public void prefixJson() throws IOException { MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); this.converter.setPrefixJson(true); this.converter.writeInternal("foo", null, outputMessage); - assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEqualTo(")]}', foo"); + assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEqualTo(")]}', \"foo\""); } @Test @@ -268,7 +268,7 @@ public void prefixJsonCustom() throws IOException { MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); this.converter.setJsonPrefix(")))"); this.converter.writeInternal("foo", null, outputMessage); - assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEqualTo(")))foo"); + assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEqualTo(")))\"foo\""); } From 48eb51a22f640f395124bf546efdb36ce9641762 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 2 Oct 2021 12:38:26 +0200 Subject: [PATCH 189/735] Upgrade to Jackson 2.13 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 569569e295e4..0ec6ff0279c8 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ configure(allprojects) { project -> dependencyManagement { imports { - mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5" + mavenBom "com.fasterxml.jackson:jackson-bom:2.13.0" mavenBom "io.netty:netty-bom:4.1.68.Final" mavenBom "io.projectreactor:reactor-bom:2020.0.11" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" From 151852b164e990dbff29235ef1bc010a3da0d723 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sun, 3 Oct 2021 07:09:24 +0200 Subject: [PATCH 190/735] Upgrade to GitHub Changelog Generator 0.0.7 in CI Closes gh-27512 --- ci/tasks/generate-changelog.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/tasks/generate-changelog.yml b/ci/tasks/generate-changelog.yml index ea048af96a0f..b3f40278c8e6 100755 --- a/ci/tasks/generate-changelog.yml +++ b/ci/tasks/generate-changelog.yml @@ -4,7 +4,7 @@ image_resource: type: registry-image source: repository: springio/github-changelog-generator - tag: '0.0.6' + tag: '0.0.7' inputs: - name: git-repo - name: artifactory-repo From e68219c1acf6f3e3b49faa4e0b49eb02465b2e13 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 5 Oct 2021 12:12:17 +0100 Subject: [PATCH 191/735] ResponseStatusExceptionHandler logs exception message only No need to log the full exception for a resolved exception, and as the comment suggests that it mirrors Spring MVC equivalent, which also logs the message only. --- .../web/server/handler/ResponseStatusExceptionHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/server/handler/ResponseStatusExceptionHandler.java b/spring-web/src/main/java/org/springframework/web/server/handler/ResponseStatusExceptionHandler.java index 52074e66f94c..618200530e09 100644 --- a/spring-web/src/main/java/org/springframework/web/server/handler/ResponseStatusExceptionHandler.java +++ b/spring-web/src/main/java/org/springframework/web/server/handler/ResponseStatusExceptionHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,7 +70,7 @@ public Mono handle(ServerWebExchange exchange, Throwable ex) { // Mirrors AbstractHandlerExceptionResolver in spring-webmvc... String logPrefix = exchange.getLogPrefix(); if (this.warnLogger != null && this.warnLogger.isWarnEnabled()) { - this.warnLogger.warn(logPrefix + formatError(ex, exchange.getRequest()), ex); + this.warnLogger.warn(logPrefix + formatError(ex, exchange.getRequest())); } else if (logger.isDebugEnabled()) { logger.debug(logPrefix + formatError(ex, exchange.getRequest())); From be3bc4c16440795368252dc2030d68b1a2c58164 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 5 Oct 2021 14:24:18 +0200 Subject: [PATCH 192/735] Comment out unused fudgeFactor --- .../src/test/java/org/springframework/util/StopWatchTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-core/src/test/java/org/springframework/util/StopWatchTests.java b/spring-core/src/test/java/org/springframework/util/StopWatchTests.java index a3458afb6a1f..396a06263b48 100644 --- a/spring-core/src/test/java/org/springframework/util/StopWatchTests.java +++ b/spring-core/src/test/java/org/springframework/util/StopWatchTests.java @@ -40,7 +40,7 @@ class StopWatchTests { private static final long duration1 = 200; private static final long duration2 = 100; - private static final long fudgeFactor = 100; + // private static final long fudgeFactor = 100; private final StopWatch stopWatch = new StopWatch(ID); From 48a507a99376165eebc020c2f61bbe412325f64c Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 5 Oct 2021 14:35:32 +0200 Subject: [PATCH 193/735] Clean up warnings --- .../AutowiredAnnotationBeanPostProcessor.java | 3 +-- .../annotation/AsyncAnnotationAdvisor.java | 1 - .../test/java/example/scannable/FooServiceImpl.java | 3 ++- .../autoproxy/AspectJAutoProxyCreatorTests.java | 7 ------- .../aop/framework/CglibProxyTests.java | 3 ++- .../AggressiveFactoryBeanInstantiationTests.java | 1 + .../ConfigurationClassPostProcessorTests.java | 4 +++- .../context/annotation/ParserStrategyUtilsTests.java | 4 ++-- .../context/annotation/Spr12278Tests.java | 3 +++ .../context/annotation/Spr16179Tests.java | 1 + .../ConfigurationClassProcessingTests.java | 10 ++++------ .../configuration/ImportResourceTests.java | 7 ++++--- .../configuration/ImportWithConditionTests.java | 4 +++- .../ImportedConfigurationClassEnhancementTests.java | 3 ++- .../annotation/configuration/Spr7167Tests.java | 3 ++- .../support/BeanFactoryPostProcessorTests.java | 6 +++--- .../context/support/LiveBeansViewTests.java | 3 ++- .../PropertyResourceConfigurerIntegrationTests.java | 1 + .../PropertySourcesPlaceholderConfigurerTests.java | 4 ++-- .../StaticApplicationContextMulticasterTests.java | 7 ++++--- .../support/StaticApplicationContextTests.java | 7 ++++--- .../context/support/StaticMessageSourceTests.java | 7 ++++--- .../EnableMBeanExportConfigurationTests.java | 4 ++-- .../core/testfixture/codec/AbstractEncoderTests.java | 10 +++------- .../orm/hibernate5/HibernateTemplate.java | 3 ++- .../springframework/r2dbc/core/binding/Bindings.java | 3 ++- .../http/codec/EncoderHttpMessageWriter.java | 3 --- .../http/codec/json/Jackson2SmileEncoder.java | 5 +---- .../http/codec/json/Jackson2JsonDecoderTests.java | 2 ++ .../http/codec/json/Jackson2JsonEncoderTests.java | 7 +++---- .../result/method/AbstractHandlerMethodMapping.java | 4 ---- .../socket/adapter/ReactorNettyWebSocketSession.java | 1 + .../adapter/UndertowWebSocketHandlerAdapter.java | 5 ++++- .../resource/AppCacheManifestTransformerTests.java | 6 +++--- .../reactive/resource/ResourceUrlProviderTests.java | 2 ++ .../web/servlet/ComplexWebApplicationContext.java | 2 ++ .../annotation/ResourceHandlerRegistryTests.java | 12 +++++++----- .../resource/AppCacheManifestTransformerTests.java | 6 +++--- .../view/ContentNegotiatingViewResolverTests.java | 9 +++++---- 39 files changed, 92 insertions(+), 84 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index 2065f6b6e9b0..e7131a562ef7 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -539,8 +539,7 @@ private MergedAnnotation findAutowiredAnnotation(AccessibleObject ao) { */ @SuppressWarnings({"deprecation", "cast"}) protected boolean determineRequiredStatus(MergedAnnotation ann) { - // The following (AnnotationAttributes) cast is required on JDK 9+. - return determineRequiredStatus((AnnotationAttributes) + return determineRequiredStatus( ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType()))); } diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java index c5636f2daa00..3b8792f7a15f 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java @@ -75,7 +75,6 @@ public AsyncAnnotationAdvisor() { * handle unexpected exception thrown by asynchronous method executions * @see AnnotationAsyncExecutionInterceptor#getDefaultExecutor(BeanFactory) */ - @SuppressWarnings("unchecked") public AsyncAnnotationAdvisor( @Nullable Executor executor, @Nullable AsyncUncaughtExceptionHandler exceptionHandler) { diff --git a/spring-context/src/test/java/example/scannable/FooServiceImpl.java b/spring-context/src/test/java/example/scannable/FooServiceImpl.java index de062761fac8..6a39aaf892e9 100644 --- a/spring-context/src/test/java/example/scannable/FooServiceImpl.java +++ b/spring-context/src/test/java/example/scannable/FooServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +47,7 @@ public abstract class FooServiceImpl implements FooService { // Just to test ASM5's bytecode parsing of INVOKESPECIAL/STATIC on interfaces + @SuppressWarnings("unused") private static final Comparator COMPARATOR_BY_MESSAGE = Comparator.comparing(MessageBean::getMessage); diff --git a/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java b/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java index 279e600ec9e8..d841044f2650 100644 --- a/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java +++ b/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java @@ -48,7 +48,6 @@ import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.lang.Nullable; -import org.springframework.util.StopWatch; import static org.assertj.core.api.Assertions.assertThat; @@ -310,12 +309,6 @@ private String qName(String fileSuffix) { return String.format("%s-%s", getClass().getSimpleName(), fileSuffix); } - private void assertStopWatchTimeLimit(final StopWatch sw, final long maxTimeMillis) { - long totalTimeMillis = sw.getTotalTimeMillis(); - assertThat(totalTimeMillis < maxTimeMillis).as("'" + sw.getLastTaskName() + "' took too long: expected less than<" + maxTimeMillis + - "> ms, actual<" + totalTimeMillis + "> ms.").isTrue(); - } - } @Aspect("pertarget(execution(* *.getSpouse()))") diff --git a/spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java b/spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java index ba247ed89a9b..b1d1cd59438b 100644 --- a/spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java +++ b/spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -513,6 +513,7 @@ public void setName(String name) { this.name = name; } + @SuppressWarnings("unused") public String getName() { return this.name; } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/AggressiveFactoryBeanInstantiationTests.java b/spring-context/src/test/java/org/springframework/context/annotation/AggressiveFactoryBeanInstantiationTests.java index 5f97cd7f5c9e..07edad06f9d6 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/AggressiveFactoryBeanInstantiationTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/AggressiveFactoryBeanInstantiationTests.java @@ -137,6 +137,7 @@ public Class getObjectType() { static class ExceptionInInitializer { + @SuppressWarnings("unused") private static final int ERROR = callInClinit(); private static int callInClinit() { diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java index 3b1f1a7f0dd9..2706511ea70f 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1956,6 +1956,7 @@ Runnable testBean(Map testBeans, } // Unrelated, not to be considered as a factory method + @SuppressWarnings("unused") private boolean testBean(boolean param) { return param; } @@ -1985,6 +1986,7 @@ Runnable testBean() { } // Unrelated, not to be considered as a factory method + @SuppressWarnings("unused") private boolean testBean(boolean param) { return param; } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ParserStrategyUtilsTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ParserStrategyUtilsTests.java index d5e5fc54664c..f13afc69740b 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ParserStrategyUtilsTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ParserStrategyUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,7 +61,7 @@ public class ParserStrategyUtilsTests { @BeforeEach void setup() { - MockitoAnnotations.initMocks(this); + MockitoAnnotations.openMocks(this); given(this.resourceLoader.getClassLoader()).willReturn(this.beanClassLoader); } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/Spr12278Tests.java b/spring-context/src/test/java/org/springframework/context/annotation/Spr12278Tests.java index afceea8a090c..c17203dbc131 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/Spr12278Tests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/Spr12278Tests.java @@ -74,6 +74,7 @@ private static class SingleConstructorComponent { private final String autowiredName; // No @Autowired - implicit wiring + @SuppressWarnings("unused") public SingleConstructorComponent(String autowiredName) { this.autowiredName = autowiredName; } @@ -88,11 +89,13 @@ public TwoConstructorsComponent(String name) { this.name = name; } + @SuppressWarnings("unused") public TwoConstructorsComponent() { this("fallback"); } } + @SuppressWarnings("unused") private static class TwoSpecificConstructorsComponent { private final Integer counter; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/Spr16179Tests.java b/spring-context/src/test/java/org/springframework/context/annotation/Spr16179Tests.java index afeae7ece20f..3bb817546445 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/Spr16179Tests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/Spr16179Tests.java @@ -70,6 +70,7 @@ public static class AssemblerInjection { Assembler> assembler2; @Autowired(required = false) + @SuppressWarnings("rawtypes") Assembler assembler3; @Autowired(required = false) diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java index 89da3b916225..ce9033334c04 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java @@ -42,7 +42,6 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.DependencyDescriptor; import org.springframework.beans.factory.config.ListFactoryBean; -import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.RootBeanDefinition; @@ -247,7 +246,9 @@ public void configurationWithAdaptiveResourcePrototypes() { public void configurationWithPostProcessor() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(ConfigWithPostProcessor.class); - RootBeanDefinition placeholderConfigurer = new RootBeanDefinition(PropertyPlaceholderConfigurer.class); + @SuppressWarnings("deprecation") + RootBeanDefinition placeholderConfigurer = new RootBeanDefinition( + org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.class); placeholderConfigurer.getPropertyValues().add("properties", "myProp=myValue"); ctx.registerBeanDefinition("placeholderConfigurer", placeholderConfigurer); ctx.refresh(); @@ -536,6 +537,7 @@ public POBPP beanPostProcessor() { String nameSuffix = "-processed-" + myProp; + @SuppressWarnings("unused") public void setNameSuffix(String nameSuffix) { this.nameSuffix = nameSuffix; } @@ -552,10 +554,6 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) { public Object postProcessAfterInitialization(Object bean, String beanName) { return bean; } - - public int getOrder() { - return 0; - } }; } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportResourceTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportResourceTests.java index 87dd37d39886..12fe608bbb06 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportResourceTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportResourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; import org.springframework.beans.testfixture.beans.TestBean; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -166,8 +165,10 @@ static class ImportXmlAutowiredConfig { } } + @SuppressWarnings("deprecation") @Configuration - @ImportResource(locations = "classpath:org/springframework/context/annotation/configuration/ImportNonXmlResourceConfig-context.properties", reader = PropertiesBeanDefinitionReader.class) + @ImportResource(locations = "classpath:org/springframework/context/annotation/configuration/ImportNonXmlResourceConfig-context.properties", + reader = org.springframework.beans.factory.support.PropertiesBeanDefinitionReader.class) static class ImportNonXmlResourceConfig { } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportWithConditionTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportWithConditionTests.java index 1a7b5f998b28..52755bd7e5f2 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportWithConditionTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportWithConditionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,6 +59,7 @@ public void unconditionalThenConditional() throws Exception { protected static class ConditionalThenUnconditional { @Autowired + @SuppressWarnings("unused") private BeanOne beanOne; } @@ -68,6 +69,7 @@ protected static class ConditionalThenUnconditional { protected static class UnconditionalThenConditional { @Autowired + @SuppressWarnings("unused") private BeanOne beanOne; } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportedConfigurationClassEnhancementTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportedConfigurationClassEnhancementTests.java index df640ffbd72d..8aa24e9f1e4b 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportedConfigurationClassEnhancementTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportedConfigurationClassEnhancementTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +47,7 @@ public void autowiredConfigClassIsEnhancedWhenRegisteredViaConstructor() { autowiredConfigClassIsEnhanced(ConfigThatDoesNotImport.class, ConfigToBeAutowired.class); } + @SuppressWarnings("deprecation") private void autowiredConfigClassIsEnhanced(Class... configClasses) { ApplicationContext ctx = new AnnotationConfigApplicationContext(configClasses); Config config = ctx.getBean(Config.class); diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/Spr7167Tests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/Spr7167Tests.java index ef73432110cc..6b66fcc5b5c0 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/Spr7167Tests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/Spr7167Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ public class Spr7167Tests { + @SuppressWarnings("deprecation") @Test public void test() { ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class); diff --git a/spring-context/src/test/java/org/springframework/context/support/BeanFactoryPostProcessorTests.java b/spring-context/src/test/java/org/springframework/context/support/BeanFactoryPostProcessorTests.java index ffbdceb815e7..93e0dfa25580 100644 --- a/spring-context/src/test/java/org/springframework/context/support/BeanFactoryPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/support/BeanFactoryPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,6 @@ import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.DefaultListableBeanFactory; @@ -75,6 +74,7 @@ public void testDefinedBeanFactoryPostProcessor() { } @Test + @SuppressWarnings("deprecation") public void testMultipleDefinedBeanFactoryPostProcessors() { StaticApplicationContext ac = new StaticApplicationContext(); ac.registerSingleton("tb1", TestBean.class); @@ -84,7 +84,7 @@ public void testMultipleDefinedBeanFactoryPostProcessors() { ac.registerSingleton("bfpp1", TestBeanFactoryPostProcessor.class, pvs1); MutablePropertyValues pvs2 = new MutablePropertyValues(); pvs2.add("properties", "key=value"); - ac.registerSingleton("bfpp2", PropertyPlaceholderConfigurer.class, pvs2); + ac.registerSingleton("bfpp2", org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.class, pvs2); ac.refresh(); TestBeanFactoryPostProcessor bfpp = (TestBeanFactoryPostProcessor) ac.getBean("bfpp1"); assertThat(bfpp.initValue).isEqualTo("value"); diff --git a/spring-context/src/test/java/org/springframework/context/support/LiveBeansViewTests.java b/spring-context/src/test/java/org/springframework/context/support/LiveBeansViewTests.java index 56c9ef44679e..983fa9bc88c7 100644 --- a/spring-context/src/test/java/org/springframework/context/support/LiveBeansViewTests.java +++ b/spring-context/src/test/java/org/springframework/context/support/LiveBeansViewTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,6 +38,7 @@ * @author Stephane Nicoll * @author Sam Brannen */ +@SuppressWarnings("deprecation") class LiveBeansViewTests { private final MockEnvironment environment = new MockEnvironment(); diff --git a/spring-context/src/test/java/org/springframework/context/support/PropertyResourceConfigurerIntegrationTests.java b/spring-context/src/test/java/org/springframework/context/support/PropertyResourceConfigurerIntegrationTests.java index 82a018cf3663..9a598631dcf0 100644 --- a/spring-context/src/test/java/org/springframework/context/support/PropertyResourceConfigurerIntegrationTests.java +++ b/spring-context/src/test/java/org/springframework/context/support/PropertyResourceConfigurerIntegrationTests.java @@ -43,6 +43,7 @@ * @author Sam Brannen * @see org.springframework.beans.factory.config.PropertyResourceConfigurerTests */ +@SuppressWarnings("deprecation") public class PropertyResourceConfigurerIntegrationTests { @Test diff --git a/spring-context/src/test/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurerTests.java b/spring-context/src/test/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurerTests.java index 03606bc6979c..8717dba116a5 100644 --- a/spring-context/src/test/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurerTests.java +++ b/spring-context/src/test/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,6 @@ */ public class PropertySourcesPlaceholderConfigurerTests { - @Test public void replacementFromEnvironmentProperties() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); @@ -397,6 +396,7 @@ public Optional getName() { return name; } + @SuppressWarnings("unused") public void setName(Optional name) { this.name = name; } diff --git a/spring-context/src/test/java/org/springframework/context/support/StaticApplicationContextMulticasterTests.java b/spring-context/src/test/java/org/springframework/context/support/StaticApplicationContextMulticasterTests.java index 403bf613befa..491af1c4db00 100644 --- a/spring-context/src/test/java/org/springframework/context/support/StaticApplicationContextMulticasterTests.java +++ b/spring-context/src/test/java/org/springframework/context/support/StaticApplicationContextMulticasterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.MutablePropertyValues; -import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; import org.springframework.beans.testfixture.beans.TestBean; import org.springframework.context.ApplicationEvent; import org.springframework.context.ConfigurableApplicationContext; @@ -48,6 +47,7 @@ public class StaticApplicationContextMulticasterTests extends AbstractApplicatio protected StaticApplicationContext sac; + @SuppressWarnings("deprecation") @Override protected ConfigurableApplicationContext createContext() throws Exception { StaticApplicationContext parent = new StaticApplicationContext(); @@ -67,7 +67,8 @@ protected ConfigurableApplicationContext createContext() throws Exception { sac.registerSingleton("beanThatListens", BeanThatListens.class, new MutablePropertyValues()); sac.registerSingleton("aca", ACATester.class, new MutablePropertyValues()); sac.registerPrototype("aca-prototype", ACATester.class, new MutablePropertyValues()); - PropertiesBeanDefinitionReader reader = new PropertiesBeanDefinitionReader(sac.getDefaultListableBeanFactory()); + org.springframework.beans.factory.support.PropertiesBeanDefinitionReader reader = + new org.springframework.beans.factory.support.PropertiesBeanDefinitionReader(sac.getDefaultListableBeanFactory()); Resource resource = new ClassPathResource("testBeans.properties", getClass()); reader.loadBeanDefinitions(new EncodedResource(resource, "ISO-8859-1")); sac.refresh(); diff --git a/spring-context/src/test/java/org/springframework/context/support/StaticApplicationContextTests.java b/spring-context/src/test/java/org/springframework/context/support/StaticApplicationContextTests.java index 91c06a88da48..023efd449bb8 100644 --- a/spring-context/src/test/java/org/springframework/context/support/StaticApplicationContextTests.java +++ b/spring-context/src/test/java/org/springframework/context/support/StaticApplicationContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.MutablePropertyValues; -import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; import org.springframework.beans.testfixture.beans.TestBean; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.testfixture.AbstractApplicationContextTests; @@ -40,6 +39,7 @@ public class StaticApplicationContextTests extends AbstractApplicationContextTes protected StaticApplicationContext sac; + @SuppressWarnings("deprecation") @Override protected ConfigurableApplicationContext createContext() throws Exception { StaticApplicationContext parent = new StaticApplicationContext(); @@ -57,7 +57,8 @@ protected ConfigurableApplicationContext createContext() throws Exception { sac.registerSingleton("beanThatListens", BeanThatListens.class, new MutablePropertyValues()); sac.registerSingleton("aca", ACATester.class, new MutablePropertyValues()); sac.registerPrototype("aca-prototype", ACATester.class, new MutablePropertyValues()); - PropertiesBeanDefinitionReader reader = new PropertiesBeanDefinitionReader(sac.getDefaultListableBeanFactory()); + org.springframework.beans.factory.support.PropertiesBeanDefinitionReader reader = + new org.springframework.beans.factory.support.PropertiesBeanDefinitionReader(sac.getDefaultListableBeanFactory()); reader.loadBeanDefinitions(new ClassPathResource("testBeans.properties", getClass())); sac.refresh(); sac.addApplicationListener(listener); diff --git a/spring-context/src/test/java/org/springframework/context/support/StaticMessageSourceTests.java b/spring-context/src/test/java/org/springframework/context/support/StaticMessageSourceTests.java index 3b84bd9a8f8f..d24f13a13c8e 100644 --- a/spring-context/src/test/java/org/springframework/context/support/StaticMessageSourceTests.java +++ b/spring-context/src/test/java/org/springframework/context/support/StaticMessageSourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.MutablePropertyValues; -import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.MessageSourceResolvable; import org.springframework.context.NoSuchMessageException; @@ -176,6 +175,7 @@ public void messageSourceResolvable() { sac.getMessage(resolvable4, Locale.US)); } + @SuppressWarnings("deprecation") @Override protected ConfigurableApplicationContext createContext() throws Exception { StaticApplicationContext parent = new StaticApplicationContext(); @@ -197,7 +197,8 @@ protected ConfigurableApplicationContext createContext() throws Exception { sac.registerPrototype("aca-prototype", ACATester.class, new MutablePropertyValues()); - PropertiesBeanDefinitionReader reader = new PropertiesBeanDefinitionReader(sac.getDefaultListableBeanFactory()); + org.springframework.beans.factory.support.PropertiesBeanDefinitionReader reader = + new org.springframework.beans.factory.support.PropertiesBeanDefinitionReader(sac.getDefaultListableBeanFactory()); reader.loadBeanDefinitions(new ClassPathResource("testBeans.properties", getClass())); sac.refresh(); sac.addApplicationListener(listener); diff --git a/spring-context/src/test/java/org/springframework/jmx/export/annotation/EnableMBeanExportConfigurationTests.java b/spring-context/src/test/java/org/springframework/jmx/export/annotation/EnableMBeanExportConfigurationTests.java index 5d7f8998a807..553a4cb14cdc 100644 --- a/spring-context/src/test/java/org/springframework/jmx/export/annotation/EnableMBeanExportConfigurationTests.java +++ b/spring-context/src/test/java/org/springframework/jmx/export/annotation/EnableMBeanExportConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -251,7 +251,7 @@ public MBeanExporterTests.Person person() { @Bean @Lazy public Object notLoadable() throws Exception { - return Class.forName("does.not.exist").newInstance(); + return Class.forName("does.not.exist").getDeclaredConstructor().newInstance(); } } diff --git a/spring-core/src/testFixtures/java/org/springframework/core/testfixture/codec/AbstractEncoderTests.java b/spring-core/src/testFixtures/java/org/springframework/core/testfixture/codec/AbstractEncoderTests.java index 106cc114e89c..0b626f94de49 100644 --- a/spring-core/src/testFixtures/java/org/springframework/core/testfixture/codec/AbstractEncoderTests.java +++ b/spring-core/src/testFixtures/java/org/springframework/core/testfixture/codec/AbstractEncoderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,8 +39,8 @@ /** * Abstract base class for {@link Encoder} unit tests. Subclasses need to implement - * {@link #canEncode()} and {@link #encode()}, possibly using the wide - * * variety of helper methods like {@link #testEncodeAll}. + * {@link #canEncode()} and {@link #encode()}, possibly using the wide variety of + * helper methods like {@link #testEncodeAll}. * * @author Arjen Poutsma * @since 5.1.3 @@ -58,9 +58,7 @@ public abstract class AbstractEncoderTests> extends Abstrac * @param encoder the encoder */ protected AbstractEncoderTests(E encoder) { - Assert.notNull(encoder, "Encoder must not be null"); - this.encoder = encoder; } @@ -253,13 +251,11 @@ protected Consumer expectString(String expected) { release(dataBuffer); assertThat(actual).isEqualTo(expected); }; - } @SuppressWarnings("unchecked") private Encoder encoder() { return (Encoder) this.encoder; - } /** diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java index e624fca329af..d4433bc98551 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -983,6 +983,7 @@ public List findByNamedQueryAndValueBean(String queryName, Object valueBean) // Convenience query methods for iteration and bulk updates/deletes //------------------------------------------------------------------------- + @SuppressWarnings("deprecation") @Deprecated @Override public Iterator iterate(String queryString, @Nullable Object... values) throws DataAccessException { diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/Bindings.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/Bindings.java index 63cf20dc5fc1..9be490287ce4 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/Bindings.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/Bindings.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -100,6 +100,7 @@ public void apply(BindTarget bindTarget) { * Exceptions thrown by the action are relayed to the * @param action the action to be performed for each {@link Binding} */ + @Override public void forEach(Consumer action) { this.bindings.forEach((marker, binding) -> action.accept(binding)); } diff --git a/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java index 3fe192077388..c2d6986bd201 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java +++ b/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java @@ -180,9 +180,6 @@ private static MediaType addDefaultCharset(MediaType main, @Nullable MediaType d return main; } - private static void touch(DataBuffer buffer, Map hints) { - } - private boolean isStreamingMediaType(@Nullable MediaType mediaType) { if (mediaType == null || !(this.encoder instanceof HttpMessageEncoder)) { return false; diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2SmileEncoder.java b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2SmileEncoder.java index 98d294d3bb35..580b35c0027d 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2SmileEncoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2SmileEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,9 +44,6 @@ public class Jackson2SmileEncoder extends AbstractJackson2Encoder { new MimeType("application", "x-jackson-smile"), new MimeType("application", "*+x-jackson-smile")}; - private static final MimeType STREAM_MIME_TYPE = - MediaType.parseMediaType("application/stream+x-jackson-smile"); - private static final byte[] STREAM_SEPARATOR = new byte[0]; diff --git a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java index 8cfeb045f82b..aa8c1f5dfd14 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java @@ -76,6 +76,7 @@ public Jackson2JsonDecoderTests() { @Override @Test + @SuppressWarnings("deprecation") public void canDecode() { assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), APPLICATION_JSON)).isTrue(); assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), APPLICATION_NDJSON)).isTrue(); @@ -311,6 +312,7 @@ private Mono stringBuffer(String value, Charset charset) { } + @SuppressWarnings("unused") private static class BeanWithNoDefaultConstructor { private final String property1; diff --git a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java index ebeed1493b7f..a7fb6873d938 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,6 +65,7 @@ public Jackson2JsonEncoderTests() { @Override @Test + @SuppressWarnings("deprecation") public void canEncode() { ResolvableType pojoType = ResolvableType.forClass(Pojo.class); assertThat(this.encoder.canEncode(pojoType, APPLICATION_JSON)).isTrue(); @@ -84,12 +85,11 @@ public void canEncode() { // SPR-15910 assertThat(this.encoder.canEncode(ResolvableType.forClass(Object.class), APPLICATION_OCTET_STREAM)).isFalse(); - - } @Override @Test + @SuppressWarnings("deprecation") public void encode() throws Exception { Flux input = Flux.just(new Pojo("foo", "bar"), new Pojo("foofoo", "barbar"), @@ -257,7 +257,6 @@ public void encodeAscii() { .consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}")) .verifyComplete(), new MimeType("application", "json", StandardCharsets.US_ASCII), null); - } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java index c2e01aaeff70..4487162cc9e6 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java @@ -639,10 +639,6 @@ public Match(T mapping, MappingRegistration registration) { this.registration = registration; } - public T getMapping() { - return this.mapping; - } - public HandlerMethod getHandlerMethod() { return this.registration.getHandlerMethod(); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/ReactorNettyWebSocketSession.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/ReactorNettyWebSocketSession.java index b84caa743902..9354318c714d 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/ReactorNettyWebSocketSession.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/ReactorNettyWebSocketSession.java @@ -64,6 +64,7 @@ public ReactorNettyWebSocketSession(WebsocketInbound inbound, WebsocketOutbound * Constructor with an additional maxFramePayloadLength argument. * @since 5.1 */ + @SuppressWarnings("rawtypes") public ReactorNettyWebSocketSession(WebsocketInbound inbound, WebsocketOutbound outbound, HandshakeInfo info, NettyDataBufferFactory bufferFactory, int maxFramePayloadLength) { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/UndertowWebSocketHandlerAdapter.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/UndertowWebSocketHandlerAdapter.java index e2b0323a6146..879ea596b229 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/UndertowWebSocketHandlerAdapter.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/UndertowWebSocketHandlerAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,18 +58,21 @@ protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage m } @Override + @SuppressWarnings("deprecation") protected void onFullBinaryMessage(WebSocketChannel channel, BufferedBinaryMessage message) { this.session.handleMessage(Type.BINARY, toMessage(Type.BINARY, message.getData().getResource())); message.getData().free(); } @Override + @SuppressWarnings("deprecation") protected void onFullPongMessage(WebSocketChannel channel, BufferedBinaryMessage message) { this.session.handleMessage(Type.PONG, toMessage(Type.PONG, message.getData().getResource())); message.getData().free(); } @Override + @SuppressWarnings("deprecation") protected void onFullCloseMessage(WebSocketChannel channel, BufferedBinaryMessage message) { CloseMessage closeMessage = new CloseMessage(message.getData().getResource()); this.session.handleClose(CloseStatus.create(closeMessage.getCode(), closeMessage.getReason())); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/AppCacheManifestTransformerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/AppCacheManifestTransformerTests.java index d58f0fb81cbf..24ce532e492b 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/AppCacheManifestTransformerTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/AppCacheManifestTransformerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,12 +37,13 @@ * @author Rossen Stoyanchev * @author Brian Clozel */ +@SuppressWarnings("deprecation") public class AppCacheManifestTransformerTests { private static final Duration TIMEOUT = Duration.ofSeconds(5); - private AppCacheManifestTransformer transformer; + private final AppCacheManifestTransformer transformer = new AppCacheManifestTransformer(); private ResourceTransformerChain chain; @@ -57,7 +58,6 @@ public void setup() { ResourceResolverChain resolverChain = new DefaultResourceResolverChain(resolvers); this.chain = new DefaultResourceTransformerChain(resolverChain, Collections.emptyList()); - this.transformer = new AppCacheManifestTransformer(); this.transformer.setResourceUrlProvider(createUrlProvider(resolvers)); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceUrlProviderTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceUrlProviderTests.java index c4ffa23a1c1c..ec5d45344aaf 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceUrlProviderTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceUrlProviderTests.java @@ -158,6 +158,8 @@ void initializeOnCurrentContext() { assertThat(parentUrlProvider.getHandlerMap()).isEmpty(); ResourceUrlProvider childUrlProvider = childContext.getBean(ResourceUrlProvider.class); assertThat(childUrlProvider.getHandlerMap()).hasKeySatisfying(pathPatternStringOf("/resources/**")); + childContext.close(); + parentContext.close(); } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/ComplexWebApplicationContext.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/ComplexWebApplicationContext.java index 9c00d1950050..be08292460d1 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/ComplexWebApplicationContext.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/ComplexWebApplicationContext.java @@ -266,6 +266,7 @@ public ModelAndView handle(HttpServletRequest request, HttpServletResponse respo } @Override + @SuppressWarnings("deprecation") public long getLastModified(HttpServletRequest request, Object delegate) { return ((MyHandler) delegate).lastModified(); } @@ -286,6 +287,7 @@ public ModelAndView handle(HttpServletRequest request, HttpServletResponse respo } @Override + @SuppressWarnings("deprecation") public long getLastModified(HttpServletRequest request, Object delegate) { return -1; } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java index 0551598c492a..cce273a24937 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,6 @@ import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; -import org.springframework.web.servlet.resource.AppCacheManifestTransformer; import org.springframework.web.servlet.resource.CachingResourceResolver; import org.springframework.web.servlet.resource.CachingResourceTransformer; import org.springframework.web.servlet.resource.CssLinkResourceTransformer; @@ -163,13 +162,14 @@ public void resourceChainWithoutCaching() throws Exception { } @Test + @SuppressWarnings("deprecation") public void resourceChainWithVersionResolver() throws Exception { VersionResourceResolver versionResolver = new VersionResourceResolver() .addFixedVersionStrategy("fixed", "/**/*.js") .addContentVersionStrategy("/**"); this.registration.resourceChain(true).addResolver(versionResolver) - .addTransformer(new AppCacheManifestTransformer()); + .addTransformer(new org.springframework.web.servlet.resource.AppCacheManifestTransformer()); ResourceHttpRequestHandler handler = getHandler("/resources/**"); List resolvers = handler.getResourceResolvers(); @@ -183,17 +183,19 @@ public void resourceChainWithVersionResolver() throws Exception { assertThat(transformers).hasSize(3); assertThat(transformers.get(0)).isInstanceOf(CachingResourceTransformer.class); assertThat(transformers.get(1)).isInstanceOf(CssLinkResourceTransformer.class); - assertThat(transformers.get(2)).isInstanceOf(AppCacheManifestTransformer.class); + assertThat(transformers.get(2)).isInstanceOf(org.springframework.web.servlet.resource.AppCacheManifestTransformer.class); } @Test + @SuppressWarnings("deprecation") public void resourceChainWithOverrides() throws Exception { CachingResourceResolver cachingResolver = Mockito.mock(CachingResourceResolver.class); VersionResourceResolver versionResolver = Mockito.mock(VersionResourceResolver.class); WebJarsResourceResolver webjarsResolver = Mockito.mock(WebJarsResourceResolver.class); PathResourceResolver pathResourceResolver = new PathResourceResolver(); CachingResourceTransformer cachingTransformer = Mockito.mock(CachingResourceTransformer.class); - AppCacheManifestTransformer appCacheTransformer = Mockito.mock(AppCacheManifestTransformer.class); + org.springframework.web.servlet.resource.AppCacheManifestTransformer appCacheTransformer = + Mockito.mock(org.springframework.web.servlet.resource.AppCacheManifestTransformer.class); CssLinkResourceTransformer cssLinkTransformer = new CssLinkResourceTransformer(); this.registration.setCachePeriod(3600) diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java index 4b12502b8e58..2b321fa7bd93 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,9 +38,10 @@ * @author Brian Clozel * @author Rossen Stoyanchev */ +@SuppressWarnings("deprecation") public class AppCacheManifestTransformerTests { - private AppCacheManifestTransformer transformer; + private final AppCacheManifestTransformer transformer = new AppCacheManifestTransformer(); private ResourceTransformerChain chain; @@ -59,7 +60,6 @@ public void setup() { ResourceResolverChain resolverChain = new DefaultResourceResolverChain(resolvers); this.chain = new DefaultResourceTransformerChain(resolverChain, Collections.emptyList()); - this.transformer = new AppCacheManifestTransformer(); this.transformer.setResourceUrlProvider(createUrlProvider(resolvers)); } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolverTests.java index ec619d54aa07..4534036b6f6d 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,6 @@ import org.springframework.web.accept.HeaderContentNegotiationStrategy; import org.springframework.web.accept.MappingMediaTypeFileExtensionResolver; import org.springframework.web.accept.ParameterContentNegotiationStrategy; -import org.springframework.web.accept.PathExtensionContentNegotiationStrategy; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.support.StaticWebApplicationContext; @@ -312,11 +311,12 @@ public void resolveViewNameAcceptHeaderDefaultView() throws Exception { } @Test + @SuppressWarnings("deprecation") public void resolveViewNameFilename() throws Exception { request.setRequestURI("/test.html"); ContentNegotiationManager manager = - new ContentNegotiationManager(new PathExtensionContentNegotiationStrategy()); + new ContentNegotiationManager(new org.springframework.web.accept.PathExtensionContentNegotiationStrategy()); ViewResolver viewResolverMock1 = mock(ViewResolver.class, "viewResolver1"); ViewResolver viewResolverMock2 = mock(ViewResolver.class, "viewResolver2"); @@ -348,7 +348,8 @@ public void resolveViewNameFilenameDefaultView() throws Exception { request.setRequestURI("/test.json"); Map mapping = Collections.singletonMap("json", MediaType.APPLICATION_JSON); - PathExtensionContentNegotiationStrategy pathStrategy = new PathExtensionContentNegotiationStrategy(mapping); + org.springframework.web.accept.PathExtensionContentNegotiationStrategy pathStrategy = + new org.springframework.web.accept.PathExtensionContentNegotiationStrategy(mapping); viewResolver.setContentNegotiationManager(new ContentNegotiationManager(pathStrategy)); ViewResolver viewResolverMock1 = mock(ViewResolver.class); From 0e834660237459069e3bc929bb5062664fa0d51b Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 5 Oct 2021 15:23:44 +0200 Subject: [PATCH 194/735] Reference Hamcrest Javadoc via javadoc.io Due to an SSL/TLS issue with hamcrest.org, the Dokka task fails with the following. > Failed to download package-list from https://hamcrest.org/JavaHamcrest/javadoc/2.1/package-list, > this might suggest that remote resource is not available, module is > empty or dokka output got corrupted See: https://github.com/hamcrest/JavaHamcrest/issues/280 As a workaround, this commit switches to javadoc.io to reference the Hamcrest Javadoc APIs. --- gradle/docs-dokka.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/docs-dokka.gradle b/gradle/docs-dokka.gradle index ef06f904185c..ac2a56885154 100644 --- a/gradle/docs-dokka.gradle +++ b/gradle/docs-dokka.gradle @@ -17,7 +17,7 @@ tasks.findByName("dokkaHtmlPartial")?.configure { url.set(new URL("https://kotlin.github.io/kotlinx.coroutines/")) } externalDocumentationLink { - url.set(new URL("https://hamcrest.org/JavaHamcrest/javadoc/2.1/")) + url.set(new URL("https://javadoc.io/doc/org.hamcrest/hamcrest/2.1/")) } externalDocumentationLink { url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/")) From 7b9848a352b0403d59fdeabeb6dc6e4ee043c1a6 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 5 Oct 2021 14:32:46 +0100 Subject: [PATCH 195/735] Replace deprecated Reactor Context related methods --- .../reactive/TransactionContextManager.java | 6 ++--- ...bstractReactiveTransactionAspectTests.java | 16 +++++++----- .../ReactiveTransactionSupportTests.java | 26 +++++++++---------- ...bstractCoroutinesTransactionAspectTests.kt | 19 +++++++------- 4 files changed, 35 insertions(+), 32 deletions(-) diff --git a/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionContextManager.java b/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionContextManager.java index 0a2cdda01a89..db6f4fb414ce 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionContextManager.java +++ b/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionContextManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,8 +68,8 @@ public static Mono currentContext() throws NoTransactionExce * Create a {@link TransactionContext} and register it in the subscriber {@link Context}. * @return functional context registration. * @throws IllegalStateException if a transaction context is already associated. - * @see Mono#subscriberContext(Function) - * @see Flux#subscriberContext(Function) + * @see Mono#contextWrite(Function) + * @see Flux#contextWrite(Function) */ public static Function createTransactionContext() { return context -> context.put(TransactionContext.class, new TransactionContext()); diff --git a/spring-tx/src/test/java/org/springframework/transaction/interceptor/AbstractReactiveTransactionAspectTests.java b/spring-tx/src/test/java/org/springframework/transaction/interceptor/AbstractReactiveTransactionAspectTests.java index 6755d5df16a4..54f9b8eaa71c 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/interceptor/AbstractReactiveTransactionAspectTests.java +++ b/spring-tx/src/test/java/org/springframework/transaction/interceptor/AbstractReactiveTransactionAspectTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -350,12 +350,14 @@ public void cannotCommitTransaction() throws Exception { } private void checkReactiveTransaction(boolean expected) { - Mono.subscriberContext().handle((context, sink) -> { - if (context.hasKey(TransactionContext.class) != expected) { - fail("Should have thrown NoTransactionException"); - } - sink.complete(); - }).block(); + Mono.deferContextual(Mono::just) + .handle((context, sink) -> { + if (context.hasKey(TransactionContext.class) != expected) { + fail("Should have thrown NoTransactionException"); + } + sink.complete(); + }) + .block(); } diff --git a/spring-tx/src/test/java/org/springframework/transaction/reactive/ReactiveTransactionSupportTests.java b/spring-tx/src/test/java/org/springframework/transaction/reactive/ReactiveTransactionSupportTests.java index b67f5bf8a4a9..4912c96226a0 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/reactive/ReactiveTransactionSupportTests.java +++ b/spring-tx/src/test/java/org/springframework/transaction/reactive/ReactiveTransactionSupportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,19 +41,19 @@ public void noExistingTransaction() { ReactiveTransactionManager tm = new ReactiveTestTransactionManager(false, true); tm.getReactiveTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS)) - .subscriberContext(TransactionContextManager.createTransactionContext()).cast(GenericReactiveTransaction.class) + .contextWrite(TransactionContextManager.createTransactionContext()).cast(GenericReactiveTransaction.class) .as(StepVerifier::create).consumeNextWith(actual -> assertThat(actual.hasTransaction()).isFalse() ).verifyComplete(); tm.getReactiveTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED)) - .cast(GenericReactiveTransaction.class).subscriberContext(TransactionContextManager.createTransactionContext()) + .cast(GenericReactiveTransaction.class).contextWrite(TransactionContextManager.createTransactionContext()) .as(StepVerifier::create).consumeNextWith(actual -> { assertThat(actual.hasTransaction()).isTrue(); assertThat(actual.isNewTransaction()).isTrue(); }).verifyComplete(); tm.getReactiveTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_MANDATORY)) - .subscriberContext(TransactionContextManager.createTransactionContext()).cast(GenericReactiveTransaction.class) + .contextWrite(TransactionContextManager.createTransactionContext()).cast(GenericReactiveTransaction.class) .as(StepVerifier::create).expectError(IllegalTransactionStateException.class).verify(); } @@ -62,21 +62,21 @@ public void existingTransaction() { ReactiveTransactionManager tm = new ReactiveTestTransactionManager(true, true); tm.getReactiveTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS)) - .subscriberContext(TransactionContextManager.createTransactionContext()).cast(GenericReactiveTransaction.class) + .contextWrite(TransactionContextManager.createTransactionContext()).cast(GenericReactiveTransaction.class) .as(StepVerifier::create).consumeNextWith(actual -> { assertThat(actual.getTransaction()).isNotNull(); assertThat(actual.isNewTransaction()).isFalse(); }).verifyComplete(); tm.getReactiveTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED)) - .subscriberContext(TransactionContextManager.createTransactionContext()).cast(GenericReactiveTransaction.class) + .contextWrite(TransactionContextManager.createTransactionContext()).cast(GenericReactiveTransaction.class) .as(StepVerifier::create).consumeNextWith(actual -> { assertThat(actual.getTransaction()).isNotNull(); assertThat(actual.isNewTransaction()).isFalse(); }).verifyComplete(); tm.getReactiveTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_MANDATORY)) - .subscriberContext(TransactionContextManager.createTransactionContext()).cast(GenericReactiveTransaction.class) + .contextWrite(TransactionContextManager.createTransactionContext()).cast(GenericReactiveTransaction.class) .as(StepVerifier::create).consumeNextWith(actual -> { assertThat(actual.getTransaction()).isNotNull(); assertThat(actual.isNewTransaction()).isFalse(); @@ -87,7 +87,7 @@ public void existingTransaction() { public void commitWithoutExistingTransaction() { ReactiveTestTransactionManager tm = new ReactiveTestTransactionManager(false, true); tm.getReactiveTransaction(new DefaultTransactionDefinition()).flatMap(tm::commit) - .subscriberContext(TransactionContextManager.createTransactionContext()) + .contextWrite(TransactionContextManager.createTransactionContext()) .as(StepVerifier::create).verifyComplete(); assertHasBegan(tm); @@ -101,7 +101,7 @@ public void commitWithoutExistingTransaction() { public void rollbackWithoutExistingTransaction() { ReactiveTestTransactionManager tm = new ReactiveTestTransactionManager(false, true); tm.getReactiveTransaction(new DefaultTransactionDefinition()).flatMap(tm::rollback) - .subscriberContext(TransactionContextManager.createTransactionContext()).as(StepVerifier::create) + .contextWrite(TransactionContextManager.createTransactionContext()).as(StepVerifier::create) .verifyComplete(); assertHasBegan(tm); @@ -116,7 +116,7 @@ public void rollbackOnlyWithoutExistingTransaction() { ReactiveTestTransactionManager tm = new ReactiveTestTransactionManager(false, true); tm.getReactiveTransaction(new DefaultTransactionDefinition()).doOnNext(ReactiveTransaction::setRollbackOnly) .flatMap(tm::commit) - .subscriberContext(TransactionContextManager.createTransactionContext()).as(StepVerifier::create) + .contextWrite(TransactionContextManager.createTransactionContext()).as(StepVerifier::create) .verifyComplete(); assertHasBegan(tm); @@ -130,7 +130,7 @@ public void rollbackOnlyWithoutExistingTransaction() { public void commitWithExistingTransaction() { ReactiveTestTransactionManager tm = new ReactiveTestTransactionManager(true, true); tm.getReactiveTransaction(new DefaultTransactionDefinition()).flatMap(tm::commit) - .subscriberContext(TransactionContextManager.createTransactionContext()) + .contextWrite(TransactionContextManager.createTransactionContext()) .as(StepVerifier::create).verifyComplete(); assertHasNotBegan(tm); @@ -144,7 +144,7 @@ public void commitWithExistingTransaction() { public void rollbackWithExistingTransaction() { ReactiveTestTransactionManager tm = new ReactiveTestTransactionManager(true, true); tm.getReactiveTransaction(new DefaultTransactionDefinition()).flatMap(tm::rollback) - .subscriberContext(TransactionContextManager.createTransactionContext()).as(StepVerifier::create) + .contextWrite(TransactionContextManager.createTransactionContext()).as(StepVerifier::create) .verifyComplete(); assertHasNotBegan(tm); @@ -158,7 +158,7 @@ public void rollbackWithExistingTransaction() { public void rollbackOnlyWithExistingTransaction() { ReactiveTestTransactionManager tm = new ReactiveTestTransactionManager(true, true); tm.getReactiveTransaction(new DefaultTransactionDefinition()).doOnNext(ReactiveTransaction::setRollbackOnly).flatMap(tm::commit) - .subscriberContext(TransactionContextManager.createTransactionContext()).as(StepVerifier::create) + .contextWrite(TransactionContextManager.createTransactionContext()).as(StepVerifier::create) .verifyComplete(); assertHasNotBegan(tm); diff --git a/spring-tx/src/test/kotlin/org/springframework/transaction/interceptor/AbstractCoroutinesTransactionAspectTests.kt b/spring-tx/src/test/kotlin/org/springframework/transaction/interceptor/AbstractCoroutinesTransactionAspectTests.kt index bf437fb430f3..e620ccf4de79 100644 --- a/spring-tx/src/test/kotlin/org/springframework/transaction/interceptor/AbstractCoroutinesTransactionAspectTests.kt +++ b/spring-tx/src/test/kotlin/org/springframework/transaction/interceptor/AbstractCoroutinesTransactionAspectTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import org.springframework.transaction.* import org.springframework.transaction.reactive.TransactionContext import reactor.core.publisher.Mono import reactor.core.publisher.SynchronousSink -import reactor.util.context.Context +import reactor.util.context.ContextView import java.lang.reflect.Method import kotlin.coroutines.Continuation @@ -299,14 +299,15 @@ abstract class AbstractCoroutinesTransactionAspectTests { } } - @Suppress("DEPRECATION") private fun checkReactiveTransaction(expected: Boolean) { - Mono.subscriberContext().handle { context: Context, sink: SynchronousSink -> - if (context.hasKey(TransactionContext::class.java) != expected) { - Fail.fail("Should have thrown NoTransactionException") - } - sink.complete() - }.block() + Mono.deferContextual{context -> Mono.just(context)} + .handle { context: ContextView, sink: SynchronousSink -> + if (context.hasKey(TransactionContext::class.java) != expected) { + Fail.fail("Should have thrown NoTransactionException") + } + sink.complete() + } + .block() } protected open fun advised(target: Any, rtm: ReactiveTransactionManager, tas: Array): Any { From c99210c01fa080758ce1e7b312a8b184dce1d7a6 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 5 Oct 2021 16:20:30 +0200 Subject: [PATCH 196/735] Propagate Reactor Context when using FluxSink This commit makes sure that the Reactor context from a given mono or flux is propagated to the Flux returned by a FluxSink. This change affects both DataBufferUtils::write and internal classes used by the DefaultPartHttpMessageReader. Closes gh-27517 --- .../core/io/buffer/DataBufferUtils.java | 13 +++++ .../core/io/buffer/DataBufferUtilsTests.java | 49 +++++++++++++++++++ .../http/codec/multipart/MultipartParser.java | 6 +++ .../http/codec/multipart/PartGenerator.java | 6 +++ 4 files changed, 74 insertions(+) diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java index 127359293740..ad0419ee4b77 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java @@ -47,6 +47,7 @@ import reactor.core.publisher.FluxSink; import reactor.core.publisher.Mono; import reactor.core.publisher.SynchronousSink; +import reactor.util.context.Context; import org.springframework.core.io.Resource; import org.springframework.lang.Nullable; @@ -1057,6 +1058,12 @@ protected void hookOnError(Throwable throwable) { protected void hookOnComplete() { this.sink.complete(); } + + @Override + public Context currentContext() { + return this.sink.currentContext(); + } + } @@ -1148,6 +1155,12 @@ private void sinkDataBuffer() { this.sink.next(dataBuffer); this.dataBuffer.set(null); } + + @Override + public Context currentContext() { + return this.sink.currentContext(); + } + } } diff --git a/spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferUtilsTests.java b/spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferUtilsTests.java index 8615551b3193..ba85a1575bc1 100644 --- a/spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferUtilsTests.java @@ -24,6 +24,7 @@ import java.nio.channels.CompletionHandler; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; +import java.nio.channels.SeekableByteChannel; import java.nio.channels.WritableByteChannel; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -43,6 +44,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import reactor.util.context.Context; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.ClassPathResource; @@ -940,6 +942,53 @@ void matcher3(String displayName, DataBufferFactory bufferFactory) { release(foo); } + @ParameterizedDataBufferAllocatingTest + void propagateContextByteChannel(String displayName, DataBufferFactory bufferFactory) throws IOException { + Path path = Paths.get(this.resource.getURI()); + try (SeekableByteChannel out = Files.newByteChannel(this.tempFile, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) { + Flux result = DataBufferUtils.read(path, bufferFactory, 1024, StandardOpenOption.READ) + .transformDeferredContextual((f, ctx) -> { + assertThat(ctx.getOrDefault("key", "EMPTY")).isEqualTo("TEST"); + return f; + }) + .transform(f -> DataBufferUtils.write(f, out)) + .transformDeferredContextual((f, ctx) -> { + assertThat(ctx.getOrDefault("key", "EMPTY")).isEqualTo("TEST"); + return f; + }) + .contextWrite(Context.of("key", "TEST")); + + StepVerifier.create(result) + .consumeNextWith(DataBufferUtils::release) + .verifyComplete(); + + + } + } + + @ParameterizedDataBufferAllocatingTest + void propagateContextAsynchronousFileChannel(String displayName, DataBufferFactory bufferFactory) throws IOException { + Path path = Paths.get(this.resource.getURI()); + try (AsynchronousFileChannel out = AsynchronousFileChannel.open(this.tempFile, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) { + Flux result = DataBufferUtils.read(path, bufferFactory, 1024, StandardOpenOption.READ) + .transformDeferredContextual((f, ctx) -> { + assertThat(ctx.getOrDefault("key", "EMPTY")).isEqualTo("TEST"); + return f; + }) + .transform(f -> DataBufferUtils.write(f, out)) + .transformDeferredContextual((f, ctx) -> { + assertThat(ctx.getOrDefault("key", "EMPTY")).isEqualTo("TEST"); + return f; + }) + .contextWrite(Context.of("key", "TEST")); + + StepVerifier.create(result) + .consumeNextWith(DataBufferUtils::release) + .verifyComplete(); + + + } + } private static class ZeroDemandSubscriber extends BaseSubscriber { 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 3d9ab7f2b3b6..d2057f53d627 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 @@ -29,6 +29,7 @@ import reactor.core.publisher.BaseSubscriber; import reactor.core.publisher.Flux; import reactor.core.publisher.FluxSink; +import reactor.util.context.Context; import org.springframework.core.codec.DecodingException; import org.springframework.core.io.buffer.DataBuffer; @@ -98,6 +99,11 @@ public static Flux parse(Flux buffers, byte[] boundary, int m }); } + @Override + public Context currentContext() { + return this.sink.currentContext(); + } + @Override protected void hookOnSubscribe(Subscription subscription) { requestBuffer(); 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 9de34009d480..32a923d8a7d5 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 @@ -42,6 +42,7 @@ import reactor.core.publisher.FluxSink; import reactor.core.publisher.Mono; import reactor.core.scheduler.Scheduler; +import reactor.util.context.Context; import org.springframework.core.codec.DecodingException; import org.springframework.core.io.buffer.DataBuffer; @@ -113,6 +114,11 @@ public static Flux createParts(Flux tokens, int max }); } + @Override + public Context currentContext() { + return this.sink.currentContext(); + } + @Override protected void hookOnSubscribe(Subscription subscription) { requestToken(); From 47b0da6b257dbe47f95e7ee3e7a55ef57e5641de Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 6 Oct 2021 11:48:30 +0200 Subject: [PATCH 197/735] Polishing --- .../src/test/java/org/springframework/util/ClassUtilsTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java index b8ddd8c4ca75..f14412ba4b18 100644 --- a/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java @@ -154,7 +154,7 @@ public Class loadClass(String name) throws ClassNotFoundException { assertThat(ClassUtils.isCacheSafe(composite, childLoader3)).isTrue(); } - @ParameterizedTest + @ParameterizedTest(name = "''{0}'' -> {1}") @CsvSource({ "boolean, boolean", "byte, byte", From 41ae9632d1ede2ceafbcb727166b6d6b6d4ab490 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 6 Oct 2021 12:02:26 +0200 Subject: [PATCH 198/735] Upgrade to Checkstyle 9.0 and spring-javaformat 0.0.29 This commit upgrades the Gradle build to use Checkstyle 9.0 and spring-javaformat 0.0.29 (which internally uses Checkstyle 8.45.1). Closes gh-27520 --- build.gradle | 5 ++--- .../java/org/springframework/beans/BeanUtils.java | 2 +- .../PropertySourcesPlaceholderConfigurer.java | 4 ++-- .../org/springframework/jndi/JndiCallback.java | 4 ++-- .../springframework/core/AttributeAccessor.java | 4 ++-- .../springframework/core/CollectionFactory.java | 14 +++++++------- .../core/annotation/AnnotationFilter.java | 4 ++-- .../core/annotation/AnnotationsProcessor.java | 6 +++--- .../core/annotation/ValueExtractor.java | 4 ++-- .../core/env/AbstractEnvironment.java | 3 +++ .../messaging/rsocket/RSocketRequester.java | 4 ++-- .../org/springframework/mock/web/MockCookie.java | 2 +- .../context/ContextConfigurationAttributes.java | 4 ++-- .../test/context/MergedContextConfiguration.java | 6 +++--- .../test/context/jdbc/MergedSqlConfig.java | 4 ++-- .../junit4/statements/ProfileValueChecker.java | 6 +++--- .../support/AbstractGenericContextLoader.java | 6 +++--- .../support/GenericGroovyXmlContextLoader.java | 4 ++-- .../web/AbstractGenericWebContextLoader.java | 4 ++-- .../web/GenericGroovyXmlWebContextLoader.java | 4 ++-- .../web/servlet/result/StatusResultMatchers.java | 6 +++--- .../transaction/reactive/TransactionCallback.java | 4 ++-- .../transaction/support/TransactionCallback.java | 4 ++-- .../java/org/springframework/http/MediaType.java | 6 +++--- .../org/springframework/http/ResponseCookie.java | 4 ++-- .../web/client/AsyncRequestCallback.java | 4 ++-- .../web/client/RequestCallback.java | 4 ++-- .../web/filter/reactive/ForwardedHeaderFilter.java | 6 +++--- .../web/reactive/function/client/WebClient.java | 2 +- .../web/servlet/HandlerAdapter.java | 2 +- .../web/servlet/mvc/LastModified.java | 10 +++++----- .../web/servlet/mvc/method/RequestMappingInfo.java | 2 +- .../view/DefaultRequestToViewNameTranslator.java | 6 +++--- src/checkstyle/checkstyle.xml | 2 +- 34 files changed, 79 insertions(+), 77 deletions(-) diff --git a/build.gradle b/build.gradle index ec48137948d3..78f42328360c 100644 --- a/build.gradle +++ b/build.gradle @@ -340,7 +340,7 @@ configure([rootProject] + javaProjects) { project -> } checkstyle { - toolVersion = "8.41" + toolVersion = "9.0" configDirectory.set(rootProject.file("src/checkstyle")) } @@ -362,8 +362,7 @@ configure([rootProject] + javaProjects) { project -> // JSR-305 only used for non-required meta-annotations compileOnly("com.google.code.findbugs:jsr305") testCompileOnly("com.google.code.findbugs:jsr305") - checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.28") - checkstyle("com.puppycrawl.tools:checkstyle:8.41") + checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.29") } ext.javadocLinks = [ diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index 3a2b3f0b03ae..77aff7ffe08e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -100,9 +100,9 @@ public abstract class BeanUtils { * @param clazz class to instantiate * @return the new instance * @throws BeanInstantiationException if the bean cannot be instantiated + * @see Class#newInstance() * @deprecated as of Spring 5.0, following the deprecation of * {@link Class#newInstance()} in JDK 9 - * @see Class#newInstance() */ @Deprecated public static T instantiate(Class clazz) throws BeanInstantiationException { diff --git a/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java b/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java index abbfec08ab2e..a0907a1f3a15 100644 --- a/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java +++ b/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -185,9 +185,9 @@ protected void processProperties(ConfigurableListableBeanFactory beanFactoryToPr /** * Implemented for compatibility with * {@link org.springframework.beans.factory.config.PlaceholderConfigurerSupport}. + * @throws UnsupportedOperationException in this implementation * @deprecated in favor of * {@link #processProperties(ConfigurableListableBeanFactory, ConfigurablePropertyResolver)} - * @throws UnsupportedOperationException in this implementation */ @Override @Deprecated diff --git a/spring-context/src/main/java/org/springframework/jndi/JndiCallback.java b/spring-context/src/main/java/org/springframework/jndi/JndiCallback.java index c463cdb10013..cf53e20a47b1 100644 --- a/spring-context/src/main/java/org/springframework/jndi/JndiCallback.java +++ b/spring-context/src/main/java/org/springframework/jndi/JndiCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,8 +44,8 @@ public interface JndiCallback { *

    Implementations don't need to worry about error handling * or cleanup, as the JndiTemplate class will handle this. * @param ctx the current JNDI context - * @throws NamingException if thrown by JNDI methods * @return a result object, or {@code null} + * @throws NamingException if thrown by JNDI methods */ @Nullable T doInContext(Context ctx) throws NamingException; diff --git a/spring-core/src/main/java/org/springframework/core/AttributeAccessor.java b/spring-core/src/main/java/org/springframework/core/AttributeAccessor.java index ea6d3a0c43f2..f8644f2cbab7 100644 --- a/spring-core/src/main/java/org/springframework/core/AttributeAccessor.java +++ b/spring-core/src/main/java/org/springframework/core/AttributeAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,9 +65,9 @@ public interface AttributeAccessor { * @param computeFunction a function that computes a new value for the attribute * name; the function must not return a {@code null} value * @return the existing value or newly computed value for the named attribute + * @since 5.3.3 * @see #getAttribute(String) * @see #setAttribute(String, Object) - * @since 5.3.3 */ @SuppressWarnings("unchecked") default T computeAttribute(String name, Function computeFunction) { diff --git a/spring-core/src/main/java/org/springframework/core/CollectionFactory.java b/spring-core/src/main/java/org/springframework/core/CollectionFactory.java index 30225a708f35..4f90a3bff18e 100644 --- a/spring-core/src/main/java/org/springframework/core/CollectionFactory.java +++ b/spring-core/src/main/java/org/springframework/core/CollectionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -169,14 +169,14 @@ public static Collection createCollection(Class collectionType, int ca * (note: only relevant for {@link EnumSet} creation) * @param capacity the initial capacity * @return a new collection instance + * @throws IllegalArgumentException if the supplied {@code collectionType} is + * {@code null}; or if the desired {@code collectionType} is {@link EnumSet} and + * the supplied {@code elementType} is not a subtype of {@link Enum} * @since 4.1.3 * @see java.util.LinkedHashSet * @see java.util.ArrayList * @see java.util.TreeSet * @see java.util.EnumSet - * @throws IllegalArgumentException if the supplied {@code collectionType} is - * {@code null}; or if the desired {@code collectionType} is {@link EnumSet} and - * the supplied {@code elementType} is not a subtype of {@link Enum} */ @SuppressWarnings({"unchecked", "cast"}) public static Collection createCollection(Class collectionType, @Nullable Class elementType, int capacity) { @@ -285,14 +285,14 @@ public static Map createMap(Class mapType, int capacity) { * (note: only relevant for {@link EnumMap} creation) * @param capacity the initial capacity * @return a new map instance + * @throws IllegalArgumentException if the supplied {@code mapType} is + * {@code null}; or if the desired {@code mapType} is {@link EnumMap} and + * the supplied {@code keyType} is not a subtype of {@link Enum} * @since 4.1.3 * @see java.util.LinkedHashMap * @see java.util.TreeMap * @see org.springframework.util.LinkedMultiValueMap * @see java.util.EnumMap - * @throws IllegalArgumentException if the supplied {@code mapType} is - * {@code null}; or if the desired {@code mapType} is {@link EnumMap} and - * the supplied {@code keyType} is not a subtype of {@link Enum} */ @SuppressWarnings({"rawtypes", "unchecked"}) public static Map createMap(Class mapType, @Nullable Class keyType, int capacity) { diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationFilter.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationFilter.java index 07963dc3e8d3..9b5e4ecd2f94 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationFilter.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,10 +74,10 @@ public String toString() { /** * {@link AnnotationFilter} that never matches and can be used when no * filtering is needed (allowing for any annotation types to be present). + * @see #PLAIN * @deprecated as of 5.2.6 since the {@link MergedAnnotations} model * always ignores lang annotations according to the {@link #PLAIN} filter * (for efficiency reasons) - * @see #PLAIN */ @Deprecated AnnotationFilter NONE = new AnnotationFilter() { diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsProcessor.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsProcessor.java index 75552f3b24ef..f7a3d16f2df3 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsProcessor.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,10 +23,10 @@ /** * Callback interface used to process annotations. * - * @param the context type - * @param the result type * @author Phillip Webb * @since 5.2 + * @param the context type + * @param the result type * @see AnnotationsScanner * @see TypeMappedAnnotations */ diff --git a/spring-core/src/main/java/org/springframework/core/annotation/ValueExtractor.java b/spring-core/src/main/java/org/springframework/core/annotation/ValueExtractor.java index 62438f629bf7..5f1b2146393c 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/ValueExtractor.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/ValueExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,8 +27,8 @@ * source object which is typically an {@link Annotation}, {@link Map}, or * {@link TypeMappedAnnotation}. * - * @since 5.2.4 * @author Sam Brannen + * @since 5.2.4 */ @FunctionalInterface interface ValueExtractor { diff --git a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java index 85968d699a89..8ce86529c7e7 100644 --- a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java +++ b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java @@ -209,10 +209,13 @@ protected final ConfigurablePropertyResolver getPropertyResolver() { * * *

    The search order is now C, D, A, B as desired. + * *

    Beyond these recommendations, subclasses may use any of the {@code add*}, * {@code remove}, or {@code replace} methods exposed by {@link MutablePropertySources} * in order to create the exact arrangement of property sources desired. + * *

    The base implementation registers no property sources. + * *

    Note that clients of any {@link ConfigurableEnvironment} may further customize * property sources via the {@link #getPropertySources()} accessor, typically within * an {@link org.springframework.context.ApplicationContextInitializer diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/RSocketRequester.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/RSocketRequester.java index 63c726037734..365d894cb953 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/RSocketRequester.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/RSocketRequester.java @@ -305,8 +305,8 @@ RSocketRequester transports( * @param host the server host * @param port the server port * @return an {@code RSocketRequester} for the connection - * @deprecated as of 5.3 in favor of {@link #tcp(String, int)} * @see TcpClientTransport + * @deprecated as of 5.3 in favor of {@link #tcp(String, int)} */ @Deprecated Mono connectTcp(String host, int port); @@ -315,8 +315,8 @@ RSocketRequester transports( * Connect to the server over WebSocket. * @param uri the RSocket server endpoint URI * @return an {@code RSocketRequester} for the connection - * @deprecated as of 5.3 in favor of {@link #websocket(URI)} * @see WebsocketClientTransport + * @deprecated as of 5.3 in favor of {@link #websocket(URI)} */ @Deprecated Mono connectWebSocket(URI uri); diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockCookie.java b/spring-test/src/main/java/org/springframework/mock/web/MockCookie.java index 372898cd5a36..759eae8f9f0f 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockCookie.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockCookie.java @@ -68,8 +68,8 @@ public void setExpires(@Nullable ZonedDateTime expires) { /** * Get the "Expires" attribute for this cookie. - * @since 5.1.11 * @return the "Expires" attribute for this cookie, or {@code null} if not set + * @since 5.1.11 */ @Nullable public ZonedDateTime getExpires() { diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java b/spring-test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java index 2f29ba978c2b..e910c4c9d5e4 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java +++ b/spring-test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -300,8 +300,8 @@ public boolean isInheritInitializers() { * Get the name of the context hierarchy level that was declared via * {@link ContextConfiguration @ContextConfiguration}. * @return the name of the context hierarchy level or {@code null} if not applicable - * @see ContextConfiguration#name() * @since 3.2.2 + * @see ContextConfiguration#name() */ @Nullable public String getName() { diff --git a/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java index f434b14022a2..2ae169bd2959 100644 --- a/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java +++ b/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -372,8 +372,8 @@ public ContextLoader getContextLoader() { * Get the {@link MergedContextConfiguration} for the parent application context * in a context hierarchy. * @return the parent configuration or {@code null} if there is no parent - * @see #getParentApplicationContext() * @since 3.2.2 + * @see #getParentApplicationContext() */ @Nullable public MergedContextConfiguration getParent() { @@ -386,8 +386,8 @@ public MergedContextConfiguration getParent() { *

    If the parent context has not yet been loaded, it will be loaded, stored * in the cache, and then returned. * @return the parent {@code ApplicationContext} or {@code null} if there is no parent - * @see #getParent() * @since 3.2.2 + * @see #getParent() */ @Nullable public ApplicationContext getParentApplicationContext() { diff --git a/spring-test/src/main/java/org/springframework/test/context/jdbc/MergedSqlConfig.java b/spring-test/src/main/java/org/springframework/test/context/jdbc/MergedSqlConfig.java index 1ca7bda328d4..8130ddd3b8bb 100644 --- a/spring-test/src/main/java/org/springframework/test/context/jdbc/MergedSqlConfig.java +++ b/spring-test/src/main/java/org/springframework/test/context/jdbc/MergedSqlConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -174,8 +174,8 @@ String getSeparator() { /** * Get the prefixes that identify single-line comments within the SQL scripts. - * @see SqlConfig#commentPrefixes() * @since 5.2 + * @see SqlConfig#commentPrefixes() */ String[] getCommentPrefixes() { return this.commentPrefixes; diff --git a/spring-test/src/main/java/org/springframework/test/context/junit4/statements/ProfileValueChecker.java b/spring-test/src/main/java/org/springframework/test/context/junit4/statements/ProfileValueChecker.java index accd806e5fed..d9162ae0d4d6 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit4/statements/ProfileValueChecker.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit4/statements/ProfileValueChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,10 +77,10 @@ public ProfileValueChecker(Statement next, Class testClass, @Nullable Method *

    If a test is not enabled, this method will abort further evaluation * of the execution chain with a failed assumption; otherwise, this method * will simply evaluate the next {@link Statement} in the execution chain. - * @see ProfileValueUtils#isTestEnabledInThisEnvironment(Class) - * @see ProfileValueUtils#isTestEnabledInThisEnvironment(Method, Class) * @throws AssumptionViolatedException if the test is disabled * @throws Throwable if evaluation of the next statement fails + * @see ProfileValueUtils#isTestEnabledInThisEnvironment(Class) + * @see ProfileValueUtils#isTestEnabledInThisEnvironment(Method, Class) */ @Override public void evaluate() throws Throwable { diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java index 8794ec49f49a..45ae716f6f02 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -97,9 +97,9 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader * context and registers a JVM shutdown hook for it. * * @return a new application context + * @since 3.1 * @see org.springframework.test.context.SmartContextLoader#loadContext(MergedContextConfiguration) * @see GenericApplicationContext - * @since 3.1 */ @Override public final ConfigurableApplicationContext loadContext(MergedContextConfiguration mergedConfig) throws Exception { @@ -170,10 +170,10 @@ protected void validateMergedContextConfiguration(MergedContextConfiguration mer * and {@link AbstractContextLoader#prepareContext(ConfigurableApplicationContext, MergedContextConfiguration)} * for an alternative. * @return a new application context + * @since 2.5 * @see org.springframework.test.context.ContextLoader#loadContext * @see GenericApplicationContext * @see #loadContext(MergedContextConfiguration) - * @since 2.5 */ @Override public final ConfigurableApplicationContext loadContext(String... locations) throws Exception { diff --git a/spring-test/src/main/java/org/springframework/test/context/support/GenericGroovyXmlContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/support/GenericGroovyXmlContextLoader.java index 86dc00da9489..4c4a02990253 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/GenericGroovyXmlContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/GenericGroovyXmlContextLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,8 +61,8 @@ protected String[] getResourceSuffixes() { * {@code GenericGroovyXmlContextLoader} supports both Groovy and XML * resource types for detection of defaults. Consequently, this method * is not supported. - * @see #getResourceSuffixes() * @throws UnsupportedOperationException in this implementation + * @see #getResourceSuffixes() */ @Override protected String getResourceSuffix() { diff --git a/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java index c363dd2d671c..e48cfecc8ac8 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -260,8 +260,8 @@ protected void customizeContext( * {@link org.springframework.test.context.SmartContextLoader SmartContextLoader}, * not as a legacy {@link org.springframework.test.context.ContextLoader ContextLoader}. * Consequently, this method is not supported. - * @see org.springframework.test.context.ContextLoader#loadContext(java.lang.String[]) * @throws UnsupportedOperationException in this implementation + * @see org.springframework.test.context.ContextLoader#loadContext(java.lang.String[]) */ @Override public final ApplicationContext loadContext(String... locations) throws Exception { diff --git a/spring-test/src/main/java/org/springframework/test/context/web/GenericGroovyXmlWebContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/web/GenericGroovyXmlWebContextLoader.java index d0f32b423971..c84f033e5a98 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/GenericGroovyXmlWebContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/GenericGroovyXmlWebContextLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,8 +61,8 @@ protected String[] getResourceSuffixes() { * {@code GenericGroovyXmlWebContextLoader} supports both Groovy and XML * resource types for detection of defaults. Consequently, this method * is not supported. - * @see #getResourceSuffixes() * @throws UnsupportedOperationException in this implementation + * @see #getResourceSuffixes() */ @Override protected String getResourceSuffix() { diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/StatusResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/StatusResultMatchers.java index a33eba0fa13b..6983b6866097 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/StatusResultMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/StatusResultMatchers.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -390,8 +390,8 @@ public ResultMatcher isPayloadTooLarge() { /** * Assert the response status code is {@code HttpStatus.REQUEST_ENTITY_TOO_LARGE} (413). - * @deprecated matching the deprecation of {@code HttpStatus.REQUEST_ENTITY_TOO_LARGE} * @see #isPayloadTooLarge() + * @deprecated matching the deprecation of {@code HttpStatus.REQUEST_ENTITY_TOO_LARGE} */ @Deprecated public ResultMatcher isRequestEntityTooLarge() { @@ -408,8 +408,8 @@ public ResultMatcher isUriTooLong() { /** * Assert the response status code is {@code HttpStatus.REQUEST_URI_TOO_LONG} (414). - * @deprecated matching the deprecation of {@code HttpStatus.REQUEST_URI_TOO_LONG} * @see #isUriTooLong() + * @deprecated matching the deprecation of {@code HttpStatus.REQUEST_URI_TOO_LONG} */ @Deprecated public ResultMatcher isRequestUriTooLong() { diff --git a/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionCallback.java b/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionCallback.java index 9ba759f0d55d..63546c24c435 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionCallback.java +++ b/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,8 +32,8 @@ * @author Mark Paluch * @author Juergen Hoeller * @since 5.2 - * @see TransactionalOperator * @param the result type + * @see TransactionalOperator */ @FunctionalInterface public interface TransactionCallback { diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/TransactionCallback.java b/spring-tx/src/main/java/org/springframework/transaction/support/TransactionCallback.java index 08bacac4ec43..926cdaf9289c 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/TransactionCallback.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/TransactionCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,9 +30,9 @@ * * @author Juergen Hoeller * @since 17.03.2003 + * @param the result type * @see TransactionTemplate * @see CallbackPreferringPlatformTransactionManager - * @param the result type */ @FunctionalInterface public interface TransactionCallback { diff --git a/spring-web/src/main/java/org/springframework/http/MediaType.java b/spring-web/src/main/java/org/springframework/http/MediaType.java index 6b51e1783df8..ec57d77a5ac2 100644 --- a/spring-web/src/main/java/org/springframework/http/MediaType.java +++ b/spring-web/src/main/java/org/springframework/http/MediaType.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -230,20 +230,20 @@ public class MediaType extends MimeType implements Serializable { /** * Public constant media type for {@code application/stream+json}. - * @deprecated as of 5.3, see notice on {@link #APPLICATION_STREAM_JSON_VALUE}. * @since 5.0 + * @deprecated as of 5.3, see notice on {@link #APPLICATION_STREAM_JSON_VALUE}. */ @Deprecated public static final MediaType APPLICATION_STREAM_JSON; /** * A String equivalent of {@link MediaType#APPLICATION_STREAM_JSON}. + * @since 5.0 * @deprecated as of 5.3 since it originates from the W3C Activity Streams * specification which has a more specific purpose and has been since * replaced with a different mime type. Use {@link #APPLICATION_NDJSON} as * a replacement or any other line-delimited JSON format (e.g. JSON Lines, * JSON Text Sequences). - * @since 5.0 */ @Deprecated public static final String APPLICATION_STREAM_JSON_VALUE = "application/stream+json"; diff --git a/spring-web/src/main/java/org/springframework/http/ResponseCookie.java b/spring-web/src/main/java/org/springframework/http/ResponseCookie.java index 01048cab83c4..bada6e559885 100644 --- a/spring-web/src/main/java/org/springframework/http/ResponseCookie.java +++ b/spring-web/src/main/java/org/springframework/http/ResponseCookie.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -120,8 +120,8 @@ public boolean isHttpOnly() { * Return the cookie "SameSite" attribute, or {@code null} if not set. *

    This limits the scope of the cookie such that it will only be attached to * same site requests if {@code "Strict"} or cross-site requests if {@code "Lax"}. - * @see RFC6265 bis * @since 5.1 + * @see RFC6265 bis */ @Nullable public String getSameSite() { diff --git a/spring-web/src/main/java/org/springframework/web/client/AsyncRequestCallback.java b/spring-web/src/main/java/org/springframework/web/client/AsyncRequestCallback.java index 4efc74eef602..00e2fdd4ab94 100644 --- a/spring-web/src/main/java/org/springframework/web/client/AsyncRequestCallback.java +++ b/spring-web/src/main/java/org/springframework/web/client/AsyncRequestCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,8 +27,8 @@ * application code. * * @author Arjen Poutsma - * @see org.springframework.web.client.AsyncRestTemplate#execute * @since 4.0 + * @see org.springframework.web.client.AsyncRestTemplate#execute * @deprecated as of Spring 5.0, in favor of * {@link org.springframework.web.reactive.function.client.ExchangeFilterFunction} */ diff --git a/spring-web/src/main/java/org/springframework/web/client/RequestCallback.java b/spring-web/src/main/java/org/springframework/web/client/RequestCallback.java index e3d32f526f14..82ef0d694e86 100644 --- a/spring-web/src/main/java/org/springframework/web/client/RequestCallback.java +++ b/spring-web/src/main/java/org/springframework/web/client/RequestCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,8 +34,8 @@ * * * @author Arjen Poutsma - * @see RestTemplate#execute * @since 3.0 + * @see RestTemplate#execute */ @FunctionalInterface public interface RequestCallback { diff --git a/spring-web/src/main/java/org/springframework/web/filter/reactive/ForwardedHeaderFilter.java b/spring-web/src/main/java/org/springframework/web/filter/reactive/ForwardedHeaderFilter.java index cf8b17b54552..85e7215b4e24 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/reactive/ForwardedHeaderFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/reactive/ForwardedHeaderFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,13 +34,13 @@ * * @author Arjen Poutsma * @author Rossen Stoyanchev + * @since 5.0 + * @see https://tools.ietf.org/html/rfc7239 * @deprecated as of 5.1 this filter is deprecated in favor of using * {@link ForwardedHeaderTransformer} which can be declared as a bean with the * name "forwardedHeaderTransformer" or registered explicitly in * {@link org.springframework.web.server.adapter.WebHttpHandlerBuilder * WebHttpHandlerBuilder}. - * @since 5.0 - * @see https://tools.ietf.org/html/rfc7239 */ @Deprecated public class ForwardedHeaderFilter extends ForwardedHeaderTransformer implements WebFilter { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java index 4d929888bde8..7e8219c1678a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java @@ -469,10 +469,10 @@ interface RequestHeadersSpec> { /** * Provide a function to populate the Reactor {@code Context}. * @param contextModifier the function to modify the context with + * @since 5.3.1 * @deprecated in 5.3.2 to be removed soon after; this method cannot * provide context to downstream (nested or subsequent) requests and is * of limited value. - * @since 5.3.1 */ @Deprecated S context(Function contextModifier); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerAdapter.java index cd43bdce5b15..2af977fea803 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerAdapter.java @@ -70,9 +70,9 @@ public interface HandlerAdapter { * @param handler the handler to use. This object must have previously been passed * to the {@code supports} method of this interface, which must have * returned {@code true}. - * @throws Exception in case of errors * @return a ModelAndView object with the name of the view and the required * model data, or {@code null} if the request has been handled directly + * @throws Exception in case of errors */ @Nullable ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/LastModified.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/LastModified.java index a6cfdcf86a69..d8bb3660f52c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/LastModified.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/LastModified.java @@ -34,16 +34,16 @@ * * @author Rod Johnson * @author Juergen Hoeller - * @deprecated as of 5.3.9 in favor of using the {@code checkNotModified} methods - * in {@link org.springframework.web.context.request.WebRequest}, or from an - * annotated controller method, returning a - * {@link org.springframework.http.ResponseEntity} with an "ETag" and/or - * "Last-Modified" headers set. * @see javax.servlet.http.HttpServlet#getLastModified * @see Controller * @see SimpleControllerHandlerAdapter * @see org.springframework.web.HttpRequestHandler * @see HttpRequestHandlerAdapter + * @deprecated as of 5.3.9 in favor of using the {@code checkNotModified} methods + * in {@link org.springframework.web.context.request.WebRequest}, or from an + * annotated controller method, returning a + * {@link org.springframework.http.ResponseEntity} with an "ETag" and/or + * "Last-Modified" headers set. */ @Deprecated public interface LastModified { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java index 79622c386169..c410a7c7f29d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java @@ -912,9 +912,9 @@ public PathPatternParser getPatternParser() { /** * Set a custom UrlPathHelper to use for the PatternsRequestCondition. *

    By default this is not set. + * @since 4.2.8 * @deprecated as of 5.3, the path is resolved externally and obtained with * {@link ServletRequestPathUtils#getCachedPathValue(ServletRequest)} - * @since 4.2.8 */ @Deprecated public void setUrlPathHelper(@Nullable UrlPathHelper urlPathHelper) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.java index 9d9bc6811ccb..1180aa734a4a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -168,10 +168,10 @@ public void setUrlPathHelper(UrlPathHelper urlPathHelper) { /** * Translates the request URI of the incoming {@link HttpServletRequest} * into the view name based on the configured parameters. - * @see ServletRequestPathUtils#getCachedPath(ServletRequest) - * @see #transformPath * @throws IllegalArgumentException if neither a parsed RequestPath, nor a * String lookupPath have been resolved and cached as a request attribute. + * @see ServletRequestPathUtils#getCachedPath(ServletRequest) + * @see #transformPath */ @Override public String getViewName(HttpServletRequest request) { diff --git a/src/checkstyle/checkstyle.xml b/src/checkstyle/checkstyle.xml index 2d8a043623c0..555364592425 100644 --- a/src/checkstyle/checkstyle.xml +++ b/src/checkstyle/checkstyle.xml @@ -160,7 +160,7 @@ - + From 2c583517cb1b3713db8fcbcf561e64424fd111f3 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 6 Oct 2021 12:51:27 +0200 Subject: [PATCH 199/735] Change Eclipse project source/target/compliance to JDK 17 See gh-27407 --- src/eclipse/org.eclipse.jdt.core.prefs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/eclipse/org.eclipse.jdt.core.prefs b/src/eclipse/org.eclipse.jdt.core.prefs index 7fafdb460983..446bdebe14b3 100644 --- a/src/eclipse/org.eclipse.jdt.core.prefs +++ b/src/eclipse/org.eclipse.jdt.core.prefs @@ -21,9 +21,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.compliance=17 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -111,7 +111,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.8 +org.eclipse.jdt.core.compiler.source=17 org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 From 5d3b16cd3a5e7915f4aeeb37c5285ac7e173f6f2 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 6 Oct 2021 15:42:52 +0200 Subject: [PATCH 200/735] Indent with tabs instead of spaces --- src/checkstyle/checkstyle.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/checkstyle/checkstyle.xml b/src/checkstyle/checkstyle.xml index 555364592425..5a9318ef3cbe 100644 --- a/src/checkstyle/checkstyle.xml +++ b/src/checkstyle/checkstyle.xml @@ -156,11 +156,11 @@ - + - + - + From 90fdcf88d832eb6d8f635d3aa727c762b273845b Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 6 Oct 2021 21:27:56 +0100 Subject: [PATCH 201/735] Generalize formatValue Provide an overload for additional control and compact output. --- .../core/log/LogFormatUtils.java | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java b/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java index c00c33464fc3..cbcd63bf6f08 100644 --- a/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java +++ b/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,30 +36,48 @@ public abstract class LogFormatUtils { /** - * Format the given value via {@code toString()}, quoting it if it is a - * {@link CharSequence}, and possibly truncating at 100 if limitLength is - * set to true. + * Variant of {@link #formatValue(Object, int, boolean)} and a convenience + * method that truncates at 100 characters when {@code limitLength} is set. * @param value the value to format - * @param limitLength whether to truncate large formatted values (over 100) + * @param limitLength whether to truncate the value at a length of 100 * @return the formatted value */ public static String formatValue(@Nullable Object value, boolean limitLength) { + return formatValue(value, 100, limitLength); + } + + /** + * Format the given value via {@code toString()}, quoting it if it is a + * {@link CharSequence}, truncating at the specified {@code maxLength}, and + * compacting it into a single line when {@code replaceNewLines} is set. + * @param value the value to be formatted + * @param maxLength the max length, after which to truncate, or -1 for unlimited + * @param replaceNewlines whether to replace newline characters with placeholders + * @return the formatted value + */ + public static String formatValue(@Nullable Object value, int maxLength, boolean replaceNewlines) { if (value == null) { return ""; } - String str; + String result; if (value instanceof CharSequence) { - str = "\"" + value + "\""; + result = "\"" + value + "\""; } else { try { - str = value.toString(); + result = value.toString(); } catch (Throwable ex) { - str = ex.toString(); + result = ex.toString(); } } - return (limitLength && str.length() > 100 ? str.substring(0, 100) + " (truncated)..." : str); + if (maxLength != -1) { + result = (result.length() > maxLength ? result.substring(0, maxLength) + " (truncated)..." : result); + } + if (replaceNewlines) { + result = result.replace("\n", "").replace("\r", ""); + } + return result; } /** From d5597a75a670becc508f6a4f7560a9ef40e70e94 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 7 Oct 2021 08:51:32 +0200 Subject: [PATCH 202/735] Start building against Reactor 2020.0.12 snapshots See gh-27527 --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 78f42328360c..af1973fefef7 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ configure(allprojects) { project -> imports { mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5" mavenBom "io.netty:netty-bom:4.1.68.Final" - mavenBom "io.projectreactor:reactor-bom:2020.0.11" + mavenBom "io.projectreactor:reactor-bom:2020.0.12-SNAPSHOT" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" mavenBom "io.rsocket:rsocket-bom:1.1.1" mavenBom "org.eclipse.jetty:jetty-bom:9.4.43.v20210629" @@ -292,6 +292,7 @@ configure(allprojects) { project -> repositories { mavenCentral() maven { url "https://repo.spring.io/libs-spring-framework-build" } + maven { url "https://repo.spring.io/snapshot" } // reactor } } configurations.all { From 9bd989f1bbf596c44b818b8979f5132b8cda0d1b Mon Sep 17 00:00:00 2001 From: Ashley Scopes <73482956+ascopes@users.noreply.github.com> Date: Wed, 11 Aug 2021 16:13:41 +0100 Subject: [PATCH 203/735] WebClient tests for socket and response format issues Added test case for malformed response chunk, which is now failing as expected. See gh-27262 --- .../client/WebClientIntegrationTests.java | 145 +++++++++++++++++- 1 file changed, 142 insertions(+), 3 deletions(-) diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java index e8a082a6b628..4878ca78c2f9 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java @@ -18,11 +18,15 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.io.UncheckedIOException; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.net.ServerSocket; +import java.net.Socket; import java.net.URI; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -31,16 +35,21 @@ import java.util.List; import java.util.Map; import java.util.function.Consumer; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; +import okhttp3.mockwebserver.SocketPolicy; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.util.SocketUtils; +import org.springframework.web.reactive.function.client.WebClient.ResponseSpec; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.netty.http.client.HttpClient; @@ -83,7 +92,7 @@ class WebClientIntegrationTests { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) - @ParameterizedTest(name = "[{index}] webClient [{0}]") + @ParameterizedTest(name = "[{index}] {displayName} [{0}]") @MethodSource("arguments") @interface ParameterizedWebClientTest { } @@ -113,7 +122,9 @@ private void startServer(ClientHttpConnector connector) { @AfterEach void shutdown() throws IOException { - this.server.shutdown(); + if (server != null) { + this.server.shutdown(); + } } @@ -1209,6 +1220,135 @@ void invalidDomain(ClientHttpConnector connector) { .verify(); } + static Stream socketFaultArguments() { + Stream.Builder argumentsBuilder = Stream.builder(); + arguments().forEach(arg -> { + argumentsBuilder.accept(Arguments.of(arg, SocketPolicy.DISCONNECT_AT_START)); + argumentsBuilder.accept(Arguments.of(arg, SocketPolicy.DISCONNECT_DURING_REQUEST_BODY)); + argumentsBuilder.accept(Arguments.of(arg, SocketPolicy.DISCONNECT_AFTER_REQUEST)); + }); + return argumentsBuilder.build(); + } + + @ParameterizedTest(name = "[{index}] {displayName} [{0}, {1}]") + @MethodSource("socketFaultArguments") + void prematureClosureFault(ClientHttpConnector connector, SocketPolicy socketPolicy) { + startServer(connector); + + prepareResponse(response -> response + .setSocketPolicy(socketPolicy) + .setStatus("HTTP/1.1 200 OK") + .setHeader("Response-Header-1", "value 1") + .setHeader("Response-Header-2", "value 2") + .setBody("{\"message\": \"Hello, World!\"}")); + + String uri = "/test"; + Mono result = this.webClient + .post() + .uri(uri) + // Random non-empty body to allow us to interrupt. + .bodyValue("{\"action\": \"Say hello!\"}") + .retrieve() + .bodyToMono(String.class); + + StepVerifier.create(result) + .expectErrorSatisfies(throwable -> { + assertThat(throwable).isInstanceOf(WebClientRequestException.class); + WebClientRequestException ex = (WebClientRequestException) throwable; + // Varies between connector providers. + assertThat(ex.getCause()).isInstanceOf(IOException.class); + }) + .verify(); + } + + static Stream malformedResponseChunkArguments() { + return Stream.of( + Arguments.of(new ReactorClientHttpConnector(), true), + Arguments.of(new JettyClientHttpConnector(), true), + // Apache injects the Transfer-Encoding header for us, and complains with an exception if we also + // add it. The other two connectors do not add the header at all. We need this header for the test + // case to work correctly. + Arguments.of(new HttpComponentsClientHttpConnector(), false) + ); + } + + @ParameterizedTest(name = "[{index}] {displayName} [{0}, {1}]") + @MethodSource("malformedResponseChunkArguments") + void malformedResponseChunksOnBodilessEntity(ClientHttpConnector connector, boolean addTransferEncodingHeader) { + Mono result = doMalformedResponseChunks(connector, addTransferEncodingHeader, ResponseSpec::toBodilessEntity); + + StepVerifier.create(result) + .expectErrorSatisfies(throwable -> { + assertThat(throwable).isInstanceOf(WebClientException.class); + WebClientException ex = (WebClientException) throwable; + assertThat(ex.getCause()).isInstanceOf(IOException.class); + }) + .verify(); + } + + @ParameterizedTest(name = "[{index}] {displayName} [{0}, {1}]") + @MethodSource("malformedResponseChunkArguments") + void malformedResponseChunksOnEntityWithBody(ClientHttpConnector connector, boolean addTransferEncodingHeader) { + Mono result = doMalformedResponseChunks(connector, addTransferEncodingHeader, spec -> spec.toEntity(String.class)); + + StepVerifier.create(result) + .expectErrorSatisfies(throwable -> { + assertThat(throwable).isInstanceOf(WebClientException.class); + WebClientException ex = (WebClientException) throwable; + assertThat(ex.getCause()).isInstanceOf(IOException.class); + }) + .verify(); + } + + private Mono doMalformedResponseChunks( + ClientHttpConnector connector, + boolean addTransferEncodingHeader, + Function> responseHandler + ) { + int port = SocketUtils.findAvailableTcpPort(); + + Thread serverThread = new Thread(() -> { + // This exists separately to the main mock server, as I had a really hard time getting that to send the + // chunked responses correctly, flushing the socket each time. This was the only way I was able to replicate + // the issue of the client not handling malformed response chunks correctly. + try (ServerSocket serverSocket = new ServerSocket(port)) { + Socket socket = serverSocket.accept(); + InputStream is = socket.getInputStream(); + + //noinspection ResultOfMethodCallIgnored + is.read(new byte[4096]); + + OutputStream os = socket.getOutputStream(); + os.write("HTTP/1.1 200 OK\r\n".getBytes(StandardCharsets.UTF_8)); + os.write("Transfer-Encoding: chunked\r\n".getBytes(StandardCharsets.UTF_8)); + os.write("\r\n".getBytes(StandardCharsets.UTF_8)); + os.write("lskdu018973t09sylgasjkfg1][]'./.sdlv".getBytes(StandardCharsets.UTF_8)); + socket.close(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + }); + + serverThread.setDaemon(true); + serverThread.start(); + + ResponseSpec spec = WebClient + .builder() + .clientConnector(connector) + .baseUrl("http://localhost:" + port) + .build() + .post() + .headers(headers -> { + if (addTransferEncodingHeader) { + headers.add(HttpHeaders.TRANSFER_ENCODING, "chunked"); + } + }) + .retrieve(); + + return responseHandler + .apply(spec) + .doFinally(signal -> serverThread.stop()); + } private void prepareResponse(Consumer consumer) { MockResponse response = new MockResponse(); @@ -1252,5 +1392,4 @@ public void setContainerValue(T containerValue) { this.containerValue = containerValue; } } - } From b6111d04a5453a1e75840c53ad6f38eb7314138a Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 7 Oct 2021 16:50:30 +0100 Subject: [PATCH 204/735] Ensure WebClientResponseException for malformed response Closes gh-27262 --- .../client/DefaultClientResponse.java | 2 +- .../function/client/DefaultWebClient.java | 4 +- .../client/WebClientIntegrationTests.java | 106 +++--------------- 3 files changed, 21 insertions(+), 91 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java index 927fcdf205d5..0931bf214072 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java @@ -203,7 +203,7 @@ public Mono createException() { return bytes; }) .defaultIfEmpty(EMPTY) - .onErrorReturn(IllegalStateException.class::isInstance, EMPTY) + .onErrorReturn(ex -> !(ex instanceof Error), EMPTY) .map(bodyBytes -> { HttpRequest request = this.requestSupplier.get(); Charset charset = headers().contentType().map(MimeType::getCharset).orElse(null); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java index aebc7760ac0e..efaf758ef43b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java @@ -612,7 +612,9 @@ public Mono>> toEntityFlux(BodyExtractor, ? s public Mono> toBodilessEntity() { return this.responseMono.flatMap(response -> WebClientUtils.mapToEntity(response, handleBodyMono(response, Mono.empty())) - .flatMap(entity -> response.releaseBody().thenReturn(entity)) + .flatMap(entity -> response.releaseBody() + .onErrorResume(WebClientUtils.WRAP_EXCEPTION_PREDICATE, exceptionWrappingFunction(response)) + .thenReturn(entity)) ); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java index 4878ca78c2f9..e7fa002ff51b 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java @@ -42,14 +42,10 @@ import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; -import okhttp3.mockwebserver.SocketPolicy; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.util.SocketUtils; -import org.springframework.web.reactive.function.client.WebClient.ResponseSpec; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.netty.http.client.HttpClient; @@ -73,7 +69,9 @@ import org.springframework.http.client.reactive.HttpComponentsClientHttpConnector; import org.springframework.http.client.reactive.JettyClientHttpConnector; import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.util.SocketUtils; import org.springframework.web.reactive.function.BodyExtractors; +import org.springframework.web.reactive.function.client.WebClient.ResponseSpec; import org.springframework.web.testfixture.xml.Pojo; import static org.assertj.core.api.Assertions.assertThat; @@ -1220,63 +1218,9 @@ void invalidDomain(ClientHttpConnector connector) { .verify(); } - static Stream socketFaultArguments() { - Stream.Builder argumentsBuilder = Stream.builder(); - arguments().forEach(arg -> { - argumentsBuilder.accept(Arguments.of(arg, SocketPolicy.DISCONNECT_AT_START)); - argumentsBuilder.accept(Arguments.of(arg, SocketPolicy.DISCONNECT_DURING_REQUEST_BODY)); - argumentsBuilder.accept(Arguments.of(arg, SocketPolicy.DISCONNECT_AFTER_REQUEST)); - }); - return argumentsBuilder.build(); - } - - @ParameterizedTest(name = "[{index}] {displayName} [{0}, {1}]") - @MethodSource("socketFaultArguments") - void prematureClosureFault(ClientHttpConnector connector, SocketPolicy socketPolicy) { - startServer(connector); - - prepareResponse(response -> response - .setSocketPolicy(socketPolicy) - .setStatus("HTTP/1.1 200 OK") - .setHeader("Response-Header-1", "value 1") - .setHeader("Response-Header-2", "value 2") - .setBody("{\"message\": \"Hello, World!\"}")); - - String uri = "/test"; - Mono result = this.webClient - .post() - .uri(uri) - // Random non-empty body to allow us to interrupt. - .bodyValue("{\"action\": \"Say hello!\"}") - .retrieve() - .bodyToMono(String.class); - - StepVerifier.create(result) - .expectErrorSatisfies(throwable -> { - assertThat(throwable).isInstanceOf(WebClientRequestException.class); - WebClientRequestException ex = (WebClientRequestException) throwable; - // Varies between connector providers. - assertThat(ex.getCause()).isInstanceOf(IOException.class); - }) - .verify(); - } - - static Stream malformedResponseChunkArguments() { - return Stream.of( - Arguments.of(new ReactorClientHttpConnector(), true), - Arguments.of(new JettyClientHttpConnector(), true), - // Apache injects the Transfer-Encoding header for us, and complains with an exception if we also - // add it. The other two connectors do not add the header at all. We need this header for the test - // case to work correctly. - Arguments.of(new HttpComponentsClientHttpConnector(), false) - ); - } - - @ParameterizedTest(name = "[{index}] {displayName} [{0}, {1}]") - @MethodSource("malformedResponseChunkArguments") - void malformedResponseChunksOnBodilessEntity(ClientHttpConnector connector, boolean addTransferEncodingHeader) { - Mono result = doMalformedResponseChunks(connector, addTransferEncodingHeader, ResponseSpec::toBodilessEntity); - + @ParameterizedWebClientTest + void malformedResponseChunksOnBodilessEntity(ClientHttpConnector connector) { + Mono result = doMalformedChunkedResponseTest(connector, ResponseSpec::toBodilessEntity); StepVerifier.create(result) .expectErrorSatisfies(throwable -> { assertThat(throwable).isInstanceOf(WebClientException.class); @@ -1286,11 +1230,9 @@ void malformedResponseChunksOnBodilessEntity(ClientHttpConnector connector, bool .verify(); } - @ParameterizedTest(name = "[{index}] {displayName} [{0}, {1}]") - @MethodSource("malformedResponseChunkArguments") - void malformedResponseChunksOnEntityWithBody(ClientHttpConnector connector, boolean addTransferEncodingHeader) { - Mono result = doMalformedResponseChunks(connector, addTransferEncodingHeader, spec -> spec.toEntity(String.class)); - + @ParameterizedWebClientTest + void malformedResponseChunksOnEntityWithBody(ClientHttpConnector connector) { + Mono result = doMalformedChunkedResponseTest(connector, spec -> spec.toEntity(String.class)); StepVerifier.create(result) .expectErrorSatisfies(throwable -> { assertThat(throwable).isInstanceOf(WebClientException.class); @@ -1300,17 +1242,13 @@ void malformedResponseChunksOnEntityWithBody(ClientHttpConnector connector, bool .verify(); } - private Mono doMalformedResponseChunks( - ClientHttpConnector connector, - boolean addTransferEncodingHeader, - Function> responseHandler - ) { + private Mono doMalformedChunkedResponseTest( + ClientHttpConnector connector, Function> handler) { + int port = SocketUtils.findAvailableTcpPort(); Thread serverThread = new Thread(() -> { - // This exists separately to the main mock server, as I had a really hard time getting that to send the - // chunked responses correctly, flushing the socket each time. This was the only way I was able to replicate - // the issue of the client not handling malformed response chunks correctly. + // No way to simulate a malformed chunked response through MockWebServer. try (ServerSocket serverSocket = new ServerSocket(port)) { Socket socket = serverSocket.accept(); InputStream is = socket.getInputStream(); @@ -1324,30 +1262,20 @@ private Mono doMalformedResponseChunks( os.write("\r\n".getBytes(StandardCharsets.UTF_8)); os.write("lskdu018973t09sylgasjkfg1][]'./.sdlv".getBytes(StandardCharsets.UTF_8)); socket.close(); - } catch (IOException ex) { + } + catch (IOException ex) { throw new RuntimeException(ex); } }); - serverThread.setDaemon(true); serverThread.start(); - ResponseSpec spec = WebClient - .builder() + WebClient client = WebClient.builder() .clientConnector(connector) .baseUrl("http://localhost:" + port) - .build() - .post() - .headers(headers -> { - if (addTransferEncodingHeader) { - headers.add(HttpHeaders.TRANSFER_ENCODING, "chunked"); - } - }) - .retrieve(); + .build(); - return responseHandler - .apply(spec) - .doFinally(signal -> serverThread.stop()); + return handler.apply(client.post().retrieve()); } private void prepareResponse(Consumer consumer) { From 6e92c4d6749e4ee4b68f74157a1c4539f19deb2d Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Fri, 8 Oct 2021 11:08:38 +0200 Subject: [PATCH 205/735] Improve Questions section in CONTRIBUTING doc Closes gh-27509 --- CONTRIBUTING.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2400b729b4c6..2a3ee1be4e84 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,7 @@ First off, thank you for taking the time to contribute! :+1: :tada: * [Code of Conduct](#code-of-conduct) * [How to Contribute](#how-to-contribute) - * [Discuss](#discuss) + * [Ask questions](#ask-questions) * [Create an Issue](#create-an-issue) * [Issue Lifecycle](#issue-lifecycle) * [Submit a Pull Request](#submit-a-pull-request) @@ -22,11 +22,10 @@ Please report unacceptable behavior to spring-code-of-conduct@pivotal.io. ### How to Contribute -#### Discuss +#### Ask questions If you have a question, check Stack Overflow using -[this list of tags](https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-remoting+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux?tab=Newest). -Find an existing discussion, or start a new one if necessary. +[this list of tags](https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-remoting+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux?tab=Newest). Find an existing discussion, or start a new one if necessary. If you believe there is an issue, search through [existing issues](https://github.com/spring-projects/spring-framework/issues) trying a @@ -39,14 +38,18 @@ decision. Reporting an issue or making a feature request is a great way to contribute. Your feedback and the conversations that result from it provide a continuous flow of ideas. However, -before creating a ticket, please take the time to [discuss and research](#discuss) first. +before creating a ticket, please take the time to [ask and research](#ask-questions) first. If creating an issue after a discussion on Stack Overflow, please provide a description in the issue instead of simply referring to Stack Overflow. The issue tracker is an important place of record for design discussions and should be self-sufficient. -Once you're ready, create an issue on -[GitHub](https://github.com/spring-projects/spring-framework/issues). +Once you're ready, create an issue on [GitHub](https://github.com/spring-projects/spring-framework/issues). + +Many issues are caused by subtle behavior, typos and unintended configuration. +Creating a [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) +(starting with https://start.spring.io for example) of the problem helps the team +triage quickly your issue adn get to the core of the problem. #### Issue Lifecycle @@ -129,3 +132,4 @@ When making changes locally, execute `./gradlew asciidoctor` and then browse the Asciidoctor also supports live editing. For more details see [AsciiDoc Tooling](https://docs.asciidoctor.org/asciidoctor/latest/tooling/). + From 932291b867d967d1b670df77e960b5f7d7a866be Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 8 Oct 2021 14:00:23 +0200 Subject: [PATCH 206/735] Polishinig --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2a3ee1be4e84..edf976fff721 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,16 +40,16 @@ Reporting an issue or making a feature request is a great way to contribute. You and the conversations that result from it provide a continuous flow of ideas. However, before creating a ticket, please take the time to [ask and research](#ask-questions) first. -If creating an issue after a discussion on Stack Overflow, please provide a description +If you create an issue after a discussion on Stack Overflow, please provide a description in the issue instead of simply referring to Stack Overflow. The issue tracker is an important place of record for design discussions and should be self-sufficient. Once you're ready, create an issue on [GitHub](https://github.com/spring-projects/spring-framework/issues). -Many issues are caused by subtle behavior, typos and unintended configuration. +Many issues are caused by subtle behavior, typos, and unintended configuration. Creating a [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) (starting with https://start.spring.io for example) of the problem helps the team -triage quickly your issue adn get to the core of the problem. +quickly triage your issue and get to the core of the problem. #### Issue Lifecycle From e3b48c23dd1e8c14c3a376b93e87fd2b0bd258a6 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 8 Oct 2021 17:59:03 +0100 Subject: [PATCH 207/735] Remove AsyncRestTemplate and related types --- .../client/MockAsyncClientHttpRequest.java | 55 -- .../MockMvcClientHttpRequestFactory.java | 25 +- .../web/client/MockRestServiceServer.java | 71 +- .../DefaultRequestExpectationTests.java | 15 +- ...orderedRequestExpectationManagerTests.java | 20 +- .../MockMvcClientHttpRequestFactoryTests.java | 15 +- .../web/client/samples/SampleAsyncTests.java | 144 ---- .../AbstractAsyncClientHttpRequest.java | 85 --- ...stractBufferingAsyncClientHttpRequest.java | 65 -- .../http/client/AsyncClientHttpRequest.java | 48 -- .../AsyncClientHttpRequestExecution.java | 50 -- .../client/AsyncClientHttpRequestFactory.java | 47 -- .../AsyncClientHttpRequestInterceptor.java | 73 -- .../HttpComponentsAsyncClientHttpRequest.java | 172 ----- ...mponentsAsyncClientHttpRequestFactory.java | 216 ------ ...HttpComponentsAsyncClientHttpResponse.java | 90 --- .../InterceptingAsyncClientHttpRequest.java | 125 --- ...rceptingAsyncClientHttpRequestFactory.java | 62 -- .../http/client/Netty4ClientHttpRequest.java | 187 ----- .../Netty4ClientHttpRequestFactory.java | 243 ------ .../http/client/Netty4ClientHttpResponse.java | 96 --- .../client/OkHttp3AsyncClientHttpRequest.java | 109 --- .../OkHttp3ClientHttpRequestFactory.java | 11 +- ...SimpleBufferingAsyncClientHttpRequest.java | 99 --- .../SimpleClientHttpRequestFactory.java | 40 +- ...SimpleStreamingAsyncClientHttpRequest.java | 125 --- .../client/support/AsyncHttpAccessor.java | 92 --- .../InterceptingAsyncHttpAccessor.java | 67 -- .../web/client/AsyncRequestCallback.java | 48 -- .../web/client/AsyncRestOperations.java | 464 ------------ .../web/client/AsyncRestTemplate.java | 714 ------------------ .../AbstractAsyncHttpRequestFactoryTests.java | 203 ----- ...redSimpleAsyncHttpRequestFactoryTests.java | 50 -- ...ntsAsyncClientHttpRequestFactoryTests.java | 88 --- ...ty4AsyncClientHttpRequestFactoryTests.java | 58 -- .../Netty4ClientHttpRequestFactoryTests.java | 58 -- ...tp3AsyncClientHttpRequestFactoryTests.java | 41 - .../AsyncRestTemplateIntegrationTests.java | 669 ---------------- .../client/RestTemplateIntegrationTests.java | 3 +- src/docs/asciidoc/integration.adoc | 7 - 40 files changed, 37 insertions(+), 4813 deletions(-) delete mode 100644 spring-test/src/main/java/org/springframework/mock/http/client/MockAsyncClientHttpRequest.java delete mode 100644 spring-test/src/test/java/org/springframework/test/web/client/samples/SampleAsyncTests.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/AbstractAsyncClientHttpRequest.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/AbstractBufferingAsyncClientHttpRequest.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequest.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestExecution.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestFactory.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestInterceptor.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequestFactory.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpResponse.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/InterceptingAsyncClientHttpRequest.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/InterceptingAsyncClientHttpRequestFactory.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequest.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequestFactory.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpResponse.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/OkHttp3AsyncClientHttpRequest.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/SimpleBufferingAsyncClientHttpRequest.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/SimpleStreamingAsyncClientHttpRequest.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/support/AsyncHttpAccessor.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/support/InterceptingAsyncHttpAccessor.java delete mode 100644 spring-web/src/main/java/org/springframework/web/client/AsyncRequestCallback.java delete mode 100644 spring-web/src/main/java/org/springframework/web/client/AsyncRestOperations.java delete mode 100644 spring-web/src/main/java/org/springframework/web/client/AsyncRestTemplate.java delete mode 100644 spring-web/src/test/java/org/springframework/http/client/AbstractAsyncHttpRequestFactoryTests.java delete mode 100644 spring-web/src/test/java/org/springframework/http/client/BufferedSimpleAsyncHttpRequestFactoryTests.java delete mode 100644 spring-web/src/test/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequestFactoryTests.java delete mode 100644 spring-web/src/test/java/org/springframework/http/client/Netty4AsyncClientHttpRequestFactoryTests.java delete mode 100644 spring-web/src/test/java/org/springframework/http/client/Netty4ClientHttpRequestFactoryTests.java delete mode 100644 spring-web/src/test/java/org/springframework/http/client/OkHttp3AsyncClientHttpRequestFactoryTests.java delete mode 100644 spring-web/src/test/java/org/springframework/web/client/AsyncRestTemplateIntegrationTests.java diff --git a/spring-test/src/main/java/org/springframework/mock/http/client/MockAsyncClientHttpRequest.java b/spring-test/src/main/java/org/springframework/mock/http/client/MockAsyncClientHttpRequest.java deleted file mode 100644 index c082fce1b857..000000000000 --- a/spring-test/src/main/java/org/springframework/mock/http/client/MockAsyncClientHttpRequest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.http.client; - -import java.io.IOException; -import java.net.URI; - -import org.springframework.http.HttpMethod; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.SettableListenableFuture; - -/** - * An extension of {@link MockClientHttpRequest} that also implements - * {@link org.springframework.http.client.AsyncClientHttpRequest} by wrapping the response in a - * {@link SettableListenableFuture}. - * - * @author Rossen Stoyanchev - * @author Sam Brannen - * @since 4.1 - * @deprecated as of Spring 5.0, with no direct replacement - */ -@Deprecated -public class MockAsyncClientHttpRequest extends MockClientHttpRequest implements org.springframework.http.client.AsyncClientHttpRequest { - - public MockAsyncClientHttpRequest() { - } - - public MockAsyncClientHttpRequest(HttpMethod httpMethod, URI uri) { - super(httpMethod, uri); - } - - - @Override - public ListenableFuture executeAsync() throws IOException { - SettableListenableFuture future = new SettableListenableFuture<>(); - future.set(execute()); - return future; - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/web/client/MockMvcClientHttpRequestFactory.java b/spring-test/src/main/java/org/springframework/test/web/client/MockMvcClientHttpRequestFactory.java index 42c7a03cefff..4c4592230d54 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/MockMvcClientHttpRequestFactory.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/MockMvcClientHttpRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.test.web.client; -import java.io.IOException; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.List; @@ -39,18 +38,10 @@ /** * A {@link ClientHttpRequestFactory} for requests executed via {@link MockMvc}. * - *

    As of 5.0 this class also implements - * {@link org.springframework.http.client.AsyncClientHttpRequestFactory - * AsyncClientHttpRequestFactory}. However note that - * {@link org.springframework.web.client.AsyncRestTemplate} and related classes - * have been deprecated at the same time. - * * @author Rossen Stoyanchev * @since 3.2 */ -@SuppressWarnings("deprecation") -public class MockMvcClientHttpRequestFactory - implements ClientHttpRequestFactory, org.springframework.http.client.AsyncClientHttpRequestFactory { +public class MockMvcClientHttpRequestFactory implements ClientHttpRequestFactory { private final MockMvc mockMvc; @@ -65,22 +56,12 @@ public MockMvcClientHttpRequestFactory(MockMvc mockMvc) { public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) { return new MockClientHttpRequest(httpMethod, uri) { @Override - public ClientHttpResponse executeInternal() throws IOException { + public ClientHttpResponse executeInternal() { return getClientHttpResponse(httpMethod, uri, getHeaders(), getBodyAsBytes()); } }; } - @Override - public org.springframework.http.client.AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod method) { - return new org.springframework.mock.http.client.MockAsyncClientHttpRequest(method, uri) { - @Override - protected ClientHttpResponse executeInternal() throws IOException { - return getClientHttpResponse(method, uri, getHeaders(), getBodyAsBytes()); - } - }; - } - private ClientHttpResponse getClientHttpResponse( HttpMethod httpMethod, URI uri, HttpHeaders requestHeaders, byte[] requestBody) { diff --git a/spring-test/src/main/java/org/springframework/test/web/client/MockRestServiceServer.java b/spring-test/src/main/java/org/springframework/test/web/client/MockRestServiceServer.java index d3c0cd7b4156..8dbeff5a6cd9 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/MockRestServiceServer.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/MockRestServiceServer.java @@ -25,7 +25,7 @@ import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpResponse; -import org.springframework.lang.Nullable; +import org.springframework.mock.http.client.MockClientHttpRequest; import org.springframework.util.Assert; import org.springframework.web.client.RestTemplate; import org.springframework.web.client.support.RestGatewaySupport; @@ -64,7 +64,6 @@ * @author Rossen Stoyanchev * @since 3.2 */ -@SuppressWarnings("deprecation") public final class MockRestServiceServer { private final RequestExpectationManager expectationManager; @@ -147,18 +146,6 @@ public static MockRestServiceServerBuilder bindTo(RestTemplate restTemplate) { return new DefaultBuilder(restTemplate); } - /** - * Return a builder for a {@code MockRestServiceServer} that should be used - * to reply to the given {@code AsyncRestTemplate}. - * @since 4.3 - * @deprecated see deprecation notice on - * {@link org.springframework.web.client.AsyncRestTemplate} itself - */ - @Deprecated - public static MockRestServiceServerBuilder bindTo(org.springframework.web.client.AsyncRestTemplate asyncRestTemplate) { - return new DefaultBuilder(asyncRestTemplate); - } - /** * Return a builder for a {@code MockRestServiceServer} that should be used * to reply to the given {@code RestGatewaySupport}. @@ -179,18 +166,6 @@ public static MockRestServiceServer createServer(RestTemplate restTemplate) { return bindTo(restTemplate).build(); } - /** - * A shortcut for {@code bindTo(asyncRestTemplate).build()}. - * @param asyncRestTemplate the AsyncRestTemplate to set up for mock testing - * @return the created mock server - * @deprecated see deprecation notice on - * {@link org.springframework.web.client.AsyncRestTemplate} itself - */ - @Deprecated - public static MockRestServiceServer createServer(org.springframework.web.client.AsyncRestTemplate asyncRestTemplate) { - return bindTo(asyncRestTemplate).build(); - } - /** * A shortcut for {@code bindTo(restGateway).build()}. * @param restGateway the REST gateway to set up for mock testing @@ -226,8 +201,8 @@ public interface MockRestServiceServerBuilder { /** * Build the {@code MockRestServiceServer} and set up the underlying - * {@code RestTemplate} or {@code AsyncRestTemplate} with a - * {@link ClientHttpRequestFactory} that creates mock requests. + * {@code RestTemplate} with a {@link ClientHttpRequestFactory} that + * creates mock requests. */ MockRestServiceServer build(); @@ -241,12 +216,8 @@ public interface MockRestServiceServerBuilder { private static class DefaultBuilder implements MockRestServiceServerBuilder { - @Nullable private final RestTemplate restTemplate; - @Nullable - private final org.springframework.web.client.AsyncRestTemplate asyncRestTemplate; - private boolean ignoreExpectOrder; private boolean bufferContent; @@ -255,13 +226,6 @@ private static class DefaultBuilder implements MockRestServiceServerBuilder { public DefaultBuilder(RestTemplate restTemplate) { Assert.notNull(restTemplate, "RestTemplate must not be null"); this.restTemplate = restTemplate; - this.asyncRestTemplate = null; - } - - public DefaultBuilder(org.springframework.web.client.AsyncRestTemplate asyncRestTemplate) { - Assert.notNull(asyncRestTemplate, "AsyncRestTemplate must not be null"); - this.restTemplate = null; - this.asyncRestTemplate = asyncRestTemplate; } @Override @@ -290,16 +254,11 @@ public MockRestServiceServer build() { public MockRestServiceServer build(RequestExpectationManager manager) { MockRestServiceServer server = new MockRestServiceServer(manager); MockClientHttpRequestFactory factory = server.new MockClientHttpRequestFactory(); - if (this.restTemplate != null) { - if (this.bufferContent) { - this.restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory)); - } - else { - this.restTemplate.setRequestFactory(factory); - } + if (this.bufferContent) { + this.restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory)); } - if (this.asyncRestTemplate != null) { - this.asyncRestTemplate.setAsyncRequestFactory(factory); + else { + this.restTemplate.setRequestFactory(factory); } return server; } @@ -310,28 +269,18 @@ public MockRestServiceServer build(RequestExpectationManager manager) { * Mock ClientHttpRequestFactory that creates requests by iterating * over the list of expected {@link DefaultRequestExpectation}'s. */ - private class MockClientHttpRequestFactory implements ClientHttpRequestFactory, - org.springframework.http.client.AsyncClientHttpRequestFactory { + private class MockClientHttpRequestFactory implements ClientHttpRequestFactory { @Override public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) { return createRequestInternal(uri, httpMethod); } - @Override - public org.springframework.http.client.AsyncClientHttpRequest createAsyncRequest( - URI uri, HttpMethod httpMethod) { - - return createRequestInternal(uri, httpMethod); - } - - private org.springframework.mock.http.client.MockAsyncClientHttpRequest createRequestInternal( - URI uri, HttpMethod httpMethod) { - + private MockClientHttpRequest createRequestInternal(URI uri, HttpMethod httpMethod) { Assert.notNull(uri, "'uri' must not be null"); Assert.notNull(httpMethod, "'httpMethod' must not be null"); - return new org.springframework.mock.http.client.MockAsyncClientHttpRequest(httpMethod, uri) { + return new MockClientHttpRequest(httpMethod, uri) { @Override protected ClientHttpResponse executeInternal() throws IOException { diff --git a/spring-test/src/test/java/org/springframework/test/web/client/DefaultRequestExpectationTests.java b/spring-test/src/test/java/org/springframework/test/web/client/DefaultRequestExpectationTests.java index 22351191513b..2c15775637e7 100644 --- a/spring-test/src/test/java/org/springframework/test/web/client/DefaultRequestExpectationTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/client/DefaultRequestExpectationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,10 +23,10 @@ import org.springframework.http.HttpMethod; import org.springframework.http.client.ClientHttpRequest; +import org.springframework.mock.http.client.MockClientHttpRequest; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; import static org.springframework.test.web.client.ExpectedCount.once; import static org.springframework.test.web.client.ExpectedCount.twice; @@ -44,15 +44,15 @@ public class DefaultRequestExpectationTests { @Test public void match() throws Exception { RequestExpectation expectation = new DefaultRequestExpectation(once(), requestTo("/foo")); - expectation.match(createRequest(GET, "/foo")); + expectation.match(createRequest()); } @Test - public void matchWithFailedExpectation() throws Exception { + public void matchWithFailedExpectation() { RequestExpectation expectation = new DefaultRequestExpectation(once(), requestTo("/foo")); expectation.andExpect(method(POST)); assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> - expectation.match(createRequest(GET, "/foo"))) + expectation.match(createRequest())) .withMessageContaining("Unexpected HttpMethod expected: but was:"); } @@ -81,10 +81,9 @@ public void isSatisfied() { } - @SuppressWarnings("deprecation") - private ClientHttpRequest createRequest(HttpMethod method, String url) { + private ClientHttpRequest createRequest() { try { - return new org.springframework.mock.http.client.MockAsyncClientHttpRequest(method, new URI(url)); + return new MockClientHttpRequest(HttpMethod.GET, new URI("/foo")); } catch (URISyntaxException ex) { throw new IllegalStateException(ex); diff --git a/spring-test/src/test/java/org/springframework/test/web/client/UnorderedRequestExpectationManagerTests.java b/spring-test/src/test/java/org/springframework/test/web/client/UnorderedRequestExpectationManagerTests.java index f8f4cfa5b018..973a44df586e 100644 --- a/spring-test/src/test/java/org/springframework/test/web/client/UnorderedRequestExpectationManagerTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/client/UnorderedRequestExpectationManagerTests.java @@ -23,6 +23,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.client.ClientHttpRequest; +import org.springframework.mock.http.client.MockClientHttpRequest; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -42,7 +43,7 @@ */ public class UnorderedRequestExpectationManagerTests { - private UnorderedRequestExpectationManager manager = new UnorderedRequestExpectationManager(); + private final UnorderedRequestExpectationManager manager = new UnorderedRequestExpectationManager(); @Test @@ -57,7 +58,7 @@ public void unexpectedRequest() throws Exception { } @Test - public void zeroExpectedRequests() throws Exception { + public void zeroExpectedRequests() { this.manager.verify(); } @@ -108,19 +109,18 @@ public void repeatedRequestsTooFew() throws Exception { this.manager.validateRequest(createRequest(GET, "/bar")); this.manager.validateRequest(createRequest(GET, "/foo")); this.manager.validateRequest(createRequest(GET, "/foo")); - assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> - this.manager.verify()) - .withMessageContaining("3 request(s) executed:\n" + - "GET /bar\n" + - "GET /foo\n" + - "GET /foo\n"); + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(this.manager::verify) + .withMessageContaining("3 request(s) executed:\n" + + "GET /bar\n" + + "GET /foo\n" + + "GET /foo\n"); } - @SuppressWarnings("deprecation") private ClientHttpRequest createRequest(HttpMethod method, String url) { try { - return new org.springframework.mock.http.client.MockAsyncClientHttpRequest(method, new URI(url)); + return new MockClientHttpRequest(method, new URI(url)); } catch (URISyntaxException ex) { throw new IllegalStateException(ex); diff --git a/spring-test/src/test/java/org/springframework/test/web/client/samples/MockMvcClientHttpRequestFactoryTests.java b/spring-test/src/test/java/org/springframework/test/web/client/samples/MockMvcClientHttpRequestFactoryTests.java index 20262f096845..fc444a423fc0 100644 --- a/spring-test/src/test/java/org/springframework/test/web/client/samples/MockMvcClientHttpRequestFactoryTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/client/samples/MockMvcClientHttpRequestFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -31,7 +30,6 @@ import org.springframework.test.web.client.MockMvcClientHttpRequestFactory; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.util.concurrent.ListenableFuture; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @@ -68,21 +66,12 @@ public void setup() { } @Test - public void test() throws Exception { + public void test() { RestTemplate template = new RestTemplate(new MockMvcClientHttpRequestFactory(this.mockMvc)); String result = template.getForObject("/foo", String.class); assertThat(result).isEqualTo("bar"); } - @Test - @SuppressWarnings("deprecation") - public void testAsyncTemplate() throws Exception { - org.springframework.web.client.AsyncRestTemplate template = new org.springframework.web.client.AsyncRestTemplate( - new MockMvcClientHttpRequestFactory(this.mockMvc)); - ListenableFuture> entity = template.getForEntity("/foo", String.class); - assertThat(entity.get().getBody()).isEqualTo("bar"); - } - @EnableWebMvc @Configuration diff --git a/spring-test/src/test/java/org/springframework/test/web/client/samples/SampleAsyncTests.java b/spring-test/src/test/java/org/springframework/test/web/client/samples/SampleAsyncTests.java deleted file mode 100644 index 975c46d384d1..000000000000 --- a/spring-test/src/test/java/org/springframework/test/web/client/samples/SampleAsyncTests.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.test.web.client.samples; - -import org.junit.jupiter.api.Test; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.test.web.Person; -import org.springframework.test.web.client.MockRestServiceServer; -import org.springframework.util.concurrent.ListenableFuture; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.test.web.client.ExpectedCount.manyTimes; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; - -/** - * Examples to demonstrate writing client-side REST tests with Spring MVC Test. - * While the tests in this class invoke the RestTemplate directly, in actual - * tests the RestTemplate may likely be invoked indirectly, i.e. through client - * code. - * - * @author Rossen Stoyanchev - * @since 4.1 - */ -@SuppressWarnings("deprecation") -public class SampleAsyncTests { - - private final org.springframework.web.client.AsyncRestTemplate restTemplate = new org.springframework.web.client.AsyncRestTemplate(); - - private final MockRestServiceServer mockServer = MockRestServiceServer.createServer(this.restTemplate); - - - @Test - public void performGet() throws Exception { - - String responseBody = "{\"name\" : \"Ludwig van Beethoven\", \"someDouble\" : \"1.6035\"}"; - - this.mockServer.expect(requestTo("/composers/42")).andExpect(method(HttpMethod.GET)) - .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); - - @SuppressWarnings("unused") - ListenableFuture> ludwig = - this.restTemplate.getForEntity("/composers/{id}", Person.class, 42); - - // We are only validating the request. The response is mocked out. - // person.getName().equals("Ludwig van Beethoven") - // person.getDouble().equals(1.6035) - - this.mockServer.verify(); - } - - @Test - public void performGetManyTimes() throws Exception { - - String responseBody = "{\"name\" : \"Ludwig van Beethoven\", \"someDouble\" : \"1.6035\"}"; - - this.mockServer.expect(manyTimes(), requestTo("/composers/42")).andExpect(method(HttpMethod.GET)) - .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); - - @SuppressWarnings("unused") - ListenableFuture> ludwig = - this.restTemplate.getForEntity("/composers/{id}", Person.class, 42); - - // We are only validating the request. The response is mocked out. - // person.getName().equals("Ludwig van Beethoven") - // person.getDouble().equals(1.6035) - - this.restTemplate.getForEntity("/composers/{id}", Person.class, 42); - this.restTemplate.getForEntity("/composers/{id}", Person.class, 42); - this.restTemplate.getForEntity("/composers/{id}", Person.class, 42); - this.restTemplate.getForEntity("/composers/{id}", Person.class, 42); - - this.mockServer.verify(); - } - - @Test - public void performGetWithResponseBodyFromFile() throws Exception { - - Resource responseBody = new ClassPathResource("ludwig.json", this.getClass()); - - this.mockServer.expect(requestTo("/composers/42")).andExpect(method(HttpMethod.GET)) - .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); - - @SuppressWarnings("unused") - ListenableFuture> ludwig = - this.restTemplate.getForEntity("/composers/{id}", Person.class, 42); - - // hotel.getId() == 42 - // hotel.getName().equals("Holiday Inn") - - this.mockServer.verify(); - } - - @Test - public void verify() { - - this.mockServer.expect(requestTo("/number")).andExpect(method(HttpMethod.GET)) - .andRespond(withSuccess("1", MediaType.TEXT_PLAIN)); - - this.mockServer.expect(requestTo("/number")).andExpect(method(HttpMethod.GET)) - .andRespond(withSuccess("2", MediaType.TEXT_PLAIN)); - - this.mockServer.expect(requestTo("/number")).andExpect(method(HttpMethod.GET)) - .andRespond(withSuccess("4", MediaType.TEXT_PLAIN)); - - this.mockServer.expect(requestTo("/number")).andExpect(method(HttpMethod.GET)) - .andRespond(withSuccess("8", MediaType.TEXT_PLAIN)); - - @SuppressWarnings("unused") - ListenableFuture> result = this.restTemplate.getForEntity("/number", String.class); - // result == "1" - - result = this.restTemplate.getForEntity("/number", String.class); - // result == "2" - - try { - this.mockServer.verify(); - } - catch (AssertionError error) { - assertThat(error.getMessage().contains("2 unsatisfied expectation(s)")).as(error.getMessage()).isTrue(); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/AbstractAsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/AbstractAsyncClientHttpRequest.java deleted file mode 100644 index 37b09134d94a..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/AbstractAsyncClientHttpRequest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.io.OutputStream; - -import org.springframework.http.HttpHeaders; -import org.springframework.util.Assert; -import org.springframework.util.concurrent.ListenableFuture; - -/** - * Abstract base for {@link AsyncClientHttpRequest} that makes sure that headers and body - * are not written multiple times. - * - * @author Arjen Poutsma - * @since 4.0 - * @deprecated as of Spring 5.0, in favor of {@link org.springframework.http.client.reactive.AbstractClientHttpRequest} - */ -@Deprecated -abstract class AbstractAsyncClientHttpRequest implements AsyncClientHttpRequest { - - private final HttpHeaders headers = new HttpHeaders(); - - private boolean executed = false; - - - @Override - public final HttpHeaders getHeaders() { - return (this.executed ? HttpHeaders.readOnlyHttpHeaders(this.headers) : this.headers); - } - - @Override - public final OutputStream getBody() throws IOException { - assertNotExecuted(); - return getBodyInternal(this.headers); - } - - @Override - public ListenableFuture executeAsync() throws IOException { - assertNotExecuted(); - ListenableFuture result = executeInternal(this.headers); - this.executed = true; - return result; - } - - /** - * Asserts that this request has not been {@linkplain #executeAsync() executed} yet. - * @throws IllegalStateException if this request has been executed - */ - protected void assertNotExecuted() { - Assert.state(!this.executed, "ClientHttpRequest already executed"); - } - - - /** - * Abstract template method that returns the body. - * @param headers the HTTP headers - * @return the body output stream - */ - protected abstract OutputStream getBodyInternal(HttpHeaders headers) throws IOException; - - /** - * Abstract template method that writes the given headers and content to the HTTP request. - * @param headers the HTTP headers - * @return the response object for the executed request - */ - protected abstract ListenableFuture executeInternal(HttpHeaders headers) - throws IOException; - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/AbstractBufferingAsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/AbstractBufferingAsyncClientHttpRequest.java deleted file mode 100644 index f5c9aafe0e9f..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/AbstractBufferingAsyncClientHttpRequest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.springframework.http.HttpHeaders; -import org.springframework.util.concurrent.ListenableFuture; - -/** - * Base implementation of {@link AsyncClientHttpRequest} that buffers output - * in a byte array before sending it over the wire. - * - * @author Arjen Poutsma - * @since 4.0 - * @deprecated as of Spring 5.0, with no direct replacement - */ -@Deprecated -abstract class AbstractBufferingAsyncClientHttpRequest extends AbstractAsyncClientHttpRequest { - - private ByteArrayOutputStream bufferedOutput = new ByteArrayOutputStream(1024); - - - @Override - protected OutputStream getBodyInternal(HttpHeaders headers) throws IOException { - return this.bufferedOutput; - } - - @Override - protected ListenableFuture executeInternal(HttpHeaders headers) throws IOException { - byte[] bytes = this.bufferedOutput.toByteArray(); - if (headers.getContentLength() < 0) { - headers.setContentLength(bytes.length); - } - ListenableFuture result = executeInternal(headers, bytes); - this.bufferedOutput = new ByteArrayOutputStream(0); - return result; - } - - /** - * Abstract template method that writes the given headers and content to the HTTP request. - * @param headers the HTTP headers - * @param bufferedOutput the body content - * @return the response object for the executed request - */ - protected abstract ListenableFuture executeInternal( - HttpHeaders headers, byte[] bufferedOutput) throws IOException; - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequest.java deleted file mode 100644 index 39f3c83ae887..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; - -import org.springframework.http.HttpOutputMessage; -import org.springframework.http.HttpRequest; -import org.springframework.util.concurrent.ListenableFuture; - -/** - * Represents a client-side asynchronous HTTP request. Created via an - * implementation of the {@link AsyncClientHttpRequestFactory}. - * - *

    A {@code AsyncHttpRequest} can be {@linkplain #executeAsync() executed}, - * getting a future {@link ClientHttpResponse} which can be read from. - * - * @author Arjen Poutsma - * @since 4.0 - * @see AsyncClientHttpRequestFactory#createAsyncRequest - * @deprecated as of Spring 5.0, in favor of {@link org.springframework.web.reactive.function.client.ClientRequest} - */ -@Deprecated -public interface AsyncClientHttpRequest extends HttpRequest, HttpOutputMessage { - - /** - * Execute this request asynchronously, resulting in a Future handle. - * {@link ClientHttpResponse} that can be read. - * @return the future response result of the execution - * @throws java.io.IOException in case of I/O errors - */ - ListenableFuture executeAsync() throws IOException; - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestExecution.java b/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestExecution.java deleted file mode 100644 index 97ecb225cb32..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestExecution.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; - -import org.springframework.http.HttpRequest; -import org.springframework.util.concurrent.ListenableFuture; - -/** - * Represents the context of a client-side HTTP request execution. - * - *

    Used to invoke the next interceptor in the interceptor chain, or - - * if the calling interceptor is last - execute the request itself. - * - * @author Jakub Narloch - * @author Rossen Stoyanchev - * @since 4.3 - * @see AsyncClientHttpRequestInterceptor - * @deprecated as of Spring 5.0, in favor of - * {@link org.springframework.web.reactive.function.client.ExchangeFilterFunction} - */ -@Deprecated -public interface AsyncClientHttpRequestExecution { - - /** - * Resume the request execution by invoking the next interceptor in the chain - * or executing the request to the remote service. - * @param request the HTTP request, containing the HTTP method and headers - * @param body the body of the request - * @return a corresponding future handle - * @throws IOException in case of I/O errors - */ - ListenableFuture executeAsync(HttpRequest request, byte[] body) throws IOException; - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestFactory.java deleted file mode 100644 index 509d1da713a3..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestFactory.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.net.URI; - -import org.springframework.http.HttpMethod; - -/** - * Factory for {@link AsyncClientHttpRequest} objects. - * Requests are created by the {@link #createAsyncRequest(URI, HttpMethod)} method. - * - * @author Arjen Poutsma - * @since 4.0 - * @deprecated as of Spring 5.0, in favor of {@link org.springframework.http.client.reactive.ClientHttpConnector} - */ -@Deprecated -public interface AsyncClientHttpRequestFactory { - - /** - * Create a new asynchronous {@link AsyncClientHttpRequest} for the specified URI - * and HTTP method. - *

    The returned request can be written to, and then executed by calling - * {@link AsyncClientHttpRequest#executeAsync()}. - * @param uri the URI to create a request for - * @param httpMethod the HTTP method to execute - * @return the created request - * @throws IOException in case of I/O errors - */ - AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException; - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestInterceptor.java b/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestInterceptor.java deleted file mode 100644 index 34ed8c024e68..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestInterceptor.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; - -import org.springframework.http.HttpRequest; -import org.springframework.util.concurrent.ListenableFuture; - -/** - * Intercepts client-side HTTP requests. Implementations of this interface can be - * {@linkplain org.springframework.web.client.AsyncRestTemplate#setInterceptors registered} - * with the {@link org.springframework.web.client.AsyncRestTemplate} as to modify - * the outgoing {@link HttpRequest} and/or register to modify the incoming - * {@link ClientHttpResponse} with help of a - * {@link org.springframework.util.concurrent.ListenableFutureAdapter}. - * - *

    The main entry point for interceptors is {@link #intercept}. - * - * @author Jakub Narloch - * @author Rossen Stoyanchev - * @since 4.3 - * @see org.springframework.web.client.AsyncRestTemplate - * @see org.springframework.http.client.support.InterceptingAsyncHttpAccessor - * @deprecated as of Spring 5.0, in favor of - * {@link org.springframework.web.reactive.function.client.ExchangeFilterFunction} - */ -@Deprecated -public interface AsyncClientHttpRequestInterceptor { - - /** - * Intercept the given request, and return a response future. The given - * {@link AsyncClientHttpRequestExecution} allows the interceptor to pass on - * the request to the next entity in the chain. - *

    An implementation might follow this pattern: - *

      - *
    1. Examine the {@linkplain HttpRequest request} and body
    2. - *
    3. Optionally {@linkplain org.springframework.http.client.support.HttpRequestWrapper - * wrap} the request to filter HTTP attributes.
    4. - *
    5. Optionally modify the body of the request.
    6. - *
    7. One of the following: - *
        - *
      • execute the request through {@link ClientHttpRequestExecution}
      • - *
      • don't execute the request to block the execution altogether
      • - *
      - *
    8. Optionally adapt the response to filter HTTP attributes with the help of - * {@link org.springframework.util.concurrent.ListenableFutureAdapter - * ListenableFutureAdapter}.
    9. - *
    - * @param request the request, containing method, URI, and headers - * @param body the body of the request - * @param execution the request execution - * @return the response future - * @throws IOException in case of I/O errors - */ - ListenableFuture intercept(HttpRequest request, byte[] body, - AsyncClientHttpRequestExecution execution) throws IOException; - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java deleted file mode 100644 index ca97edde0bb8..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.net.URI; -import java.util.concurrent.Future; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpEntityEnclosingRequest; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.concurrent.FutureCallback; -import org.apache.http.nio.client.HttpAsyncClient; -import org.apache.http.nio.entity.NByteArrayEntity; -import org.apache.http.protocol.HttpContext; - -import org.springframework.http.HttpHeaders; -import org.springframework.util.concurrent.FailureCallback; -import org.springframework.util.concurrent.FutureAdapter; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; -import org.springframework.util.concurrent.ListenableFutureCallbackRegistry; -import org.springframework.util.concurrent.SuccessCallback; - - -/** - * {@link ClientHttpRequest} implementation based on - * Apache HttpComponents HttpAsyncClient. - * - *

    Created via the {@link HttpComponentsClientHttpRequestFactory}. - * - * @author Oleg Kalnichevski - * @author Arjen Poutsma - * @since 4.0 - * @see HttpComponentsClientHttpRequestFactory#createRequest - * @deprecated as of Spring 5.0, in favor of - * {@link org.springframework.http.client.reactive.HttpComponentsClientHttpConnector} - */ -@Deprecated -final class HttpComponentsAsyncClientHttpRequest extends AbstractBufferingAsyncClientHttpRequest { - - private final HttpAsyncClient httpClient; - - private final HttpUriRequest httpRequest; - - private final HttpContext httpContext; - - - HttpComponentsAsyncClientHttpRequest(HttpAsyncClient client, HttpUriRequest request, HttpContext context) { - this.httpClient = client; - this.httpRequest = request; - this.httpContext = context; - } - - - @Override - public String getMethodValue() { - return this.httpRequest.getMethod(); - } - - @Override - public URI getURI() { - return this.httpRequest.getURI(); - } - - HttpContext getHttpContext() { - return this.httpContext; - } - - @Override - protected ListenableFuture executeInternal(HttpHeaders headers, byte[] bufferedOutput) - throws IOException { - - HttpComponentsClientHttpRequest.addHeaders(this.httpRequest, headers); - - if (this.httpRequest instanceof HttpEntityEnclosingRequest) { - HttpEntityEnclosingRequest entityEnclosingRequest = (HttpEntityEnclosingRequest) this.httpRequest; - HttpEntity requestEntity = new NByteArrayEntity(bufferedOutput); - entityEnclosingRequest.setEntity(requestEntity); - } - - HttpResponseFutureCallback callback = new HttpResponseFutureCallback(this.httpRequest); - Future futureResponse = this.httpClient.execute(this.httpRequest, this.httpContext, callback); - return new ClientHttpResponseFuture(futureResponse, callback); - } - - - private static class HttpResponseFutureCallback implements FutureCallback { - - private final HttpUriRequest request; - - private final ListenableFutureCallbackRegistry callbacks = - new ListenableFutureCallbackRegistry<>(); - - public HttpResponseFutureCallback(HttpUriRequest request) { - this.request = request; - } - - public void addCallback(ListenableFutureCallback callback) { - this.callbacks.addCallback(callback); - } - - public void addSuccessCallback(SuccessCallback callback) { - this.callbacks.addSuccessCallback(callback); - } - - public void addFailureCallback(FailureCallback callback) { - this.callbacks.addFailureCallback(callback); - } - - @Override - public void completed(HttpResponse result) { - this.callbacks.success(new HttpComponentsAsyncClientHttpResponse(result)); - } - - @Override - public void failed(Exception ex) { - this.callbacks.failure(ex); - } - - @Override - public void cancelled() { - this.request.abort(); - } - } - - - private static class ClientHttpResponseFuture extends FutureAdapter - implements ListenableFuture { - - private final HttpResponseFutureCallback callback; - - public ClientHttpResponseFuture(Future response, HttpResponseFutureCallback callback) { - super(response); - this.callback = callback; - } - - @Override - protected ClientHttpResponse adapt(HttpResponse response) { - return new HttpComponentsAsyncClientHttpResponse(response); - } - - @Override - public void addCallback(ListenableFutureCallback callback) { - this.callback.addCallback(callback); - } - - @Override - public void addCallback(SuccessCallback successCallback, - FailureCallback failureCallback) { - - this.callback.addSuccessCallback(successCallback); - this.callback.addFailureCallback(failureCallback); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequestFactory.java deleted file mode 100644 index 84bd07a159e6..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequestFactory.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.Closeable; -import java.io.IOException; -import java.net.URI; - -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.Configurable; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; -import org.apache.http.impl.nio.client.HttpAsyncClients; -import org.apache.http.nio.client.HttpAsyncClient; -import org.apache.http.protocol.HttpContext; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.http.HttpMethod; -import org.springframework.util.Assert; - -/** - * Asynchronous extension of the {@link HttpComponentsClientHttpRequestFactory}. Uses - * Apache HttpComponents - * HttpAsyncClient 4.0 to create requests. - * - * @author Arjen Poutsma - * @author Stephane Nicoll - * @since 4.0 - * @see HttpAsyncClient - * @deprecated as of Spring 5.0, in favor of - * {@link org.springframework.http.client.reactive.HttpComponentsClientHttpConnector} - */ -@Deprecated -public class HttpComponentsAsyncClientHttpRequestFactory extends HttpComponentsClientHttpRequestFactory - implements AsyncClientHttpRequestFactory, InitializingBean { - - private HttpAsyncClient asyncClient; - - - /** - * Create a new instance of the {@code HttpComponentsAsyncClientHttpRequestFactory} - * with a default {@link HttpAsyncClient} and {@link HttpClient}. - */ - public HttpComponentsAsyncClientHttpRequestFactory() { - super(); - this.asyncClient = HttpAsyncClients.createSystem(); - } - - /** - * Create a new instance of the {@code HttpComponentsAsyncClientHttpRequestFactory} - * with the given {@link HttpAsyncClient} instance and a default {@link HttpClient}. - * @param asyncClient the HttpAsyncClient instance to use for this request factory - * @since 4.3.10 - */ - public HttpComponentsAsyncClientHttpRequestFactory(HttpAsyncClient asyncClient) { - super(); - this.asyncClient = asyncClient; - } - - /** - * Create a new instance of the {@code HttpComponentsAsyncClientHttpRequestFactory} - * with the given {@link CloseableHttpAsyncClient} instance and a default {@link HttpClient}. - * @param asyncClient the CloseableHttpAsyncClient instance to use for this request factory - */ - public HttpComponentsAsyncClientHttpRequestFactory(CloseableHttpAsyncClient asyncClient) { - super(); - this.asyncClient = asyncClient; - } - - /** - * Create a new instance of the {@code HttpComponentsAsyncClientHttpRequestFactory} - * with the given {@link HttpClient} and {@link HttpAsyncClient} instances. - * @param httpClient the HttpClient instance to use for this request factory - * @param asyncClient the HttpAsyncClient instance to use for this request factory - * @since 4.3.10 - */ - public HttpComponentsAsyncClientHttpRequestFactory(HttpClient httpClient, HttpAsyncClient asyncClient) { - super(httpClient); - this.asyncClient = asyncClient; - } - - /** - * Create a new instance of the {@code HttpComponentsAsyncClientHttpRequestFactory} - * with the given {@link CloseableHttpClient} and {@link CloseableHttpAsyncClient} instances. - * @param httpClient the CloseableHttpClient instance to use for this request factory - * @param asyncClient the CloseableHttpAsyncClient instance to use for this request factory - */ - public HttpComponentsAsyncClientHttpRequestFactory( - CloseableHttpClient httpClient, CloseableHttpAsyncClient asyncClient) { - - super(httpClient); - this.asyncClient = asyncClient; - } - - - /** - * Set the {@code HttpAsyncClient} used for - * {@linkplain #createAsyncRequest(URI, HttpMethod) synchronous execution}. - * @since 4.3.10 - * @see #setHttpClient(HttpClient) - */ - public void setAsyncClient(HttpAsyncClient asyncClient) { - Assert.notNull(asyncClient, "HttpAsyncClient must not be null"); - this.asyncClient = asyncClient; - } - - /** - * Return the {@code HttpAsyncClient} used for - * {@linkplain #createAsyncRequest(URI, HttpMethod) synchronous execution}. - * @since 4.3.10 - * @see #getHttpClient() - */ - public HttpAsyncClient getAsyncClient() { - return this.asyncClient; - } - - /** - * Set the {@code CloseableHttpAsyncClient} used for - * {@linkplain #createAsyncRequest(URI, HttpMethod) asynchronous execution}. - * @deprecated as of 4.3.10, in favor of {@link #setAsyncClient(HttpAsyncClient)} - */ - @Deprecated - public void setHttpAsyncClient(CloseableHttpAsyncClient asyncClient) { - this.asyncClient = asyncClient; - } - - /** - * Return the {@code CloseableHttpAsyncClient} used for - * {@linkplain #createAsyncRequest(URI, HttpMethod) asynchronous execution}. - * @deprecated as of 4.3.10, in favor of {@link #getAsyncClient()} - */ - @Deprecated - public CloseableHttpAsyncClient getHttpAsyncClient() { - Assert.state(this.asyncClient instanceof CloseableHttpAsyncClient, - "No CloseableHttpAsyncClient - use getAsyncClient() instead"); - return (CloseableHttpAsyncClient) this.asyncClient; - } - - - @Override - public void afterPropertiesSet() { - startAsyncClient(); - } - - private HttpAsyncClient startAsyncClient() { - HttpAsyncClient client = getAsyncClient(); - if (client instanceof CloseableHttpAsyncClient) { - @SuppressWarnings("resource") - CloseableHttpAsyncClient closeableAsyncClient = (CloseableHttpAsyncClient) client; - if (!closeableAsyncClient.isRunning()) { - closeableAsyncClient.start(); - } - } - return client; - } - - @Override - public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException { - HttpAsyncClient client = startAsyncClient(); - - HttpUriRequest httpRequest = createHttpUriRequest(httpMethod, uri); - postProcessHttpRequest(httpRequest); - HttpContext context = createHttpContext(httpMethod, uri); - if (context == null) { - context = HttpClientContext.create(); - } - - // Request configuration not set in the context - if (context.getAttribute(HttpClientContext.REQUEST_CONFIG) == null) { - // Use request configuration given by the user, when available - RequestConfig config = null; - if (httpRequest instanceof Configurable) { - config = ((Configurable) httpRequest).getConfig(); - } - if (config == null) { - config = createRequestConfig(client); - } - if (config != null) { - context.setAttribute(HttpClientContext.REQUEST_CONFIG, config); - } - } - - return new HttpComponentsAsyncClientHttpRequest(client, httpRequest, context); - } - - @Override - public void destroy() throws Exception { - try { - super.destroy(); - } - finally { - HttpAsyncClient asyncClient = getAsyncClient(); - if (asyncClient instanceof Closeable) { - ((Closeable) asyncClient).close(); - } - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpResponse.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpResponse.java deleted file mode 100644 index 54297db86008..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpResponse.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; - -import org.springframework.http.HttpHeaders; -import org.springframework.lang.Nullable; -import org.springframework.util.StreamUtils; - -/** - * {@link ClientHttpResponse} implementation based on - * Apache HttpComponents HttpAsyncClient. - * - *

    Created via the {@link HttpComponentsAsyncClientHttpRequest}. - * - * @author Oleg Kalnichevski - * @author Arjen Poutsma - * @since 4.0 - * @see HttpComponentsAsyncClientHttpRequest#executeAsync() - * @deprecated as of Spring 5.0, in favor of - * {@link org.springframework.http.client.reactive.HttpComponentsClientHttpConnector} - */ -@Deprecated -final class HttpComponentsAsyncClientHttpResponse extends AbstractClientHttpResponse { - - private final HttpResponse httpResponse; - - @Nullable - private HttpHeaders headers; - - - HttpComponentsAsyncClientHttpResponse(HttpResponse httpResponse) { - this.httpResponse = httpResponse; - } - - - @Override - public int getRawStatusCode() throws IOException { - return this.httpResponse.getStatusLine().getStatusCode(); - } - - @Override - public String getStatusText() throws IOException { - return this.httpResponse.getStatusLine().getReasonPhrase(); - } - - @Override - public HttpHeaders getHeaders() { - if (this.headers == null) { - this.headers = new HttpHeaders(); - for (Header header : this.httpResponse.getAllHeaders()) { - this.headers.add(header.getName(), header.getValue()); - } - } - return this.headers; - } - - @Override - public InputStream getBody() throws IOException { - HttpEntity entity = this.httpResponse.getEntity(); - return (entity != null ? entity.getContent() : StreamUtils.emptyInput()); - } - - @Override - public void close() { - // HTTP responses returned by async HTTP client are not bound to an - // active connection and do not have to deallocate any resources... - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/InterceptingAsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/InterceptingAsyncClientHttpRequest.java deleted file mode 100644 index 4dd835f29404..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/InterceptingAsyncClientHttpRequest.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.net.URI; -import java.util.Iterator; -import java.util.List; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; -import org.springframework.util.Assert; -import org.springframework.util.StreamUtils; -import org.springframework.util.concurrent.ListenableFuture; - -/** - * An {@link AsyncClientHttpRequest} wrapper that enriches it proceeds the actual - * request execution with calling the registered interceptors. - * - * @author Jakub Narloch - * @author Rossen Stoyanchev - * @see InterceptingAsyncClientHttpRequestFactory - * @deprecated as of Spring 5.0, with no direct replacement - */ -@Deprecated -class InterceptingAsyncClientHttpRequest extends AbstractBufferingAsyncClientHttpRequest { - - private AsyncClientHttpRequestFactory requestFactory; - - private List interceptors; - - private URI uri; - - private HttpMethod httpMethod; - - - /** - * Create new instance of {@link InterceptingAsyncClientHttpRequest}. - * @param requestFactory the async request factory - * @param interceptors the list of interceptors - * @param uri the request URI - * @param httpMethod the HTTP method - */ - public InterceptingAsyncClientHttpRequest(AsyncClientHttpRequestFactory requestFactory, - List interceptors, URI uri, HttpMethod httpMethod) { - - this.requestFactory = requestFactory; - this.interceptors = interceptors; - this.uri = uri; - this.httpMethod = httpMethod; - } - - - @Override - protected ListenableFuture executeInternal(HttpHeaders headers, byte[] body) - throws IOException { - - return new AsyncRequestExecution().executeAsync(this, body); - } - - @Override - public HttpMethod getMethod() { - return this.httpMethod; - } - - @Override - public String getMethodValue() { - return this.httpMethod.name(); - } - - @Override - public URI getURI() { - return this.uri; - } - - - private class AsyncRequestExecution implements AsyncClientHttpRequestExecution { - - private Iterator iterator; - - public AsyncRequestExecution() { - this.iterator = interceptors.iterator(); - } - - @Override - public ListenableFuture executeAsync(HttpRequest request, byte[] body) - throws IOException { - - if (this.iterator.hasNext()) { - AsyncClientHttpRequestInterceptor interceptor = this.iterator.next(); - return interceptor.intercept(request, body, this); - } - else { - URI uri = request.getURI(); - HttpMethod method = request.getMethod(); - HttpHeaders headers = request.getHeaders(); - - Assert.state(method != null, "No standard HTTP method"); - AsyncClientHttpRequest delegate = requestFactory.createAsyncRequest(uri, method); - delegate.getHeaders().putAll(headers); - if (body.length > 0) { - StreamUtils.copy(body, delegate.getBody()); - } - - return delegate.executeAsync(); - } - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/InterceptingAsyncClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/InterceptingAsyncClientHttpRequestFactory.java deleted file mode 100644 index 9721e46cc2cc..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/InterceptingAsyncClientHttpRequestFactory.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.net.URI; -import java.util.Collections; -import java.util.List; - -import org.springframework.http.HttpMethod; -import org.springframework.lang.Nullable; - -/** - * Wrapper for a {@link AsyncClientHttpRequestFactory} that has support for - * {@link AsyncClientHttpRequestInterceptor AsyncClientHttpRequestInterceptors}. - * - * @author Jakub Narloch - * @since 4.3 - * @see InterceptingAsyncClientHttpRequest - * @deprecated as of Spring 5.0, with no direct replacement - */ -@Deprecated -public class InterceptingAsyncClientHttpRequestFactory implements AsyncClientHttpRequestFactory { - - private AsyncClientHttpRequestFactory delegate; - - private List interceptors; - - - /** - * Create new instance of {@link InterceptingAsyncClientHttpRequestFactory} - * with delegated request factory and list of interceptors. - * @param delegate the request factory to delegate to - * @param interceptors the list of interceptors to use - */ - public InterceptingAsyncClientHttpRequestFactory(AsyncClientHttpRequestFactory delegate, - @Nullable List interceptors) { - - this.delegate = delegate; - this.interceptors = (interceptors != null ? interceptors : Collections.emptyList()); - } - - - @Override - public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod method) { - return new InterceptingAsyncClientHttpRequest(this.delegate, this.interceptors, uri, method); - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequest.java deleted file mode 100644 index c4c7d6f37d40..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequest.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.URI; -import java.util.concurrent.ExecutionException; - -import io.netty.bootstrap.Bootstrap; -import io.netty.buffer.ByteBufOutputStream; -import io.netty.buffer.Unpooled; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.handler.codec.http.DefaultFullHttpRequest; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.HttpVersion; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.SettableListenableFuture; - -/** - * {@link ClientHttpRequest} implementation based on Netty 4. - * - *

    Created via the {@link Netty4ClientHttpRequestFactory}. - * - * @author Arjen Poutsma - * @author Rossen Stoyanchev - * @author Brian Clozel - * @since 4.1.2 - * @deprecated as of Spring 5.0, in favor of - * {@link org.springframework.http.client.reactive.ReactorClientHttpConnector} - */ -@Deprecated -class Netty4ClientHttpRequest extends AbstractAsyncClientHttpRequest implements ClientHttpRequest { - - private final Bootstrap bootstrap; - - private final URI uri; - - private final HttpMethod method; - - private final ByteBufOutputStream body; - - - public Netty4ClientHttpRequest(Bootstrap bootstrap, URI uri, HttpMethod method) { - this.bootstrap = bootstrap; - this.uri = uri; - this.method = method; - this.body = new ByteBufOutputStream(Unpooled.buffer(1024)); - } - - - @Override - public HttpMethod getMethod() { - return this.method; - } - - @Override - public String getMethodValue() { - return this.method.name(); - } - - @Override - public URI getURI() { - return this.uri; - } - - @Override - public ClientHttpResponse execute() throws IOException { - try { - return executeAsync().get(); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - throw new IOException("Interrupted during request execution", ex); - } - catch (ExecutionException ex) { - if (ex.getCause() instanceof IOException) { - throw (IOException) ex.getCause(); - } - else { - throw new IOException(ex.getMessage(), ex.getCause()); - } - } - } - - @Override - protected OutputStream getBodyInternal(HttpHeaders headers) throws IOException { - return this.body; - } - - @Override - protected ListenableFuture executeInternal(final HttpHeaders headers) throws IOException { - final SettableListenableFuture responseFuture = new SettableListenableFuture<>(); - - ChannelFutureListener connectionListener = future -> { - if (future.isSuccess()) { - Channel channel = future.channel(); - channel.pipeline().addLast(new RequestExecuteHandler(responseFuture)); - FullHttpRequest nettyRequest = createFullHttpRequest(headers); - channel.writeAndFlush(nettyRequest); - } - else { - responseFuture.setException(future.cause()); - } - }; - - this.bootstrap.connect(this.uri.getHost(), getPort(this.uri)).addListener(connectionListener); - return responseFuture; - } - - private FullHttpRequest createFullHttpRequest(HttpHeaders headers) { - io.netty.handler.codec.http.HttpMethod nettyMethod = - io.netty.handler.codec.http.HttpMethod.valueOf(this.method.name()); - - String authority = this.uri.getRawAuthority(); - String path = this.uri.toString().substring(this.uri.toString().indexOf(authority) + authority.length()); - FullHttpRequest nettyRequest = new DefaultFullHttpRequest( - HttpVersion.HTTP_1_1, nettyMethod, path, this.body.buffer()); - - nettyRequest.headers().set(HttpHeaders.HOST, this.uri.getHost() + ":" + getPort(this.uri)); - nettyRequest.headers().set(HttpHeaders.CONNECTION, "close"); - headers.forEach((headerName, headerValues) -> nettyRequest.headers().add(headerName, headerValues)); - if (!nettyRequest.headers().contains(HttpHeaders.CONTENT_LENGTH) && this.body.buffer().readableBytes() > 0) { - nettyRequest.headers().set(HttpHeaders.CONTENT_LENGTH, this.body.buffer().readableBytes()); - } - - return nettyRequest; - } - - private static int getPort(URI uri) { - int port = uri.getPort(); - if (port == -1) { - if ("http".equalsIgnoreCase(uri.getScheme())) { - port = 80; - } - else if ("https".equalsIgnoreCase(uri.getScheme())) { - port = 443; - } - } - return port; - } - - - /** - * A SimpleChannelInboundHandler to update the given SettableListenableFuture. - */ - private static class RequestExecuteHandler extends SimpleChannelInboundHandler { - - private final SettableListenableFuture responseFuture; - - public RequestExecuteHandler(SettableListenableFuture responseFuture) { - this.responseFuture = responseFuture; - } - - @Override - protected void channelRead0(ChannelHandlerContext context, FullHttpResponse response) throws Exception { - this.responseFuture.set(new Netty4ClientHttpResponse(context, response)); - } - - @Override - public void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception { - this.responseFuture.setException(cause); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequestFactory.java deleted file mode 100644 index bc0c83472fb9..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequestFactory.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.net.URI; -import java.util.concurrent.TimeUnit; - -import javax.net.ssl.SSLException; - -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.ChannelConfig; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.SocketChannelConfig; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.codec.http.HttpClientCodec; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslContextBuilder; -import io.netty.handler.timeout.ReadTimeoutHandler; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.http.HttpMethod; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * {@link org.springframework.http.client.ClientHttpRequestFactory} implementation - * that uses Netty 4 to create requests. - * - *

    Allows to use a pre-configured {@link EventLoopGroup} instance: useful for - * sharing across multiple clients. - * - *

    Note that this implementation consistently closes the HTTP connection on each - * request. - * - * @author Arjen Poutsma - * @author Rossen Stoyanchev - * @author Brian Clozel - * @author Mark Paluch - * @since 4.1.2 - * @deprecated as of Spring 5.0, in favor of - * {@link org.springframework.http.client.reactive.ReactorClientHttpConnector} - */ -@Deprecated -public class Netty4ClientHttpRequestFactory implements ClientHttpRequestFactory, - AsyncClientHttpRequestFactory, InitializingBean, DisposableBean { - - /** - * The default maximum response size. - * @see #setMaxResponseSize(int) - */ - public static final int DEFAULT_MAX_RESPONSE_SIZE = 1024 * 1024 * 10; - - - private final EventLoopGroup eventLoopGroup; - - private final boolean defaultEventLoopGroup; - - private int maxResponseSize = DEFAULT_MAX_RESPONSE_SIZE; - - @Nullable - private SslContext sslContext; - - private int connectTimeout = -1; - - private int readTimeout = -1; - - @Nullable - private volatile Bootstrap bootstrap; - - - /** - * Create a new {@code Netty4ClientHttpRequestFactory} with a default - * {@link NioEventLoopGroup}. - */ - public Netty4ClientHttpRequestFactory() { - int ioWorkerCount = Runtime.getRuntime().availableProcessors() * 2; - this.eventLoopGroup = new NioEventLoopGroup(ioWorkerCount); - this.defaultEventLoopGroup = true; - } - - /** - * Create a new {@code Netty4ClientHttpRequestFactory} with the given - * {@link EventLoopGroup}. - *

    NOTE: the given group will not be - * {@linkplain EventLoopGroup#shutdownGracefully() shutdown} by this factory; - * doing so becomes the responsibility of the caller. - */ - public Netty4ClientHttpRequestFactory(EventLoopGroup eventLoopGroup) { - Assert.notNull(eventLoopGroup, "EventLoopGroup must not be null"); - this.eventLoopGroup = eventLoopGroup; - this.defaultEventLoopGroup = false; - } - - - /** - * Set the default maximum response size. - *

    By default this is set to {@link #DEFAULT_MAX_RESPONSE_SIZE}. - * @since 4.1.5 - * @see HttpObjectAggregator#HttpObjectAggregator(int) - */ - public void setMaxResponseSize(int maxResponseSize) { - this.maxResponseSize = maxResponseSize; - } - - /** - * Set the SSL context. When configured it is used to create and insert an - * {@link io.netty.handler.ssl.SslHandler} in the channel pipeline. - *

    A default client SslContext is configured if none has been provided. - */ - public void setSslContext(SslContext sslContext) { - this.sslContext = sslContext; - } - - /** - * Set the underlying connect timeout (in milliseconds). - * A timeout value of 0 specifies an infinite timeout. - * @see ChannelConfig#setConnectTimeoutMillis(int) - */ - public void setConnectTimeout(int connectTimeout) { - this.connectTimeout = connectTimeout; - } - - /** - * Set the underlying URLConnection's read timeout (in milliseconds). - * A timeout value of 0 specifies an infinite timeout. - * @see ReadTimeoutHandler - */ - public void setReadTimeout(int readTimeout) { - this.readTimeout = readTimeout; - } - - - @Override - public void afterPropertiesSet() { - if (this.sslContext == null) { - this.sslContext = getDefaultClientSslContext(); - } - } - - private SslContext getDefaultClientSslContext() { - try { - return SslContextBuilder.forClient().build(); - } - catch (SSLException ex) { - throw new IllegalStateException("Could not create default client SslContext", ex); - } - } - - - @Override - public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { - return createRequestInternal(uri, httpMethod); - } - - @Override - public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException { - return createRequestInternal(uri, httpMethod); - } - - private Netty4ClientHttpRequest createRequestInternal(URI uri, HttpMethod httpMethod) { - return new Netty4ClientHttpRequest(getBootstrap(uri), uri, httpMethod); - } - - private Bootstrap getBootstrap(URI uri) { - boolean isSecure = (uri.getPort() == 443 || "https".equalsIgnoreCase(uri.getScheme())); - if (isSecure) { - return buildBootstrap(uri, true); - } - else { - Bootstrap bootstrap = this.bootstrap; - if (bootstrap == null) { - bootstrap = buildBootstrap(uri, false); - this.bootstrap = bootstrap; - } - return bootstrap; - } - } - - private Bootstrap buildBootstrap(URI uri, boolean isSecure) { - Bootstrap bootstrap = new Bootstrap(); - bootstrap.group(this.eventLoopGroup).channel(NioSocketChannel.class) - .handler(new ChannelInitializer() { - @Override - protected void initChannel(SocketChannel channel) throws Exception { - configureChannel(channel.config()); - ChannelPipeline pipeline = channel.pipeline(); - if (isSecure) { - Assert.notNull(sslContext, "sslContext should not be null"); - pipeline.addLast(sslContext.newHandler(channel.alloc(), uri.getHost(), uri.getPort())); - } - pipeline.addLast(new HttpClientCodec()); - pipeline.addLast(new HttpObjectAggregator(maxResponseSize)); - if (readTimeout > 0) { - pipeline.addLast(new ReadTimeoutHandler(readTimeout, - TimeUnit.MILLISECONDS)); - } - } - }); - return bootstrap; - } - - /** - * Template method for changing properties on the given {@link SocketChannelConfig}. - *

    The default implementation sets the connect timeout based on the set property. - * @param config the channel configuration - */ - protected void configureChannel(SocketChannelConfig config) { - if (this.connectTimeout >= 0) { - config.setConnectTimeoutMillis(this.connectTimeout); - } - } - - - @Override - public void destroy() throws InterruptedException { - if (this.defaultEventLoopGroup) { - // Clean up the EventLoopGroup if we created it in the constructor - this.eventLoopGroup.shutdownGracefully().sync(); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpResponse.java b/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpResponse.java deleted file mode 100644 index 6ac0de0a19e6..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpResponse.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import io.netty.buffer.ByteBufInputStream; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.FullHttpResponse; - -import org.springframework.http.HttpHeaders; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * {@link ClientHttpResponse} implementation based on Netty 4. - * - * @author Arjen Poutsma - * @since 4.1.2 - * @deprecated as of Spring 5.0, in favor of - * {@link org.springframework.http.client.reactive.ReactorClientHttpConnector} - */ -@Deprecated -class Netty4ClientHttpResponse extends AbstractClientHttpResponse { - - private final ChannelHandlerContext context; - - private final FullHttpResponse nettyResponse; - - private final ByteBufInputStream body; - - @Nullable - private volatile HttpHeaders headers; - - - public Netty4ClientHttpResponse(ChannelHandlerContext context, FullHttpResponse nettyResponse) { - Assert.notNull(context, "ChannelHandlerContext must not be null"); - Assert.notNull(nettyResponse, "FullHttpResponse must not be null"); - this.context = context; - this.nettyResponse = nettyResponse; - this.body = new ByteBufInputStream(this.nettyResponse.content()); - this.nettyResponse.retain(); - } - - - @Override - public int getRawStatusCode() throws IOException { - return this.nettyResponse.getStatus().code(); - } - - @Override - public String getStatusText() throws IOException { - return this.nettyResponse.getStatus().reasonPhrase(); - } - - @Override - public HttpHeaders getHeaders() { - HttpHeaders headers = this.headers; - if (headers == null) { - headers = new HttpHeaders(); - for (Map.Entry entry : this.nettyResponse.headers()) { - headers.add(entry.getKey(), entry.getValue()); - } - this.headers = headers; - } - return headers; - } - - @Override - public InputStream getBody() throws IOException { - return this.body; - } - - @Override - public void close() { - this.nettyResponse.release(); - this.context.close(); - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttp3AsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/OkHttp3AsyncClientHttpRequest.java deleted file mode 100644 index ee8d2eb23394..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/OkHttp3AsyncClientHttpRequest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.net.URI; - -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.SettableListenableFuture; - -/** - * {@link AsyncClientHttpRequest} implementation based on OkHttp 3.x. - * - *

    Created via the {@link OkHttp3ClientHttpRequestFactory}. - * - * @author Luciano Leggieri - * @author Arjen Poutsma - * @author Roy Clarkson - * @since 4.3 - * @deprecated as of Spring 5.0, with no direct replacement - */ -@Deprecated -class OkHttp3AsyncClientHttpRequest extends AbstractBufferingAsyncClientHttpRequest { - - private final OkHttpClient client; - - private final URI uri; - - private final HttpMethod method; - - - public OkHttp3AsyncClientHttpRequest(OkHttpClient client, URI uri, HttpMethod method) { - this.client = client; - this.uri = uri; - this.method = method; - } - - - @Override - public HttpMethod getMethod() { - return this.method; - } - - @Override - public String getMethodValue() { - return this.method.name(); - } - - @Override - public URI getURI() { - return this.uri; - } - - @Override - protected ListenableFuture executeInternal(HttpHeaders headers, byte[] content) - throws IOException { - - Request request = OkHttp3ClientHttpRequestFactory.buildRequest(headers, content, this.uri, this.method); - return new OkHttpListenableFuture(this.client.newCall(request)); - } - - - private static class OkHttpListenableFuture extends SettableListenableFuture { - - private final Call call; - - public OkHttpListenableFuture(Call call) { - this.call = call; - this.call.enqueue(new Callback() { - @Override - public void onResponse(Call call, Response response) { - set(new OkHttp3ClientHttpResponse(response)); - } - @Override - public void onFailure(Call call, IOException ex) { - setException(ex); - } - }); - } - - @Override - protected void interruptTask() { - this.call.cancel(); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactory.java index f23febf88d5c..e81bbe61a4ca 100644 --- a/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,9 +42,7 @@ * @author Roy Clarkson * @since 4.3 */ -@SuppressWarnings("deprecation") -public class OkHttp3ClientHttpRequestFactory - implements ClientHttpRequestFactory, AsyncClientHttpRequestFactory, DisposableBean { +public class OkHttp3ClientHttpRequestFactory implements ClientHttpRequestFactory, DisposableBean { private OkHttpClient client; @@ -106,11 +104,6 @@ public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) { return new OkHttp3ClientHttpRequest(this.client, uri, httpMethod); } - @Override - public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) { - return new OkHttp3AsyncClientHttpRequest(this.client, uri, httpMethod); - } - @Override public void destroy() throws IOException { diff --git a/spring-web/src/main/java/org/springframework/http/client/SimpleBufferingAsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/SimpleBufferingAsyncClientHttpRequest.java deleted file mode 100644 index ec2672534d11..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/SimpleBufferingAsyncClientHttpRequest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URISyntaxException; - -import org.springframework.core.task.AsyncListenableTaskExecutor; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.concurrent.ListenableFuture; - -/** - * {@link org.springframework.http.client.ClientHttpRequest} implementation that uses - * standard JDK facilities to execute buffered requests. Created via the - * {@link org.springframework.http.client.SimpleClientHttpRequestFactory}. - * - * @author Arjen Poutsma - * @since 3.0 - * @see org.springframework.http.client.SimpleClientHttpRequestFactory#createRequest - * @deprecated as of Spring 5.0, with no direct replacement - */ -@Deprecated -final class SimpleBufferingAsyncClientHttpRequest extends AbstractBufferingAsyncClientHttpRequest { - - private final HttpURLConnection connection; - - private final boolean outputStreaming; - - private final AsyncListenableTaskExecutor taskExecutor; - - - SimpleBufferingAsyncClientHttpRequest(HttpURLConnection connection, - boolean outputStreaming, AsyncListenableTaskExecutor taskExecutor) { - - this.connection = connection; - this.outputStreaming = outputStreaming; - this.taskExecutor = taskExecutor; - } - - - @Override - public String getMethodValue() { - return this.connection.getRequestMethod(); - } - - @Override - public URI getURI() { - try { - return this.connection.getURL().toURI(); - } - catch (URISyntaxException ex) { - throw new IllegalStateException("Could not get HttpURLConnection URI: " + ex.getMessage(), ex); - } - } - - @Override - protected ListenableFuture executeInternal( - HttpHeaders headers, byte[] bufferedOutput) throws IOException { - - return this.taskExecutor.submitListenable(() -> { - SimpleBufferingClientHttpRequest.addHeaders(this.connection, headers); - // JDK <1.8 doesn't support getOutputStream with HTTP DELETE - if (getMethod() == HttpMethod.DELETE && bufferedOutput.length == 0) { - this.connection.setDoOutput(false); - } - if (this.connection.getDoOutput() && this.outputStreaming) { - this.connection.setFixedLengthStreamingMode(bufferedOutput.length); - } - this.connection.connect(); - if (this.connection.getDoOutput()) { - FileCopyUtils.copy(bufferedOutput, this.connection.getOutputStream()); - } - else { - // Immediately trigger the request in a no-output scenario as well - this.connection.getResponseCode(); - } - return new SimpleClientHttpResponse(this.connection); - }); - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java index 4674df6e476c..091b345a26fd 100644 --- a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,10 +23,8 @@ import java.net.URL; import java.net.URLConnection; -import org.springframework.core.task.AsyncListenableTaskExecutor; import org.springframework.http.HttpMethod; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; /** * {@link ClientHttpRequestFactory} implementation that uses standard JDK facilities. @@ -37,8 +35,7 @@ * @see java.net.HttpURLConnection * @see HttpComponentsClientHttpRequestFactory */ -@SuppressWarnings("deprecation") -public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory, AsyncClientHttpRequestFactory { +public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory { private static final int DEFAULT_CHUNK_SIZE = 4096; @@ -56,9 +53,6 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory, private boolean outputStreaming = true; - @Nullable - private AsyncListenableTaskExecutor taskExecutor; - /** * Set the {@link Proxy} to use for this request factory. @@ -130,15 +124,6 @@ public void setOutputStreaming(boolean outputStreaming) { this.outputStreaming = outputStreaming; } - /** - * Set the task executor for this request factory. Setting this property is required - * for {@linkplain #createAsyncRequest(URI, HttpMethod) creating asynchronous requests}. - * @param taskExecutor the task executor - */ - public void setTaskExecutor(AsyncListenableTaskExecutor taskExecutor) { - this.taskExecutor = taskExecutor; - } - @Override public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { @@ -153,27 +138,6 @@ public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IO } } - /** - * {@inheritDoc} - *

    Setting the {@link #setTaskExecutor taskExecutor} property is required before calling this method. - */ - @Override - public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException { - Assert.state(this.taskExecutor != null, "Asynchronous execution requires TaskExecutor to be set"); - - HttpURLConnection connection = openConnection(uri.toURL(), this.proxy); - prepareConnection(connection, httpMethod.name()); - - if (this.bufferRequestBody) { - return new SimpleBufferingAsyncClientHttpRequest( - connection, this.outputStreaming, this.taskExecutor); - } - else { - return new SimpleStreamingAsyncClientHttpRequest( - connection, this.chunkSize, this.outputStreaming, this.taskExecutor); - } - } - /** * Opens and returns a connection to the given URL. *

    The default implementation uses the given {@linkplain #setProxy(java.net.Proxy) proxy} - diff --git a/spring-web/src/main/java/org/springframework/http/client/SimpleStreamingAsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/SimpleStreamingAsyncClientHttpRequest.java deleted file mode 100644 index eb8ef1adf8d8..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/SimpleStreamingAsyncClientHttpRequest.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URISyntaxException; - -import org.springframework.core.task.AsyncListenableTaskExecutor; -import org.springframework.http.HttpHeaders; -import org.springframework.lang.Nullable; -import org.springframework.util.StreamUtils; -import org.springframework.util.concurrent.ListenableFuture; - -/** - * {@link org.springframework.http.client.ClientHttpRequest} implementation - * that uses standard Java facilities to execute streaming requests. Created - * via the {@link org.springframework.http.client.SimpleClientHttpRequestFactory}. - * - * @author Arjen Poutsma - * @since 3.0 - * @see org.springframework.http.client.SimpleClientHttpRequestFactory#createRequest - * @see org.springframework.http.client.support.AsyncHttpAccessor - * @see org.springframework.web.client.AsyncRestTemplate - * @deprecated as of Spring 5.0, with no direct replacement - */ -@Deprecated -final class SimpleStreamingAsyncClientHttpRequest extends AbstractAsyncClientHttpRequest { - - private final HttpURLConnection connection; - - private final int chunkSize; - - @Nullable - private OutputStream body; - - private final boolean outputStreaming; - - private final AsyncListenableTaskExecutor taskExecutor; - - - SimpleStreamingAsyncClientHttpRequest(HttpURLConnection connection, int chunkSize, - boolean outputStreaming, AsyncListenableTaskExecutor taskExecutor) { - - this.connection = connection; - this.chunkSize = chunkSize; - this.outputStreaming = outputStreaming; - this.taskExecutor = taskExecutor; - } - - - @Override - public String getMethodValue() { - return this.connection.getRequestMethod(); - } - - @Override - public URI getURI() { - try { - return this.connection.getURL().toURI(); - } - catch (URISyntaxException ex) { - throw new IllegalStateException( - "Could not get HttpURLConnection URI: " + ex.getMessage(), ex); - } - } - - @Override - protected OutputStream getBodyInternal(HttpHeaders headers) throws IOException { - if (this.body == null) { - if (this.outputStreaming) { - long contentLength = headers.getContentLength(); - if (contentLength >= 0) { - this.connection.setFixedLengthStreamingMode(contentLength); - } - else { - this.connection.setChunkedStreamingMode(this.chunkSize); - } - } - SimpleBufferingClientHttpRequest.addHeaders(this.connection, headers); - this.connection.connect(); - this.body = this.connection.getOutputStream(); - } - return StreamUtils.nonClosing(this.body); - } - - @Override - protected ListenableFuture executeInternal(HttpHeaders headers) throws IOException { - return this.taskExecutor.submitListenable(() -> { - try { - if (this.body != null) { - this.body.close(); - } - else { - SimpleBufferingClientHttpRequest.addHeaders(this.connection, headers); - this.connection.connect(); - // Immediately trigger the request in a no-output scenario as well - this.connection.getResponseCode(); - } - } - catch (IOException ex) { - // ignore - } - return new SimpleClientHttpResponse(this.connection); - }); - - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/support/AsyncHttpAccessor.java b/spring-web/src/main/java/org/springframework/http/client/support/AsyncHttpAccessor.java deleted file mode 100644 index faf8c309c727..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/support/AsyncHttpAccessor.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client.support; - -import java.io.IOException; -import java.net.URI; - -import org.apache.commons.logging.Log; - -import org.springframework.http.HttpLogging; -import org.springframework.http.HttpMethod; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Base class for {@link org.springframework.web.client.AsyncRestTemplate} - * and other HTTP accessing gateway helpers, defining common properties - * such as the {@link org.springframework.http.client.AsyncClientHttpRequestFactory} - * to operate on. - * - *

    Not intended to be used directly. See - * {@link org.springframework.web.client.AsyncRestTemplate}. - * - * @author Arjen Poutsma - * @since 4.0 - * @see org.springframework.web.client.AsyncRestTemplate - * @deprecated as of Spring 5.0, with no direct replacement - */ -@Deprecated -public class AsyncHttpAccessor { - - /** Logger available to subclasses. */ - protected final Log logger = HttpLogging.forLogName(getClass()); - - @Nullable - private org.springframework.http.client.AsyncClientHttpRequestFactory asyncRequestFactory; - - - /** - * Set the request factory that this accessor uses for obtaining {@link - * org.springframework.http.client.ClientHttpRequest HttpRequests}. - */ - public void setAsyncRequestFactory( - org.springframework.http.client.AsyncClientHttpRequestFactory asyncRequestFactory) { - - Assert.notNull(asyncRequestFactory, "AsyncClientHttpRequestFactory must not be null"); - this.asyncRequestFactory = asyncRequestFactory; - } - - /** - * Return the request factory that this accessor uses for obtaining {@link - * org.springframework.http.client.ClientHttpRequest HttpRequests}. - */ - public org.springframework.http.client.AsyncClientHttpRequestFactory getAsyncRequestFactory() { - Assert.state(this.asyncRequestFactory != null, "No AsyncClientHttpRequestFactory set"); - return this.asyncRequestFactory; - } - - /** - * Create a new {@link org.springframework.http.client.AsyncClientHttpRequest} via this template's - * {@link org.springframework.http.client.AsyncClientHttpRequestFactory}. - * @param url the URL to connect to - * @param method the HTTP method to execute (GET, POST, etc.) - * @return the created request - * @throws IOException in case of I/O errors - */ - protected org.springframework.http.client.AsyncClientHttpRequest createAsyncRequest(URI url, HttpMethod method) - throws IOException { - - org.springframework.http.client.AsyncClientHttpRequest request = - getAsyncRequestFactory().createAsyncRequest(url, method); - if (logger.isDebugEnabled()) { - logger.debug("Created asynchronous " + method.name() + " request for \"" + url + "\""); - } - return request; - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/support/InterceptingAsyncHttpAccessor.java b/spring-web/src/main/java/org/springframework/http/client/support/InterceptingAsyncHttpAccessor.java deleted file mode 100644 index 9f8586ec84e1..000000000000 --- a/spring-web/src/main/java/org/springframework/http/client/support/InterceptingAsyncHttpAccessor.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client.support; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.util.CollectionUtils; - -/** - * The HTTP accessor that extends the base {@link AsyncHttpAccessor} with - * request intercepting functionality. - * - * @author Jakub Narloch - * @author Rossen Stoyanchev - * @since 4.3 - * @deprecated as of Spring 5.0, with no direct replacement - */ -@Deprecated -public abstract class InterceptingAsyncHttpAccessor extends AsyncHttpAccessor { - - private List interceptors = - new ArrayList<>(); - - - /** - * Set the request interceptors that this accessor should use. - * @param interceptors the list of interceptors - */ - public void setInterceptors(List interceptors) { - this.interceptors = interceptors; - } - - /** - * Return the request interceptor that this accessor uses. - */ - public List getInterceptors() { - return this.interceptors; - } - - - @Override - public org.springframework.http.client.AsyncClientHttpRequestFactory getAsyncRequestFactory() { - org.springframework.http.client.AsyncClientHttpRequestFactory delegate = super.getAsyncRequestFactory(); - if (!CollectionUtils.isEmpty(getInterceptors())) { - return new org.springframework.http.client.InterceptingAsyncClientHttpRequestFactory(delegate, getInterceptors()); - } - else { - return delegate; - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/client/AsyncRequestCallback.java b/spring-web/src/main/java/org/springframework/web/client/AsyncRequestCallback.java deleted file mode 100644 index 00e2fdd4ab94..000000000000 --- a/spring-web/src/main/java/org/springframework/web/client/AsyncRequestCallback.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.client; - -import java.io.IOException; - -/** - * Callback interface for code that operates on an - * {@link org.springframework.http.client.AsyncClientHttpRequest}. Allows to - * manipulate the request headers, and write to the request body. - * - *

    Used internally by the {@link AsyncRestTemplate}, but also useful for - * application code. - * - * @author Arjen Poutsma - * @since 4.0 - * @see org.springframework.web.client.AsyncRestTemplate#execute - * @deprecated as of Spring 5.0, in favor of - * {@link org.springframework.web.reactive.function.client.ExchangeFilterFunction} - */ -@FunctionalInterface -@Deprecated -public interface AsyncRequestCallback { - - /** - * Gets called by {@link AsyncRestTemplate#execute} with an opened {@code ClientHttpRequest}. - * Does not need to care about closing the request or about handling errors: - * this will all be handled by the {@code RestTemplate}. - * @param request the active HTTP request - * @throws java.io.IOException in case of I/O errors - */ - void doWithRequest(org.springframework.http.client.AsyncClientHttpRequest request) throws IOException; - -} diff --git a/spring-web/src/main/java/org/springframework/web/client/AsyncRestOperations.java b/spring-web/src/main/java/org/springframework/web/client/AsyncRestOperations.java deleted file mode 100644 index c9d92a2aff4b..000000000000 --- a/spring-web/src/main/java/org/springframework/web/client/AsyncRestOperations.java +++ /dev/null @@ -1,464 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.client; - -import java.net.URI; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Future; - -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.lang.Nullable; -import org.springframework.util.concurrent.ListenableFuture; - -/** - * Interface specifying a basic set of asynchronous RESTful operations. - * Implemented by {@link AsyncRestTemplate}. Not often used directly, but a useful - * option to enhance testability, as it can easily be mocked or stubbed. - * - * @author Arjen Poutsma - * @since 4.0 - * @see AsyncRestTemplate - * @see RestOperations - * @deprecated as of Spring 5.0, in favor of {@link org.springframework.web.reactive.function.client.WebClient} - */ -@Deprecated -public interface AsyncRestOperations { - - /** - * Expose the synchronous Spring RestTemplate to allow synchronous invocation. - */ - RestOperations getRestOperations(); - - - // GET - - /** - * Asynchronously retrieve an entity by doing a GET on the specified URL. - * The response is converted and stored in an {@link ResponseEntity}. - *

    URI Template variables are expanded using the given URI variables, if any. - * @param url the URL - * @param responseType the type of the return value - * @param uriVariables the variables to expand the template - * @return the entity wrapped in a {@link Future} - */ - ListenableFuture> getForEntity(String url, Class responseType, - Object... uriVariables) throws RestClientException; - - /** - * Asynchronously retrieve a representation by doing a GET on the URI template. - * The response is converted and stored in an {@link ResponseEntity}. - *

    URI Template variables are expanded using the given map. - * @param url the URL - * @param responseType the type of the return value - * @param uriVariables the map containing variables for the URI template - * @return the entity wrapped in a {@link Future} - */ - ListenableFuture> getForEntity(String url, Class responseType, - Map uriVariables) throws RestClientException; - - /** - * Asynchronously retrieve a representation by doing a GET on the URL. - * The response is converted and stored in an {@link ResponseEntity}. - * @param url the URL - * @param responseType the type of the return value - * @return the entity wrapped in a {@link Future} - */ - ListenableFuture> getForEntity(URI url, Class responseType) - throws RestClientException; - - - // HEAD - - /** - * Asynchronously retrieve all headers of the resource specified by the URI template. - *

    URI Template variables are expanded using the given URI variables, if any. - * @param url the URL - * @param uriVariables the variables to expand the template - * @return all HTTP headers of that resource wrapped in a {@link Future} - */ - ListenableFuture headForHeaders(String url, Object... uriVariables) - throws RestClientException; - - /** - * Asynchronously retrieve all headers of the resource specified by the URI template. - *

    URI Template variables are expanded using the given map. - * @param url the URL - * @param uriVariables the map containing variables for the URI template - * @return all HTTP headers of that resource wrapped in a {@link Future} - */ - ListenableFuture headForHeaders(String url, Map uriVariables) - throws RestClientException; - - /** - * Asynchronously retrieve all headers of the resource specified by the URL. - * @param url the URL - * @return all HTTP headers of that resource wrapped in a {@link Future} - */ - ListenableFuture headForHeaders(URI url) throws RestClientException; - - - // POST - - /** - * Create a new resource by POSTing the given object to the URI template, and - * asynchronously returns the value of the {@code Location} header. This header - * typically indicates where the new resource is stored. - *

    URI Template variables are expanded using the given URI variables, if any. - * @param url the URL - * @param request the Object to be POSTed (may be {@code null}) - * @param uriVariables the variables to expand the template - * @return the value for the {@code Location} header wrapped in a {@link Future} - * @see org.springframework.http.HttpEntity - */ - ListenableFuture postForLocation(String url, @Nullable HttpEntity request, Object... uriVariables) - throws RestClientException; - - /** - * Create a new resource by POSTing the given object to the URI template, and - * asynchronously returns the value of the {@code Location} header. This header - * typically indicates where the new resource is stored. - *

    URI Template variables are expanded using the given map. - * @param url the URL - * @param request the Object to be POSTed (may be {@code null}) - * @param uriVariables the variables to expand the template - * @return the value for the {@code Location} header wrapped in a {@link Future} - * @see org.springframework.http.HttpEntity - */ - ListenableFuture postForLocation(String url, @Nullable HttpEntity request, Map uriVariables) - throws RestClientException; - - /** - * Create a new resource by POSTing the given object to the URL, and asynchronously - * returns the value of the {@code Location} header. This header typically indicates - * where the new resource is stored. - * @param url the URL - * @param request the Object to be POSTed (may be {@code null}) - * @return the value for the {@code Location} header wrapped in a {@link Future} - * @see org.springframework.http.HttpEntity - */ - ListenableFuture postForLocation(URI url, @Nullable HttpEntity request) throws RestClientException; - - /** - * Create a new resource by POSTing the given object to the URI template, - * and asynchronously returns the response as {@link ResponseEntity}. - *

    URI Template variables are expanded using the given URI variables, if any. - * @param url the URL - * @param request the Object to be POSTed (may be {@code null}) - * @param uriVariables the variables to expand the template - * @return the entity wrapped in a {@link Future} - * @see org.springframework.http.HttpEntity - */ - ListenableFuture> postForEntity(String url, @Nullable HttpEntity request, - Class responseType, Object... uriVariables) throws RestClientException; - - /** - * Create a new resource by POSTing the given object to the URI template, - * and asynchronously returns the response as {@link ResponseEntity}. - *

    URI Template variables are expanded using the given map. - * @param url the URL - * @param request the Object to be POSTed (may be {@code null}) - * @param uriVariables the variables to expand the template - * @return the entity wrapped in a {@link Future} - * @see org.springframework.http.HttpEntity - */ - ListenableFuture> postForEntity(String url, @Nullable HttpEntity request, - Class responseType, Map uriVariables) throws RestClientException; - - /** - * Create a new resource by POSTing the given object to the URL, - * and asynchronously returns the response as {@link ResponseEntity}. - * @param url the URL - * @param request the Object to be POSTed (may be {@code null}) - * @return the entity wrapped in a {@link Future} - * @see org.springframework.http.HttpEntity - */ - ListenableFuture> postForEntity(URI url, @Nullable HttpEntity request, - Class responseType) throws RestClientException; - - - // PUT - - /** - * Create or update a resource by PUTting the given object to the URI. - *

    URI Template variables are expanded using the given URI variables, if any. - *

    The Future will return a {@code null} result upon completion. - * @param url the URL - * @param request the Object to be PUT (may be {@code null}) - * @param uriVariables the variables to expand the template - * @see HttpEntity - */ - ListenableFuture put(String url, @Nullable HttpEntity request, Object... uriVariables) - throws RestClientException; - - /** - * Creates a new resource by PUTting the given object to URI template. - *

    URI Template variables are expanded using the given map. - *

    The Future will return a {@code null} result upon completion. - * @param url the URL - * @param request the Object to be PUT (may be {@code null}) - * @param uriVariables the variables to expand the template - * @see HttpEntity - */ - ListenableFuture put(String url, @Nullable HttpEntity request, Map uriVariables) - throws RestClientException; - - /** - * Creates a new resource by PUTting the given object to URL. - *

    The Future will return a {@code null} result upon completion. - * @param url the URL - * @param request the Object to be PUT (may be {@code null}) - * @see HttpEntity - */ - ListenableFuture put(URI url, @Nullable HttpEntity request) throws RestClientException; - - - // DELETE - - /** - * Asynchronously delete the resources at the specified URI. - *

    URI Template variables are expanded using the given URI variables, if any. - *

    The Future will return a {@code null} result upon completion. - * @param url the URL - * @param uriVariables the variables to expand in the template - */ - ListenableFuture delete(String url, Object... uriVariables) throws RestClientException; - - /** - * Asynchronously delete the resources at the specified URI. - *

    URI Template variables are expanded using the given URI variables, if any. - *

    The Future will return a {@code null} result upon completion. - * @param url the URL - * @param uriVariables the variables to expand in the template - */ - ListenableFuture delete(String url, Map uriVariables) throws RestClientException; - - /** - * Asynchronously delete the resources at the specified URI. - *

    URI Template variables are expanded using the given URI variables, if any. - *

    The Future will return a {@code null} result upon completion. - * @param url the URL - */ - ListenableFuture delete(URI url) throws RestClientException; - - - // OPTIONS - - /** - * Asynchronously return the value of the Allow header for the given URI. - *

    URI Template variables are expanded using the given URI variables, if any. - * @param url the URL - * @param uriVariables the variables to expand in the template - * @return the value of the allow header wrapped in a {@link Future} - */ - ListenableFuture> optionsForAllow(String url, Object... uriVariables) - throws RestClientException; - - /** - * Asynchronously return the value of the Allow header for the given URI. - *

    URI Template variables are expanded using the given map. - * @param url the URL - * @param uriVariables the variables to expand in the template - * @return the value of the allow header wrapped in a {@link Future} - */ - ListenableFuture> optionsForAllow(String url, Map uriVariables) - throws RestClientException; - - /** - * Asynchronously return the value of the Allow header for the given URL. - * @param url the URL - * @return the value of the allow header wrapped in a {@link Future} - */ - ListenableFuture> optionsForAllow(URI url) throws RestClientException; - - - // exchange - - /** - * Asynchronously execute the HTTP method to the given URI template, writing the - * given request entity to the request, and returns the response as - * {@link ResponseEntity}. - *

    URI Template variables are expanded using the given URI variables, if any. - * @param url the URL - * @param method the HTTP method (GET, POST, etc) - * @param requestEntity the entity (headers and/or body) to write to the request - * (may be {@code null}) - * @param responseType the type of the return value - * @param uriVariables the variables to expand in the template - * @return the response as entity wrapped in a {@link Future} - */ - ListenableFuture> exchange(String url, HttpMethod method, - @Nullable HttpEntity requestEntity, Class responseType, Object... uriVariables) - throws RestClientException; - - /** - * Asynchronously execute the HTTP method to the given URI template, writing the - * given request entity to the request, and returns the response as - * {@link ResponseEntity}. - *

    URI Template variables are expanded using the given URI variables, if any. - * @param url the URL - * @param method the HTTP method (GET, POST, etc) - * @param requestEntity the entity (headers and/or body) to write to the request - * (may be {@code null}) - * @param responseType the type of the return value - * @param uriVariables the variables to expand in the template - * @return the response as entity wrapped in a {@link Future} - */ - ListenableFuture> exchange(String url, HttpMethod method, - @Nullable HttpEntity requestEntity, Class responseType, - Map uriVariables) throws RestClientException; - - /** - * Asynchronously execute the HTTP method to the given URI template, writing the - * given request entity to the request, and returns the response as - * {@link ResponseEntity}. - * @param url the URL - * @param method the HTTP method (GET, POST, etc) - * @param requestEntity the entity (headers and/or body) to write to the request - * (may be {@code null}) - * @param responseType the type of the return value - * @return the response as entity wrapped in a {@link Future} - */ - ListenableFuture> exchange(URI url, HttpMethod method, - @Nullable HttpEntity requestEntity, Class responseType) - throws RestClientException; - - /** - * Asynchronously execute the HTTP method to the given URI template, writing the given - * request entity to the request, and returns the response as {@link ResponseEntity}. - * The given {@link ParameterizedTypeReference} is used to pass generic type - * information: - *

    -	 * ParameterizedTypeReference<List<MyBean>> myBean =
    -	 *     new ParameterizedTypeReference<List<MyBean>>() {};
    -	 *
    -	 * ResponseEntity<List<MyBean>> response =
    -	 *     template.exchange("https://example.com",HttpMethod.GET, null, myBean);
    -	 * 
    - * @param url the URL - * @param method the HTTP method (GET, POST, etc) - * @param requestEntity the entity (headers and/or body) to write to the - * request (may be {@code null}) - * @param responseType the type of the return value - * @param uriVariables the variables to expand in the template - * @return the response as entity wrapped in a {@link Future} - */ - ListenableFuture> exchange(String url, HttpMethod method, - @Nullable HttpEntity requestEntity, ParameterizedTypeReference responseType, - Object... uriVariables) throws RestClientException; - - /** - * Asynchronously execute the HTTP method to the given URI template, writing the given - * request entity to the request, and returns the response as {@link ResponseEntity}. - * The given {@link ParameterizedTypeReference} is used to pass generic type - * information: - *
    -	 * ParameterizedTypeReference<List<MyBean>> myBean =
    -	 *     new ParameterizedTypeReference<List<MyBean>>() {};
    -	 *
    -	 * ResponseEntity<List<MyBean>> response =
    -	 *     template.exchange("https://example.com",HttpMethod.GET, null, myBean);
    -	 * 
    - * @param url the URL - * @param method the HTTP method (GET, POST, etc) - * @param requestEntity the entity (headers and/or body) to write to the request - * (may be {@code null}) - * @param responseType the type of the return value - * @param uriVariables the variables to expand in the template - * @return the response as entity wrapped in a {@link Future} - */ - ListenableFuture> exchange(String url, HttpMethod method, - @Nullable HttpEntity requestEntity, ParameterizedTypeReference responseType, - Map uriVariables) throws RestClientException; - - /** - * Asynchronously execute the HTTP method to the given URI template, writing the given - * request entity to the request, and returns the response as {@link ResponseEntity}. - * The given {@link ParameterizedTypeReference} is used to pass generic type - * information: - *
    -	 * ParameterizedTypeReference<List<MyBean>> myBean =
    -	 *     new ParameterizedTypeReference<List<MyBean>>() {};
    -	 *
    -	 * ResponseEntity<List<MyBean>> response =
    -	 *     template.exchange("https://example.com",HttpMethod.GET, null, myBean);
    -	 * 
    - * @param url the URL - * @param method the HTTP method (GET, POST, etc) - * @param requestEntity the entity (headers and/or body) to write to the request - * (may be {@code null}) - * @param responseType the type of the return value - * @return the response as entity wrapped in a {@link Future} - */ - ListenableFuture> exchange(URI url, HttpMethod method, - @Nullable HttpEntity requestEntity, ParameterizedTypeReference responseType) - throws RestClientException; - - - // general execution - - /** - * Asynchronously execute the HTTP method to the given URI template, preparing the - * request with the {@link AsyncRequestCallback}, and reading the response with a - * {@link ResponseExtractor}. - *

    URI Template variables are expanded using the given URI variables, if any. - * @param url the URL - * @param method the HTTP method (GET, POST, etc) - * @param requestCallback object that prepares the request - * @param responseExtractor object that extracts the return value from the response - * @param uriVariables the variables to expand in the template - * @return an arbitrary object, as returned by the {@link ResponseExtractor} - */ - ListenableFuture execute(String url, HttpMethod method, - @Nullable AsyncRequestCallback requestCallback, @Nullable ResponseExtractor responseExtractor, - Object... uriVariables) throws RestClientException; - - /** - * Asynchronously execute the HTTP method to the given URI template, preparing the - * request with the {@link AsyncRequestCallback}, and reading the response with a - * {@link ResponseExtractor}. - *

    URI Template variables are expanded using the given URI variables map. - * @param url the URL - * @param method the HTTP method (GET, POST, etc) - * @param requestCallback object that prepares the request - * @param responseExtractor object that extracts the return value from the response - * @param uriVariables the variables to expand in the template - * @return an arbitrary object, as returned by the {@link ResponseExtractor} - */ - ListenableFuture execute(String url, HttpMethod method, - @Nullable AsyncRequestCallback requestCallback, @Nullable ResponseExtractor responseExtractor, - Map uriVariables) throws RestClientException; - - /** - * Asynchronously execute the HTTP method to the given URL, preparing the request - * with the {@link AsyncRequestCallback}, and reading the response with a - * {@link ResponseExtractor}. - * @param url the URL - * @param method the HTTP method (GET, POST, etc) - * @param requestCallback object that prepares the request - * @param responseExtractor object that extracts the return value from the response - * @return an arbitrary object, as returned by the {@link ResponseExtractor} - */ - ListenableFuture execute(URI url, HttpMethod method, - @Nullable AsyncRequestCallback requestCallback, @Nullable ResponseExtractor responseExtractor) - throws RestClientException; - -} diff --git a/spring-web/src/main/java/org/springframework/web/client/AsyncRestTemplate.java b/spring-web/src/main/java/org/springframework/web/client/AsyncRestTemplate.java deleted file mode 100644 index f94359de4aeb..000000000000 --- a/spring-web/src/main/java/org/springframework/web/client/AsyncRestTemplate.java +++ /dev/null @@ -1,714 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.client; - -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.Type; -import java.net.URI; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutionException; - -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.core.task.AsyncListenableTaskExecutor; -import org.springframework.core.task.AsyncTaskExecutor; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpRequest; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureAdapter; -import org.springframework.web.util.DefaultUriBuilderFactory; -import org.springframework.web.util.UriTemplateHandler; - -/** - * Spring's central class for asynchronous client-side HTTP access. - * Exposes similar methods as {@link RestTemplate}, but returns {@link ListenableFuture} - * wrappers as opposed to concrete results. - * - *

    The {@code AsyncRestTemplate} exposes a synchronous {@link RestTemplate} via the - * {@link #getRestOperations()} method and shares its {@linkplain #setErrorHandler error handler} - * and {@linkplain #setMessageConverters message converters} with that {@code RestTemplate}. - * - *

    Note: by default {@code AsyncRestTemplate} relies on - * standard JDK facilities to establish HTTP connections. You can switch to use - * a different HTTP library such as Apache HttpComponents, Netty, and OkHttp by - * using a constructor accepting an {@link org.springframework.http.client.AsyncClientHttpRequestFactory}. - * - *

    For more information, please refer to the {@link RestTemplate} API documentation. - * - * @author Arjen Poutsma - * @since 4.0 - * @see RestTemplate - * @deprecated as of Spring 5.0, in favor of {@link org.springframework.web.reactive.function.client.WebClient} - */ -@Deprecated -public class AsyncRestTemplate extends org.springframework.http.client.support.InterceptingAsyncHttpAccessor - implements AsyncRestOperations { - - private final RestTemplate syncTemplate; - - - /** - * Create a new instance of the {@code AsyncRestTemplate} using default settings. - *

    This constructor uses a {@link SimpleClientHttpRequestFactory} in combination - * with a {@link SimpleAsyncTaskExecutor} for asynchronous execution. - */ - public AsyncRestTemplate() { - this(new SimpleAsyncTaskExecutor()); - } - - /** - * Create a new instance of the {@code AsyncRestTemplate} using the given - * {@link AsyncTaskExecutor}. - *

    This constructor uses a {@link SimpleClientHttpRequestFactory} in combination - * with the given {@code AsyncTaskExecutor} for asynchronous execution. - */ - public AsyncRestTemplate(AsyncListenableTaskExecutor taskExecutor) { - Assert.notNull(taskExecutor, "AsyncTaskExecutor must not be null"); - SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); - requestFactory.setTaskExecutor(taskExecutor); - this.syncTemplate = new RestTemplate(requestFactory); - setAsyncRequestFactory(requestFactory); - } - - /** - * Create a new instance of the {@code AsyncRestTemplate} using the given - * {@link org.springframework.http.client.AsyncClientHttpRequestFactory}. - *

    This constructor will cast the given asynchronous - * {@code AsyncClientHttpRequestFactory} to a {@link ClientHttpRequestFactory}. Since - * all implementations of {@code ClientHttpRequestFactory} provided in Spring also - * implement {@code AsyncClientHttpRequestFactory}, this should not result in a - * {@code ClassCastException}. - */ - public AsyncRestTemplate(org.springframework.http.client.AsyncClientHttpRequestFactory asyncRequestFactory) { - this(asyncRequestFactory, (ClientHttpRequestFactory) asyncRequestFactory); - } - - /** - * Creates a new instance of the {@code AsyncRestTemplate} using the given - * asynchronous and synchronous request factories. - * @param asyncRequestFactory the asynchronous request factory - * @param syncRequestFactory the synchronous request factory - */ - public AsyncRestTemplate(org.springframework.http.client.AsyncClientHttpRequestFactory asyncRequestFactory, - ClientHttpRequestFactory syncRequestFactory) { - - this(asyncRequestFactory, new RestTemplate(syncRequestFactory)); - } - - /** - * Create a new instance of the {@code AsyncRestTemplate} using the given - * {@link org.springframework.http.client.AsyncClientHttpRequestFactory} and synchronous {@link RestTemplate}. - * @param requestFactory the asynchronous request factory to use - * @param restTemplate the synchronous template to use - */ - public AsyncRestTemplate(org.springframework.http.client.AsyncClientHttpRequestFactory requestFactory, - RestTemplate restTemplate) { - - Assert.notNull(restTemplate, "RestTemplate must not be null"); - this.syncTemplate = restTemplate; - setAsyncRequestFactory(requestFactory); - } - - - /** - * Set the error handler. - *

    By default, AsyncRestTemplate uses a - * {@link org.springframework.web.client.DefaultResponseErrorHandler}. - */ - public void setErrorHandler(ResponseErrorHandler errorHandler) { - this.syncTemplate.setErrorHandler(errorHandler); - } - - /** - * Return the error handler. - */ - public ResponseErrorHandler getErrorHandler() { - return this.syncTemplate.getErrorHandler(); - } - - /** - * Configure default URI variable values. This is a shortcut for: - *

    -	 * DefaultUriTemplateHandler handler = new DefaultUriTemplateHandler();
    -	 * handler.setDefaultUriVariables(...);
    -	 *
    -	 * AsyncRestTemplate restTemplate = new AsyncRestTemplate();
    -	 * restTemplate.setUriTemplateHandler(handler);
    -	 * 
    - * @param defaultUriVariables the default URI variable values - * @since 4.3 - */ - @SuppressWarnings("deprecation") - public void setDefaultUriVariables(Map defaultUriVariables) { - UriTemplateHandler handler = this.syncTemplate.getUriTemplateHandler(); - if (handler instanceof DefaultUriBuilderFactory) { - ((DefaultUriBuilderFactory) handler).setDefaultUriVariables(defaultUriVariables); - } - else if (handler instanceof org.springframework.web.util.AbstractUriTemplateHandler) { - ((org.springframework.web.util.AbstractUriTemplateHandler) handler) - .setDefaultUriVariables(defaultUriVariables); - } - else { - throw new IllegalArgumentException( - "This property is not supported with the configured UriTemplateHandler."); - } - } - - /** - * This property has the same purpose as the corresponding property on the - * {@code RestTemplate}. For more details see - * {@link RestTemplate#setUriTemplateHandler}. - * @param handler the URI template handler to use - */ - public void setUriTemplateHandler(UriTemplateHandler handler) { - this.syncTemplate.setUriTemplateHandler(handler); - } - - /** - * Return the configured URI template handler. - */ - public UriTemplateHandler getUriTemplateHandler() { - return this.syncTemplate.getUriTemplateHandler(); - } - - @Override - public RestOperations getRestOperations() { - return this.syncTemplate; - } - - /** - * Set the message body converters to use. - *

    These converters are used to convert from and to HTTP requests and responses. - */ - public void setMessageConverters(List> messageConverters) { - this.syncTemplate.setMessageConverters(messageConverters); - } - - /** - * Return the message body converters. - */ - public List> getMessageConverters() { - return this.syncTemplate.getMessageConverters(); - } - - - // GET - - @Override - public ListenableFuture> getForEntity(String url, Class responseType, Object... uriVariables) - throws RestClientException { - - AsyncRequestCallback requestCallback = acceptHeaderRequestCallback(responseType); - ResponseExtractor> responseExtractor = responseEntityExtractor(responseType); - return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables); - } - - @Override - public ListenableFuture> getForEntity(String url, Class responseType, - Map uriVariables) throws RestClientException { - - AsyncRequestCallback requestCallback = acceptHeaderRequestCallback(responseType); - ResponseExtractor> responseExtractor = responseEntityExtractor(responseType); - return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables); - } - - @Override - public ListenableFuture> getForEntity(URI url, Class responseType) - throws RestClientException { - - AsyncRequestCallback requestCallback = acceptHeaderRequestCallback(responseType); - ResponseExtractor> responseExtractor = responseEntityExtractor(responseType); - return execute(url, HttpMethod.GET, requestCallback, responseExtractor); - } - - - // HEAD - - @Override - public ListenableFuture headForHeaders(String url, Object... uriVariables) - throws RestClientException { - - ResponseExtractor headersExtractor = headersExtractor(); - return execute(url, HttpMethod.HEAD, null, headersExtractor, uriVariables); - } - - @Override - public ListenableFuture headForHeaders(String url, Map uriVariables) - throws RestClientException { - - ResponseExtractor headersExtractor = headersExtractor(); - return execute(url, HttpMethod.HEAD, null, headersExtractor, uriVariables); - } - - @Override - public ListenableFuture headForHeaders(URI url) throws RestClientException { - ResponseExtractor headersExtractor = headersExtractor(); - return execute(url, HttpMethod.HEAD, null, headersExtractor); - } - - - // POST - - @Override - public ListenableFuture postForLocation(String url, @Nullable HttpEntity request, Object... uriVars) - throws RestClientException { - - AsyncRequestCallback callback = httpEntityCallback(request); - ResponseExtractor extractor = headersExtractor(); - ListenableFuture future = execute(url, HttpMethod.POST, callback, extractor, uriVars); - return adaptToLocationHeader(future); - } - - @Override - public ListenableFuture postForLocation(String url, @Nullable HttpEntity request, Map uriVars) - throws RestClientException { - - AsyncRequestCallback callback = httpEntityCallback(request); - ResponseExtractor extractor = headersExtractor(); - ListenableFuture future = execute(url, HttpMethod.POST, callback, extractor, uriVars); - return adaptToLocationHeader(future); - } - - @Override - public ListenableFuture postForLocation(URI url, @Nullable HttpEntity request) - throws RestClientException { - - AsyncRequestCallback callback = httpEntityCallback(request); - ResponseExtractor extractor = headersExtractor(); - ListenableFuture future = execute(url, HttpMethod.POST, callback, extractor); - return adaptToLocationHeader(future); - } - - private static ListenableFuture adaptToLocationHeader(ListenableFuture future) { - return new ListenableFutureAdapter(future) { - @Override - @Nullable - protected URI adapt(HttpHeaders headers) throws ExecutionException { - return headers.getLocation(); - } - }; - } - - @Override - public ListenableFuture> postForEntity(String url, @Nullable HttpEntity request, - Class responseType, Object... uriVariables) throws RestClientException { - - AsyncRequestCallback requestCallback = httpEntityCallback(request, responseType); - ResponseExtractor> responseExtractor = responseEntityExtractor(responseType); - return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables); - } - - @Override - public ListenableFuture> postForEntity(String url, @Nullable HttpEntity request, - Class responseType, Map uriVariables) throws RestClientException { - - AsyncRequestCallback requestCallback = httpEntityCallback(request, responseType); - ResponseExtractor> responseExtractor = responseEntityExtractor(responseType); - return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables); - } - - @Override - public ListenableFuture> postForEntity(URI url, - @Nullable HttpEntity request, Class responseType) throws RestClientException { - - AsyncRequestCallback requestCallback = httpEntityCallback(request, responseType); - ResponseExtractor> responseExtractor = responseEntityExtractor(responseType); - return execute(url, HttpMethod.POST, requestCallback, responseExtractor); - } - - - // PUT - - @Override - public ListenableFuture put(String url, @Nullable HttpEntity request, Object... uriVars) - throws RestClientException { - - AsyncRequestCallback requestCallback = httpEntityCallback(request); - return execute(url, HttpMethod.PUT, requestCallback, null, uriVars); - } - - @Override - public ListenableFuture put(String url, @Nullable HttpEntity request, Map uriVars) - throws RestClientException { - - AsyncRequestCallback requestCallback = httpEntityCallback(request); - return execute(url, HttpMethod.PUT, requestCallback, null, uriVars); - } - - @Override - public ListenableFuture put(URI url, @Nullable HttpEntity request) throws RestClientException { - AsyncRequestCallback requestCallback = httpEntityCallback(request); - return execute(url, HttpMethod.PUT, requestCallback, null); - } - - - // DELETE - - @Override - public ListenableFuture delete(String url, Object... uriVariables) throws RestClientException { - return execute(url, HttpMethod.DELETE, null, null, uriVariables); - } - - @Override - public ListenableFuture delete(String url, Map uriVariables) throws RestClientException { - return execute(url, HttpMethod.DELETE, null, null, uriVariables); - } - - @Override - public ListenableFuture delete(URI url) throws RestClientException { - return execute(url, HttpMethod.DELETE, null, null); - } - - - // OPTIONS - - @Override - public ListenableFuture> optionsForAllow(String url, Object... uriVars) - throws RestClientException { - - ResponseExtractor extractor = headersExtractor(); - ListenableFuture future = execute(url, HttpMethod.OPTIONS, null, extractor, uriVars); - return adaptToAllowHeader(future); - } - - @Override - public ListenableFuture> optionsForAllow(String url, Map uriVars) - throws RestClientException { - - ResponseExtractor extractor = headersExtractor(); - ListenableFuture future = execute(url, HttpMethod.OPTIONS, null, extractor, uriVars); - return adaptToAllowHeader(future); - } - - @Override - public ListenableFuture> optionsForAllow(URI url) throws RestClientException { - ResponseExtractor extractor = headersExtractor(); - ListenableFuture future = execute(url, HttpMethod.OPTIONS, null, extractor); - return adaptToAllowHeader(future); - } - - private static ListenableFuture> adaptToAllowHeader(ListenableFuture future) { - return new ListenableFutureAdapter, HttpHeaders>(future) { - @Override - protected Set adapt(HttpHeaders headers) throws ExecutionException { - return headers.getAllow(); - } - }; - } - - // exchange - - @Override - public ListenableFuture> exchange(String url, HttpMethod method, - @Nullable HttpEntity requestEntity, Class responseType, Object... uriVariables) - throws RestClientException { - - AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, responseType); - ResponseExtractor> responseExtractor = responseEntityExtractor(responseType); - return execute(url, method, requestCallback, responseExtractor, uriVariables); - } - - @Override - public ListenableFuture> exchange(String url, HttpMethod method, - @Nullable HttpEntity requestEntity, Class responseType, Map uriVariables) - throws RestClientException { - - AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, responseType); - ResponseExtractor> responseExtractor = responseEntityExtractor(responseType); - return execute(url, method, requestCallback, responseExtractor, uriVariables); - } - - @Override - public ListenableFuture> exchange(URI url, HttpMethod method, - @Nullable HttpEntity requestEntity, Class responseType) throws RestClientException { - - AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, responseType); - ResponseExtractor> responseExtractor = responseEntityExtractor(responseType); - return execute(url, method, requestCallback, responseExtractor); - } - - @Override - public ListenableFuture> exchange(String url, HttpMethod method, - @Nullable HttpEntity requestEntity, ParameterizedTypeReference responseType, - Object... uriVariables) throws RestClientException { - - Type type = responseType.getType(); - AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, type); - ResponseExtractor> responseExtractor = responseEntityExtractor(type); - return execute(url, method, requestCallback, responseExtractor, uriVariables); - } - - @Override - public ListenableFuture> exchange(String url, HttpMethod method, - @Nullable HttpEntity requestEntity, ParameterizedTypeReference responseType, - Map uriVariables) throws RestClientException { - - Type type = responseType.getType(); - AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, type); - ResponseExtractor> responseExtractor = responseEntityExtractor(type); - return execute(url, method, requestCallback, responseExtractor, uriVariables); - } - - @Override - public ListenableFuture> exchange(URI url, HttpMethod method, - @Nullable HttpEntity requestEntity, ParameterizedTypeReference responseType) - throws RestClientException { - - Type type = responseType.getType(); - AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, type); - ResponseExtractor> responseExtractor = responseEntityExtractor(type); - return execute(url, method, requestCallback, responseExtractor); - } - - - // general execution - - @Override - public ListenableFuture execute(String url, HttpMethod method, @Nullable AsyncRequestCallback requestCallback, - @Nullable ResponseExtractor responseExtractor, Object... uriVariables) throws RestClientException { - - URI expanded = getUriTemplateHandler().expand(url, uriVariables); - return doExecute(expanded, method, requestCallback, responseExtractor); - } - - @Override - public ListenableFuture execute(String url, HttpMethod method, - @Nullable AsyncRequestCallback requestCallback, @Nullable ResponseExtractor responseExtractor, - Map uriVariables) throws RestClientException { - - URI expanded = getUriTemplateHandler().expand(url, uriVariables); - return doExecute(expanded, method, requestCallback, responseExtractor); - } - - @Override - public ListenableFuture execute(URI url, HttpMethod method, - @Nullable AsyncRequestCallback requestCallback, - @Nullable ResponseExtractor responseExtractor) throws RestClientException { - - return doExecute(url, method, requestCallback, responseExtractor); - } - - /** - * Execute the given method on the provided URI. The - * {@link org.springframework.http.client.ClientHttpRequest} - * is processed using the {@link RequestCallback}; the response with - * the {@link ResponseExtractor}. - * @param url the fully-expanded URL to connect to - * @param method the HTTP method to execute (GET, POST, etc.) - * @param requestCallback object that prepares the request (can be {@code null}) - * @param responseExtractor object that extracts the return value from the response (can - * be {@code null}) - * @return an arbitrary object, as returned by the {@link ResponseExtractor} - */ - protected ListenableFuture doExecute(URI url, HttpMethod method, - @Nullable AsyncRequestCallback requestCallback, - @Nullable ResponseExtractor responseExtractor) throws RestClientException { - - Assert.notNull(url, "'url' must not be null"); - Assert.notNull(method, "'method' must not be null"); - try { - org.springframework.http.client.AsyncClientHttpRequest request = createAsyncRequest(url, method); - if (requestCallback != null) { - requestCallback.doWithRequest(request); - } - ListenableFuture responseFuture = request.executeAsync(); - return new ResponseExtractorFuture<>(method, url, responseFuture, responseExtractor); - } - catch (IOException ex) { - throw new ResourceAccessException("I/O error on " + method.name() + - " request for \"" + url + "\":" + ex.getMessage(), ex); - } - } - - private void logResponseStatus(HttpMethod method, URI url, ClientHttpResponse response) { - if (logger.isDebugEnabled()) { - try { - logger.debug("Async " + method.name() + " request for \"" + url + "\" resulted in " + - response.getRawStatusCode() + " (" + response.getStatusText() + ")"); - } - catch (IOException ex) { - // ignore - } - } - } - - private void handleResponseError(HttpMethod method, URI url, ClientHttpResponse response) throws IOException { - if (logger.isWarnEnabled()) { - try { - logger.warn("Async " + method.name() + " request for \"" + url + "\" resulted in " + - response.getRawStatusCode() + " (" + response.getStatusText() + "); invoking error handler"); - } - catch (IOException ex) { - // ignore - } - } - getErrorHandler().handleError(url, method, response); - } - - /** - * Returns a request callback implementation that prepares the request {@code Accept} - * headers based on the given response type and configured {@linkplain - * #getMessageConverters() message converters}. - */ - protected AsyncRequestCallback acceptHeaderRequestCallback(Class responseType) { - return new AsyncRequestCallbackAdapter(this.syncTemplate.acceptHeaderRequestCallback(responseType)); - } - - /** - * Returns a request callback implementation that writes the given object to the - * request stream. - */ - protected AsyncRequestCallback httpEntityCallback(@Nullable HttpEntity requestBody) { - return new AsyncRequestCallbackAdapter(this.syncTemplate.httpEntityCallback(requestBody)); - } - - /** - * Returns a request callback implementation that writes the given object to the - * request stream. - */ - protected AsyncRequestCallback httpEntityCallback(@Nullable HttpEntity request, Type responseType) { - return new AsyncRequestCallbackAdapter(this.syncTemplate.httpEntityCallback(request, responseType)); - } - - /** - * Returns a response extractor for {@link ResponseEntity}. - */ - protected ResponseExtractor> responseEntityExtractor(Type responseType) { - return this.syncTemplate.responseEntityExtractor(responseType); - } - - /** - * Returns a response extractor for {@link HttpHeaders}. - */ - protected ResponseExtractor headersExtractor() { - return this.syncTemplate.headersExtractor(); - } - - - /** - * Future returned from - * {@link #doExecute(URI, HttpMethod, AsyncRequestCallback, ResponseExtractor)}. - */ - private class ResponseExtractorFuture extends ListenableFutureAdapter { - - private final HttpMethod method; - - private final URI url; - - @Nullable - private final ResponseExtractor responseExtractor; - - public ResponseExtractorFuture(HttpMethod method, URI url, - ListenableFuture clientHttpResponseFuture, - @Nullable ResponseExtractor responseExtractor) { - - super(clientHttpResponseFuture); - this.method = method; - this.url = url; - this.responseExtractor = responseExtractor; - } - - @Override - @Nullable - protected final T adapt(ClientHttpResponse response) throws ExecutionException { - try { - if (!getErrorHandler().hasError(response)) { - logResponseStatus(this.method, this.url, response); - } - else { - handleResponseError(this.method, this.url, response); - } - return convertResponse(response); - } - catch (Throwable ex) { - throw new ExecutionException(ex); - } - finally { - response.close(); - } - } - - @Nullable - protected T convertResponse(ClientHttpResponse response) throws IOException { - return (this.responseExtractor != null ? this.responseExtractor.extractData(response) : null); - } - } - - - /** - * Adapts a {@link RequestCallback} to the {@link AsyncRequestCallback} interface. - */ - private static class AsyncRequestCallbackAdapter implements AsyncRequestCallback { - - private final RequestCallback adaptee; - - /** - * Create a new {@code AsyncRequestCallbackAdapter} from the given - * {@link RequestCallback}. - * @param requestCallback the callback to base this adapter on - */ - public AsyncRequestCallbackAdapter(RequestCallback requestCallback) { - this.adaptee = requestCallback; - } - - @Override - public void doWithRequest(final org.springframework.http.client.AsyncClientHttpRequest request) - throws IOException { - - this.adaptee.doWithRequest(new ClientHttpRequest() { - @Override - public ClientHttpResponse execute() throws IOException { - throw new UnsupportedOperationException("execute not supported"); - } - @Override - public OutputStream getBody() throws IOException { - return request.getBody(); - } - @Override - @Nullable - public HttpMethod getMethod() { - return request.getMethod(); - } - @Override - public String getMethodValue() { - return request.getMethodValue(); - } - @Override - public URI getURI() { - return request.getURI(); - } - @Override - public HttpHeaders getHeaders() { - return request.getHeaders(); - } - }); - } - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/client/AbstractAsyncHttpRequestFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/AbstractAsyncHttpRequestFactoryTests.java deleted file mode 100644 index 4ae702d55111..000000000000 --- a/spring-web/src/test/java/org/springframework/http/client/AbstractAsyncHttpRequestFactoryTests.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.net.URI; -import java.util.Arrays; -import java.util.Locale; -import java.util.concurrent.Future; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.StreamingHttpOutputMessage; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.StreamUtils; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -@SuppressWarnings("deprecation") -public abstract class AbstractAsyncHttpRequestFactoryTests extends AbstractMockWebServerTests { - - protected AsyncClientHttpRequestFactory factory; - - - @BeforeEach - public final void createFactory() throws Exception { - this.factory = createRequestFactory(); - if (this.factory instanceof InitializingBean) { - ((InitializingBean) this.factory).afterPropertiesSet(); - } - } - - @AfterEach - public final void destroyFactory() throws Exception { - if (this.factory instanceof DisposableBean) { - ((DisposableBean) this.factory).destroy(); - } - } - - protected abstract AsyncClientHttpRequestFactory createRequestFactory(); - - - @Test - public void status() throws Exception { - URI uri = new URI(baseUrl + "/status/notfound"); - AsyncClientHttpRequest request = this.factory.createAsyncRequest(uri, HttpMethod.GET); - assertThat(request.getMethod()).as("Invalid HTTP method").isEqualTo(HttpMethod.GET); - assertThat(request.getURI()).as("Invalid HTTP URI").isEqualTo(uri); - Future futureResponse = request.executeAsync(); - try (ClientHttpResponse response = futureResponse.get()) { - assertThat(response.getStatusCode()).as("Invalid status code").isEqualTo(HttpStatus.NOT_FOUND); - } - } - - @Test - public void statusCallback() throws Exception { - URI uri = new URI(baseUrl + "/status/notfound"); - AsyncClientHttpRequest request = this.factory.createAsyncRequest(uri, HttpMethod.GET); - assertThat(request.getMethod()).as("Invalid HTTP method").isEqualTo(HttpMethod.GET); - assertThat(request.getURI()).as("Invalid HTTP URI").isEqualTo(uri); - ListenableFuture listenableFuture = request.executeAsync(); - listenableFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(ClientHttpResponse result) { - try { - assertThat(result.getStatusCode()).as("Invalid status code").isEqualTo(HttpStatus.NOT_FOUND); - } - catch (IOException ex) { - throw new AssertionError(ex.getMessage(), ex); - } - } - @Override - public void onFailure(Throwable ex) { - throw new AssertionError(ex.getMessage(), ex); - } - }); - try (ClientHttpResponse response = listenableFuture.get()) { - assertThat(response.getStatusCode()).as("Invalid status code").isEqualTo(HttpStatus.NOT_FOUND); - } - } - - @Test - public void echo() throws Exception { - AsyncClientHttpRequest request = this.factory.createAsyncRequest(new URI(baseUrl + "/echo"), HttpMethod.PUT); - assertThat(request.getMethod()).as("Invalid HTTP method").isEqualTo(HttpMethod.PUT); - String headerName = "MyHeader"; - String headerValue1 = "value1"; - request.getHeaders().add(headerName, headerValue1); - String headerValue2 = "value2"; - request.getHeaders().add(headerName, headerValue2); - final byte[] body = "Hello World".getBytes("UTF-8"); - request.getHeaders().setContentLength(body.length); - - if (request instanceof StreamingHttpOutputMessage) { - StreamingHttpOutputMessage streamingRequest = (StreamingHttpOutputMessage) request; - streamingRequest.setBody(outputStream -> StreamUtils.copy(body, outputStream)); - } - else { - StreamUtils.copy(body, request.getBody()); - } - - Future futureResponse = request.executeAsync(); - try ( ClientHttpResponse response = futureResponse.get()) { - assertThat(response.getStatusCode()).as("Invalid status code").isEqualTo(HttpStatus.OK); - assertThat(response.getHeaders().containsKey(headerName)).as("Header not found").isTrue(); - assertThat(response.getHeaders().get(headerName)).as("Header value not found").isEqualTo(Arrays.asList(headerValue1, headerValue2)); - byte[] result = FileCopyUtils.copyToByteArray(response.getBody()); - assertThat(Arrays.equals(body, result)).as("Invalid body").isTrue(); - } - } - - @Test - public void multipleWrites() throws Exception { - AsyncClientHttpRequest request = this.factory.createAsyncRequest(new URI(baseUrl + "/echo"), HttpMethod.POST); - final byte[] body = "Hello World".getBytes("UTF-8"); - - if (request instanceof StreamingHttpOutputMessage) { - StreamingHttpOutputMessage streamingRequest = (StreamingHttpOutputMessage) request; - streamingRequest.setBody(outputStream -> StreamUtils.copy(body, outputStream)); - } - else { - StreamUtils.copy(body, request.getBody()); - } - - Future futureResponse = request.executeAsync(); - try (ClientHttpResponse response = futureResponse.get()) { - assertThat(response).isNotNull(); - assertThatIllegalStateException().isThrownBy(() -> FileCopyUtils.copy(body, request.getBody())); - } - } - - @Test - public void headersAfterExecute() throws Exception { - AsyncClientHttpRequest request = this.factory.createAsyncRequest(new URI(baseUrl + "/echo"), HttpMethod.POST); - request.getHeaders().add("MyHeader", "value"); - byte[] body = "Hello World".getBytes("UTF-8"); - FileCopyUtils.copy(body, request.getBody()); - - Future futureResponse = request.executeAsync(); - try (ClientHttpResponse response = futureResponse.get()) { - assertThat(response).isNotNull(); - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> - request.getHeaders().add("MyHeader", "value")); - } - } - - @Test - public void httpMethods() throws Exception { - assertHttpMethod("get", HttpMethod.GET); - assertHttpMethod("head", HttpMethod.HEAD); - assertHttpMethod("post", HttpMethod.POST); - assertHttpMethod("put", HttpMethod.PUT); - assertHttpMethod("options", HttpMethod.OPTIONS); - assertHttpMethod("delete", HttpMethod.DELETE); - } - - protected void assertHttpMethod(String path, HttpMethod method) throws Exception { - AsyncClientHttpRequest request = this.factory.createAsyncRequest(new URI(baseUrl + "/methods/" + path), method); - if (method == HttpMethod.POST || method == HttpMethod.PUT || method == HttpMethod.PATCH) { - // requires a body - request.getBody().write(32); - } - Future futureResponse = request.executeAsync(); - try (ClientHttpResponse response = futureResponse.get()) { - assertThat(response.getStatusCode()).as("Invalid response status").isEqualTo(HttpStatus.OK); - assertThat(request.getMethod().name()).as("Invalid method").isEqualTo(path.toUpperCase(Locale.ENGLISH)); - } - } - - @Test - public void cancel() throws Exception { - URI uri = new URI(baseUrl + "/status/notfound"); - AsyncClientHttpRequest request = this.factory.createAsyncRequest(uri, HttpMethod.GET); - Future futureResponse = request.executeAsync(); - futureResponse.cancel(true); - assertThat(futureResponse.isCancelled()).isTrue(); - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/client/BufferedSimpleAsyncHttpRequestFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/BufferedSimpleAsyncHttpRequestFactoryTests.java deleted file mode 100644 index f019ddd797bc..000000000000 --- a/spring-web/src/test/java/org/springframework/http/client/BufferedSimpleAsyncHttpRequestFactoryTests.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2002-2013 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.net.ProtocolException; - -import org.junit.jupiter.api.Test; - -import org.springframework.core.task.AsyncListenableTaskExecutor; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.http.HttpMethod; - -public class BufferedSimpleAsyncHttpRequestFactoryTests extends AbstractAsyncHttpRequestFactoryTests { - - @SuppressWarnings("deprecation") - @Override - protected AsyncClientHttpRequestFactory createRequestFactory() { - SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); - AsyncListenableTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(); - requestFactory.setTaskExecutor(taskExecutor); - return requestFactory; - } - - @Override - @Test - public void httpMethods() throws Exception { - super.httpMethods(); - try { - assertHttpMethod("patch", HttpMethod.PATCH); - } - catch (ProtocolException ex) { - // Currently HttpURLConnection does not support HTTP PATCH - } - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequestFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequestFactoryTests.java deleted file mode 100644 index 7ae09ce86962..000000000000 --- a/spring-web/src/test/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequestFactoryTests.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.net.URI; - -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; -import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; -import org.junit.jupiter.api.Test; - -import org.springframework.http.HttpMethod; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Arjen Poutsma - * @author Stephane Nicoll - */ -@SuppressWarnings("deprecation") -public class HttpComponentsAsyncClientHttpRequestFactoryTests extends AbstractAsyncHttpRequestFactoryTests { - - @Override - protected AsyncClientHttpRequestFactory createRequestFactory() { - return new HttpComponentsAsyncClientHttpRequestFactory(); - } - - - @Override - @Test - public void httpMethods() throws Exception { - super.httpMethods(); - assertHttpMethod("patch", HttpMethod.PATCH); - } - - @Test - public void customHttpAsyncClientUsesItsDefault() throws Exception { - HttpComponentsAsyncClientHttpRequestFactory factory = - new HttpComponentsAsyncClientHttpRequestFactory(); - - URI uri = new URI(baseUrl + "/status/ok"); - HttpComponentsAsyncClientHttpRequest request = (HttpComponentsAsyncClientHttpRequest) - factory.createAsyncRequest(uri, HttpMethod.GET); - - assertThat(request.getHttpContext().getAttribute(HttpClientContext.REQUEST_CONFIG)).as("No custom config should be set with a custom HttpAsyncClient").isNull(); - } - - @Test - public void defaultSettingsOfHttpAsyncClientLostOnExecutorCustomization() throws Exception { - CloseableHttpAsyncClient client = HttpAsyncClientBuilder.create() - .setDefaultRequestConfig(RequestConfig.custom().setConnectTimeout(1234).build()) - .build(); - HttpComponentsAsyncClientHttpRequestFactory factory = new HttpComponentsAsyncClientHttpRequestFactory(client); - - URI uri = new URI(baseUrl + "/status/ok"); - HttpComponentsAsyncClientHttpRequest request = (HttpComponentsAsyncClientHttpRequest) - factory.createAsyncRequest(uri, HttpMethod.GET); - - assertThat(request.getHttpContext().getAttribute(HttpClientContext.REQUEST_CONFIG)).as("No custom config should be set with a custom HttpClient").isNull(); - - factory.setConnectionRequestTimeout(4567); - HttpComponentsAsyncClientHttpRequest request2 = (HttpComponentsAsyncClientHttpRequest) - factory.createAsyncRequest(uri, HttpMethod.GET); - Object requestConfigAttribute = request2.getHttpContext().getAttribute(HttpClientContext.REQUEST_CONFIG); - assertThat(requestConfigAttribute).isNotNull(); - RequestConfig requestConfig = (RequestConfig) requestConfigAttribute; - - assertThat(requestConfig.getConnectionRequestTimeout()).isEqualTo(4567); - // No way to access the request config of the HTTP client so no way to "merge" our customizations - assertThat(requestConfig.getConnectTimeout()).isEqualTo(-1); - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/client/Netty4AsyncClientHttpRequestFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/Netty4AsyncClientHttpRequestFactoryTests.java deleted file mode 100644 index 87ed2ae399a4..000000000000 --- a/spring-web/src/test/java/org/springframework/http/client/Netty4AsyncClientHttpRequestFactoryTests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import org.springframework.http.HttpMethod; - -/** - * @author Arjen Poutsma - */ -public class Netty4AsyncClientHttpRequestFactoryTests extends AbstractAsyncHttpRequestFactoryTests { - - private static EventLoopGroup eventLoopGroup; - - - @BeforeAll - public static void createEventLoopGroup() { - eventLoopGroup = new NioEventLoopGroup(); - } - - @AfterAll - public static void shutdownEventLoopGroup() throws InterruptedException { - eventLoopGroup.shutdownGracefully().sync(); - } - - @SuppressWarnings("deprecation") - @Override - protected AsyncClientHttpRequestFactory createRequestFactory() { - return new Netty4ClientHttpRequestFactory(eventLoopGroup); - } - - @Override - @Test - public void httpMethods() throws Exception { - super.httpMethods(); - assertHttpMethod("patch", HttpMethod.PATCH); - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/client/Netty4ClientHttpRequestFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/Netty4ClientHttpRequestFactoryTests.java deleted file mode 100644 index bfc087f84806..000000000000 --- a/spring-web/src/test/java/org/springframework/http/client/Netty4ClientHttpRequestFactoryTests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import org.springframework.http.HttpMethod; - -/** - * @author Arjen Poutsma - */ -public class Netty4ClientHttpRequestFactoryTests extends AbstractHttpRequestFactoryTests { - - private static EventLoopGroup eventLoopGroup; - - - @BeforeAll - public static void createEventLoopGroup() { - eventLoopGroup = new NioEventLoopGroup(); - } - - @AfterAll - public static void shutdownEventLoopGroup() throws InterruptedException { - eventLoopGroup.shutdownGracefully().sync(); - } - - @Override - @SuppressWarnings("deprecation") - protected ClientHttpRequestFactory createRequestFactory() { - return new Netty4ClientHttpRequestFactory(eventLoopGroup); - } - - @Override - @Test - public void httpMethods() throws Exception { - super.httpMethods(); - assertHttpMethod("patch", HttpMethod.PATCH); - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/client/OkHttp3AsyncClientHttpRequestFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/OkHttp3AsyncClientHttpRequestFactoryTests.java deleted file mode 100644 index 541b7bd693c0..000000000000 --- a/spring-web/src/test/java/org/springframework/http/client/OkHttp3AsyncClientHttpRequestFactoryTests.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import org.junit.jupiter.api.Test; - -import org.springframework.http.HttpMethod; - -/** - * @author Roy Clarkson - */ -public class OkHttp3AsyncClientHttpRequestFactoryTests extends AbstractAsyncHttpRequestFactoryTests { - - @SuppressWarnings("deprecation") - @Override - protected AsyncClientHttpRequestFactory createRequestFactory() { - return new OkHttp3ClientHttpRequestFactory(); - } - - @Override - @Test - public void httpMethods() throws Exception { - super.httpMethods(); - assertHttpMethod("patch", HttpMethod.PATCH); - } - -} diff --git a/spring-web/src/test/java/org/springframework/web/client/AsyncRestTemplateIntegrationTests.java b/spring-web/src/test/java/org/springframework/web/client/AsyncRestTemplateIntegrationTests.java deleted file mode 100644 index 245172958b2c..000000000000 --- a/spring-web/src/test/java/org/springframework/web/client/AsyncRestTemplateIntegrationTests.java +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.client; - -import java.io.IOException; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.EnumSet; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import org.junit.jupiter.api.Test; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.fail; - -/** - * Integration tests for {@link AsyncRestTemplate}. - * - *

    Logging configuration for {@code MockWebServer}

    - * - *

    In order for our log4j2 configuration to be used in an IDE, you must - * set the following system property before running any tests — for - * example, in Run Configurations in Eclipse. - * - *

    - * -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
    - * 
    - * - * @author Arjen Poutsma - * @author Sebastien Deleuze - */ -@SuppressWarnings("deprecation") -public class AsyncRestTemplateIntegrationTests extends AbstractMockWebServerTests { - - private final AsyncRestTemplate template = new AsyncRestTemplate( - new org.springframework.http.client.HttpComponentsAsyncClientHttpRequestFactory()); - - - @Test - public void getEntity() throws Exception { - Future> future = template.getForEntity(baseUrl + "/{method}", String.class, "get"); - ResponseEntity entity = future.get(); - assertThat(entity.getBody()).as("Invalid content").isEqualTo(helloWorld); - assertThat(entity.getHeaders().isEmpty()).as("No headers").isFalse(); - assertThat(entity.getHeaders().getContentType()).as("Invalid content-type").isEqualTo(textContentType); - assertThat(entity.getStatusCode()).as("Invalid status code").isEqualTo(HttpStatus.OK); - } - - @Test - public void getEntityFromCompletable() throws Exception { - ListenableFuture> future = template.getForEntity(baseUrl + "/{method}", String.class, "get"); - ResponseEntity entity = future.completable().get(); - assertThat(entity.getBody()).as("Invalid content").isEqualTo(helloWorld); - assertThat(entity.getHeaders().isEmpty()).as("No headers").isFalse(); - assertThat(entity.getHeaders().getContentType()).as("Invalid content-type").isEqualTo(textContentType); - assertThat(entity.getStatusCode()).as("Invalid status code").isEqualTo(HttpStatus.OK); - } - - @Test - public void multipleFutureGets() throws Exception { - Future> future = template.getForEntity(baseUrl + "/{method}", String.class, "get"); - future.get(); - future.get(); - } - - @Test - public void getEntityCallback() throws Exception { - ListenableFuture> futureEntity = - template.getForEntity(baseUrl + "/{method}", String.class, "get"); - futureEntity.addCallback(new ListenableFutureCallback>() { - @Override - public void onSuccess(ResponseEntity entity) { - assertThat(entity.getBody()).as("Invalid content").isEqualTo(helloWorld); - assertThat(entity.getHeaders().isEmpty()).as("No headers").isFalse(); - assertThat(entity.getHeaders().getContentType()).as("Invalid content-type").isEqualTo(textContentType); - assertThat(entity.getStatusCode()).as("Invalid status code").isEqualTo(HttpStatus.OK); - } - @Override - public void onFailure(Throwable ex) { - fail(ex.getMessage()); - } - }); - waitTillDone(futureEntity); - } - - @Test - public void getEntityCallbackWithLambdas() throws Exception { - ListenableFuture> futureEntity = - template.getForEntity(baseUrl + "/{method}", String.class, "get"); - futureEntity.addCallback(entity -> { - assertThat(entity.getBody()).as("Invalid content").isEqualTo(helloWorld); - assertThat(entity.getHeaders().isEmpty()).as("No headers").isFalse(); - assertThat(entity.getHeaders().getContentType()).as("Invalid content-type").isEqualTo(textContentType); - assertThat(entity.getStatusCode()).as("Invalid status code").isEqualTo(HttpStatus.OK); - }, ex -> fail(ex.getMessage())); - waitTillDone(futureEntity); - } - - @Test - public void getNoResponse() throws Exception { - Future> futureEntity = template.getForEntity(baseUrl + "/get/nothing", String.class); - ResponseEntity entity = futureEntity.get(); - assertThat(entity.getBody()).as("Invalid content").isNull(); - } - - @Test - public void getNoContentTypeHeader() throws Exception { - Future> futureEntity = template.getForEntity(baseUrl + "/get/nocontenttype", byte[].class); - ResponseEntity responseEntity = futureEntity.get(); - assertThat(responseEntity.getBody()).as("Invalid content").isEqualTo(helloWorld.getBytes("UTF-8")); - } - - @Test - public void getNoContent() throws Exception { - Future> responseFuture = template.getForEntity(baseUrl + "/status/nocontent", String.class); - ResponseEntity entity = responseFuture.get(); - assertThat(entity.getStatusCode()).as("Invalid response code").isEqualTo(HttpStatus.NO_CONTENT); - assertThat(entity.getBody()).as("Invalid content").isNull(); - } - - @Test - public void getNotModified() throws Exception { - Future> responseFuture = template.getForEntity(baseUrl + "/status/notmodified", String.class); - ResponseEntity entity = responseFuture.get(); - assertThat(entity.getStatusCode()).as("Invalid response code").isEqualTo(HttpStatus.NOT_MODIFIED); - assertThat(entity.getBody()).as("Invalid content").isNull(); - } - - @Test - public void headForHeaders() throws Exception { - Future headersFuture = template.headForHeaders(baseUrl + "/get"); - HttpHeaders headers = headersFuture.get(); - assertThat(headers.containsKey("Content-Type")).as("No Content-Type header").isTrue(); - } - - @Test - public void headForHeadersCallback() throws Exception { - ListenableFuture headersFuture = template.headForHeaders(baseUrl + "/get"); - headersFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(HttpHeaders result) { - assertThat(result.containsKey("Content-Type")).as("No Content-Type header").isTrue(); - } - @Override - public void onFailure(Throwable ex) { - fail(ex.getMessage()); - } - }); - waitTillDone(headersFuture); - } - - @Test - public void headForHeadersCallbackWithLambdas() throws Exception { - ListenableFuture headersFuture = template.headForHeaders(baseUrl + "/get"); - headersFuture.addCallback(result -> assertThat(result.containsKey("Content-Type")).as("No Content-Type header").isTrue(), ex -> fail(ex.getMessage())); - waitTillDone(headersFuture); - } - - @Test - public void postForLocation() throws Exception { - HttpHeaders entityHeaders = new HttpHeaders(); - entityHeaders.setContentType(new MediaType("text", "plain", StandardCharsets.ISO_8859_1)); - HttpEntity entity = new HttpEntity<>(helloWorld, entityHeaders); - Future locationFuture = template.postForLocation(baseUrl + "/{method}", entity, "post"); - URI location = locationFuture.get(); - assertThat(location).as("Invalid location").isEqualTo(new URI(baseUrl + "/post/1")); - } - - @Test - public void postForLocationCallback() throws Exception { - HttpHeaders entityHeaders = new HttpHeaders(); - entityHeaders.setContentType(new MediaType("text", "plain", StandardCharsets.ISO_8859_1)); - HttpEntity entity = new HttpEntity<>(helloWorld, entityHeaders); - final URI expected = new URI(baseUrl + "/post/1"); - ListenableFuture locationFuture = template.postForLocation(baseUrl + "/{method}", entity, "post"); - locationFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(URI result) { - assertThat(result).as("Invalid location").isEqualTo(expected); - } - @Override - public void onFailure(Throwable ex) { - fail(ex.getMessage()); - } - }); - waitTillDone(locationFuture); - } - - @Test - public void postForLocationCallbackWithLambdas() throws Exception { - HttpHeaders entityHeaders = new HttpHeaders(); - entityHeaders.setContentType(new MediaType("text", "plain", StandardCharsets.ISO_8859_1)); - HttpEntity entity = new HttpEntity<>(helloWorld, entityHeaders); - final URI expected = new URI(baseUrl + "/post/1"); - ListenableFuture locationFuture = template.postForLocation(baseUrl + "/{method}", entity, "post"); - locationFuture.addCallback(result -> assertThat(result).as("Invalid location").isEqualTo(expected), - ex -> fail(ex.getMessage())); - waitTillDone(locationFuture); - } - - @Test - public void postForEntity() throws Exception { - HttpEntity requestEntity = new HttpEntity<>(helloWorld); - Future> responseEntityFuture = - template.postForEntity(baseUrl + "/{method}", requestEntity, String.class, "post"); - ResponseEntity responseEntity = responseEntityFuture.get(); - assertThat(responseEntity.getBody()).as("Invalid content").isEqualTo(helloWorld); - } - - @Test - public void postForEntityCallback() throws Exception { - HttpEntity requestEntity = new HttpEntity<>(helloWorld); - ListenableFuture> responseEntityFuture = - template.postForEntity(baseUrl + "/{method}", requestEntity, String.class, "post"); - responseEntityFuture.addCallback(new ListenableFutureCallback>() { - @Override - public void onSuccess(ResponseEntity result) { - assertThat(result.getBody()).as("Invalid content").isEqualTo(helloWorld); - } - @Override - public void onFailure(Throwable ex) { - fail(ex.getMessage()); - } - }); - waitTillDone(responseEntityFuture); - } - - @Test - public void postForEntityCallbackWithLambdas() throws Exception { - HttpEntity requestEntity = new HttpEntity<>(helloWorld); - ListenableFuture> responseEntityFuture = - template.postForEntity(baseUrl + "/{method}", requestEntity, String.class, "post"); - responseEntityFuture.addCallback( - result -> assertThat(result.getBody()).as("Invalid content").isEqualTo(helloWorld), - ex -> fail(ex.getMessage())); - waitTillDone(responseEntityFuture); - } - - @Test - public void put() throws Exception { - HttpEntity requestEntity = new HttpEntity<>(helloWorld); - Future responseEntityFuture = template.put(baseUrl + "/{method}", requestEntity, "put"); - responseEntityFuture.get(); - } - - @Test - public void putCallback() throws Exception { - HttpEntity requestEntity = new HttpEntity<>(helloWorld); - ListenableFuture responseEntityFuture = template.put(baseUrl + "/{method}", requestEntity, "put"); - responseEntityFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(Object result) { - assertThat(result).isNull(); - } - @Override - public void onFailure(Throwable ex) { - fail(ex.getMessage()); - } - }); - waitTillDone(responseEntityFuture); - } - - @Test - public void delete() throws Exception { - Future deletedFuture = template.delete(new URI(baseUrl + "/delete")); - deletedFuture.get(); - } - - @Test - public void deleteCallback() throws Exception { - ListenableFuture deletedFuture = template.delete(new URI(baseUrl + "/delete")); - deletedFuture.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(Object result) { - assertThat(result).isNull(); - } - @Override - public void onFailure(Throwable ex) { - fail(ex.getMessage()); - } - }); - waitTillDone(deletedFuture); - } - - @Test - public void deleteCallbackWithLambdas() throws Exception { - ListenableFuture deletedFuture = template.delete(new URI(baseUrl + "/delete")); - deletedFuture.addCallback(result -> assertThat(result).isNull(), ex -> fail(ex.getMessage())); - waitTillDone(deletedFuture); - } - - @Test - public void identicalExceptionThroughGetAndCallback() throws Exception { - final HttpClientErrorException[] callbackException = new HttpClientErrorException[1]; - - final CountDownLatch latch = new CountDownLatch(1); - ListenableFuture future = template.execute(baseUrl + "/status/notfound", HttpMethod.GET, null, null); - future.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(Object result) { - fail("onSuccess not expected"); - } - @Override - public void onFailure(Throwable ex) { - boolean condition = ex instanceof HttpClientErrorException; - assertThat(condition).isTrue(); - callbackException[0] = (HttpClientErrorException) ex; - latch.countDown(); - } - }); - - try { - future.get(); - fail("Exception expected"); - } - catch (ExecutionException ex) { - Throwable cause = ex.getCause(); - boolean condition = cause instanceof HttpClientErrorException; - assertThat(condition).isTrue(); - latch.await(5, TimeUnit.SECONDS); - assertThat(cause).isSameAs(callbackException[0]); - } - } - - @Test - public void notFoundGet() throws Exception { - assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> { - Future future = template.execute(baseUrl + "/status/notfound", HttpMethod.GET, null, null); - future.get(); - }) - .withCauseInstanceOf(HttpClientErrorException.class) - .satisfies(ex -> { - HttpClientErrorException cause = (HttpClientErrorException) ex.getCause(); - assertThat(cause.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - assertThat(cause.getStatusText()).isNotNull(); - assertThat(cause.getResponseBodyAsString()).isNotNull(); - }); - } - - @Test - public void notFoundCallback() throws Exception { - ListenableFuture future = template.execute(baseUrl + "/status/notfound", HttpMethod.GET, null, null); - future.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(Object result) { - fail("onSuccess not expected"); - } - @Override - public void onFailure(Throwable t) { - boolean condition = t instanceof HttpClientErrorException; - assertThat(condition).isTrue(); - HttpClientErrorException ex = (HttpClientErrorException) t; - assertThat(ex.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - assertThat(ex.getStatusText()).isNotNull(); - assertThat(ex.getResponseBodyAsString()).isNotNull(); - } - }); - waitTillDone(future); - } - - @Test - public void notFoundCallbackWithLambdas() throws Exception { - ListenableFuture future = template.execute(baseUrl + "/status/notfound", HttpMethod.GET, null, null); - future.addCallback(result -> fail("onSuccess not expected"), ex -> { - boolean condition = ex instanceof HttpClientErrorException; - assertThat(condition).isTrue(); - HttpClientErrorException hcex = (HttpClientErrorException) ex; - assertThat(hcex.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - assertThat(hcex.getStatusText()).isNotNull(); - assertThat(hcex.getResponseBodyAsString()).isNotNull(); - }); - waitTillDone(future); - } - - @Test - public void serverError() throws Exception { - try { - Future future = template.execute(baseUrl + "/status/server", HttpMethod.GET, null, null); - future.get(); - fail("HttpServerErrorException expected"); - } - catch (ExecutionException ex) { - boolean condition = ex.getCause() instanceof HttpServerErrorException; - assertThat(condition).isTrue(); - HttpServerErrorException cause = (HttpServerErrorException)ex.getCause(); - - assertThat(cause.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - assertThat(cause.getStatusText()).isNotNull(); - assertThat(cause.getResponseBodyAsString()).isNotNull(); - } - } - - @Test - public void serverErrorCallback() throws Exception { - ListenableFuture future = template.execute(baseUrl + "/status/server", HttpMethod.GET, null, null); - future.addCallback(new ListenableFutureCallback() { - @Override - public void onSuccess(Void result) { - fail("onSuccess not expected"); - } - @Override - public void onFailure(Throwable ex) { - boolean condition = ex instanceof HttpServerErrorException; - assertThat(condition).isTrue(); - HttpServerErrorException hsex = (HttpServerErrorException) ex; - assertThat(hsex.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - assertThat(hsex.getStatusText()).isNotNull(); - assertThat(hsex.getResponseBodyAsString()).isNotNull(); - } - }); - waitTillDone(future); - } - - @Test - public void serverErrorCallbackWithLambdas() throws Exception { - ListenableFuture future = template.execute(baseUrl + "/status/server", HttpMethod.GET, null, null); - future.addCallback(result -> fail("onSuccess not expected"), ex -> { - boolean condition = ex instanceof HttpServerErrorException; - assertThat(condition).isTrue(); - HttpServerErrorException hsex = (HttpServerErrorException) ex; - assertThat(hsex.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - assertThat(hsex.getStatusText()).isNotNull(); - assertThat(hsex.getResponseBodyAsString()).isNotNull(); - }); - waitTillDone(future); - } - - @Test - public void optionsForAllow() throws Exception { - Future> allowedFuture = template.optionsForAllow(new URI(baseUrl + "/get")); - Set allowed = allowedFuture.get(); - assertThat(allowed).as("Invalid response").isEqualTo(EnumSet.of(HttpMethod.GET, HttpMethod.OPTIONS, HttpMethod.HEAD, HttpMethod.TRACE)); - } - - @Test - public void optionsForAllowCallback() throws Exception { - ListenableFuture> allowedFuture = template.optionsForAllow(new URI(baseUrl + "/get")); - allowedFuture.addCallback(new ListenableFutureCallback>() { - @Override - public void onSuccess(Set result) { - assertThat(result).as("Invalid response").isEqualTo(EnumSet.of(HttpMethod.GET, HttpMethod.OPTIONS, - HttpMethod.HEAD, HttpMethod.TRACE)); - } - @Override - public void onFailure(Throwable ex) { - fail(ex.getMessage()); - } - }); - waitTillDone(allowedFuture); - } - - @Test - public void optionsForAllowCallbackWithLambdas() throws Exception{ - ListenableFuture> allowedFuture = template.optionsForAllow(new URI(baseUrl + "/get")); - allowedFuture.addCallback(result -> assertThat(result).as("Invalid response").isEqualTo(EnumSet.of(HttpMethod.GET, HttpMethod.OPTIONS, HttpMethod.HEAD,HttpMethod.TRACE)), - ex -> fail(ex.getMessage())); - waitTillDone(allowedFuture); - } - - @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void exchangeGet() throws Exception { - HttpHeaders requestHeaders = new HttpHeaders(); - requestHeaders.set("MyHeader", "MyValue"); - HttpEntity requestEntity = new HttpEntity(requestHeaders); - Future> responseFuture = - template.exchange(baseUrl + "/{method}", HttpMethod.GET, requestEntity, String.class, "get"); - ResponseEntity response = responseFuture.get(); - assertThat(response.getBody()).as("Invalid content").isEqualTo(helloWorld); - } - - @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void exchangeGetCallback() throws Exception { - HttpHeaders requestHeaders = new HttpHeaders(); - requestHeaders.set("MyHeader", "MyValue"); - HttpEntity requestEntity = new HttpEntity(requestHeaders); - ListenableFuture> responseFuture = - template.exchange(baseUrl + "/{method}", HttpMethod.GET, requestEntity, String.class, "get"); - responseFuture.addCallback(new ListenableFutureCallback>() { - @Override - public void onSuccess(ResponseEntity result) { - assertThat(result.getBody()).as("Invalid content").isEqualTo(helloWorld); - } - @Override - public void onFailure(Throwable ex) { - fail(ex.getMessage()); - } - }); - waitTillDone(responseFuture); - } - - @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void exchangeGetCallbackWithLambdas() throws Exception { - HttpHeaders requestHeaders = new HttpHeaders(); - requestHeaders.set("MyHeader", "MyValue"); - HttpEntity requestEntity = new HttpEntity(requestHeaders); - ListenableFuture> responseFuture = - template.exchange(baseUrl + "/{method}", HttpMethod.GET, requestEntity, String.class, "get"); - responseFuture.addCallback(result -> assertThat(result.getBody()).as("Invalid content").isEqualTo(helloWorld), ex -> fail(ex.getMessage())); - waitTillDone(responseFuture); - } - - @Test - public void exchangePost() throws Exception { - HttpHeaders requestHeaders = new HttpHeaders(); - requestHeaders.set("MyHeader", "MyValue"); - requestHeaders.setContentType(MediaType.TEXT_PLAIN); - HttpEntity requestEntity = new HttpEntity<>(helloWorld, requestHeaders); - Future> resultFuture = - template.exchange(baseUrl + "/{method}", HttpMethod.POST, requestEntity, Void.class, "post"); - ResponseEntity result = resultFuture.get(); - assertThat(result.getHeaders().getLocation()).as("Invalid location").isEqualTo(new URI(baseUrl + "/post/1")); - assertThat(result.hasBody()).isFalse(); - } - - @Test - public void exchangePostCallback() throws Exception { - HttpHeaders requestHeaders = new HttpHeaders(); - requestHeaders.set("MyHeader", "MyValue"); - requestHeaders.setContentType(MediaType.TEXT_PLAIN); - HttpEntity requestEntity = new HttpEntity<>(helloWorld, requestHeaders); - ListenableFuture> resultFuture = - template.exchange(baseUrl + "/{method}", HttpMethod.POST, requestEntity, Void.class, "post"); - final URI expected =new URI(baseUrl + "/post/1"); - resultFuture.addCallback(new ListenableFutureCallback>() { - @Override - public void onSuccess(ResponseEntity result) { - assertThat(result.getHeaders().getLocation()).as("Invalid location").isEqualTo(expected); - assertThat(result.hasBody()).isFalse(); - } - @Override - public void onFailure(Throwable ex) { - fail(ex.getMessage()); - } - }); - waitTillDone(resultFuture); - } - - @Test - public void exchangePostCallbackWithLambdas() throws Exception { - HttpHeaders requestHeaders = new HttpHeaders(); - requestHeaders.set("MyHeader", "MyValue"); - requestHeaders.setContentType(MediaType.TEXT_PLAIN); - HttpEntity requestEntity = new HttpEntity<>(helloWorld, requestHeaders); - ListenableFuture> resultFuture = - template.exchange(baseUrl + "/{method}", HttpMethod.POST, requestEntity, Void.class, "post"); - final URI expected =new URI(baseUrl + "/post/1"); - resultFuture.addCallback(result -> { - assertThat(result.getHeaders().getLocation()).as("Invalid location").isEqualTo(expected); - assertThat(result.hasBody()).isFalse(); - }, ex -> fail(ex.getMessage())); - waitTillDone(resultFuture); - } - - @Test - public void multipartFormData() throws Exception { - MultiValueMap parts = new LinkedMultiValueMap<>(); - parts.add("name 1", "value 1"); - parts.add("name 2", "value 2+1"); - parts.add("name 2", "value 2+2"); - Resource logo = new ClassPathResource("/org/springframework/http/converter/logo.jpg"); - parts.add("logo", logo); - - HttpEntity> requestBody = new HttpEntity<>(parts); - Future future = template.postForLocation(baseUrl + "/multipartFormData", requestBody); - future.get(); - } - - @Test - public void getAndInterceptResponse() throws Exception { - RequestInterceptor interceptor = new RequestInterceptor(); - template.setInterceptors(Collections.singletonList(interceptor)); - ListenableFuture> future = template.getForEntity(baseUrl + "/get", String.class); - - interceptor.latch.await(5, TimeUnit.SECONDS); - assertThat(interceptor.response).isNotNull(); - assertThat(interceptor.response.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(interceptor.exception).isNull(); - assertThat(future.get().getBody()).isEqualTo(helloWorld); - } - - @Test - public void getAndInterceptError() throws Exception { - RequestInterceptor interceptor = new RequestInterceptor(); - template.setInterceptors(Collections.singletonList(interceptor)); - template.getForEntity(baseUrl + "/status/notfound", String.class); - - interceptor.latch.await(5, TimeUnit.SECONDS); - assertThat(interceptor.response).isNotNull(); - assertThat(interceptor.response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - assertThat(interceptor.exception).isNull(); - } - - private void waitTillDone(ListenableFuture future) { - while (!future.isDone()) { - try { - Thread.sleep(5); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - } - - - private static class RequestInterceptor implements org.springframework.http.client.AsyncClientHttpRequestInterceptor { - - private final CountDownLatch latch = new CountDownLatch(1); - - private volatile ClientHttpResponse response; - - private volatile Throwable exception; - - @Override - public ListenableFuture intercept(HttpRequest request, byte[] body, - org.springframework.http.client.AsyncClientHttpRequestExecution execution) throws IOException { - - ListenableFuture future = execution.executeAsync(request, body); - future.addCallback( - resp -> { - response = resp; - this.latch.countDown(); - }, - ex -> { - exception = ex; - this.latch.countDown(); - }); - return future; - } - } - -} diff --git a/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java b/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java index f53cf890c79b..cc684fe001bc 100644 --- a/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -92,7 +92,6 @@ static Stream clientHttpRequestFactories() { return Stream.of( new SimpleClientHttpRequestFactory(), new HttpComponentsClientHttpRequestFactory(), - new org.springframework.http.client.Netty4ClientHttpRequestFactory(), new OkHttp3ClientHttpRequestFactory() ); } diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index c299efbe5e47..c895bb9c5a4e 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -344,13 +344,6 @@ to `multipart/form-data` by the `FormHttpMessageConverter`. If the `MultiValueMa If necessary the `Content-Type` may also be set explicitly. -[[rest-async-resttemplate]] -=== Using `AsyncRestTemplate` (Deprecated) - -The `AsyncRestTemplate` is deprecated. For all use cases where you might consider using -`AsyncRestTemplate`, use the <> instead. - - [[remoting]] == Remoting and Web Services From f14bd5003373fc6ddd81b7efdedeffbdb0333685 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 8 Oct 2021 18:19:59 +0100 Subject: [PATCH 208/735] Prune empty method adapter classes --- .../support/ChannelInterceptorAdapter.java | 64 ------ .../CallableProcessingInterceptorAdapter.java | 61 ------ ...redResultProcessingInterceptorAdapter.java | 82 -------- .../annotation/WebMvcConfigurerAdapter.java | 191 ------------------ .../handler/HandlerInterceptorAdapter.java | 34 ---- 5 files changed, 432 deletions(-) delete mode 100644 spring-messaging/src/main/java/org/springframework/messaging/support/ChannelInterceptorAdapter.java delete mode 100644 spring-web/src/main/java/org/springframework/web/context/request/async/CallableProcessingInterceptorAdapter.java delete mode 100644 spring-web/src/main/java/org/springframework/web/context/request/async/DeferredResultProcessingInterceptorAdapter.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerInterceptorAdapter.java diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/ChannelInterceptorAdapter.java b/spring-messaging/src/main/java/org/springframework/messaging/support/ChannelInterceptorAdapter.java deleted file mode 100644 index a8477f58436f..000000000000 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/ChannelInterceptorAdapter.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2002-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.messaging.support; - -import org.springframework.lang.Nullable; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageChannel; - -/** - * A {@link ChannelInterceptor} base class with empty method implementations - * as a convenience. - * - * @author Mark Fisher - * @author Rossen Stoyanchev - * @since 4.0 - * @deprecated as of 5.0.7 {@link ChannelInterceptor} has default methods (made - * possible by a Java 8 baseline) and can be implemented directly without the - * need for this no-op adapter - */ -@Deprecated -public abstract class ChannelInterceptorAdapter implements ChannelInterceptor { - - @Override - public Message preSend(Message message, MessageChannel channel) { - return message; - } - - @Override - public void postSend(Message message, MessageChannel channel, boolean sent) { - } - - @Override - public void afterSendCompletion(Message message, MessageChannel channel, boolean sent, @Nullable Exception ex) { - } - - @Override - public boolean preReceive(MessageChannel channel) { - return true; - } - - @Override - public Message postReceive(Message message, MessageChannel channel) { - return message; - } - - @Override - public void afterReceiveCompletion(@Nullable Message message, MessageChannel channel, @Nullable Exception ex) { - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/CallableProcessingInterceptorAdapter.java b/spring-web/src/main/java/org/springframework/web/context/request/async/CallableProcessingInterceptorAdapter.java deleted file mode 100644 index 4c04274e7406..000000000000 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/CallableProcessingInterceptorAdapter.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.context.request.async; - -import java.util.concurrent.Callable; - -import org.springframework.web.context.request.NativeWebRequest; - -/** - * Abstract adapter class for the {@link CallableProcessingInterceptor} interface, - * for simplified implementation of individual methods. - * - * @author Rossen Stoyanchev - * @author Rob Winch - * @since 3.2 - * @deprecated as of 5.0 where CallableProcessingInterceptor has default methods - */ -@Deprecated -public abstract class CallableProcessingInterceptorAdapter implements CallableProcessingInterceptor { - - @Override - public void beforeConcurrentHandling(NativeWebRequest request, Callable task) throws Exception { - } - - @Override - public void preProcess(NativeWebRequest request, Callable task) throws Exception { - } - - @Override - public void postProcess(NativeWebRequest request, Callable task, Object concurrentResult) throws Exception { - } - - @Override - public Object handleTimeout(NativeWebRequest request, Callable task) throws Exception { - return RESULT_NONE; - } - - @Override - public Object handleError(NativeWebRequest request, Callable task, Throwable t) throws Exception { - return RESULT_NONE; - } - - @Override - public void afterCompletion(NativeWebRequest request, Callable task) throws Exception { - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/DeferredResultProcessingInterceptorAdapter.java b/spring-web/src/main/java/org/springframework/web/context/request/async/DeferredResultProcessingInterceptorAdapter.java deleted file mode 100644 index 9afac024a51a..000000000000 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/DeferredResultProcessingInterceptorAdapter.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.context.request.async; - -import org.springframework.web.context.request.NativeWebRequest; - -/** - * Abstract adapter class for the {@link DeferredResultProcessingInterceptor} - * interface for simplified implementation of individual methods. - * - * @author Rossen Stoyanchev - * @author Rob Winch - * @since 3.2 - * @deprecated as of 5.0 where DeferredResultProcessingInterceptor has default methods - */ -@Deprecated -public abstract class DeferredResultProcessingInterceptorAdapter implements DeferredResultProcessingInterceptor { - - /** - * This implementation is empty. - */ - @Override - public void beforeConcurrentHandling(NativeWebRequest request, DeferredResult deferredResult) - throws Exception { - } - - /** - * This implementation is empty. - */ - @Override - public void preProcess(NativeWebRequest request, DeferredResult deferredResult) throws Exception { - } - - /** - * This implementation is empty. - */ - @Override - public void postProcess(NativeWebRequest request, DeferredResult deferredResult, - Object concurrentResult) throws Exception { - } - - /** - * This implementation returns {@code true} by default allowing other interceptors - * to be given a chance to handle the timeout. - */ - @Override - public boolean handleTimeout(NativeWebRequest request, DeferredResult deferredResult) throws Exception { - return true; - } - - /** - * This implementation returns {@code true} by default allowing other interceptors - * to be given a chance to handle the error. - */ - @Override - public boolean handleError(NativeWebRequest request, DeferredResult deferredResult, Throwable t) - throws Exception { - return true; - } - - /** - * This implementation is empty. - */ - @Override - public void afterCompletion(NativeWebRequest request, DeferredResult deferredResult) throws Exception { - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java deleted file mode 100644 index 3c9acbf1ec72..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.config.annotation; - -import java.util.List; - -import org.springframework.format.FormatterRegistry; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.lang.Nullable; -import org.springframework.validation.MessageCodesResolver; -import org.springframework.validation.Validator; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.method.support.HandlerMethodReturnValueHandler; -import org.springframework.web.servlet.HandlerExceptionResolver; - -/** - * An implementation of {@link WebMvcConfigurer} with empty methods allowing - * subclasses to override only the methods they're interested in. - * - * @author Rossen Stoyanchev - * @since 3.1 - * @deprecated as of 5.0 {@link WebMvcConfigurer} has default methods (made - * possible by a Java 8 baseline) and can be implemented directly without the - * need for this adapter - */ -@Deprecated -public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void configurePathMatch(PathMatchConfigurer configurer) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void configureAsyncSupport(AsyncSupportConfigurer configurer) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void addFormatters(FormatterRegistry registry) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void addInterceptors(InterceptorRegistry registry) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void addCorsMappings(CorsRegistry registry) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void addViewControllers(ViewControllerRegistry registry) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void configureViewResolvers(ViewResolverRegistry registry) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void addArgumentResolvers(List argumentResolvers) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void addReturnValueHandlers(List returnValueHandlers) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void configureMessageConverters(List> converters) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void extendMessageConverters(List> converters) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void configureHandlerExceptionResolvers(List exceptionResolvers) { - } - - /** - * {@inheritDoc} - *

    This implementation is empty. - */ - @Override - public void extendHandlerExceptionResolvers(List exceptionResolvers) { - } - - /** - * {@inheritDoc} - *

    This implementation returns {@code null}. - */ - @Override - @Nullable - public Validator getValidator() { - return null; - } - - /** - * {@inheritDoc} - *

    This implementation returns {@code null}. - */ - @Override - @Nullable - public MessageCodesResolver getMessageCodesResolver() { - return null; - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerInterceptorAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerInterceptorAdapter.java deleted file mode 100644 index 9681be818dc5..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerInterceptorAdapter.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.handler; - -import org.springframework.web.servlet.AsyncHandlerInterceptor; -import org.springframework.web.servlet.HandlerInterceptor; - -/** - * Abstract adapter class for the {@link AsyncHandlerInterceptor} interface, - * for simplified implementation of pre-only/post-only interceptors. - * - * @author Juergen Hoeller - * @since 05.12.2003 - * @deprecated as of 5.3 in favor of implementing {@link HandlerInterceptor} - * and/or {@link AsyncHandlerInterceptor} directly. - */ -@Deprecated -public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor { - -} From fa3a2dc98142d397c8394e93d79749f345c149a7 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 8 Oct 2021 19:27:06 +0200 Subject: [PATCH 209/735] Upgrade to AspectJ 1.9.8 RC1 for Java 17 support See gh-27537 --- build.gradle | 2 +- spring-aspects/spring-aspects.gradle | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index ef49f6bad0d5..e872cdedb5a1 100644 --- a/build.gradle +++ b/build.gradle @@ -51,7 +51,7 @@ configure(allprojects) { project -> } dependency "com.google.code.findbugs:jsr305:3.0.2" - dependencySet(group: 'org.aspectj', version: '1.9.7') { + dependencySet(group: 'org.aspectj', version: '1.9.8.RC1') { entry 'aspectjrt' entry 'aspectjtools' entry 'aspectjweaver' diff --git a/spring-aspects/spring-aspects.gradle b/spring-aspects/spring-aspects.gradle index ec29638bf5ec..0461a8be3fb2 100644 --- a/spring-aspects/spring-aspects.gradle +++ b/spring-aspects/spring-aspects.gradle @@ -11,12 +11,12 @@ sourceSets.test.java.srcDirs = files() aspectj.version = dependencyManagement.managedVersions['org.aspectj:aspectjweaver'] compileAspectj { - sourceCompatibility "1.8" - targetCompatibility "1.8" + sourceCompatibility "17" + targetCompatibility "17" } compileTestAspectj { - sourceCompatibility "1.8" - targetCompatibility "1.8" + sourceCompatibility "17" + targetCompatibility "17" } dependencies { From 4b01370f54f284f377d2c3dbc725a886fa105e97 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 8 Oct 2021 20:41:18 +0200 Subject: [PATCH 210/735] UriTemplateRequestEntity overrides equals/hashCode Closes gh-27531 --- .../springframework/http/RequestEntity.java | 35 +++++++++++++----- .../http/RequestEntityTests.java | 36 ++++++++++++++++++- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/RequestEntity.java b/spring-web/src/main/java/org/springframework/http/RequestEntity.java index 4c77123332c6..6dd27d02db20 100644 --- a/spring-web/src/main/java/org/springframework/http/RequestEntity.java +++ b/spring-web/src/main/java/org/springframework/http/RequestEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -194,15 +194,15 @@ public boolean equals(@Nullable Object other) { return false; } RequestEntity otherEntity = (RequestEntity) other; - return (ObjectUtils.nullSafeEquals(getMethod(), otherEntity.getMethod()) && - ObjectUtils.nullSafeEquals(getUrl(), otherEntity.getUrl())); + return (ObjectUtils.nullSafeEquals(this.method, otherEntity.method) && + ObjectUtils.nullSafeEquals(this.url, otherEntity.url)); } @Override public int hashCode() { int hashCode = super.hashCode(); hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.method); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getUrl()); + hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.url); return hashCode; } @@ -544,13 +544,13 @@ private static class DefaultBodyBuilder implements BodyBuilder { private final URI uri; @Nullable - String uriTemplate; + private final String uriTemplate; @Nullable - private Object[] uriVarsArray; + private final Object[] uriVarsArray; @Nullable - Map uriVarsMap; + private final Map uriVarsMap; DefaultBodyBuilder(HttpMethod method, URI url) { this.method = method; @@ -661,7 +661,7 @@ public RequestEntity body(T body, Type type) { return buildInternal(body, type); } - private RequestEntity buildInternal(@Nullable T body, @Nullable Type type) { + private RequestEntity buildInternal(@Nullable T body, @Nullable Type type) { if (this.uri != null) { return new RequestEntity<>(body, this.headers, this.method, this.uri, type); } @@ -716,6 +716,25 @@ public Object[] getVars() { return this.uriVarsMap; } + @Override + public boolean equals(@Nullable Object other) { + if (this == other) { + return true; + } + if (!super.equals(other)) { + return false; + } + UriTemplateRequestEntity otherEntity = (UriTemplateRequestEntity) other; + return (ObjectUtils.nullSafeEquals(this.uriTemplate, otherEntity.uriTemplate) && + ObjectUtils.nullSafeEquals(this.uriVarsArray, otherEntity.uriVarsArray) && + ObjectUtils.nullSafeEquals(this.uriVarsMap, otherEntity.uriVarsMap)); + } + + @Override + public int hashCode() { + return (29 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.uriTemplate)); + } + @Override public String toString() { return format(getMethod(), getUriTemplate(), getBody(), getHeaders()); diff --git a/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java b/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java index e165ef8082d5..1c979728f9b4 100644 --- a/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java +++ b/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -175,4 +176,37 @@ void types() throws URISyntaxException { assertThat(entity.getType()).isEqualTo(typeReference.getType()); } + @Test + void equalityWithUrl() { + RequestEntity requestEntity1 = RequestEntity.method(HttpMethod.GET, "http://test.api/path/").build(); + RequestEntity requestEntity2 = RequestEntity.method(HttpMethod.GET, "http://test.api/path/").build(); + RequestEntity requestEntity3 = RequestEntity.method(HttpMethod.GET, "http://test.api/pathX/").build(); + + assertThat(requestEntity1).isEqualTo(requestEntity2); + assertThat(requestEntity2).isEqualTo(requestEntity1); + assertThat(requestEntity1).isNotEqualTo(requestEntity3); + assertThat(requestEntity3).isNotEqualTo(requestEntity2); + assertThat(requestEntity1.hashCode()).isEqualTo(requestEntity2.hashCode()); + assertThat(requestEntity1.hashCode()).isNotEqualTo(requestEntity3.hashCode()); + } + + @Test // gh-27531 + void equalityWithUriTemplate() { + Map vars = Collections.singletonMap("id", "1"); + + RequestEntity requestEntity1 = + RequestEntity.method(HttpMethod.GET, "http://test.api/path/{id}", vars).build(); + RequestEntity requestEntity2 = + RequestEntity.method(HttpMethod.GET, "http://test.api/path/{id}", vars).build(); + RequestEntity requestEntity3 = + RequestEntity.method(HttpMethod.GET, "http://test.api/pathX/{id}", vars).build(); + + assertThat(requestEntity1).isEqualTo(requestEntity2); + assertThat(requestEntity2).isEqualTo(requestEntity1); + assertThat(requestEntity1).isNotEqualTo(requestEntity3); + assertThat(requestEntity3).isNotEqualTo(requestEntity2); + assertThat(requestEntity1.hashCode()).isEqualTo(requestEntity2.hashCode()); + assertThat(requestEntity1.hashCode()).isNotEqualTo(requestEntity3.hashCode()); + } + } From 87aaf5049b81bce2a8bbb37e7aef69128f79a1e5 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 8 Oct 2021 20:41:51 +0200 Subject: [PATCH 211/735] Polishing --- .../org/springframework/core/ReactiveAdapterRegistry.java | 2 +- .../web/bind/MethodArgumentNotValidException.java | 4 ++-- .../result/method/AbstractHandlerMethodMapping.java | 6 ++---- .../mvc/support/DefaultHandlerExceptionResolver.java | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java index 0193dff6c256..9e56b5d5e37d 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -41,7 +41,7 @@ /** * A registry of adapters to adapt Reactive Streams {@link Publisher} to/from * various async/reactive types such as {@code CompletableFuture}, RxJava - * {@code Observable}, and others. + * {@code Flowable}, and others. * *

    By default, depending on classpath availability, adapters are registered * for Reactor, RxJava 3, {@link CompletableFuture}, {@code Flow.Publisher}, diff --git a/spring-web/src/main/java/org/springframework/web/bind/MethodArgumentNotValidException.java b/spring-web/src/main/java/org/springframework/web/bind/MethodArgumentNotValidException.java index e51f136e4755..3638ac1411b3 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/MethodArgumentNotValidException.java +++ b/spring-web/src/main/java/org/springframework/web/bind/MethodArgumentNotValidException.java @@ -56,8 +56,8 @@ public final MethodParameter getParameter() { @Override public String getMessage() { StringBuilder sb = new StringBuilder("Validation failed for argument [") - .append(this.parameter.getParameterIndex()).append("] in ") - .append(this.parameter.getExecutable().toGenericString()); + .append(this.parameter.getParameterIndex()).append("] in ") + .append(this.parameter.getExecutable().toGenericString()); BindingResult bindingResult = getBindingResult(); if (bindingResult.getErrorCount() > 1) { sb.append(" with ").append(bindingResult.getErrorCount()).append(" errors"); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java index 4487162cc9e6..7d59209955d6 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java @@ -157,12 +157,10 @@ public void unregisterMapping(T mapping) { */ @Override public void afterPropertiesSet() { - initHandlerMethods(); - // Total includes detected mappings + explicit registrations via registerMapping.. - int total = this.getHandlerMethods().size(); - + // Total includes detected mappings + explicit registrations via registerMapping + int total = getHandlerMethods().size(); if ((logger.isTraceEnabled() && total == 0) || (logger.isDebugEnabled() && total > 0) ) { logger.debug(total + " mappings in " + formatMappingName()); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java index acb57f665210..47bb3de32563 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java @@ -520,7 +520,7 @@ protected ModelAndView handleNoHandlerFoundException(NoHandlerFoundException ex, /** * Handle the case where an async request timed out. *

    The default implementation sends an HTTP 503 error. - * @param ex the {@link AsyncRequestTimeoutException }to be handled + * @param ex the {@link AsyncRequestTimeoutException} to be handled * @param request current HTTP request * @param response current HTTP response * @param handler the executed handler, or {@code null} if none chosen From bdfd983bb4d855218f2c07d40ddd33d754559fdb Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 8 Oct 2021 21:30:39 +0200 Subject: [PATCH 212/735] Fix example code formatting in @EnableWebMvc --- .../config/annotation/EnableWebMvc.java | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java index acdb6e05640a..2f03b7135a39 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,6 @@ * @EnableWebMvc * @ComponentScan(basePackageClasses = MyConfiguration.class) * public class MyConfiguration { - * * } * * @@ -46,15 +45,15 @@ * @ComponentScan(basePackageClasses = MyConfiguration.class) * public class MyConfiguration implements WebMvcConfigurer { * - * @Override - * public void addFormatters(FormatterRegistry formatterRegistry) { + * @Override + * public void addFormatters(FormatterRegistry formatterRegistry) { * formatterRegistry.addConverter(new MyConverter()); - * } + * } * - * @Override - * public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { + * @Override + * public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { * converters.add(new MyHttpMessageConverter()); - * } + * } * * } * @@ -66,7 +65,7 @@ * configuration. * *

    If {@link WebMvcConfigurer} does not expose some more advanced setting that - * needs to be configured consider removing the {@code @EnableWebMvc} + * needs to be configured, consider removing the {@code @EnableWebMvc} * annotation and extending directly from {@link WebMvcConfigurationSupport} * or {@link DelegatingWebMvcConfiguration}, e.g.: * @@ -75,16 +74,16 @@ * @ComponentScan(basePackageClasses = { MyConfiguration.class }) * public class MyConfiguration extends WebMvcConfigurationSupport { * - * @Override - * public void addFormatters(FormatterRegistry formatterRegistry) { + * @Override + * public void addFormatters(FormatterRegistry formatterRegistry) { * formatterRegistry.addConverter(new MyConverter()); - * } + * } * - * @Bean - * public RequestMappingHandlerAdapter requestMappingHandlerAdapter() { + * @Bean + * public RequestMappingHandlerAdapter requestMappingHandlerAdapter() { * // Create or delegate to "super" to create and * // customize properties of RequestMappingHandlerAdapter - * } + * } * } * * From 47b8e8d528e150fe595b33101daee7b9f2c1d9c6 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 10 Oct 2021 23:26:07 +0200 Subject: [PATCH 213/735] Upgrade to Mockito 4 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index af1973fefef7..3c5f9af16f2c 100644 --- a/build.gradle +++ b/build.gradle @@ -198,7 +198,7 @@ configure(allprojects) { project -> exclude group: "org.hamcrest", name: "hamcrest-core" } } - dependencySet(group: 'org.mockito', version: '3.12.4') { + dependencySet(group: 'org.mockito', version: '4.0.0') { entry('mockito-core') { exclude group: "org.hamcrest", name: "hamcrest-core" } From e8f6cd10a543d4f03da8e8a9750091ec9291e703 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 11 Oct 2021 11:14:02 +0100 Subject: [PATCH 214/735] Apply value formatting to resolved exceptions --- .../java/org/springframework/core/log/LogFormatUtils.java | 2 +- .../web/server/handler/ResponseStatusExceptionHandler.java | 6 ++++-- .../servlet/handler/AbstractHandlerExceptionResolver.java | 7 ++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java b/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java index cbcd63bf6f08..8ef04c71baf7 100644 --- a/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java +++ b/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java @@ -43,7 +43,7 @@ public abstract class LogFormatUtils { * @return the formatted value */ public static String formatValue(@Nullable Object value, boolean limitLength) { - return formatValue(value, 100, limitLength); + return formatValue(value, (limitLength ? 100 : -1), limitLength); } /** diff --git a/spring-web/src/main/java/org/springframework/web/server/handler/ResponseStatusExceptionHandler.java b/spring-web/src/main/java/org/springframework/web/server/handler/ResponseStatusExceptionHandler.java index 618200530e09..47ae9ce358ce 100644 --- a/spring-web/src/main/java/org/springframework/web/server/handler/ResponseStatusExceptionHandler.java +++ b/spring-web/src/main/java/org/springframework/web/server/handler/ResponseStatusExceptionHandler.java @@ -20,6 +20,7 @@ import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Mono; +import org.springframework.core.log.LogFormatUtils; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; @@ -81,9 +82,10 @@ else if (logger.isDebugEnabled()) { private String formatError(Throwable ex, ServerHttpRequest request) { - String reason = ex.getClass().getSimpleName() + ": " + ex.getMessage(); + String className = ex.getClass().getSimpleName(); + String message = LogFormatUtils.formatValue(ex.getMessage(), -1, true); String path = request.getURI().getRawPath(); - return "Resolved [" + reason + "] for HTTP " + request.getMethod() + " " + path; + return "Resolved [" + className + ": " + message + "] for HTTP " + request.getMethod() + " " + path; } private boolean updateResponse(ServerHttpResponse response, Throwable ex) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java index e5e2db0b6a16..e96c43987a87 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.core.Ordered; +import org.springframework.core.log.LogFormatUtils; import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerExceptionResolver; @@ -142,7 +143,7 @@ public ModelAndView resolveException( if (result != null) { // Print debug message when warn logger is not enabled. if (logger.isDebugEnabled() && (this.warnLogger == null || !this.warnLogger.isWarnEnabled())) { - logger.debug("Resolved [" + ex + "]" + (result.isEmpty() ? "" : " to " + result)); + logger.debug(buildLogMessage(ex, request) + (result.isEmpty() ? "" : " to " + result)); } // Explicitly configured warn logger in logException method. logException(ex, request); @@ -215,7 +216,7 @@ protected void logException(Exception ex, HttpServletRequest request) { * @return the log message to use */ protected String buildLogMessage(Exception ex, HttpServletRequest request) { - return "Resolved [" + ex + "]"; + return "Resolved [" + LogFormatUtils.formatValue(ex, -1, true) + "]"; } /** From 63fac1b7c871ce3c8129baf12705ee8e15a01f5c Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 10 Oct 2021 22:40:26 +0200 Subject: [PATCH 215/735] Allow default CacheAwareContextLoaderDelegate configuration via system property Prior to this commit, the default CacheAwareContextLoaderDelegate could be configured by extending AbstractTestContextBootstrapper and overriding getCacheAwareContextLoaderDelegate(); however, this required that the user configure the custom TestContextBootstrapper via @BootstrapWith. This commit introduces a new "spring.test.context.default.CacheAwareContextLoaderDelegate" property that can be configured via a JVM system property or via the SpringProperties mechanism. BootstrapUtils uses this new property to load the default CacheAwareContextLoaderDelegate. If the property is not defined, BootstrapUtils will fall back to creating a DefaultCacheAwareContextLoaderDelegate as it did previously. This allows third parties to configure the default CacheAwareContextLoaderDelegate transparently for the user -- for example, to intercept context loading in order to load the context in a different manner -- for example, to make use of ahead of time (AOT) techniques for implementing a different type of ApplicationContext at build time. Closes gh-27540 --- .../test/context/BootstrapUtils.java | 26 +++-- .../CacheAwareContextLoaderDelegate.java | 16 +++- ...tCacheAwareContextLoaderDelegateTests.java | 95 +++++++++++++++++++ 3 files changed, 127 insertions(+), 10 deletions(-) create mode 100644 spring-test/src/test/java/org/springframework/test/context/support/CustomDefaultCacheAwareContextLoaderDelegateTests.java diff --git a/spring-test/src/main/java/org/springframework/test/context/BootstrapUtils.java b/spring-test/src/main/java/org/springframework/test/context/BootstrapUtils.java index ff88ade86241..0336e4d513c1 100644 --- a/spring-test/src/main/java/org/springframework/test/context/BootstrapUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/BootstrapUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,9 +25,11 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeanUtils; +import org.springframework.core.SpringProperties; import org.springframework.lang.Nullable; import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor; import org.springframework.util.ClassUtils; +import org.springframework.util.StringUtils; /** * {@code BootstrapUtils} is a collection of utility methods to assist with @@ -65,7 +67,11 @@ abstract class BootstrapUtils { /** * Create the {@code BootstrapContext} for the specified {@linkplain Class test class}. *

    Uses reflection to create a {@link org.springframework.test.context.support.DefaultBootstrapContext} - * that uses a {@link org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate}. + * that uses a default {@link CacheAwareContextLoaderDelegate} — configured + * via the {@link CacheAwareContextLoaderDelegate#DEFAULT_CACHE_AWARE_CONTEXT_LOADER_DELEGATE_PROPERTY_NAME} + * system property or falling back to the + * {@link org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate} + * if the system property is not defined. * @param testClass the test class for which the bootstrap context should be created * @return a new {@code BootstrapContext}; never {@code null} */ @@ -90,19 +96,21 @@ static BootstrapContext createBootstrapContext(Class testClass) { @SuppressWarnings("unchecked") private static CacheAwareContextLoaderDelegate createCacheAwareContextLoaderDelegate() { - Class clazz = null; + String className = SpringProperties.getProperty( + CacheAwareContextLoaderDelegate.DEFAULT_CACHE_AWARE_CONTEXT_LOADER_DELEGATE_PROPERTY_NAME); + className = (StringUtils.hasText(className) ? className.trim() : + DEFAULT_CACHE_AWARE_CONTEXT_LOADER_DELEGATE_CLASS_NAME); try { - clazz = (Class) ClassUtils.forName( - DEFAULT_CACHE_AWARE_CONTEXT_LOADER_DELEGATE_CLASS_NAME, BootstrapUtils.class.getClassLoader()); - + Class clazz = + (Class) ClassUtils.forName( + className, BootstrapUtils.class.getClassLoader()); if (logger.isDebugEnabled()) { - logger.debug(String.format("Instantiating CacheAwareContextLoaderDelegate from class [%s]", - clazz.getName())); + logger.debug(String.format("Instantiating CacheAwareContextLoaderDelegate from class [%s]", className)); } return BeanUtils.instantiateClass(clazz, CacheAwareContextLoaderDelegate.class); } catch (Throwable ex) { - throw new IllegalStateException("Could not load CacheAwareContextLoaderDelegate [" + clazz + "]", ex); + throw new IllegalStateException("Could not create CacheAwareContextLoaderDelegate [" + className + "]", ex); } } diff --git a/spring-test/src/main/java/org/springframework/test/context/CacheAwareContextLoaderDelegate.java b/spring-test/src/main/java/org/springframework/test/context/CacheAwareContextLoaderDelegate.java index fd9e8bb6971f..d05da0c51d15 100644 --- a/spring-test/src/main/java/org/springframework/test/context/CacheAwareContextLoaderDelegate.java +++ b/spring-test/src/main/java/org/springframework/test/context/CacheAwareContextLoaderDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,20 @@ */ public interface CacheAwareContextLoaderDelegate { + /** + * System property used to configure the fully qualified class name of the + * default {@code CacheAwareContextLoaderDelegate}. + *

    May alternatively be configured via the + * {@link org.springframework.core.SpringProperties} mechanism. + *

    If this property is not defined, the + * {@link org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate + * DefaultCacheAwareContextLoaderDelegate} will be used as the default. + * @since 5.3.11 + */ + String DEFAULT_CACHE_AWARE_CONTEXT_LOADER_DELEGATE_PROPERTY_NAME = + "spring.test.context.default.CacheAwareContextLoaderDelegate"; + + /** * Determine if the {@linkplain ApplicationContext application context} for * the supplied {@link MergedContextConfiguration} has been loaded (i.e., diff --git a/spring-test/src/test/java/org/springframework/test/context/support/CustomDefaultCacheAwareContextLoaderDelegateTests.java b/spring-test/src/test/java/org/springframework/test/context/support/CustomDefaultCacheAwareContextLoaderDelegateTests.java new file mode 100644 index 000000000000..963b616354f2 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/support/CustomDefaultCacheAwareContextLoaderDelegateTests.java @@ -0,0 +1,95 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.support; + +import org.junit.jupiter.api.Test; +import org.junit.platform.testkit.engine.EngineTestKit; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.SpringProperties; +import org.springframework.test.context.CacheAwareContextLoaderDelegate; +import org.springframework.test.context.MergedContextConfiguration; +import org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; + +/** + * Integration tests for configuring a custom default {@link CacheAwareContextLoaderDelegate} + * via {@link SpringProperties}. + * + * @author sbrannen + * @since 5.3.11 + */ +class CustomDefaultCacheAwareContextLoaderDelegateTests { + + @Test + void customDefaultCacheAwareContextLoaderDelegateConfiguredViaSpringProperties() { + String key = CacheAwareContextLoaderDelegate.DEFAULT_CACHE_AWARE_CONTEXT_LOADER_DELEGATE_PROPERTY_NAME; + + try { + SpringProperties.setProperty(key, AotCacheAwareContextLoaderDelegate.class.getName()); + + EngineTestKit.engine("junit-jupiter")// + .selectors(selectClass(TestCase.class))// + .execute()// + .testEvents()// + .assertStatistics(stats -> stats.started(1).succeeded(1).failed(0)); + } + finally { + SpringProperties.setProperty(key, null); + } + } + + + @SpringJUnitConfig + static class TestCase { + + @Test + void test(@Autowired String foo) { + // foo will be "bar" unless the AotCacheAwareContextLoaderDelegate is registered. + assertThat(foo).isEqualTo("AOT"); + } + + + @Configuration + static class Config { + + @Bean + String foo() { + return "bar"; + } + } + } + + static class AotCacheAwareContextLoaderDelegate extends DefaultCacheAwareContextLoaderDelegate { + + @Override + protected ApplicationContext loadContextInternal(MergedContextConfiguration mergedContextConfiguration) { + GenericApplicationContext applicationContext = new GenericApplicationContext(); + applicationContext.registerBean("foo", String.class, () -> "AOT"); + applicationContext.refresh(); + return applicationContext; + } + } + +} From 114fa47171e666cfd2214cf436f99c267b6a2d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=A6=D1=8B=D0=BF?= =?UTF-8?q?=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Mon, 11 Oct 2021 10:55:00 +0300 Subject: [PATCH 216/735] Use Arrays.hashCode() in ByteArrayResource.hashCode() --- .../java/org/springframework/core/io/ByteArrayResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-core/src/main/java/org/springframework/core/io/ByteArrayResource.java b/spring-core/src/main/java/org/springframework/core/io/ByteArrayResource.java index 359d6b8574b1..6a2e666b6b1e 100644 --- a/spring-core/src/main/java/org/springframework/core/io/ByteArrayResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/ByteArrayResource.java @@ -126,7 +126,7 @@ public boolean equals(@Nullable Object other) { */ @Override public int hashCode() { - return (byte[].class.hashCode() * 29 * this.byteArray.length); + return Arrays.hashCode(byteArray); } } From eb07dea7958b0314fc79ea4f4b5e8ce710c169ef Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 11 Oct 2021 15:31:40 +0200 Subject: [PATCH 217/735] Polish contribution See gh-27544 --- .../java/org/springframework/core/io/ByteArrayResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/io/ByteArrayResource.java b/spring-core/src/main/java/org/springframework/core/io/ByteArrayResource.java index 6a2e666b6b1e..c5989b8330dc 100644 --- a/spring-core/src/main/java/org/springframework/core/io/ByteArrayResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/ByteArrayResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -126,7 +126,7 @@ public boolean equals(@Nullable Object other) { */ @Override public int hashCode() { - return Arrays.hashCode(byteArray); + return Arrays.hashCode(this.byteArray); } } From 83eac9af187c0151bf8039f1827649a8c3ca588f Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 11 Oct 2021 16:18:35 +0200 Subject: [PATCH 218/735] Upgrade CI to github-release resource 1.5.5 Closes gh-27459 --- ci/pipeline.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ci/pipeline.yml b/ci/pipeline.yml index b9fe3db2f917..64f6ffe3ad1a 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -46,6 +46,11 @@ resource_types: source: repository: springio/artifactory-resource tag: 0.0.17 +- name: github-release + type: registry-image + source: + repository: concourse/github-release-resource + tag: 1.5.5 - name: github-status-resource type: registry-image source: From 276aa46a1c7c4bdd8ed23bd70e569334435ab4c7 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 11 Oct 2021 16:22:30 +0200 Subject: [PATCH 219/735] Polish --- ci/README.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/README.adoc b/ci/README.adoc index cb617637d9b4..9ff0d5b1e86c 100644 --- a/ci/README.adoc +++ b/ci/README.adoc @@ -2,7 +2,7 @@ The Spring Framework uses https://concourse-ci.org/[Concourse] for its CI build and other automated tasks. The Spring team has a dedicated Concourse instance available at https://ci.spring.io with a build pipeline -for https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x[Spring Framework 5.3.x]. +for https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-6.0.x[Spring Framework 6.0.x]. === Setting up your development environment @@ -51,7 +51,7 @@ The pipeline can be deployed using the following command: [source] ---- -$ fly -t spring set-pipeline -p spring-framework-5.3.x -c ci/pipeline.yml -l ci/parameters.yml +$ fly -t spring set-pipeline -p spring-framework-6.0.x -c ci/pipeline.yml -l ci/parameters.yml ---- NOTE: This assumes that you have credhub integration configured with the appropriate secrets. From 50ccb1bfcd93318508ec656e2cfe513b2e2bc6d2 Mon Sep 17 00:00:00 2001 From: Nick Date: Thu, 30 Sep 2021 22:40:21 +0300 Subject: [PATCH 220/735] Avoid duplicate JCacheOperationSource bean registration in In our application we use XML context and declaration. Also we disable bean definition duplication by setting GenericApplicationContext.setAllowBeanDefinitionOverriding(false) in an ApplicationContextInitializer. This combination leads to a BeanDefinitionOverrideException because the DefaultJCacheOperationSource bean is registered twice. - once for: parserContext.getReaderContext().registerWithGeneratedName(sourceDef); - once for: parserContext.registerBeanComponent(new BeanComponentDefinition(sourceDef, sourceName)); This commit refactors JCacheCachingConfigurer.registerCacheAspect(...) so that the JCacheOperationSource bean is registered only once. Closes gh-27499 --- .../AnnotationDrivenCacheBeanDefinitionParser.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java index 41c0bbc7b6d5..c7466616d496 100644 --- a/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java +++ b/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java @@ -245,16 +245,20 @@ private static void registerCacheAdvisor(Element element, ParserContext parserCo private static void registerCacheAspect(Element element, ParserContext parserContext) { if (!parserContext.getRegistry().containsBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)) { Object eleSource = parserContext.extractSource(element); + + BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, eleSource); + String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef); + RootBeanDefinition def = new RootBeanDefinition(); def.setBeanClassName(JCACHE_ASPECT_CLASS_NAME); def.setFactoryMethodName("aspectOf"); - BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, eleSource); - String sourceName = - parserContext.getReaderContext().registerWithGeneratedName(sourceDef); def.getPropertyValues().add("cacheOperationSource", new RuntimeBeanReference(sourceName)); + parserContext.getRegistry().registerBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME, def); - parserContext.registerBeanComponent(new BeanComponentDefinition(sourceDef, sourceName)); - parserContext.registerBeanComponent(new BeanComponentDefinition(def, CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)); + CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource); + compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName)); + compositeDef.addNestedComponent(new BeanComponentDefinition(def, CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)); + parserContext.registerComponent(compositeDef); } } From 5bd90538b32a84fd84026bceeae17b901cc39910 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 12 Oct 2021 12:22:24 +0200 Subject: [PATCH 221/735] Introduce test for gh-27499 and polish contribution --- .../JCacheAspectJNamespaceConfigTests.java | 11 ++++++--- ...tationDrivenCacheBeanDefinitionParser.java | 24 +++++++++---------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/spring-aspects/src/test/java/org/springframework/cache/aspectj/JCacheAspectJNamespaceConfigTests.java b/spring-aspects/src/test/java/org/springframework/cache/aspectj/JCacheAspectJNamespaceConfigTests.java index 81ba6d0faff9..c755d8c3f4aa 100644 --- a/spring-aspects/src/test/java/org/springframework/cache/aspectj/JCacheAspectJNamespaceConfigTests.java +++ b/spring-aspects/src/test/java/org/springframework/cache/aspectj/JCacheAspectJNamespaceConfigTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,13 +22,18 @@ /** * @author Stephane Nicoll + * @author Sam Brannen */ public class JCacheAspectJNamespaceConfigTests extends AbstractJCacheAnnotationTests { @Override protected ApplicationContext getApplicationContext() { - return new GenericXmlApplicationContext( - "/org/springframework/cache/config/annotation-jcache-aspectj.xml"); + GenericXmlApplicationContext context = new GenericXmlApplicationContext(); + // Disallow bean definition overriding to test https://github.com/spring-projects/spring-framework/pull/27499 + context.setAllowBeanDefinitionOverriding(false); + context.load("/org/springframework/cache/config/annotation-jcache-aspectj.xml"); + context.refresh(); + return context; } } diff --git a/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java index c7466616d496..f2768059a0db 100644 --- a/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java +++ b/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -244,20 +244,20 @@ private static void registerCacheAdvisor(Element element, ParserContext parserCo private static void registerCacheAspect(Element element, ParserContext parserContext) { if (!parserContext.getRegistry().containsBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)) { - Object eleSource = parserContext.extractSource(element); + Object source = parserContext.extractSource(element); - BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, eleSource); - String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef); + BeanDefinition cacheOperationSourceDef = createJCacheOperationSourceBeanDefinition(element, source); + String cacheOperationSourceName = parserContext.getReaderContext().registerWithGeneratedName(cacheOperationSourceDef); - RootBeanDefinition def = new RootBeanDefinition(); - def.setBeanClassName(JCACHE_ASPECT_CLASS_NAME); - def.setFactoryMethodName("aspectOf"); - def.getPropertyValues().add("cacheOperationSource", new RuntimeBeanReference(sourceName)); - parserContext.getRegistry().registerBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME, def); + RootBeanDefinition jcacheAspectDef = new RootBeanDefinition(); + jcacheAspectDef.setBeanClassName(JCACHE_ASPECT_CLASS_NAME); + jcacheAspectDef.setFactoryMethodName("aspectOf"); + jcacheAspectDef.getPropertyValues().add("cacheOperationSource", new RuntimeBeanReference(cacheOperationSourceName)); + parserContext.getRegistry().registerBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME, jcacheAspectDef); - CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource); - compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName)); - compositeDef.addNestedComponent(new BeanComponentDefinition(def, CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)); + CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source); + compositeDef.addNestedComponent(new BeanComponentDefinition(cacheOperationSourceDef, cacheOperationSourceName)); + compositeDef.addNestedComponent(new BeanComponentDefinition(jcacheAspectDef, CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)); parserContext.registerComponent(compositeDef); } } From a2c52a97babdb927d809ad55c696c42d160d4fff Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 12 Oct 2021 11:59:39 +0100 Subject: [PATCH 222/735] Filter non-existing static resource locations See gh-27538 --- .../resource/ResourceHttpRequestHandler.java | 10 ++++++++-- .../ResourceHttpRequestHandlerTests.java | 20 ++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index ed49cf3cd201..0831a2a2f29b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.stream.Collectors; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -424,6 +425,7 @@ public void afterPropertiesSet() throws Exception { } private void resolveResourceLocations() { + List result = new ArrayList<>(); if (!this.locationValues.isEmpty()) { ApplicationContext applicationContext = obtainApplicationContext(); for (String location : this.locationValues) { @@ -452,7 +454,7 @@ private void resolveResourceLocations() { "but resolved to a Resource of type: " + resource.getClass() + ". " + "If this is intentional, please pass it as a pre-configured Resource via setLocations."); } - this.locationsToUse.add(resource); + result.add(resource); if (charset != null) { if (!(resource instanceof UrlResource)) { throw new IllegalArgumentException("Unexpected charset for non-UrlResource: " + resource); @@ -461,7 +463,11 @@ private void resolveResourceLocations() { } } } - this.locationsToUse.addAll(this.locationResources); + + result.addAll(this.locationResources); + result = result.stream().filter(Resource::exists).collect(Collectors.toList()); + + this.locationsToUse.addAll(result); } /** diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index 6ced3a30d33e..2d3ce439569b 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -312,6 +312,24 @@ public String getMimeType(String filePath) { assertThat(this.response.getContentAsString()).isEqualTo("h1 { color:red; }"); } + @Test // gh-27538 + public void filterNonExistingLocations() throws Exception { + List inputLocations = Arrays.asList( + new ClassPathResource("test/", getClass()), + new ClassPathResource("testalternatepath/", getClass()), + new ClassPathResource("nosuchpath/", getClass())); + + ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler(); + handler.setServletContext(new MockServletContext()); + handler.setLocations(inputLocations); + handler.afterPropertiesSet(); + + List actual = handler.getLocations(); + assertThat(actual).hasSize(2); + assertThat(actual.get(0).getURL().toString()).endsWith("test/"); + assertThat(actual.get(1).getURL().toString()).endsWith("testalternatepath/"); + } + @Test public void testInvalidPath() throws Exception { From 1490d27d7581e3741a10252d9ed0bdb81a8dbf34 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 12 Oct 2021 15:10:19 +0200 Subject: [PATCH 223/735] Decouple urlResourceWithCharset test from existence of tmp directory See gh-25738 --- .../ResourceHandlerRegistryTests.java | 30 +++++++++---------- .../ResourceHttpRequestHandlerTests.java | 8 ++--- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java index cce273a24937..fccde83979de 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java @@ -27,7 +27,6 @@ import org.springframework.cache.concurrent.ConcurrentMapCache; import org.springframework.core.io.Resource; -import org.springframework.core.io.UrlResource; import org.springframework.http.CacheControl; import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.context.support.GenericWebApplicationContext; @@ -64,7 +63,7 @@ public class ResourceHandlerRegistryTests { @BeforeEach - public void setUp() { + public void setup() { GenericWebApplicationContext appContext = new GenericWebApplicationContext(); appContext.refresh(); @@ -76,8 +75,14 @@ public void setUp() { this.response = new MockHttpServletResponse(); } + private ResourceHttpRequestHandler getHandler(String pathPattern) { + SimpleUrlHandlerMapping hm = (SimpleUrlHandlerMapping) this.registry.getHandlerMapping(); + return (ResourceHttpRequestHandler) hm.getUrlMap().get(pathPattern); + } + + @Test - public void noResourceHandlers() throws Exception { + public void noResourceHandlers() { this.registry = new ResourceHandlerRegistry(new GenericWebApplicationContext(), new MockServletContext()); assertThat((Object) this.registry.getHandlerMapping()).isNull(); } @@ -126,7 +131,7 @@ public void hasMappingForPattern() { } @Test - public void resourceChain() throws Exception { + public void resourceChain() { ResourceResolver mockResolver = Mockito.mock(ResourceResolver.class); ResourceTransformer mockTransformer = Mockito.mock(ResourceTransformer.class); this.registration.resourceChain(true).addResolver(mockResolver).addTransformer(mockTransformer); @@ -148,7 +153,7 @@ public void resourceChain() throws Exception { } @Test - public void resourceChainWithoutCaching() throws Exception { + public void resourceChainWithoutCaching() { this.registration.resourceChain(false); ResourceHttpRequestHandler handler = getHandler("/resources/**"); @@ -163,7 +168,7 @@ public void resourceChainWithoutCaching() throws Exception { @Test @SuppressWarnings("deprecation") - public void resourceChainWithVersionResolver() throws Exception { + public void resourceChainWithVersionResolver() { VersionResourceResolver versionResolver = new VersionResourceResolver() .addFixedVersionStrategy("fixed", "/**/*.js") .addContentVersionStrategy("/**"); @@ -188,7 +193,7 @@ public void resourceChainWithVersionResolver() throws Exception { @Test @SuppressWarnings("deprecation") - public void resourceChainWithOverrides() throws Exception { + public void resourceChainWithOverrides() { CachingResourceResolver cachingResolver = Mockito.mock(CachingResourceResolver.class); VersionResourceResolver versionResolver = Mockito.mock(VersionResourceResolver.class); WebJarsResourceResolver webjarsResolver = Mockito.mock(WebJarsResourceResolver.class); @@ -224,13 +229,11 @@ public void resourceChainWithOverrides() throws Exception { } @Test - public void urlResourceWithCharset() throws Exception { + public void urlResourceWithCharset() { this.registration.addResourceLocations("[charset=ISO-8859-1]file:///tmp"); this.registration.resourceChain(true); ResourceHttpRequestHandler handler = getHandler("/resources/**"); - UrlResource resource = (UrlResource) handler.getLocations().get(1); - assertThat(resource.getURL().toString()).isEqualTo("file:/tmp"); assertThat(handler.getUrlPathHelper()).isNotNull(); List resolvers = handler.getResourceResolvers(); @@ -241,15 +244,10 @@ public void urlResourceWithCharset() throws Exception { } @Test - void lastModifiedDisabled() { + public void lastModifiedDisabled() { this.registration.setUseLastModified(false); ResourceHttpRequestHandler handler = getHandler("/resources/**"); assertThat(handler.isUseLastModified()).isFalse(); } - private ResourceHttpRequestHandler getHandler(String pathPattern) { - SimpleUrlHandlerMapping hm = (SimpleUrlHandlerMapping) this.registry.getHandlerMapping(); - return (ResourceHttpRequestHandler) hm.getUrlMap().get(pathPattern); - } - } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index 2d3ce439569b..9aefd7f9d07b 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -290,7 +290,6 @@ public void getMediaTypeWithFavorPathExtensionOff() throws Exception { @Test // SPR-14368 public void getResourceWithMediaTypeResolvedThroughServletContext() throws Exception { - MockServletContext servletContext = new MockServletContext() { @Override public String getMimeType(String filePath) { @@ -312,7 +311,7 @@ public String getMimeType(String filePath) { assertThat(this.response.getContentAsString()).isEqualTo("h1 { color:red; }"); } - @Test // gh-27538 + @Test // gh-27538 public void filterNonExistingLocations() throws Exception { List inputLocations = Arrays.asList( new ClassPathResource("test/", getClass()), @@ -332,7 +331,6 @@ public void filterNonExistingLocations() throws Exception { @Test public void testInvalidPath() throws Exception { - // Use mock ResourceResolver: i.e. we're only testing upfront validations... Resource resource = mock(Resource.class); @@ -678,7 +676,7 @@ public void partialContentMultipleByteRanges() throws Exception { assertThat(ranges[11]).isEqualTo("t."); } - @Test // gh-25976 + @Test // gh-25976 public void partialContentByteRangeWithEncodedResource(GzipSupport.GzippedFiles gzippedFiles) throws Exception { String path = "js/foo.js"; gzippedFiles.create(path); @@ -707,7 +705,7 @@ public void partialContentByteRangeWithEncodedResource(GzipSupport.GzippedFiles assertThat(this.response.getHeaderValues("Vary")).containsExactly("Accept-Encoding"); } - @Test // gh-25976 + @Test // gh-25976 public void partialContentWithHttpHead() throws Exception { this.request.setMethod("HEAD"); this.request.addHeader("Range", "bytes=0-1"); From b53275f2d2344ce3ad52dfbd7be7183fbb093789 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 12 Oct 2021 15:13:05 +0200 Subject: [PATCH 224/735] Add efficient existence check to ClassPathResource.isReadable() Includes reduced isReadable() check in PathResourceLookupFunction, aligned with PathResourceResolver. Closes gh-27538 See gh-21372 --- .../core/io/AbstractFileResolvingResource.java | 12 ++++++++++-- .../springframework/core/io/ClassPathResource.java | 12 ++++++++++++ .../function/server/PathResourceLookupFunction.java | 4 ++-- .../servlet/function/PathResourceLookupFunction.java | 4 ++-- 4 files changed, 26 insertions(+), 6 deletions(-) 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 958b3babce7c..ac9ea29a5dca 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,7 +88,15 @@ else if (code == HttpURLConnection.HTTP_NOT_FOUND) { @Override public boolean isReadable() { try { - URL url = getURL(); + return checkReadable(getURL()); + } + catch (IOException ex) { + return false; + } + } + + boolean checkReadable(URL url) { + try { if (ResourceUtils.isFileURL(url)) { // Proceed with file system resolution File file = getFile(); diff --git a/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java b/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java index 6374f2768b9d..f99adce06ce4 100644 --- a/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java @@ -142,6 +142,18 @@ public boolean exists() { return (resolveURL() != null); } + /** + * This implementation checks for the resolution of a resource URL upfront, + * then proceeding with {@link AbstractFileResolvingResource}'s length check. + * @see java.lang.ClassLoader#getResource(String) + * @see java.lang.Class#getResource(String) + */ + @Override + public boolean isReadable() { + URL url = resolveURL(); + return (url != null && checkReadable(url)); + } + /** * Resolves a URL for the underlying class path resource. * @return the resolved URL, or {@code null} if not resolvable diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/PathResourceLookupFunction.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/PathResourceLookupFunction.java index e17cca7906e4..60caf7c19e38 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/PathResourceLookupFunction.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/PathResourceLookupFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +72,7 @@ public Mono apply(ServerRequest request) { try { Resource resource = this.location.createRelative(path); - if (resource.exists() && resource.isReadable() && isResourceUnderLocation(resource)) { + if (resource.isReadable() && isResourceUnderLocation(resource)) { return Mono.just(resource); } else { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/PathResourceLookupFunction.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/PathResourceLookupFunction.java index 7079290f30a0..c37bbfdce919 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/PathResourceLookupFunction.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/PathResourceLookupFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,7 +71,7 @@ public Optional apply(ServerRequest request) { try { Resource resource = this.location.createRelative(path); - if (resource.exists() && resource.isReadable() && isResourceUnderLocation(resource)) { + if (resource.isReadable() && isResourceUnderLocation(resource)) { return Optional.of(resource); } else { From 715f300fa11e4c20a7aaa9f9ac8439fc4072b00b Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 12 Oct 2021 15:15:51 +0200 Subject: [PATCH 225/735] Avoid expensive isReadable() check during classpath scan Closes gh-25741 See gh-21372 --- ...athScanningCandidateComponentProvider.java | 47 +++++++++---------- .../core/io/InputStreamSource.java | 5 +- .../LocalSessionFactoryBuilder.java | 8 +++- .../DefaultPersistenceUnitManager.java | 8 +++- 4 files changed, 38 insertions(+), 30 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java b/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java index 05ea7a5159a5..92d502a13f0b 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.context.annotation; +import java.io.FileNotFoundException; import java.io.IOException; import java.lang.annotation.Annotation; import java.util.ArrayList; @@ -424,40 +425,38 @@ private Set scanCandidateComponents(String basePackage) { if (traceEnabled) { logger.trace("Scanning " + resource); } - if (resource.isReadable()) { - try { - MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource); - if (isCandidateComponent(metadataReader)) { - ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); - sbd.setSource(resource); - if (isCandidateComponent(sbd)) { - if (debugEnabled) { - logger.debug("Identified candidate component class: " + resource); - } - candidates.add(sbd); - } - else { - if (debugEnabled) { - logger.debug("Ignored because not a concrete top-level class: " + resource); - } + try { + MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource); + if (isCandidateComponent(metadataReader)) { + ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); + sbd.setSource(resource); + if (isCandidateComponent(sbd)) { + if (debugEnabled) { + logger.debug("Identified candidate component class: " + resource); } + candidates.add(sbd); } else { - if (traceEnabled) { - logger.trace("Ignored because not matching any filter: " + resource); + if (debugEnabled) { + logger.debug("Ignored because not a concrete top-level class: " + resource); } } } - catch (Throwable ex) { - throw new BeanDefinitionStoreException( - "Failed to read candidate component class: " + resource, ex); + else { + if (traceEnabled) { + logger.trace("Ignored because not matching any filter: " + resource); + } } } - else { + catch (FileNotFoundException ex) { if (traceEnabled) { - logger.trace("Ignored because not readable: " + resource); + logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage()); } } + catch (Throwable ex) { + throw new BeanDefinitionStoreException( + "Failed to read candidate component class: " + resource, ex); + } } } catch (IOException ex) { diff --git a/spring-core/src/main/java/org/springframework/core/io/InputStreamSource.java b/spring-core/src/main/java/org/springframework/core/io/InputStreamSource.java index b769895ece77..8d72c9cd8bbc 100644 --- a/spring-core/src/main/java/org/springframework/core/io/InputStreamSource.java +++ b/spring-core/src/main/java/org/springframework/core/io/InputStreamSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,8 +48,9 @@ public interface InputStreamSource { * creating mail attachments. For such a use case, it is required * that each {@code getInputStream()} call returns a fresh stream. * @return the input stream for the underlying resource (must not be {@code null}) - * @throws java.io.FileNotFoundException if the underlying resource doesn't exist + * @throws java.io.FileNotFoundException if the underlying resource does not exist * @throws IOException if the content stream could not be opened + * @see Resource#isReadable() */ InputStream getInputStream() throws IOException; diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java index 9011db8fb55b..a21b13579ed1 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.orm.hibernate5; +import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; @@ -320,7 +321,7 @@ public LocalSessionFactoryBuilder scanPackages(String... packagesToScan) throws Resource[] resources = this.resourcePatternResolver.getResources(pattern); MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver); for (Resource resource : resources) { - if (resource.isReadable()) { + try { MetadataReader reader = readerFactory.getMetadataReader(resource); String className = reader.getClassMetadata().getClassName(); if (matchesEntityTypeFilter(reader, readerFactory)) { @@ -333,6 +334,9 @@ else if (className.endsWith(PACKAGE_INFO_SUFFIX)) { packageNames.add(className.substring(0, className.length() - PACKAGE_INFO_SUFFIX.length())); } } + catch (FileNotFoundException ex) { + // Ignore non-readable resource + } } } } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java index 8e2fd410d54b..310e2e55e4e1 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.orm.jpa.persistenceunit; +import java.io.FileNotFoundException; import java.io.IOException; import java.net.URL; import java.util.ArrayList; @@ -585,7 +586,7 @@ private void scanPackage(SpringPersistenceUnitInfo scannedUnit, String pkg) { Resource[] resources = this.resourcePatternResolver.getResources(pattern); MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver); for (Resource resource : resources) { - if (resource.isReadable()) { + try { MetadataReader reader = readerFactory.getMetadataReader(resource); String className = reader.getClassMetadata().getClassName(); if (matchesFilter(reader, readerFactory)) { @@ -602,6 +603,9 @@ else if (className.endsWith(PACKAGE_INFO_SUFFIX)) { className.substring(0, className.length() - PACKAGE_INFO_SUFFIX.length())); } } + catch (FileNotFoundException ex) { + // Ignore non-readable resource + } } } catch (IOException ex) { From e4934a90ebf22adfde31a8e44b32d88cae5ed7c1 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 12 Oct 2021 15:17:18 +0200 Subject: [PATCH 226/735] Use TriggerContext's Clock instead of new Date() Closes gh-27546 --- .../org/springframework/scheduling/support/CronTrigger.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/CronTrigger.java b/spring-context/src/main/java/org/springframework/scheduling/support/CronTrigger.java index 3af71481c27d..6581cdd61fe0 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/CronTrigger.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/CronTrigger.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -105,11 +105,11 @@ public Date nextExecutionTime(TriggerContext triggerContext) { } } else { - date = new Date(); + date = new Date(triggerContext.getClock().millis()); } ZonedDateTime dateTime = ZonedDateTime.ofInstant(date.toInstant(), this.zoneId); ZonedDateTime next = this.expression.next(dateTime); - return next != null ? Date.from(next.toInstant()) : null; + return (next != null ? Date.from(next.toInstant()) : null); } From eda3ca5fbc3520f22cecd726e211dca053a8cb99 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 12 Oct 2021 15:17:44 +0200 Subject: [PATCH 227/735] Remove unnecessary final declarations at method level --- .../beans/factory/xml/ParserContext.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java index 2223f789ae1c..4bd6ef58e966 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,24 +64,24 @@ public ParserContext(XmlReaderContext readerContext, BeanDefinitionParserDelegat } - public final XmlReaderContext getReaderContext() { + public XmlReaderContext getReaderContext() { return this.readerContext; } - public final BeanDefinitionRegistry getRegistry() { + public BeanDefinitionRegistry getRegistry() { return this.readerContext.getRegistry(); } - public final BeanDefinitionParserDelegate getDelegate() { + public BeanDefinitionParserDelegate getDelegate() { return this.delegate; } @Nullable - public final BeanDefinition getContainingBeanDefinition() { + public BeanDefinition getContainingBeanDefinition() { return this.containingBeanDefinition; } - public final boolean isNested() { + public boolean isNested() { return (this.containingBeanDefinition != null); } From 800922266ab46c20cadd41dabfd3a4bce97ee3e0 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 12 Oct 2021 16:23:10 +0100 Subject: [PATCH 228/735] Upgrade to Reactor 2021.0.12 Closes gh-27527 --- build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 3c5f9af16f2c..015d5c019801 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ configure(allprojects) { project -> imports { mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5" mavenBom "io.netty:netty-bom:4.1.68.Final" - mavenBom "io.projectreactor:reactor-bom:2020.0.12-SNAPSHOT" + mavenBom "io.projectreactor:reactor-bom:2020.0.12" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" mavenBom "io.rsocket:rsocket-bom:1.1.1" mavenBom "org.eclipse.jetty:jetty-bom:9.4.43.v20210629" @@ -292,7 +292,6 @@ configure(allprojects) { project -> repositories { mavenCentral() maven { url "https://repo.spring.io/libs-spring-framework-build" } - maven { url "https://repo.spring.io/snapshot" } // reactor } } configurations.all { From 8820c893e64ffe83b2ba90f5e820c291507517a6 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 12 Oct 2021 17:23:47 +0200 Subject: [PATCH 229/735] Add note about Groovy Tools not working in Eclipse 2021-09 with Java 17 Closes gh-27407 --- import-into-eclipse.md | 1 + 1 file changed, 1 insertion(+) diff --git a/import-into-eclipse.md b/import-into-eclipse.md index 1ab36c1fcfd3..d2a8b154bbd5 100644 --- a/import-into-eclipse.md +++ b/import-into-eclipse.md @@ -21,6 +21,7 @@ from the Eclipse Marketplace. _When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._ 1. Install the [Groovy Development Tools](https://marketplace.eclipse.org/content/groovy-development-tools). + - **NOTE**: As of October 12, 2021, the Groovy Development Tools do not work in Eclipse 2021-09 (4.21). See [Groovy Eclipse #1303](https://github.com/groovy/groovy-eclipse/issues/1303) for details. 1. Switch to Groovy 3.0 in Eclipse (Preferences → Groovy → Compiler → Switch to 3.0...). - If you encounter build errors stating something similar to _"Groovy: compiler mismatch: project level is 2.5, workspace level is 3.0"_, change the Groovy compiler version to 3.0 for each affected project. 1. Ensure that the _Forbidden reference (access rule)_ in Eclipse is set to `Info` From 2cbba0923b17af2e29e7a8e99fa737279d11e832 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 13 Oct 2021 12:38:06 +0200 Subject: [PATCH 230/735] Upgrade to Netty 4.1.69, Jetty 9.4.44, Kotlin 1.5.31 --- build.gradle | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index 015d5c019801..8ff65cc6f42b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,17 +1,17 @@ plugins { id 'io.spring.dependency-management' version '1.0.11.RELEASE' apply false id 'io.spring.nohttp' version '0.0.10' - id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false + id "io.freefair.aspectj" version '6.2.0' apply false id 'org.jetbrains.dokka' version '1.5.0' apply false + id 'org.jetbrains.kotlin.jvm' version '1.5.31' apply false + id "org.jetbrains.kotlin.plugin.serialization" version "1.5.31" apply false id 'org.asciidoctor.jvm.convert' version '3.3.2' id 'org.asciidoctor.jvm.pdf' version '3.3.2' - id 'de.undercouch.download' version '4.1.2' - id "io.freefair.aspectj" version '6.2.0' apply false + id "org.unbroken-dome.xjc" version '2.0.0' apply false id "com.github.ben-manes.versions" version '0.39.0' id "com.github.johnrengelman.shadow" version '7.0.0' apply false + id 'de.undercouch.download' version '4.1.2' id "me.champeau.jmh" version "0.6.6" apply false - id "org.jetbrains.kotlin.plugin.serialization" version "1.5.30" apply false - id "org.unbroken-dome.xjc" version '2.0.0' apply false } ext { @@ -28,12 +28,12 @@ configure(allprojects) { project -> dependencyManagement { imports { mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5" - mavenBom "io.netty:netty-bom:4.1.68.Final" + mavenBom "io.netty:netty-bom:4.1.69.Final" mavenBom "io.projectreactor:reactor-bom:2020.0.12" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" mavenBom "io.rsocket:rsocket-bom:1.1.1" - mavenBom "org.eclipse.jetty:jetty-bom:9.4.43.v20210629" - mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.30" + mavenBom "org.eclipse.jetty:jetty-bom:9.4.44.v20210927" + mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.31" mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2" mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2" mavenBom "org.junit:junit-bom:5.8.1" From 0f36569d75b814a43b081d5a8036534fc1090d62 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 13 Oct 2021 12:38:39 +0200 Subject: [PATCH 231/735] Remove dead fallback code --- .../config/FreeMarkerConfigurerBeanDefinitionParser.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/FreeMarkerConfigurerBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/FreeMarkerConfigurerBeanDefinitionParser.java index 30b3716999bb..7524e63a63b9 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/FreeMarkerConfigurerBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/FreeMarkerConfigurerBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,9 +61,6 @@ protected void doParse(Element element, ParserContext parserContext, BeanDefinit for (Element childElement : childElements) { locations.add(childElement.getAttribute("location")); } - if (locations.isEmpty()) { - locations.add("/WEB-INF/"); - } builder.addPropertyValue("templateLoaderPaths", StringUtils.toStringArray(locations)); } } From b1c7f7d12732d820b144781c919351d933995424 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 13 Oct 2021 12:48:47 +0200 Subject: [PATCH 232/735] Polishing --- .../pattern/CaptureTheRestPathElement.java | 19 +++++------ .../pattern/CaptureVariablePathElement.java | 27 ++++++++-------- .../web/util/pattern/LiteralPathElement.java | 9 +++--- .../web/util/pattern/PathPattern.java | 12 +++---- .../util/pattern/PatternParseException.java | 14 ++++---- .../web/util/pattern/RegexPathElement.java | 32 +++++++++---------- .../util/pattern/SeparatorPathElement.java | 11 ++++--- .../SingleCharWildcardedPathElement.java | 12 +++---- .../web/util/pattern/WildcardPathElement.java | 11 ++++--- .../pattern/WildcardTheRestPathElement.java | 11 ++++--- 10 files changed, 82 insertions(+), 76 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureTheRestPathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureTheRestPathElement.java index 4cf59596397b..3ee4ff2ebac0 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureTheRestPathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureTheRestPathElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83,17 +83,17 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) { } private String pathToString(int fromSegment, List pathElements) { - StringBuilder buf = new StringBuilder(); + StringBuilder sb = new StringBuilder(); for (int i = fromSegment, max = pathElements.size(); i < max; i++) { Element element = pathElements.get(i); if (element instanceof PathSegment) { - buf.append(((PathSegment)element).valueToMatch()); + sb.append(((PathSegment)element).valueToMatch()); } else { - buf.append(element.value()); + sb.append(element.value()); } } - return buf.toString(); + return sb.toString(); } @Override @@ -101,6 +101,11 @@ public int getNormalizedLength() { return 1; } + @Override + public char[] getChars() { + return ("/{*" + this.variableName + "}").toCharArray(); + } + @Override public int getWildcardCount() { return 0; @@ -117,8 +122,4 @@ public String toString() { return "CaptureTheRest(/{*" + this.variableName + "})"; } - @Override - public char[] getChars() { - return ("/{*"+this.variableName+"}").toCharArray(); - } } diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java index 0e7b812323c9..856c35af986d 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java @@ -35,7 +35,7 @@ class CaptureVariablePathElement extends PathElement { private final String variableName; @Nullable - private Pattern constraintPattern; + private final Pattern constraintPattern; /** @@ -55,6 +55,7 @@ class CaptureVariablePathElement extends PathElement { if (colon == -1) { // no constraint this.variableName = new String(captureDescriptor, 1, captureDescriptor.length - 2); + this.constraintPattern = null; } else { this.variableName = new String(captureDescriptor, 1, colon - 1); @@ -134,6 +135,18 @@ public int getNormalizedLength() { return 1; } + @Override + public char[] getChars() { + StringBuilder sb = new StringBuilder(); + sb.append('{'); + sb.append(this.variableName); + if (this.constraintPattern != null) { + sb.append(':').append(this.constraintPattern.pattern()); + } + sb.append('}'); + return sb.toString().toCharArray(); + } + @Override public int getWildcardCount() { return 0; @@ -156,16 +169,4 @@ public String toString() { (this.constraintPattern != null ? ":" + this.constraintPattern.pattern() : "") + "})"; } - @Override - public char[] getChars() { - StringBuilder b = new StringBuilder(); - b.append('{'); - b.append(this.variableName); - if (this.constraintPattern != null) { - b.append(':').append(this.constraintPattern.pattern()); - } - b.append('}'); - return b.toString().toCharArray(); - } - } diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java index 224d5d721708..70160199f726 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,14 +26,15 @@ * literal path elements 'foo', 'bar' and 'goo'. * * @author Andy Clement + * @since 5.0 */ class LiteralPathElement extends PathElement { - private char[] text; + private final char[] text; - private int len; + private final int len; - private boolean caseSensitive; + private final boolean caseSensitive; public LiteralPathElement(int pos, char[] literalText, boolean caseSensitive, char separator) { diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java b/spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java index 777b83720e30..ba87fd6b6f75 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java @@ -336,18 +336,18 @@ public PathContainer extractPathWithinPattern(PathContainer path) { PathContainer resultPath = null; if (multipleAdjacentSeparators) { // Need to rebuild the path without the duplicate adjacent separators - StringBuilder buf = new StringBuilder(); + StringBuilder sb = new StringBuilder(); int i = startIndex; while (i < endIndex) { Element e = pathElements.get(i++); - buf.append(e.value()); + sb.append(e.value()); if (e instanceof Separator) { while (i < endIndex && (pathElements.get(i) instanceof Separator)) { i++; } } } - resultPath = PathContainer.parsePath(buf.toString(), this.pathOptions); + resultPath = PathContainer.parsePath(sb.toString(), this.pathOptions); } else if (startIndex >= endIndex) { resultPath = PathContainer.parsePath(""); @@ -491,13 +491,13 @@ String toChainString() { * @return the string form of the pattern */ String computePatternString() { - StringBuilder buf = new StringBuilder(); + StringBuilder sb = new StringBuilder(); PathElement pe = this.head; while (pe != null) { - buf.append(pe.getChars()); + sb.append(pe.getChars()); pe = pe.next; } - return buf.toString(); + return sb.toString(); } @Nullable diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/PatternParseException.java b/spring-web/src/main/java/org/springframework/web/util/pattern/PatternParseException.java index 824357596375..1e49751da82c 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/PatternParseException.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/PatternParseException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,14 +66,14 @@ public String getMessage() { * with a pointer to the error position, as well as the error message. */ public String toDetailedString() { - StringBuilder buf = new StringBuilder(); - buf.append(this.pattern).append('\n'); + StringBuilder sb = new StringBuilder(); + sb.append(this.pattern).append('\n'); for (int i = 0; i < this.position; i++) { - buf.append(' '); + sb.append(' '); } - buf.append("^\n"); - buf.append(getMessage()); - return buf.toString(); + sb.append("^\n"); + sb.append(getMessage()); + return sb.toString(); } public int getPosition() { diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java index cdbad924bb4f..c5cd8f588ff2 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java @@ -136,20 +136,19 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) { if (matches) { if (isNoMorePattern()) { if (matchingContext.determineRemainingPath && - (this.variableNames.isEmpty() || textToMatch.length() > 0)) { + (this.variableNames.isEmpty() || textToMatch.length() > 0)) { matchingContext.remainingPathIndex = pathIndex + 1; matches = true; } else { // No more pattern, is there more data? // If pattern is capturing variables there must be some actual data to bind to them - matches = (pathIndex + 1) >= matchingContext.pathLength - && (this.variableNames.isEmpty() || textToMatch.length() > 0); + matches = (pathIndex + 1 >= matchingContext.pathLength) && + (this.variableNames.isEmpty() || textToMatch.length() > 0); if (!matches && matchingContext.isMatchOptionalTrailingSeparator()) { - matches = (this.variableNames.isEmpty() - || textToMatch.length() > 0) - && (pathIndex + 2) >= matchingContext.pathLength - && matchingContext.isSeparator(pathIndex + 1); + matches = (this.variableNames.isEmpty() || textToMatch.length() > 0) && + (pathIndex + 2 >= matchingContext.pathLength) && + matchingContext.isSeparator(pathIndex + 1); } } } @@ -160,11 +159,11 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) { if (matches && matchingContext.extractingVariables) { // Process captures - if (this.variableNames.size() != matcher.groupCount()) { // SPR-8455 - throw new IllegalArgumentException("The number of capturing groups in the pattern segment " - + this.pattern + " does not match the number of URI template variables it defines, " - + "which can occur if capturing groups are used in a URI template regex. " - + "Use non-capturing groups instead."); + if (this.variableNames.size() != matcher.groupCount()) { // SPR-8455 + throw new IllegalArgumentException("The number of capturing groups in the pattern segment " + + this.pattern + " does not match the number of URI template variables it defines, " + + "which can occur if capturing groups are used in a URI template regex. " + + "Use non-capturing groups instead."); } for (int i = 1; i <= matcher.groupCount(); i++) { String name = this.variableNames.get(i - 1); @@ -187,6 +186,11 @@ public int getNormalizedLength() { return (this.regex.length - varsLength - this.variableNames.size()); } + @Override + public char[] getChars() { + return this.regex; + } + @Override public int getCaptureCount() { return this.variableNames.size(); @@ -208,8 +212,4 @@ public String toString() { return "Regex(" + String.valueOf(this.regex) + ")"; } - @Override - public char[] getChars() { - return this.regex; - } } diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/SeparatorPathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/SeparatorPathElement.java index 19cbd3d319e3..b140e88b44e3 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/SeparatorPathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/SeparatorPathElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,13 +63,14 @@ public int getNormalizedLength() { } @Override - public String toString() { - return "Separator(" + this.separator + ")"; + public char[] getChars() { + return new char[] {this.separator}; } + @Override - public char[] getChars() { - return new char[] {this.separator}; + public String toString() { + return "Separator(" + this.separator + ")"; } } diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/SingleCharWildcardedPathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/SingleCharWildcardedPathElement.java index 7aa748af6f47..d249cf7d78b3 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/SingleCharWildcardedPathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/SingleCharWildcardedPathElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -124,15 +124,15 @@ public int getNormalizedLength() { return this.len; } - @Override - public String toString() { - return "SingleCharWildcarded(" + String.valueOf(this.text) + ")"; + public char[] getChars() { + return this.text; } + @Override - public char[] getChars() { - return this.text; + public String toString() { + return "SingleCharWildcarded(" + String.valueOf(this.text) + ")"; } } diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/WildcardPathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/WildcardPathElement.java index 1f4f0b3e87a1..5413dedc7957 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/WildcardPathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/WildcardPathElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86,6 +86,11 @@ public int getNormalizedLength() { return 1; } + @Override + public char[] getChars() { + return new char[] {'*'}; + } + @Override public int getWildcardCount() { return 1; @@ -102,8 +107,4 @@ public String toString() { return "Wildcard(*)"; } - @Override - public char[] getChars() { - return new char[] {'*'}; - } } diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/WildcardTheRestPathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/WildcardTheRestPathElement.java index 25a72d58831c..e3b83634dc42 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/WildcardTheRestPathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/WildcardTheRestPathElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +47,11 @@ public int getNormalizedLength() { return 1; } + @Override + public char[] getChars() { + return (this.separator + "**").toCharArray(); + } + @Override public int getWildcardCount() { return 1; @@ -58,8 +63,4 @@ public String toString() { return "WildcardTheRest(" + this.separator + "**)"; } - @Override - public char[] getChars() { - return (this.separator+"**").toCharArray(); - } } From daf10d6c459ea547f2a66d0e770e9e20fbad35d6 Mon Sep 17 00:00:00 2001 From: Koen Punt Date: Wed, 13 Oct 2021 14:00:29 +0200 Subject: [PATCH 233/735] Include correct keyword in CookieAssertions failure messages Closes gh-27550 --- .../test/web/reactive/server/CookieAssertions.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/CookieAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/CookieAssertions.java index 0745ef7d7fd1..26b28b486a41 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/CookieAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/CookieAssertions.java @@ -188,7 +188,7 @@ public WebTestClient.ResponseSpec secure(String name, boolean expected) { public WebTestClient.ResponseSpec httpOnly(String name, boolean expected) { boolean isHttpOnly = getCookie(name).isHttpOnly(); this.exchangeResult.assertWithDiagnostics(() -> { - String message = getMessage(name) + " secure"; + String message = getMessage(name) + " httpOnly"; AssertionErrors.assertEquals(message, expected, isHttpOnly); }); return this.responseSpec; @@ -200,7 +200,7 @@ public WebTestClient.ResponseSpec httpOnly(String name, boolean expected) { public WebTestClient.ResponseSpec sameSite(String name, String expected) { String sameSite = getCookie(name).getSameSite(); this.exchangeResult.assertWithDiagnostics(() -> { - String message = getMessage(name) + " secure"; + String message = getMessage(name) + " sameSite"; AssertionErrors.assertEquals(message, expected, sameSite); }); return this.responseSpec; From 50b92118a966af79718dcf7b14d541b4dc13bf73 Mon Sep 17 00:00:00 2001 From: Koen Punt Date: Wed, 13 Oct 2021 14:00:29 +0200 Subject: [PATCH 234/735] Include correct keyword in CookieAssertions failure messages Closes gh-27550 --- .../test/web/reactive/server/CookieAssertions.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/CookieAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/CookieAssertions.java index 0745ef7d7fd1..26b28b486a41 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/CookieAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/CookieAssertions.java @@ -188,7 +188,7 @@ public WebTestClient.ResponseSpec secure(String name, boolean expected) { public WebTestClient.ResponseSpec httpOnly(String name, boolean expected) { boolean isHttpOnly = getCookie(name).isHttpOnly(); this.exchangeResult.assertWithDiagnostics(() -> { - String message = getMessage(name) + " secure"; + String message = getMessage(name) + " httpOnly"; AssertionErrors.assertEquals(message, expected, isHttpOnly); }); return this.responseSpec; @@ -200,7 +200,7 @@ public WebTestClient.ResponseSpec httpOnly(String name, boolean expected) { public WebTestClient.ResponseSpec sameSite(String name, String expected) { String sameSite = getCookie(name).getSameSite(); this.exchangeResult.assertWithDiagnostics(() -> { - String message = getMessage(name) + " secure"; + String message = getMessage(name) + " sameSite"; AssertionErrors.assertEquals(message, expected, sameSite); }); return this.responseSpec; From 1e3996ea78f8540217037ebad8899ee9b6c9cab9 Mon Sep 17 00:00:00 2001 From: Hantsy Bai Date: Wed, 13 Oct 2021 21:27:02 +0800 Subject: [PATCH 235/735] Upgrade SmallRye Mutiny to 1.1.1 Closes gh-27555 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8ff65cc6f42b..e5aa6b6b7d1d 100644 --- a/build.gradle +++ b/build.gradle @@ -68,7 +68,7 @@ configure(allprojects) { project -> dependency "io.reactivex:rxjava-reactive-streams:1.2.1" dependency "io.reactivex.rxjava2:rxjava:2.2.21" dependency "io.reactivex.rxjava3:rxjava:3.1.1" - dependency "io.smallrye.reactive:mutiny:1.0.0" + dependency "io.smallrye.reactive:mutiny:1.1.1" dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE" dependency "com.caucho:hessian:4.0.63" From 0436dd04bff89670a0e307e7183220b04f97878a Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 13 Oct 2021 13:03:09 +0100 Subject: [PATCH 236/735] Correctly handle coroutine with ResponseEntity ResponseEntityResultHandler nests correctly, only once for the ResponseEntity, when there is a Mono adapted from a Kotlin Continuation. Closes gh-27292 --- .../AbstractMessageWriterResultHandler.java | 2 +- .../ResponseEntityResultHandler.java | 8 ++++-- .../annotation/CoroutinesIntegrationTests.kt | 27 ++++++++++++++++--- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java index cbdd2f851fce..45e1e17974c3 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java @@ -52,7 +52,7 @@ */ public abstract class AbstractMessageWriterResultHandler extends HandlerResultHandlerSupport { - private static final String COROUTINES_FLOW_CLASS_NAME = "kotlinx.coroutines.flow.Flow"; + protected static final String COROUTINES_FLOW_CLASS_NAME = "kotlinx.coroutines.flow.Flow"; private final List> messageWriters; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java index 3ad66a9bfce0..26b59a4bd4b7 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import reactor.core.publisher.Mono; +import org.springframework.core.KotlinDetector; import org.springframework.core.MethodParameter; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; @@ -108,6 +109,7 @@ private boolean isSupportedType(@Nullable Class clazz) { @Override + @SuppressWarnings("ConstantConditions") public Mono handleResult(ServerWebExchange exchange, HandlerResult result) { Mono returnValueMono; @@ -118,7 +120,9 @@ public Mono handleResult(ServerWebExchange exchange, HandlerResult result) if (adapter != null) { Assert.isTrue(!adapter.isMultiValue(), "Only a single ResponseEntity supported"); returnValueMono = Mono.from(adapter.toPublisher(result.getReturnValue())); - bodyParameter = actualParameter.nested().nested(); + boolean isContinuation = (KotlinDetector.isSuspendingFunction(actualParameter.getMethod()) && + !COROUTINES_FLOW_CLASS_NAME.equals(actualParameter.getParameterType().getName())); + bodyParameter = (isContinuation ? actualParameter.nested() : actualParameter.nested().nested()); } else { returnValueMono = Mono.justOrEmpty(result.getReturnValue()); diff --git a/spring-webflux/src/test/kotlin/org/springframework/web/reactive/result/method/annotation/CoroutinesIntegrationTests.kt b/spring-webflux/src/test/kotlin/org/springframework/web/reactive/result/method/annotation/CoroutinesIntegrationTests.kt index af2502c09f87..7a43168c7b35 100644 --- a/spring-webflux/src/test/kotlin/org/springframework/web/reactive/result/method/annotation/CoroutinesIntegrationTests.kt +++ b/spring-webflux/src/test/kotlin/org/springframework/web/reactive/result/method/annotation/CoroutinesIntegrationTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,18 +22,20 @@ import kotlinx.coroutines.async import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow -import org.assertj.core.api.Assertions.* +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.springframework.context.ApplicationContext import org.springframework.context.annotation.AnnotationConfigApplicationContext import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration import org.springframework.http.HttpHeaders import org.springframework.http.HttpStatus -import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer +import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RestController import org.springframework.web.client.HttpServerErrorException import org.springframework.web.reactive.config.EnableWebFlux +import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer class CoroutinesIntegrationTests : AbstractRequestMappingIntegrationTests() { @@ -63,6 +65,15 @@ class CoroutinesIntegrationTests : AbstractRequestMappingIntegrationTests() { assertThat(entity.body).isEqualTo("foo") } + @ParameterizedHttpServerTest // gh-27292 + fun `Suspending ResponseEntity handler method`(httpServer: HttpServer) { + startServer(httpServer) + + val entity = performGet("/suspend-response-entity", HttpHeaders.EMPTY, String::class.java) + assertThat(entity.statusCode).isEqualTo(HttpStatus.OK) + assertThat(entity.body).isEqualTo("{\"value\":\"foo\"}") + } + @ParameterizedHttpServerTest fun `Handler method returning Flow`(httpServer: HttpServer) { startServer(httpServer) @@ -119,6 +130,12 @@ class CoroutinesIntegrationTests : AbstractRequestMappingIntegrationTests() { "foo" } + @GetMapping("/suspend-response-entity") + suspend fun suspendingResponseEntityEndpoint(): ResponseEntity> { + delay(1) + return ResponseEntity.ok(FooContainer("foo")) + } + @GetMapping("/flow") fun flowEndpoint()= flow { emit("foo") @@ -151,4 +168,8 @@ class CoroutinesIntegrationTests : AbstractRequestMappingIntegrationTests() { } } + + + class FooContainer(val value: T) + } From 4dac8339ffb4705554458bf2c32d81fc16b61f43 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 13 Oct 2021 14:37:03 +0100 Subject: [PATCH 237/735] Filter non-existing static resource locations Same as a2c52a97babdb927d809ad55c696c42d160d4fff, on the WebFlux side. See gh-27538 --- .../reactive/resource/ResourceWebHandler.java | 52 +++++++++++-------- .../resource/ResourceWebHandlerTests.java | 17 ++++++ .../resource/ResourceHttpRequestHandler.java | 4 ++ 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java index be4edf688ce2..2361d1532895 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -96,7 +96,9 @@ public class ResourceWebHandler implements WebHandler, InitializingBean { private final List locationValues = new ArrayList<>(4); - private final List locations = new ArrayList<>(4); + private final List locationResources = new ArrayList<>(4); + + private final List locationsToUse = new ArrayList<>(4); private final List resourceResolvers = new ArrayList<>(4); @@ -147,9 +149,9 @@ public List getLocationValues() { * for serving static resources. */ public void setLocations(@Nullable List locations) { - this.locations.clear(); + this.locationResources.clear(); if (locations != null) { - this.locations.addAll(locations); + this.locationResources.addAll(locations); } } @@ -159,11 +161,18 @@ public void setLocations(@Nullable List locations) { *

    Note that if {@link #setLocationValues(List) locationValues} are provided, * instead of loaded Resource-based locations, this method will return * empty until after initialization via {@link #afterPropertiesSet()}. + *

    Note: As of 5.3.11 the list of locations is filtered + * to exclude those that don't actually exist and therefore the list returned + * from this method may be a subset of all given locations. * @see #setLocationValues * @see #setLocations */ public List getLocations() { - return this.locations; + if (this.locationsToUse.isEmpty()) { + // Possibly not yet initialized, return only what we have so far + return this.locationResources; + } + return this.locationsToUse; } /** @@ -295,7 +304,7 @@ public void setUseLastModified(boolean useLastModified) { public void afterPropertiesSet() throws Exception { resolveResourceLocations(); - if (logger.isWarnEnabled() && CollectionUtils.isEmpty(this.locations)) { + if (logger.isWarnEnabled() && CollectionUtils.isEmpty(getLocations())) { logger.warn("Locations list is empty. No resources will be served unless a " + "custom ResourceResolver is configured as an alternative to PathResourceResolver."); } @@ -316,21 +325,22 @@ public void afterPropertiesSet() throws Exception { } private void resolveResourceLocations() { - if (CollectionUtils.isEmpty(this.locationValues)) { - return; - } - else if (!CollectionUtils.isEmpty(this.locations)) { - throw new IllegalArgumentException("Please set either Resource-based \"locations\" or " + - "String-based \"locationValues\", but not both."); + List result = new ArrayList<>(this.locationResources); + + if (!this.locationValues.isEmpty()) { + Assert.notNull(this.resourceLoader, + "ResourceLoader is required when \"locationValues\" are configured."); + Assert.isTrue(CollectionUtils.isEmpty(this.locationResources), "Please set " + + "either Resource-based \"locations\" or String-based \"locationValues\", but not both."); + for (String location : this.locationValues) { + result.add(this.resourceLoader.getResource(location)); + } } - Assert.notNull(this.resourceLoader, - "ResourceLoader is required when \"locationValues\" are configured."); + result = result.stream().filter(Resource::exists).collect(Collectors.toList()); - for (String location : this.locationValues) { - Resource resource = this.resourceLoader.getResource(location); - this.locations.add(resource); - } + this.locationsToUse.clear(); + this.locationsToUse.addAll(result); } /** @@ -339,7 +349,7 @@ else if (!CollectionUtils.isEmpty(this.locations)) { * match the {@link #setLocations locations} configured on this class. */ protected void initAllowedLocations() { - if (CollectionUtils.isEmpty(this.locations)) { + if (CollectionUtils.isEmpty(getLocations())) { if (logger.isInfoEnabled()) { logger.info("Locations list is empty. No resources will be served unless a " + "custom ResourceResolver is configured as an alternative to PathResourceResolver."); @@ -618,8 +628,8 @@ private Object formatLocations() { if (!this.locationValues.isEmpty()) { return this.locationValues.stream().collect(Collectors.joining("\", \"", "[\"", "\"]")); } - else if (!this.locations.isEmpty()) { - return "[" + this.locations.toString() + if (!getLocations().isEmpty()) { + return "[" + getLocations().toString() .replaceAll("class path resource", "Classpath") .replaceAll("ServletContext resource", "ServletContext") + "]"; } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceWebHandlerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceWebHandlerTests.java index 691afde68ee3..b668172197d6 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceWebHandlerTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceWebHandlerTests.java @@ -253,6 +253,23 @@ public void getResourceFromFileSystem() throws Exception { assertResponseBody(exchange, "h1 { color:red; }"); } + @Test // gh-27538 + public void filterNonExistingLocations() throws Exception { + List inputLocations = Arrays.asList( + new ClassPathResource("test/", getClass()), + new ClassPathResource("testalternatepath/", getClass()), + new ClassPathResource("nosuchpath/", getClass())); + + ResourceWebHandler handler = new ResourceWebHandler(); + handler.setLocations(inputLocations); + handler.afterPropertiesSet(); + + List actual = handler.getLocations(); + assertThat(actual).hasSize(2); + assertThat(actual.get(0).getURL().toString()).endsWith("test/"); + assertThat(actual.get(1).getURL().toString()).endsWith("testalternatepath/"); + } + @Test // SPR-14577 public void getMediaTypeWithFavorPathExtensionOff() throws Exception { List paths = Collections.singletonList(new ClassPathResource("test/", getClass())); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index 0831a2a2f29b..6e556e9af5fa 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -189,6 +189,9 @@ public void setLocations(List locations) { * locations provided via {@link #setLocations(List) setLocations}. *

    Note that the returned list is fully initialized only after * initialization via {@link #afterPropertiesSet()}. + *

    Note: As of 5.3.11 the list of locations is filtered + * to exclude those that don't actually exist and therefore the list returned + * from this method may be a subset of all given locations. * @see #setLocationValues * @see #setLocations */ @@ -467,6 +470,7 @@ private void resolveResourceLocations() { result.addAll(this.locationResources); result = result.stream().filter(Resource::exists).collect(Collectors.toList()); + this.locationsToUse.clear(); this.locationsToUse.addAll(result); } From 89c7797ffbe2f50c4087a9ada1ebf2fbd10462d9 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 13 Oct 2021 19:09:53 +0200 Subject: [PATCH 238/735] Commit in DatabasePopulatorUtils if Connection has auto-commit=false Prior to this commit, DatabasePopulatorUtils.execute(...) did not perform a commit for the current Connection. This works for most use cases; however, when DatabasePopulatorUtils is used to execute initialization scripts without a managed transaction -- for example, via a DataSourceInitializer configured as a bean in the ApplicationContext or via Spring Boot configuration in application.properties -- if the underlying database is configured with auto-commit=false, the results of executing the SQL scripts are not committed to the database which can lead to data being silently lost. This commit addresses this issue by committing the Connection for the supplied DataSource if the connection is not configured for auto-commit and is not transactional. Existing use cases running with a managed transaction should therefore not be affected by this change. Closes gh-27008 --- .../jdbc/datasource/DataSourceUtils.java | 6 +- .../init/DatabasePopulatorUtils.java | 10 +- ...tDisabledH2EmbeddedDatabaseConfigurer.java | 51 ++++++++ .../H2DatabasePopulatorIntegrationTests.java | 54 --------- .../init/H2DatabasePopulatorTests.java | 111 ++++++++++++++++++ .../init/HsqlDatabasePopulatorTests.java | 4 +- 6 files changed, 177 insertions(+), 59 deletions(-) create mode 100644 spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/AutoCommitDisabledH2EmbeddedDatabaseConfigurer.java delete mode 100644 spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/H2DatabasePopulatorIntegrationTests.java create mode 100644 spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/H2DatabasePopulatorTests.java diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java index 67c8338394db..ae708030bcc1 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +72,8 @@ public abstract class DataSourceUtils { * @return a JDBC Connection from the given DataSource * @throws org.springframework.jdbc.CannotGetJdbcConnectionException * if the attempt to get a Connection failed - * @see #releaseConnection + * @see #releaseConnection(Connection, DataSource) + * @see #isConnectionTransactional(Connection, DataSource) */ public static Connection getConnection(DataSource dataSource) throws CannotGetJdbcConnectionException { try { @@ -298,6 +299,7 @@ public static void resetConnectionAfterTransaction(Connection con, @Nullable Int * @param dataSource the DataSource that the Connection was obtained from * (may be {@code null}) * @return whether the Connection is transactional + * @see #getConnection(DataSource) */ public static boolean isConnectionTransactional(Connection con, @Nullable DataSource dataSource) { if (dataSource == null) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java index 3861cb5e54b2..f3f0d5780f92 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,9 +36,14 @@ public abstract class DatabasePopulatorUtils { /** * Execute the given {@link DatabasePopulator} against the given {@link DataSource}. + *

    As of Spring Framework 5.3.11, the {@link Connection} for the supplied + * {@code DataSource} will be {@linkplain Connection#commit() committed} if + * it is not configured for {@link Connection#getAutoCommit() auto-commit} and + * is not {@linkplain DataSourceUtils#isConnectionTransactional transactional}. * @param populator the {@code DatabasePopulator} to execute * @param dataSource the {@code DataSource} to execute against * @throws DataAccessException if an error occurs, specifically a {@link ScriptException} + * @see DataSourceUtils#isConnectionTransactional(Connection, DataSource) */ public static void execute(DatabasePopulator populator, DataSource dataSource) throws DataAccessException { Assert.notNull(populator, "DatabasePopulator must not be null"); @@ -47,6 +52,9 @@ public static void execute(DatabasePopulator populator, DataSource dataSource) t Connection connection = DataSourceUtils.getConnection(dataSource); try { populator.populate(connection); + if (!connection.getAutoCommit() && !DataSourceUtils.isConnectionTransactional(connection, dataSource)) { + connection.commit(); + } } finally { DataSourceUtils.releaseConnection(connection, dataSource); diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/AutoCommitDisabledH2EmbeddedDatabaseConfigurer.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/AutoCommitDisabledH2EmbeddedDatabaseConfigurer.java new file mode 100644 index 000000000000..723d6d915c4e --- /dev/null +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/AutoCommitDisabledH2EmbeddedDatabaseConfigurer.java @@ -0,0 +1,51 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.datasource.embedded; + +import java.sql.Driver; + +import org.springframework.util.ClassUtils; + +/** + * {@link EmbeddedDatabaseConfigurer} for an H2 embedded database instance + * with auto-commit disabled. + * + * @author Sam Brannen + * @since 5.3.11 + */ +public class AutoCommitDisabledH2EmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigurer { + + private final Class driverClass; + + + @SuppressWarnings("unchecked") + public AutoCommitDisabledH2EmbeddedDatabaseConfigurer() throws Exception { + this.driverClass = (Class) ClassUtils.forName("org.h2.Driver", + AutoCommitDisabledH2EmbeddedDatabaseConfigurer.class.getClassLoader()); + } + + @Override + public void configureConnectionProperties(ConnectionProperties properties, String databaseName) { + String url = String.format("jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;AUTOCOMMIT=false", databaseName); + + properties.setDriverClass(this.driverClass); + properties.setUrl(url); + properties.setUsername("sa"); + properties.setPassword(""); + } + +} diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/H2DatabasePopulatorIntegrationTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/H2DatabasePopulatorIntegrationTests.java deleted file mode 100644 index 37ea29bbf85c..000000000000 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/H2DatabasePopulatorIntegrationTests.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jdbc.datasource.init; - -import org.junit.jupiter.api.Test; - -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Sam Brannen - * @since 4.0.3 - */ -class H2DatabasePopulatorIntegrationTests extends AbstractDatabasePopulatorTests { - - @Override - protected EmbeddedDatabaseType getEmbeddedDatabaseType() { - return EmbeddedDatabaseType.H2; - } - - /** - * https://jira.spring.io/browse/SPR-15896 - * - * @since 5.0 - */ - @Test - void scriptWithH2Alias() throws Exception { - databasePopulator.addScript(usersSchema()); - databasePopulator.addScript(resource("db-test-data-h2-alias.sql")); - // Set statement separator to double newline so that ";" is not - // considered a statement separator within the source code of the - // aliased function 'REVERSE'. - databasePopulator.setSeparator("\n\n"); - DatabasePopulatorUtils.execute(databasePopulator, db); - String sql = "select REVERSE(first_name) from users where last_name='Brannen'"; - assertThat(jdbcTemplate.queryForObject(sql, String.class)).isEqualTo("maS"); - } - -} diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/H2DatabasePopulatorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/H2DatabasePopulatorTests.java new file mode 100644 index 000000000000..6a67619bc893 --- /dev/null +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/H2DatabasePopulatorTests.java @@ -0,0 +1,111 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.datasource.init; + +import java.sql.Connection; +import java.util.List; + +import javax.sql.DataSource; + +import org.junit.jupiter.api.Test; + +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceUtils; +import org.springframework.jdbc.datasource.embedded.AutoCommitDisabledH2EmbeddedDatabaseConfigurer; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Sam Brannen + * @since 4.0.3 + */ +class H2DatabasePopulatorTests extends AbstractDatabasePopulatorTests { + + @Override + protected EmbeddedDatabaseType getEmbeddedDatabaseType() { + return EmbeddedDatabaseType.H2; + } + + /** + * https://jira.spring.io/browse/SPR-15896 + * + * @since 5.0 + */ + @Test + void scriptWithH2Alias() throws Exception { + databasePopulator.addScript(usersSchema()); + databasePopulator.addScript(resource("db-test-data-h2-alias.sql")); + // Set statement separator to double newline so that ";" is not + // considered a statement separator within the source code of the + // aliased function 'REVERSE'. + databasePopulator.setSeparator("\n\n"); + DatabasePopulatorUtils.execute(databasePopulator, db); + String sql = "select REVERSE(first_name) from users where last_name='Brannen'"; + assertThat(jdbcTemplate.queryForObject(sql, String.class)).isEqualTo("maS"); + } + + /** + * https://github.com/spring-projects/spring-framework/issues/27008 + * + * @since 5.3.11 + */ + @Test + void automaticallyCommitsIfAutoCommitIsDisabled() throws Exception { + EmbeddedDatabase database = null; + try { + EmbeddedDatabaseFactory databaseFactory = new EmbeddedDatabaseFactory(); + databaseFactory.setDatabaseConfigurer(new AutoCommitDisabledH2EmbeddedDatabaseConfigurer()); + database = databaseFactory.getDatabase(); + + assertAutoCommitDisabledPreconditions(database); + + // Set up schema + databasePopulator.setScripts(usersSchema()); + DatabasePopulatorUtils.execute(databasePopulator, database); + assertThat(selectFirstNames(database)).isEmpty(); + + // Insert data + databasePopulator.setScripts(resource("users-data.sql")); + DatabasePopulatorUtils.execute(databasePopulator, database); + assertThat(selectFirstNames(database)).containsExactly("Sam"); + } + finally { + if (database != null) { + database.shutdown(); + } + } + } + + /** + * DatabasePopulatorUtils.execute() will obtain a new Connection, so we're + * really just testing the configuration of the database here. + */ + private void assertAutoCommitDisabledPreconditions(DataSource dataSource) throws Exception { + Connection connection = DataSourceUtils.getConnection(dataSource); + assertThat(connection.getAutoCommit()).as("auto-commit").isFalse(); + assertThat(DataSourceUtils.isConnectionTransactional(connection, dataSource)).as("transactional").isFalse(); + connection.close(); + } + + private List selectFirstNames(DataSource dataSource) { + return new JdbcTemplate(dataSource).queryForList("select first_name from users", String.class); + } + +} diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/HsqlDatabasePopulatorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/HsqlDatabasePopulatorTests.java index 0b43cd74a3cf..9135c2055856 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/HsqlDatabasePopulatorTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/HsqlDatabasePopulatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ * @author Sam Brannen * @since 4.0.3 */ -public class HsqlDatabasePopulatorTests extends AbstractDatabasePopulatorTests { +class HsqlDatabasePopulatorTests extends AbstractDatabasePopulatorTests { @Override protected EmbeddedDatabaseType getEmbeddedDatabaseType() { From fcf4315e020c9d76ed66e1a4fea4ee908fd563ec Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 13 Oct 2021 20:04:40 +0200 Subject: [PATCH 239/735] Indent with tabs instead of spaces --- gradle/docs-dokka.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle/docs-dokka.gradle b/gradle/docs-dokka.gradle index ac2a56885154..dfe137d9cfe6 100644 --- a/gradle/docs-dokka.gradle +++ b/gradle/docs-dokka.gradle @@ -1,7 +1,7 @@ tasks.findByName("dokkaHtmlPartial")?.configure { - outputDirectory.set(new File(buildDir, "docs/kdoc")) - dokkaSourceSets { - configureEach { + outputDirectory.set(new File(buildDir, "docs/kdoc")) + dokkaSourceSets { + configureEach { sourceRoots.setFrom(file("src/main/kotlin")) classpath.from(sourceSets["main"].runtimeClasspath) externalDocumentationLink { @@ -26,5 +26,5 @@ tasks.findByName("dokkaHtmlPartial")?.configure { url.set(new URL("https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/")) } } - } + } } From 1ef47fa3691f8d43aacb0f6d626a92811931869c Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 13 Oct 2021 20:41:49 +0200 Subject: [PATCH 240/735] Use instanceof pattern matching in select classes in spring-test --- .../test/util/AopTestUtils.java | 10 ++++----- .../test/util/ExceptionCollector.java | 8 +++---- .../test/util/JsonPathExpectationsHelper.java | 22 +++++++++---------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/util/AopTestUtils.java b/spring-test/src/main/java/org/springframework/test/util/AopTestUtils.java index a9a7e41b0f3c..9080c252cb2f 100644 --- a/spring-test/src/main/java/org/springframework/test/util/AopTestUtils.java +++ b/spring-test/src/main/java/org/springframework/test/util/AopTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,8 +54,8 @@ public abstract class AopTestUtils { public static T getTargetObject(Object candidate) { Assert.notNull(candidate, "Candidate must not be null"); try { - if (AopUtils.isAopProxy(candidate) && candidate instanceof Advised) { - Object target = ((Advised) candidate).getTargetSource().getTarget(); + if (AopUtils.isAopProxy(candidate) && candidate instanceof Advised advised) { + Object target = advised.getTargetSource().getTarget(); if (target != null) { return (T) target; } @@ -86,8 +86,8 @@ public static T getTargetObject(Object candidate) { public static T getUltimateTargetObject(Object candidate) { Assert.notNull(candidate, "Candidate must not be null"); try { - if (AopUtils.isAopProxy(candidate) && candidate instanceof Advised) { - Object target = ((Advised) candidate).getTargetSource().getTarget(); + if (AopUtils.isAopProxy(candidate) && candidate instanceof Advised advised) { + Object target = advised.getTargetSource().getTarget(); if (target != null) { return (T) getUltimateTargetObject(target); } diff --git a/spring-test/src/main/java/org/springframework/test/util/ExceptionCollector.java b/spring-test/src/main/java/org/springframework/test/util/ExceptionCollector.java index f53190b7aff7..68b84e0eb91d 100644 --- a/spring-test/src/main/java/org/springframework/test/util/ExceptionCollector.java +++ b/spring-test/src/main/java/org/springframework/test/util/ExceptionCollector.java @@ -87,11 +87,11 @@ public void assertEmpty() throws Exception { if (this.exceptions.size() == 1) { Throwable exception = this.exceptions.get(0); - if (exception instanceof Error) { - throw (Error) exception; + if (exception instanceof Error error) { + throw error; } - if (exception instanceof Exception) { - throw (Exception) exception; + if (exception instanceof Exception ex) { + throw ex; } AssertionError assertionError = new AssertionError(exception.getMessage()); assertionError.initCause(exception); diff --git a/spring-test/src/main/java/org/springframework/test/util/JsonPathExpectationsHelper.java b/spring-test/src/main/java/org/springframework/test/util/JsonPathExpectationsHelper.java index e8c1b475222e..6bf523226e93 100644 --- a/spring-test/src/main/java/org/springframework/test/util/JsonPathExpectationsHelper.java +++ b/spring-test/src/main/java/org/springframework/test/util/JsonPathExpectationsHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -97,9 +97,7 @@ public void assertValue(String content, Matcher matcher, Class */ public void assertValue(String content, @Nullable Object expectedValue) { Object actualValue = evaluateJsonPath(content); - if ((actualValue instanceof List) && !(expectedValue instanceof List)) { - @SuppressWarnings("rawtypes") - List actualValueList = (List) actualValue; + if ((actualValue instanceof List actualValueList) && !(expectedValue instanceof List)) { if (actualValueList.isEmpty()) { AssertionErrors.fail("No matching value at JSON path \"" + this.expression + "\""); } @@ -209,8 +207,8 @@ public void doesNotExist(String content) { return; } String reason = failureReason("no value", value); - if (pathIsIndefinite() && value instanceof List) { - AssertionErrors.assertTrue(reason, ((List) value).isEmpty()); + if (pathIsIndefinite() && value instanceof List list) { + AssertionErrors.assertTrue(reason, list.isEmpty()); } else { AssertionErrors.assertTrue(reason, (value == null)); @@ -252,9 +250,9 @@ public void assertValueIsNotEmpty(String content) { */ public void hasJsonPath(String content) { Object value = evaluateJsonPath(content); - if (pathIsIndefinite() && value instanceof List) { + if (pathIsIndefinite() && value instanceof List list) { String message = "No values for JSON path \"" + this.expression + "\""; - AssertionErrors.assertTrue(message, !((List) value).isEmpty()); + AssertionErrors.assertTrue(message, !list.isEmpty()); } } @@ -276,8 +274,8 @@ public void doesNotHaveJsonPath(String content) { catch (AssertionError ex) { return; } - if (pathIsIndefinite() && value instanceof List) { - AssertionErrors.assertTrue(failureReason("no values", value), ((List) value).isEmpty()); + if (pathIsIndefinite() && value instanceof List list) { + AssertionErrors.assertTrue(failureReason("no values", value), list.isEmpty()); } else { AssertionErrors.fail(failureReason("no value", value)); @@ -328,8 +326,8 @@ private Object assertExistsAndReturn(String content) { Object value = evaluateJsonPath(content); String reason = "No value at JSON path \"" + this.expression + "\""; AssertionErrors.assertTrue(reason, value != null); - if (pathIsIndefinite() && value instanceof List) { - AssertionErrors.assertTrue(reason, !((List) value).isEmpty()); + if (pathIsIndefinite() && value instanceof List list) { + AssertionErrors.assertTrue(reason, !list.isEmpty()); } return value; } From 373b90d26319d0e741b940de9bec1d22fa7983b8 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 13 Oct 2021 20:43:13 +0200 Subject: [PATCH 241/735] Simplify JsonPathExpectationsHelperTests with text blocks --- .../util/JsonPathExpectationsHelperTests.java | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/spring-test/src/test/java/org/springframework/test/util/JsonPathExpectationsHelperTests.java b/spring-test/src/test/java/org/springframework/test/util/JsonPathExpectationsHelperTests.java index 177e1da909cc..1f8145cbc030 100644 --- a/spring-test/src/test/java/org/springframework/test/util/JsonPathExpectationsHelperTests.java +++ b/spring-test/src/test/java/org/springframework/test/util/JsonPathExpectationsHelperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,25 +30,29 @@ */ class JsonPathExpectationsHelperTests { - private static final String CONTENT = "{" + // - "'str': 'foo', " + // - "'num': 5, " + // - "'bool': true, " + // - "'arr': [42], " + // - "'colorMap': {'red': 'rojo'}, " + // - "'whitespace': ' ', " + // - "'emptyString': '', " + // - "'emptyArray': [], " + // - "'emptyMap': {} " + // - "}"; - - private static final String SIMPSONS = "{ 'familyMembers': [ " + // - "{'name': 'Homer' }, " + // - "{'name': 'Marge' }, " + // - "{'name': 'Bart' }, " + // - "{'name': 'Lisa' }, " + // - "{'name': 'Maggie'} " + // - " ] }"; + private static final String CONTENT = """ + { + 'str': 'foo', + 'num': 5, + 'bool': true, + 'arr': [42], + 'colorMap': {'red': 'rojo'}, + 'whitespace': ' ', + 'emptyString': '', + 'emptyArray': [], + 'emptyMap': {} + }"""; + + private static final String SIMPSONS = """ + { + 'familyMembers': [ + {'name': 'Homer' }, + {'name': 'Marge' }, + {'name': 'Bart' }, + {'name': 'Lisa' }, + {'name': 'Maggie'} + ] + }"""; @Test From a178bbe86fb4ef408e5b43f6789f9e8e4cc54b86 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 13 Oct 2021 20:51:10 +0100 Subject: [PATCH 242/735] DefaultResponseErrorHandler shows full error details Closes gh-27552 --- .../core/log/LogFormatUtils.java | 16 +++++----- .../client/DefaultResponseErrorHandler.java | 31 +++++-------------- .../DefaultResponseErrorHandlerTests.java | 23 ++------------ 3 files changed, 16 insertions(+), 54 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java b/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java index 8ef04c71baf7..e3ae033e9f22 100644 --- a/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java +++ b/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java @@ -60,16 +60,11 @@ public static String formatValue(@Nullable Object value, int maxLength, boolean return ""; } String result; - if (value instanceof CharSequence) { - result = "\"" + value + "\""; + try { + result = value.toString(); } - else { - try { - result = value.toString(); - } - catch (Throwable ex) { - result = ex.toString(); - } + catch (Throwable ex) { + result = ex.toString(); } if (maxLength != -1) { result = (result.length() > maxLength ? result.substring(0, maxLength) + " (truncated)..." : result); @@ -77,6 +72,9 @@ public static String formatValue(@Nullable Object value, int maxLength, boolean if (replaceNewlines) { result = result.replace("\n", "").replace("\r", ""); } + if (value instanceof CharSequence) { + result = "\"" + result + "\""; + } return result; } diff --git a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java index 31355571c685..70e1038871a5 100644 --- a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,11 @@ package org.springframework.web.client; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import org.springframework.core.log.LogFormatUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -135,31 +132,17 @@ private String getErrorMessage( int rawStatusCode, String statusText, @Nullable byte[] responseBody, @Nullable Charset charset) { String preface = rawStatusCode + " " + statusText + ": "; + if (ObjectUtils.isEmpty(responseBody)) { return preface + "[no body]"; } - if (charset == null) { - charset = StandardCharsets.UTF_8; - } - int maxChars = 200; + charset = (charset != null ? charset : StandardCharsets.UTF_8); - if (responseBody.length < maxChars * 2) { - return preface + "[" + new String(responseBody, charset) + "]"; - } + String bodyText = new String(responseBody, charset); + bodyText = LogFormatUtils.formatValue(bodyText, -1, true); - try { - Reader reader = new InputStreamReader(new ByteArrayInputStream(responseBody), charset); - CharBuffer buffer = CharBuffer.allocate(maxChars); - reader.read(buffer); - reader.close(); - buffer.flip(); - return preface + "[" + buffer.toString() + "... (" + responseBody.length + " bytes)]"; - } - catch (IOException ex) { - // should never happen - throw new IllegalStateException(ex); - } + return preface + bodyText; } /** diff --git a/spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java b/spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java index cea2263411e3..a455f7088d55 100644 --- a/spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,10 +19,8 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.function.Function; import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -74,27 +72,10 @@ public void handleError() throws Exception { assertThatExceptionOfType(HttpClientErrorException.class) .isThrownBy(() -> handler.handleError(response)) - .withMessage("404 Not Found: [Hello World]") + .withMessage("404 Not Found: \"Hello World\"") .satisfies(ex -> assertThat(ex.getResponseHeaders()).isSameAs(headers)); } - @Test - public void handleErrorWithLongBody() throws Exception { - - Function bodyGenerator = - size -> Flux.just("a").repeat(size-1).reduce((s, s2) -> s + s2).block(); - - given(response.getRawStatusCode()).willReturn(HttpStatus.NOT_FOUND.value()); - given(response.getStatusText()).willReturn("Not Found"); - given(response.getHeaders()).willReturn(new HttpHeaders()); - given(response.getBody()).willReturn( - new ByteArrayInputStream(bodyGenerator.apply(500).getBytes(StandardCharsets.UTF_8))); - - assertThatExceptionOfType(HttpClientErrorException.class) - .isThrownBy(() -> handler.handleError(response)) - .withMessage("404 Not Found: [" + bodyGenerator.apply(200) + "... (500 bytes)]"); - } - @Test public void handleErrorIOException() throws Exception { HttpHeaders headers = new HttpHeaders(); From ca999fb38c37e9eba4916bf0399d9b9a9d0e4662 Mon Sep 17 00:00:00 2001 From: liuzhifei <2679431923@qq.com> Date: Tue, 28 Sep 2021 19:22:51 +0800 Subject: [PATCH 243/735] fix Javadoc typo in PathMatchConfigurer#setUseSuffixPatternMatch --- .../web/servlet/config/annotation/PathMatchConfigurer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java index 9eca10f1ccad..113d59cfb31b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java @@ -120,7 +120,7 @@ public PathMatchConfigurer addPathPrefix(String prefix, Predicate> pred /** * Whether to use suffix pattern match (".*") when matching patterns to * requests. If enabled a method mapped to "/users" also matches to "/users.*". - *

    By default this is set to {@code true}. + *

    By default this is set to {@code false}. *

    Note: This property is mutually exclusive with and * ignored when {@link #setPatternParser(PathPatternParser)} is set. * @deprecated as of 5.2.4. See class-level note in From 0705454ce012b6390ba50744f59a98223c0464a6 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 14 Oct 2021 09:42:40 +0100 Subject: [PATCH 244/735] Fix typo in Javadoc See gh-27484 --- .../web/servlet/config/annotation/PathMatchConfigurer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java index 9eca10f1ccad..113d59cfb31b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java @@ -120,7 +120,7 @@ public PathMatchConfigurer addPathPrefix(String prefix, Predicate> pred /** * Whether to use suffix pattern match (".*") when matching patterns to * requests. If enabled a method mapped to "/users" also matches to "/users.*". - *

    By default this is set to {@code true}. + *

    By default this is set to {@code false}. *

    Note: This property is mutually exclusive with and * ignored when {@link #setPatternParser(PathPatternParser)} is set. * @deprecated as of 5.2.4. See class-level note in From bf461ba0b2e3beb14f27f2ec53d2f85bfca7095c Mon Sep 17 00:00:00 2001 From: Spring Builds Date: Thu, 14 Oct 2021 09:35:45 +0000 Subject: [PATCH 245/735] Next development version (v5.3.12-SNAPSHOT) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 237a595d4483..aea3f16f967a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=5.3.11-SNAPSHOT +version=5.3.12-SNAPSHOT org.gradle.jvmargs=-Xmx1536M org.gradle.caching=true org.gradle.parallel=true From d312c1372188f98402d413b55eb07528152c4edf Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 14 Oct 2021 14:48:56 +0200 Subject: [PATCH 246/735] Upgrade to Hibernate ORM 5.6 Final, RxJava 3.1.2, JRuby 9.3.1 --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index ac36b1b71eb3..5829d4212a4b 100644 --- a/build.gradle +++ b/build.gradle @@ -64,7 +64,7 @@ configure(allprojects) { project -> entry 'groovy-xml' } - dependency "io.reactivex.rxjava3:rxjava:3.1.1" + dependency "io.reactivex.rxjava3:rxjava:3.1.2" dependency "io.smallrye.reactive:mutiny:1.1.1" dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE" @@ -112,7 +112,7 @@ configure(allprojects) { project -> dependency "org.quartz-scheduler:quartz:2.3.2" dependency "org.ehcache:jcache:1.0.1" dependency "org.ehcache:ehcache:3.4.0" - dependency "org.hibernate:hibernate-core-jakarta:5.6.0.CR1" + dependency "org.hibernate:hibernate-core-jakarta:5.6.0.Final" dependency "org.hibernate:hibernate-validator:7.0.1.Final" dependency "org.webjars:webjars-locator-core:0.48" dependency "org.webjars:underscorejs:1.8.3" @@ -150,7 +150,7 @@ configure(allprojects) { project -> dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.1' dependency "org.eclipse.jetty:jetty-reactive-httpclient:3.0.4" - dependency "org.jruby:jruby:9.3.0.0" + dependency "org.jruby:jruby:9.3.1.0" dependency "org.python:jython-standalone:2.7.1" dependency "org.mozilla:rhino:1.7.11" From 0853baaa3f9644df4de205a2472e71a748353e25 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 15:15:23 +0200 Subject: [PATCH 247/735] Fix Javadoc in [NamedParameter]JdbcOperations.queryForObject methods This commit fixes the Javadoc in all queryForObject(...) methods in JdbcOperations and NamedParameterJdbcOperations regarding what kinds of exceptions are thrown under which conditions. Closes gh-27559 --- .../jdbc/core/JdbcOperations.java | 63 ++++++++++--------- .../NamedParameterJdbcOperations.java | 19 +++--- 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java index c285ddcb978e..7910753806aa 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,22 +22,21 @@ import java.util.stream.Stream; import org.springframework.dao.DataAccessException; -import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.support.KeyHolder; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.lang.Nullable; /** * Interface specifying a basic set of JDBC operations. - * Implemented by {@link JdbcTemplate}. Not often used directly, but a useful + * + *

    Implemented by {@link JdbcTemplate}. Not often used directly, but a useful * option to enhance testability, as it can easily be mocked or stubbed. * *

    Alternatively, the standard JDBC infrastructure can be mocked. * However, mocking this interface constitutes significantly less work. * As an alternative to a mock objects approach to testing data access code, - * consider the powerful integration testing support provided in the - * {@code org.springframework.test} package, shipped in - * {@code spring-test.jar}. + * consider the powerful integration testing support provided via the Spring + * TestContext Framework, in the {@code spring-test} artifact. * * @author Rod Johnson * @author Juergen Hoeller @@ -160,8 +159,8 @@ public interface JdbcOperations { * @param rowMapper a callback that will map one object per row * @return the single mapped object (may be {@code null} if the given * {@link RowMapper} returned {@code} null) - * @throws IncorrectResultSizeDataAccessException if the query does not - * return exactly one row + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException + * if the query does not return exactly one row * @throws DataAccessException if there is any problem executing the query * @see #queryForObject(String, RowMapper, Object...) */ @@ -180,8 +179,10 @@ public interface JdbcOperations { * @param sql the SQL query to execute * @param requiredType the type that the result object is expected to match * @return the result object of the required type, or {@code null} in case of SQL NULL - * @throws IncorrectResultSizeDataAccessException if the query does not return - * exactly one row, or does not return exactly one column in that row + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException + * if the query does not return exactly one row + * @throws org.springframework.jdbc.IncorrectResultSetColumnCountException + * if the query does not return a row containing a single column * @throws DataAccessException if there is any problem executing the query * @see #queryForObject(String, Class, Object...) */ @@ -198,8 +199,8 @@ public interface JdbcOperations { * mapped to a Map (one entry for each column, using the column name as the key). * @param sql the SQL query to execute * @return the result Map (one entry per column, with column name as key) - * @throws IncorrectResultSizeDataAccessException if the query does not - * return exactly one row + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException + * if the query does not return exactly one row * @throws DataAccessException if there is any problem executing the query * @see #queryForMap(String, Object...) * @see ColumnMapRowMapper @@ -603,8 +604,8 @@ Stream queryForStream(String sql, RowMapper rowMapper, @Nullable Objec * @param rowMapper a callback that will map one object per row * @return the single mapped object (may be {@code null} if the given * {@link RowMapper} returned {@code} null) - * @throws IncorrectResultSizeDataAccessException if the query does not - * return exactly one row + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException + * if the query does not return exactly one row * @throws DataAccessException if the query fails */ @Nullable @@ -623,8 +624,8 @@ T queryForObject(String sql, Object[] args, int[] argTypes, RowMapper row * @param rowMapper a callback that will map one object per row * @return the single mapped object (may be {@code null} if the given * {@link RowMapper} returned {@code} null) - * @throws IncorrectResultSizeDataAccessException if the query does not - * return exactly one row + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException + * if the query does not return exactly one row * @throws DataAccessException if the query fails * @deprecated as of 5.3, in favor of {@link #queryForObject(String, RowMapper, Object...)} */ @@ -644,8 +645,8 @@ T queryForObject(String sql, Object[] args, int[] argTypes, RowMapper row * only the argument value but also the SQL type and optionally the scale * @return the single mapped object (may be {@code null} if the given * {@link RowMapper} returned {@code} null) - * @throws IncorrectResultSizeDataAccessException if the query does not - * return exactly one row + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException + * if the query does not return exactly one row * @throws DataAccessException if the query fails * @since 3.0.1 */ @@ -663,8 +664,10 @@ T queryForObject(String sql, Object[] args, int[] argTypes, RowMapper row * (constants from {@code java.sql.Types}) * @param requiredType the type that the result object is expected to match * @return the result object of the required type, or {@code null} in case of SQL NULL - * @throws IncorrectResultSizeDataAccessException if the query does not return - * exactly one row, or does not return exactly one column in that row + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException + * if the query does not return exactly one row + * @throws org.springframework.jdbc.IncorrectResultSetColumnCountException + * if the query does not return a row containing a single column * @throws DataAccessException if the query fails * @see #queryForObject(String, Class) * @see java.sql.Types @@ -685,8 +688,10 @@ T queryForObject(String sql, Object[] args, int[] argTypes, Class require * only the argument value but also the SQL type and optionally the scale * @param requiredType the type that the result object is expected to match * @return the result object of the required type, or {@code null} in case of SQL NULL - * @throws IncorrectResultSizeDataAccessException if the query does not return - * exactly one row, or does not return exactly one column in that row + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException + * if the query does not return exactly one row + * @throws org.springframework.jdbc.IncorrectResultSetColumnCountException + * if the query does not return a row containing a single column * @throws DataAccessException if the query fails * @see #queryForObject(String, Class) * @deprecated as of 5.3, in favor of {@link #queryForObject(String, Class, Object...)} @@ -707,8 +712,10 @@ T queryForObject(String sql, Object[] args, int[] argTypes, Class require * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @return the result object of the required type, or {@code null} in case of SQL NULL - * @throws IncorrectResultSizeDataAccessException if the query does not return - * exactly one row, or does not return exactly one column in that row + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException + * if the query does not return exactly one row + * @throws org.springframework.jdbc.IncorrectResultSetColumnCountException + * if the query does not return a row containing a single column * @throws DataAccessException if the query fails * @since 3.0.1 * @see #queryForObject(String, Class) @@ -726,8 +733,8 @@ T queryForObject(String sql, Object[] args, int[] argTypes, Class require * @param argTypes the SQL types of the arguments * (constants from {@code java.sql.Types}) * @return the result Map (one entry per column, with column name as key) - * @throws IncorrectResultSizeDataAccessException if the query does not - * return exactly one row + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException + * if the query does not return exactly one row * @throws DataAccessException if the query fails * @see #queryForMap(String) * @see ColumnMapRowMapper @@ -750,8 +757,8 @@ T queryForObject(String sql, Object[] args, int[] argTypes, Class require * only the argument value but also the SQL type and optionally the scale * @return the result Map (one entry for each column, using the * column name as the key) - * @throws IncorrectResultSizeDataAccessException if the query does not - * return exactly one row + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException + * if the query does not return exactly one row * @throws DataAccessException if the query fails * @see #queryForMap(String) * @see ColumnMapRowMapper diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcOperations.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcOperations.java index 5d22b535e612..b308e06f735b 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcOperations.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -268,8 +268,7 @@ Stream queryForStream(String sql, Map paramMap, RowMapper r * @return the single mapped object (may be {@code null} if the given * {@link RowMapper} returned {@code} null) * @throws org.springframework.dao.IncorrectResultSizeDataAccessException - * if the query does not return exactly one row, or does not return exactly - * one column in that row + * if the query does not return exactly one row * @throws DataAccessException if the query fails */ @Nullable @@ -287,8 +286,7 @@ T queryForObject(String sql, SqlParameterSource paramSource, RowMapper ro * @return the single mapped object (may be {@code null} if the given * {@link RowMapper} returned {@code} null) * @throws org.springframework.dao.IncorrectResultSizeDataAccessException - * if the query does not return exactly one row, or does not return exactly - * one column in that row + * if the query does not return exactly one row * @throws DataAccessException if the query fails */ @Nullable @@ -305,10 +303,12 @@ T queryForObject(String sql, Map paramMap, RowMapper rowMapper * @param requiredType the type that the result object is expected to match * @return the result object of the required type, or {@code null} in case of SQL NULL * @throws org.springframework.dao.IncorrectResultSizeDataAccessException - * if the query does not return exactly one row, or does not return exactly - * one column in that row + * if the query does not return exactly one row + * @throws org.springframework.jdbc.IncorrectResultSetColumnCountException + * if the query does not return a row containing a single column * @throws DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForObject(String, Class) + * @see org.springframework.jdbc.core.SingleColumnRowMapper */ @Nullable T queryForObject(String sql, SqlParameterSource paramSource, Class requiredType) @@ -325,8 +325,9 @@ T queryForObject(String sql, SqlParameterSource paramSource, Class requir * @param requiredType the type that the result object is expected to match * @return the result object of the required type, or {@code null} in case of SQL NULL * @throws org.springframework.dao.IncorrectResultSizeDataAccessException - * if the query does not return exactly one row, or does not return exactly - * one column in that row + * if the query does not return exactly one row + * @throws org.springframework.jdbc.IncorrectResultSetColumnCountException + * if the query does not return a row containing a single column * @throws DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForObject(String, Class) */ From 7e4870577dd37098452fdec9ee2ecfe0c3950bb1 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 15:50:36 +0200 Subject: [PATCH 248/735] Apply "instanceof pattern matching" Eclipse clean-up in spring-test This has only been applied to `src/main/java`. --- .../springframework/mock/web/MockHttpServletRequest.java | 3 +-- .../springframework/mock/web/MockHttpServletResponse.java | 3 +-- .../test/context/ContextConfigurationAttributes.java | 3 +-- .../cache/DefaultCacheAwareContextLoaderDelegate.java | 3 +-- .../test/context/event/DefaultApplicationEvents.java | 6 +++--- .../context/support/AbstractTestContextBootstrapper.java | 3 +-- .../test/context/support/DefaultTestContext.java | 4 +--- .../context/transaction/TestContextTransactionUtils.java | 8 ++------ .../test/context/web/ServletTestExecutionListener.java | 7 ++----- .../web/socket/MockServerContainerContextCustomizer.java | 3 +-- .../web/servlet/client/AbstractMockMvcServerSpec.java | 1 + .../test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java | 3 +-- .../servlet/request/MockHttpServletRequestBuilder.java | 4 +--- .../request/MockMultipartHttpServletRequestBuilder.java | 3 +-- .../test/web/servlet/result/PrintingResultHandler.java | 3 +-- 15 files changed, 19 insertions(+), 38 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java index 1a3e7102e9e1..2ac4b33e4c76 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java @@ -1279,8 +1279,7 @@ public String getServletPath() { public void setSession(HttpSession session) { this.session = session; - if (session instanceof MockHttpSession) { - MockHttpSession mockSession = ((MockHttpSession) session); + if (session instanceof MockHttpSession mockSession) { mockSession.access(); } } diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java index df02fa4deba8..981f3a515ad3 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java @@ -444,8 +444,7 @@ else if (expires != null) { if (cookie.isHttpOnly()) { buf.append("; HttpOnly"); } - if (cookie instanceof MockCookie) { - MockCookie mockCookie = (MockCookie) cookie; + if (cookie instanceof MockCookie mockCookie) { if (StringUtils.hasText(mockCookie.getSameSite())) { buf.append("; SameSite=").append(mockCookie.getSameSite()); } diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java b/spring-test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java index e910c4c9d5e4..7b2e275c2b3d 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java +++ b/spring-test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java @@ -335,10 +335,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ContextConfigurationAttributes)) { + if (!(other instanceof ContextConfigurationAttributes otherAttr)) { return false; } - ContextConfigurationAttributes otherAttr = (ContextConfigurationAttributes) other; return (ObjectUtils.nullSafeEquals(this.declaringClass, otherAttr.declaringClass) && Arrays.equals(this.classes, otherAttr.classes)) && Arrays.equals(this.locations, otherAttr.locations) && diff --git a/spring-test/src/main/java/org/springframework/test/context/cache/DefaultCacheAwareContextLoaderDelegate.java b/spring-test/src/main/java/org/springframework/test/context/cache/DefaultCacheAwareContextLoaderDelegate.java index 133373dc7f41..2e5e54eed13d 100644 --- a/spring-test/src/main/java/org/springframework/test/context/cache/DefaultCacheAwareContextLoaderDelegate.java +++ b/spring-test/src/main/java/org/springframework/test/context/cache/DefaultCacheAwareContextLoaderDelegate.java @@ -94,8 +94,7 @@ protected ApplicationContext loadContextInternal(MergedContextConfiguration merg ApplicationContext applicationContext; - if (contextLoader instanceof SmartContextLoader) { - SmartContextLoader smartContextLoader = (SmartContextLoader) contextLoader; + if (contextLoader instanceof SmartContextLoader smartContextLoader) { applicationContext = smartContextLoader.loadContext(mergedContextConfiguration); } else { diff --git a/spring-test/src/main/java/org/springframework/test/context/event/DefaultApplicationEvents.java b/spring-test/src/main/java/org/springframework/test/context/event/DefaultApplicationEvents.java index 22d2eff61bfb..b7638ba2d551 100644 --- a/spring-test/src/main/java/org/springframework/test/context/event/DefaultApplicationEvents.java +++ b/spring-test/src/main/java/org/springframework/test/context/event/DefaultApplicationEvents.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,8 +58,8 @@ public void clear() { } private Object unwrapPayloadEvent(Object source) { - return (PayloadApplicationEvent.class.isInstance(source) ? - ((PayloadApplicationEvent) source).getPayload() : source); + return ((source instanceof PayloadApplicationEvent payloadApplicationEvent) ? + payloadApplicationEvent.getPayload() : source); } } diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java index 17bddaf5b4ce..be2b3b8d57cb 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java @@ -352,8 +352,7 @@ private MergedContextConfiguration buildMergedContextConfiguration(Class test logger.trace(String.format("Processing locations and classes for context configuration attributes %s", configAttributes)); } - if (contextLoader instanceof SmartContextLoader) { - SmartContextLoader smartContextLoader = (SmartContextLoader) contextLoader; + if (contextLoader instanceof SmartContextLoader smartContextLoader) { smartContextLoader.processContextConfiguration(configAttributes); locations.addAll(0, Arrays.asList(configAttributes.getLocations())); classes.addAll(0, Arrays.asList(configAttributes.getClasses())); diff --git a/spring-test/src/main/java/org/springframework/test/context/support/DefaultTestContext.java b/spring-test/src/main/java/org/springframework/test/context/support/DefaultTestContext.java index 0d0d0af7e139..ff318f8c3da5 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/DefaultTestContext.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/DefaultTestContext.java @@ -122,9 +122,7 @@ public boolean hasApplicationContext() { @Override public ApplicationContext getApplicationContext() { ApplicationContext context = this.cacheAwareContextLoaderDelegate.loadContext(this.mergedContextConfiguration); - if (context instanceof ConfigurableApplicationContext) { - @SuppressWarnings("resource") - ConfigurableApplicationContext cac = (ConfigurableApplicationContext) context; + if (context instanceof ConfigurableApplicationContext cac) { Assert.state(cac.isActive(), () -> "The ApplicationContext loaded for [" + this.mergedContextConfiguration + "] is not active. This may be due to one of the following reasons: " + diff --git a/spring-test/src/main/java/org/springframework/test/context/transaction/TestContextTransactionUtils.java b/spring-test/src/main/java/org/springframework/test/context/transaction/TestContextTransactionUtils.java index fc2c8be8e248..8b10ae16a09b 100644 --- a/spring-test/src/main/java/org/springframework/test/context/transaction/TestContextTransactionUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/transaction/TestContextTransactionUtils.java @@ -106,9 +106,7 @@ public static DataSource retrieveDataSource(TestContext testContext, @Nullable S } try { - if (bf instanceof ListableBeanFactory) { - ListableBeanFactory lbf = (ListableBeanFactory) bf; - + if (bf instanceof ListableBeanFactory lbf) { // Look up single bean by type Map dataSources = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, DataSource.class); @@ -180,9 +178,7 @@ public static PlatformTransactionManager retrieveTransactionManager(TestContext } try { - if (bf instanceof ListableBeanFactory) { - ListableBeanFactory lbf = (ListableBeanFactory) bf; - + if (bf instanceof ListableBeanFactory lbf) { // Look up single TransactionManagementConfigurer Map configurers = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, TransactionManagementConfigurer.class); diff --git a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java index 3051524eb899..0badc4476c68 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java @@ -188,8 +188,7 @@ private void setUpRequestContextIfNecessary(TestContext testContext) { ApplicationContext context = testContext.getApplicationContext(); - if (context instanceof WebApplicationContext) { - WebApplicationContext wac = (WebApplicationContext) context; + if (context instanceof WebApplicationContext wac) { ServletContext servletContext = wac.getServletContext(); Assert.state(servletContext instanceof MockServletContext, () -> String.format( "The WebApplicationContext for test context %s must be configured with a MockServletContext.", @@ -211,9 +210,7 @@ private void setUpRequestContextIfNecessary(TestContext testContext) { testContext.setAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE); testContext.setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE); - if (wac instanceof ConfigurableApplicationContext) { - @SuppressWarnings("resource") - ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) wac; + if (wac instanceof ConfigurableApplicationContext configurableApplicationContext) { ConfigurableListableBeanFactory bf = configurableApplicationContext.getBeanFactory(); bf.registerResolvableDependency(MockHttpServletResponse.class, response); bf.registerResolvableDependency(ServletWebRequest.class, servletWebRequest); diff --git a/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizer.java b/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizer.java index c746941672bf..7a4222833be4 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizer.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizer.java @@ -36,8 +36,7 @@ class MockServerContainerContextCustomizer implements ContextCustomizer { @Override public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { - if (context instanceof WebApplicationContext) { - WebApplicationContext wac = (WebApplicationContext) context; + if (context instanceof WebApplicationContext wac) { ServletContext sc = wac.getServletContext(); if (sc != null) { sc.setAttribute("jakarta.websocket.server.ServerContainer", new MockServerContainer()); diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java index d811cdb12e31..252e70a0bfc4 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java @@ -45,6 +45,7 @@ public T filters(Filter... filters) { return self(); } + @Override public final T filter(Filter filter, String... urlPatterns) { getMockMvcBuilder().addFilter(filter, urlPatterns); return self(); diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java index 16df1e7e4894..81bde230655b 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java @@ -370,8 +370,7 @@ private void params(MockHttpServletRequest request, UriComponents uriComponents) }); }); for (NameValuePair param : this.webRequest.getRequestParameters()) { - if (param instanceof KeyDataPair) { - KeyDataPair pair = (KeyDataPair) param; + if (param instanceof KeyDataPair pair) { File file = pair.getFile(); MockPart part; if (file != null) { diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java index e7122070f130..d9d45f34c8e4 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java @@ -561,11 +561,9 @@ public Object merge(@Nullable Object parent) { if (parent == null) { return this; } - if (!(parent instanceof MockHttpServletRequestBuilder)) { + if (!(parent instanceof MockHttpServletRequestBuilder parentBuilder)) { throw new IllegalArgumentException("Cannot merge with [" + parent.getClass().getName() + "]"); } - MockHttpServletRequestBuilder parentBuilder = (MockHttpServletRequestBuilder) parent; - if (!StringUtils.hasText(this.contextPath)) { this.contextPath = parentBuilder.contextPath; } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java index e9a8b694493e..0ead22c22f5b 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java @@ -122,8 +122,7 @@ public Object merge(@Nullable Object parent) { } if (parent instanceof MockHttpServletRequestBuilder) { super.merge(parent); - if (parent instanceof MockMultipartHttpServletRequestBuilder) { - MockMultipartHttpServletRequestBuilder parentBuilder = (MockMultipartHttpServletRequestBuilder) parent; + if (parent instanceof MockMultipartHttpServletRequestBuilder parentBuilder) { this.files.addAll(parentBuilder.files); parentBuilder.parts.keySet().forEach(name -> this.parts.putIfAbsent(name, parentBuilder.parts.get(name))); diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/PrintingResultHandler.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/PrintingResultHandler.java index f9539b1a6a0a..7f1cc67268e7 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/PrintingResultHandler.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/PrintingResultHandler.java @@ -179,8 +179,7 @@ protected void printHandler(@Nullable Object handler, @Nullable HandlerIntercept this.printer.printValue("Type", null); } else { - if (handler instanceof HandlerMethod) { - HandlerMethod handlerMethod = (HandlerMethod) handler; + if (handler instanceof HandlerMethod handlerMethod) { this.printer.printValue("Type", handlerMethod.getBeanType().getName()); this.printer.printValue("Method", handlerMethod); } From 940a37f9cefb33fd9c70072e8ced6a21d4a98a2b Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 15:53:54 +0200 Subject: [PATCH 249/735] Apply "final fields" Eclipse clean-up in spring-test This has only been applied to `src/main/java`. --- .../main/java/org/springframework/mock/env/MockEnvironment.java | 2 +- .../test/web/client/response/DefaultResponseCreator.java | 2 +- .../test/web/servlet/setup/AbstractMockMvcBuilder.java | 2 +- .../test/web/servlet/setup/StandaloneMockMvcBuilder.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/mock/env/MockEnvironment.java b/spring-test/src/main/java/org/springframework/mock/env/MockEnvironment.java index 8495e7c37b06..447352f87cf1 100644 --- a/spring-test/src/main/java/org/springframework/mock/env/MockEnvironment.java +++ b/spring-test/src/main/java/org/springframework/mock/env/MockEnvironment.java @@ -31,7 +31,7 @@ */ public class MockEnvironment extends AbstractEnvironment { - private MockPropertySource propertySource = new MockPropertySource(); + private final MockPropertySource propertySource = new MockPropertySource(); /** * Create a new {@code MockEnvironment} with a single {@link MockPropertySource}. diff --git a/spring-test/src/main/java/org/springframework/test/web/client/response/DefaultResponseCreator.java b/spring-test/src/main/java/org/springframework/test/web/client/response/DefaultResponseCreator.java index 5170d5a515dd..f76553c7feb3 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/response/DefaultResponseCreator.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/response/DefaultResponseCreator.java @@ -40,7 +40,7 @@ */ public class DefaultResponseCreator implements ResponseCreator { - private HttpStatus statusCode; + private final HttpStatus statusCode; private byte[] content = new byte[0]; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/AbstractMockMvcBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/AbstractMockMvcBuilder.java index dcf4b06b687e..f8636fbd91e9 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/AbstractMockMvcBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/AbstractMockMvcBuilder.java @@ -56,7 +56,7 @@ public abstract class AbstractMockMvcBuilder> extends MockMvcBuilderSupport implements ConfigurableMockMvcBuilder { - private List filters = new ArrayList<>(); + private final List filters = new ArrayList<>(); @Nullable private RequestBuilder defaultRequestBuilder; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java index ac94d5c103fc..7a547b5fe130 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java @@ -137,7 +137,7 @@ public class StandaloneMockMvcBuilder extends AbstractMockMvcBuilder placeholderValues = new HashMap<>(); + private final Map placeholderValues = new HashMap<>(); private Supplier handlerMappingFactory = RequestMappingHandlerMapping::new; From fba92c012042a48443a169cf3f42dabb542aa8c1 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 16:03:39 +0200 Subject: [PATCH 250/735] Update copyright date --- .../main/java/org/springframework/mock/env/MockEnvironment.java | 2 +- .../context/cache/DefaultCacheAwareContextLoaderDelegate.java | 2 +- .../test/context/support/AbstractTestContextBootstrapper.java | 2 +- .../test/context/support/DefaultTestContext.java | 2 +- .../test/context/transaction/TestContextTransactionUtils.java | 2 +- .../test/context/web/ServletTestExecutionListener.java | 2 +- .../web/socket/MockServerContainerContextCustomizer.java | 2 +- .../test/web/client/response/DefaultResponseCreator.java | 2 +- .../test/web/servlet/client/AbstractMockMvcServerSpec.java | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/mock/env/MockEnvironment.java b/spring-test/src/main/java/org/springframework/mock/env/MockEnvironment.java index 447352f87cf1..fd5e36da3131 100644 --- a/spring-test/src/main/java/org/springframework/mock/env/MockEnvironment.java +++ b/spring-test/src/main/java/org/springframework/mock/env/MockEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/main/java/org/springframework/test/context/cache/DefaultCacheAwareContextLoaderDelegate.java b/spring-test/src/main/java/org/springframework/test/context/cache/DefaultCacheAwareContextLoaderDelegate.java index 2e5e54eed13d..8cb5c9ab383b 100644 --- a/spring-test/src/main/java/org/springframework/test/context/cache/DefaultCacheAwareContextLoaderDelegate.java +++ b/spring-test/src/main/java/org/springframework/test/context/cache/DefaultCacheAwareContextLoaderDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java index be2b3b8d57cb..c242a0c7edcd 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/main/java/org/springframework/test/context/support/DefaultTestContext.java b/spring-test/src/main/java/org/springframework/test/context/support/DefaultTestContext.java index ff318f8c3da5..2c2f1318a7cc 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/DefaultTestContext.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/DefaultTestContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/main/java/org/springframework/test/context/transaction/TestContextTransactionUtils.java b/spring-test/src/main/java/org/springframework/test/context/transaction/TestContextTransactionUtils.java index 8b10ae16a09b..a91f4a1f44c7 100644 --- a/spring-test/src/main/java/org/springframework/test/context/transaction/TestContextTransactionUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/transaction/TestContextTransactionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java index 0badc4476c68..322a826ca218 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizer.java b/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizer.java index 7a4222833be4..441615cf1c68 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizer.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/socket/MockServerContainerContextCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/main/java/org/springframework/test/web/client/response/DefaultResponseCreator.java b/spring-test/src/main/java/org/springframework/test/web/client/response/DefaultResponseCreator.java index f76553c7feb3..8a10c217209d 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/response/DefaultResponseCreator.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/response/DefaultResponseCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java index 252e70a0bfc4..ac693c0293ed 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/AbstractMockMvcServerSpec.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 07cd6ab76181e2e9e30063bb3a9f1892f02b6f05 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 16:13:50 +0200 Subject: [PATCH 251/735] Apply "instanceof pattern matching" Eclipse clean-up in spring-aop This commit also applies additional clean-up tasks such as the following. - final fields This has only been applied to `src/main/java`. --- .../aop/aspectj/AbstractAspectJAdvice.java | 6 ++---- .../aspectj/AspectJAdviceParameterNameDiscoverer.java | 6 +++--- .../aop/aspectj/AspectJAroundAdvice.java | 3 +-- .../aop/aspectj/AspectJExpressionPointcut.java | 3 +-- .../aop/aspectj/AspectJPointcutAdvisor.java | 3 +-- .../annotation/AbstractAspectJAdvisorFactory.java | 3 +-- .../config/AspectJAutoProxyBeanDefinitionParser.java | 3 +-- .../aop/config/ConfigBeanDefinitionParser.java | 2 +- .../config/ScopedProxyBeanDefinitionDecorator.java | 3 +-- .../framework/AbstractAdvisingBeanPostProcessor.java | 3 +-- .../springframework/aop/framework/AdvisedSupport.java | 3 +-- .../springframework/aop/framework/CglibAopProxy.java | 3 +-- .../aop/framework/DefaultAdvisorChainFactory.java | 11 ++++------- .../aop/framework/ProxyFactoryBean.java | 3 +-- .../aop/framework/ReflectiveMethodInvocation.java | 6 ++---- .../adapter/DefaultAdvisorAdapterRegistry.java | 3 +-- .../aop/interceptor/ExposeBeanNameAdvisors.java | 9 +++------ .../aop/scope/ScopedProxyFactoryBean.java | 4 +--- .../aop/support/AbstractPointcutAdvisor.java | 3 +-- .../aop/support/AbstractRegexpMethodPointcut.java | 3 +-- .../org/springframework/aop/support/AopUtils.java | 3 +-- .../aop/support/ComposablePointcut.java | 3 +-- .../aop/support/ControlFlowPointcut.java | 3 +-- .../aop/support/DefaultIntroductionAdvisor.java | 3 +-- ...elegatePerTargetObjectIntroductionInterceptor.java | 4 ++-- .../springframework/aop/support/MethodMatchers.java | 9 +++------ .../aop/support/annotation/AnnotationClassFilter.java | 3 +-- .../annotation/AnnotationMatchingPointcut.java | 6 ++---- .../support/annotation/AnnotationMethodMatcher.java | 3 +-- .../springframework/aop/target/EmptyTargetSource.java | 3 +-- .../aop/target/SingletonTargetSource.java | 3 +-- 31 files changed, 44 insertions(+), 82 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java index 8ef1bf148a17..5beb29f55b5e 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java @@ -78,10 +78,9 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence */ public static JoinPoint currentJoinPoint() { MethodInvocation mi = ExposeInvocationInterceptor.currentInvocation(); - if (!(mi instanceof ProxyMethodInvocation)) { + if (!(mi instanceof ProxyMethodInvocation pmi)) { throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } - ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi; JoinPoint jp = (JoinPoint) pmi.getUserAttribute(JOIN_POINT_KEY); if (jp == null) { jp = new MethodInvocationProceedingJoinPoint(pmi); @@ -714,10 +713,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof AdviceExcludingMethodMatcher)) { + if (!(other instanceof AdviceExcludingMethodMatcher otherMm)) { return false; } - AdviceExcludingMethodMatcher otherMm = (AdviceExcludingMethodMatcher) other; return this.adviceMethod.equals(otherMm.adviceMethod); } 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 60a45977513e..9497eb30a266 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 @@ -158,7 +158,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov /** The pointcut expression associated with the advice, as a simple String. */ @Nullable - private String pointcutExpression; + private final String pointcutExpression; private boolean raiseExceptions; @@ -759,10 +759,10 @@ private void findAndBind(Class argumentType, String varName) { */ private static class PointcutBody { - private int numTokensConsumed; + private final int numTokensConsumed; @Nullable - private String text; + private final String text; public PointcutBody(int tokens, @Nullable String text) { this.numTokensConsumed = tokens; diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java index 7a7029323d26..e3530a11a5ac 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java @@ -63,10 +63,9 @@ protected boolean supportsProceedingJoinPoint() { @Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { - if (!(mi instanceof ProxyMethodInvocation)) { + if (!(mi instanceof ProxyMethodInvocation pmi)) { throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } - ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi; ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi); JoinPointMatch jpm = getJoinPointMatch(pmi); return invokeAdviceMethod(pjp, jpm, null, null); diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java index 8b5e5f6f3e0f..40aa1c95f74e 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java @@ -523,10 +523,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof AspectJExpressionPointcut)) { + if (!(other instanceof AspectJExpressionPointcut otherPc)) { return false; } - AspectJExpressionPointcut otherPc = (AspectJExpressionPointcut) other; return ObjectUtils.nullSafeEquals(this.getExpression(), otherPc.getExpression()) && ObjectUtils.nullSafeEquals(this.pointcutDeclarationScope, otherPc.pointcutDeclarationScope) && ObjectUtils.nullSafeEquals(this.pointcutParameterNames, otherPc.pointcutParameterNames) && diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java index b1a12175212b..17fc3422a966 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java @@ -97,10 +97,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof AspectJPointcutAdvisor)) { + if (!(other instanceof AspectJPointcutAdvisor otherAdvisor)) { return false; } - AspectJPointcutAdvisor otherAdvisor = (AspectJPointcutAdvisor) other; return this.advice.equals(otherAdvisor.advice); } diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java index 58f3c23b459f..54110bcd0d81 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java @@ -214,8 +214,7 @@ private AspectJAnnotationType determineAnnotationType(A annotation) { private String resolveExpression(A annotation) { for (String attributeName : EXPRESSION_ATTRIBUTES) { Object val = AnnotationUtils.getValue(annotation, attributeName); - if (val instanceof String) { - String str = (String) val; + if (val instanceof String str) { if (!str.isEmpty()) { return str; } diff --git a/spring-aop/src/main/java/org/springframework/aop/config/AspectJAutoProxyBeanDefinitionParser.java b/spring-aop/src/main/java/org/springframework/aop/config/AspectJAutoProxyBeanDefinitionParser.java index 4271bec65d5e..1f23b5ecb7e4 100644 --- a/spring-aop/src/main/java/org/springframework/aop/config/AspectJAutoProxyBeanDefinitionParser.java +++ b/spring-aop/src/main/java/org/springframework/aop/config/AspectJAutoProxyBeanDefinitionParser.java @@ -59,8 +59,7 @@ private void addIncludePatterns(Element element, ParserContext parserContext, Be NodeList childNodes = element.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); - if (node instanceof Element) { - Element includeElement = (Element) node; + if (node instanceof Element includeElement) { TypedStringValue valueHolder = new TypedStringValue(includeElement.getAttribute("name")); valueHolder.setSource(parserContext.extractSource(includeElement)); includePatterns.add(valueHolder); diff --git a/spring-aop/src/main/java/org/springframework/aop/config/ConfigBeanDefinitionParser.java b/spring-aop/src/main/java/org/springframework/aop/config/ConfigBeanDefinitionParser.java index de31818c70a6..70b6870f75c1 100644 --- a/spring-aop/src/main/java/org/springframework/aop/config/ConfigBeanDefinitionParser.java +++ b/spring-aop/src/main/java/org/springframework/aop/config/ConfigBeanDefinitionParser.java @@ -93,7 +93,7 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser { private static final int POINTCUT_INDEX = 1; private static final int ASPECT_INSTANCE_FACTORY_INDEX = 2; - private ParseState parseState = new ParseState(); + private final ParseState parseState = new ParseState(); @Override diff --git a/spring-aop/src/main/java/org/springframework/aop/config/ScopedProxyBeanDefinitionDecorator.java b/spring-aop/src/main/java/org/springframework/aop/config/ScopedProxyBeanDefinitionDecorator.java index ca940ec518f1..0e51956f940a 100644 --- a/spring-aop/src/main/java/org/springframework/aop/config/ScopedProxyBeanDefinitionDecorator.java +++ b/spring-aop/src/main/java/org/springframework/aop/config/ScopedProxyBeanDefinitionDecorator.java @@ -42,8 +42,7 @@ class ScopedProxyBeanDefinitionDecorator implements BeanDefinitionDecorator { @Override public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) { boolean proxyTargetClass = true; - if (node instanceof Element) { - Element ele = (Element) node; + if (node instanceof Element ele) { if (ele.hasAttribute(PROXY_TARGET_CLASS)) { proxyTargetClass = Boolean.parseBoolean(ele.getAttribute(PROXY_TARGET_CLASS)); } diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java b/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java index d941bdac4c9c..57c301e9b11e 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java @@ -69,8 +69,7 @@ public Object postProcessAfterInitialization(Object bean, String beanName) { return bean; } - if (bean instanceof Advised) { - Advised advised = (Advised) bean; + if (bean instanceof Advised advised) { if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) { // Add our local Advisor to the existing proxy's Advisor chain... if (this.beforeExistingAdvisors) { diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java b/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java index b2b8060b8a6a..65ca054410eb 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java @@ -283,8 +283,7 @@ public void removeAdvisor(int index) throws AopConfigException { } Advisor advisor = this.advisors.remove(index); - if (advisor instanceof IntroductionAdvisor) { - IntroductionAdvisor ia = (IntroductionAdvisor) advisor; + if (advisor instanceof IntroductionAdvisor ia) { // We need to remove introduction interfaces. for (Class ifc : ia.getInterfaces()) { removeInterface(ifc); diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java index 022cc0fddf24..0e6504b64a0f 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java @@ -949,10 +949,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ProxyCallbackFilter)) { + if (!(other instanceof ProxyCallbackFilter otherCallbackFilter)) { return false; } - ProxyCallbackFilter otherCallbackFilter = (ProxyCallbackFilter) other; AdvisedSupport otherAdvised = otherCallbackFilter.advised; if (this.advised.isFrozen() != otherAdvised.isFrozen()) { return false; diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAdvisorChainFactory.java b/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAdvisorChainFactory.java index a8f458781d65..67e435a88357 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAdvisorChainFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAdvisorChainFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,9 +60,8 @@ public List getInterceptorsAndDynamicInterceptionAdvice( Boolean hasIntroductions = null; for (Advisor advisor : advisors) { - if (advisor instanceof PointcutAdvisor) { + if (advisor instanceof PointcutAdvisor pointcutAdvisor) { // Add it conditionally. - PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); boolean match; @@ -90,8 +89,7 @@ public List getInterceptorsAndDynamicInterceptionAdvice( } } } - else if (advisor instanceof IntroductionAdvisor) { - IntroductionAdvisor ia = (IntroductionAdvisor) advisor; + else if (advisor instanceof IntroductionAdvisor ia) { if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); @@ -111,8 +109,7 @@ else if (advisor instanceof IntroductionAdvisor) { */ private static boolean hasMatchingIntroductions(Advisor[] advisors, Class actualClass) { for (Advisor advisor : advisors) { - if (advisor instanceof IntroductionAdvisor) { - IntroductionAdvisor ia = (IntroductionAdvisor) advisor; + if (advisor instanceof IntroductionAdvisor ia) { if (ia.getClassFilter().matches(actualClass)) { return true; } diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java b/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java index 6c9efc49f0d7..d14f8008eddd 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java @@ -479,8 +479,7 @@ private List freshAdvisorChain() { Advisor[] advisors = getAdvisors(); List freshAdvisors = new ArrayList<>(advisors.length); for (Advisor advisor : advisors) { - if (advisor instanceof PrototypePlaceholderAdvisor) { - PrototypePlaceholderAdvisor pa = (PrototypePlaceholderAdvisor) advisor; + if (advisor instanceof PrototypePlaceholderAdvisor pa) { if (logger.isDebugEnabled()) { logger.debug("Refreshing bean named '" + pa.getBeanName() + "'"); } diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/ReflectiveMethodInvocation.java b/spring-aop/src/main/java/org/springframework/aop/framework/ReflectiveMethodInvocation.java index 1db34223cb41..6b57eb9fa49a 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/ReflectiveMethodInvocation.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/ReflectiveMethodInvocation.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -165,11 +165,9 @@ public Object proceed() throws Throwable { Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); - if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { + if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher dm) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. - InterceptorAndDynamicMethodMatcher dm = - (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; Class targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass()); if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) { return dm.interceptor.invoke(this); diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/adapter/DefaultAdvisorAdapterRegistry.java b/spring-aop/src/main/java/org/springframework/aop/framework/adapter/DefaultAdvisorAdapterRegistry.java index 7f2c66144b66..da24c8017cff 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/adapter/DefaultAdvisorAdapterRegistry.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/adapter/DefaultAdvisorAdapterRegistry.java @@ -58,10 +58,9 @@ public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException { if (adviceObject instanceof Advisor) { return (Advisor) adviceObject; } - if (!(adviceObject instanceof Advice)) { + if (!(adviceObject instanceof Advice advice)) { throw new UnknownAdviceTypeException(adviceObject); } - Advice advice = (Advice) adviceObject; if (advice instanceof MethodInterceptor) { // So well-known it doesn't even need an adapter. return new DefaultPointcutAdvisor(advice); diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/ExposeBeanNameAdvisors.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/ExposeBeanNameAdvisors.java index 7dfb777dee39..17aa3bfaf527 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/ExposeBeanNameAdvisors.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/ExposeBeanNameAdvisors.java @@ -68,10 +68,9 @@ public static String getBeanName() throws IllegalStateException { * @throws IllegalStateException if the bean name has not been exposed */ public static String getBeanName(MethodInvocation mi) throws IllegalStateException { - if (!(mi instanceof ProxyMethodInvocation)) { + if (!(mi instanceof ProxyMethodInvocation pmi)) { throw new IllegalArgumentException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } - ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi; String beanName = (String) pmi.getUserAttribute(BEAN_NAME_ATTRIBUTE); if (beanName == null) { throw new IllegalStateException("Cannot get bean name; not set on MethodInvocation: " + mi); @@ -113,10 +112,9 @@ public ExposeBeanNameInterceptor(String beanName) { @Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { - if (!(mi instanceof ProxyMethodInvocation)) { + if (!(mi instanceof ProxyMethodInvocation pmi)) { throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } - ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi; pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, this.beanName); return mi.proceed(); } @@ -138,10 +136,9 @@ public ExposeBeanNameIntroduction(String beanName) { @Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { - if (!(mi instanceof ProxyMethodInvocation)) { + if (!(mi instanceof ProxyMethodInvocation pmi)) { throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } - ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi; pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, this.beanName); return super.invoke(mi); } diff --git a/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java b/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java index 281b975a4c8c..2a77bf6b54b7 100644 --- a/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java +++ b/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java @@ -85,11 +85,9 @@ public void setTargetBeanName(String targetBeanName) { @Override public void setBeanFactory(BeanFactory beanFactory) { - if (!(beanFactory instanceof ConfigurableBeanFactory)) { + if (!(beanFactory instanceof ConfigurableBeanFactory cbf)) { throw new IllegalStateException("Not running in a ConfigurableBeanFactory: " + beanFactory); } - ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory; - this.scopedTargetSource.setBeanFactory(beanFactory); ProxyFactory pf = new ProxyFactory(); diff --git a/spring-aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java b/spring-aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java index 7b7c95a8ac5e..9c515e8ed04f 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java @@ -69,10 +69,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof PointcutAdvisor)) { + if (!(other instanceof PointcutAdvisor otherAdvisor)) { return false; } - PointcutAdvisor otherAdvisor = (PointcutAdvisor) other; return (ObjectUtils.nullSafeEquals(getAdvice(), otherAdvisor.getAdvice()) && ObjectUtils.nullSafeEquals(getPointcut(), otherAdvisor.getPointcut())); } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/AbstractRegexpMethodPointcut.java b/spring-aop/src/main/java/org/springframework/aop/support/AbstractRegexpMethodPointcut.java index a6ca47c15c37..8add9103caa1 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/AbstractRegexpMethodPointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/AbstractRegexpMethodPointcut.java @@ -200,10 +200,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof AbstractRegexpMethodPointcut)) { + if (!(other instanceof AbstractRegexpMethodPointcut otherPointcut)) { return false; } - AbstractRegexpMethodPointcut otherPointcut = (AbstractRegexpMethodPointcut) other; return (Arrays.equals(this.patterns, otherPointcut.patterns) && Arrays.equals(this.excludedPatterns, otherPointcut.excludedPatterns)); } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java b/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java index 8055ec98cb60..1260627ff3f8 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java @@ -284,8 +284,7 @@ public static boolean canApply(Advisor advisor, Class targetClass, boolean ha if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); } - else if (advisor instanceof PointcutAdvisor) { - PointcutAdvisor pca = (PointcutAdvisor) advisor; + else if (advisor instanceof PointcutAdvisor pca) { return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { diff --git a/spring-aop/src/main/java/org/springframework/aop/support/ComposablePointcut.java b/spring-aop/src/main/java/org/springframework/aop/support/ComposablePointcut.java index 4bbcaf333411..b73c40bd4c10 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/ComposablePointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/ComposablePointcut.java @@ -188,10 +188,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ComposablePointcut)) { + if (!(other instanceof ComposablePointcut otherPointcut)) { return false; } - ComposablePointcut otherPointcut = (ComposablePointcut) other; return (this.classFilter.equals(otherPointcut.classFilter) && this.methodMatcher.equals(otherPointcut.methodMatcher)); } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/ControlFlowPointcut.java b/spring-aop/src/main/java/org/springframework/aop/support/ControlFlowPointcut.java index 1c4dd8bf43fa..788eae69a5fe 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/ControlFlowPointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/ControlFlowPointcut.java @@ -128,10 +128,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ControlFlowPointcut)) { + if (!(other instanceof ControlFlowPointcut that)) { return false; } - ControlFlowPointcut that = (ControlFlowPointcut) other; return (this.clazz.equals(that.clazz)) && ObjectUtils.nullSafeEquals(this.methodName, that.methodName); } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java b/spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java index ff2370a32233..5fefc059f36a 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java @@ -155,10 +155,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof DefaultIntroductionAdvisor)) { + if (!(other instanceof DefaultIntroductionAdvisor otherAdvisor)) { return false; } - DefaultIntroductionAdvisor otherAdvisor = (DefaultIntroductionAdvisor) other; return (this.advice.equals(otherAdvisor.advice) && this.interfaces.equals(otherAdvisor.interfaces)); } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/DelegatePerTargetObjectIntroductionInterceptor.java b/spring-aop/src/main/java/org/springframework/aop/support/DelegatePerTargetObjectIntroductionInterceptor.java index e55cf0b6d3bd..a212e8983c4f 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/DelegatePerTargetObjectIntroductionInterceptor.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/DelegatePerTargetObjectIntroductionInterceptor.java @@ -61,9 +61,9 @@ public class DelegatePerTargetObjectIntroductionInterceptor extends Introduction */ private final Map delegateMap = new WeakHashMap<>(); - private Class defaultImplType; + private final Class defaultImplType; - private Class interfaceType; + private final Class interfaceType; public DelegatePerTargetObjectIntroductionInterceptor(Class defaultImplType, Class interfaceType) { 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 23b4d9b78de5..6fbd38279dc5 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 @@ -146,10 +146,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof UnionMethodMatcher)) { + if (!(other instanceof UnionMethodMatcher that)) { return false; } - UnionMethodMatcher that = (UnionMethodMatcher) other; return (this.mm1.equals(that.mm1) && this.mm2.equals(that.mm2)); } @@ -223,8 +222,7 @@ public boolean equals(@Nullable Object other) { } ClassFilter otherCf1 = ClassFilter.TRUE; ClassFilter otherCf2 = ClassFilter.TRUE; - if (other instanceof ClassFilterAwareUnionMethodMatcher) { - ClassFilterAwareUnionMethodMatcher cfa = (ClassFilterAwareUnionMethodMatcher) other; + if (other instanceof ClassFilterAwareUnionMethodMatcher cfa) { otherCf1 = cfa.cf1; otherCf2 = cfa.cf2; } @@ -312,10 +310,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof IntersectionMethodMatcher)) { + if (!(other instanceof IntersectionMethodMatcher that)) { return false; } - IntersectionMethodMatcher that = (IntersectionMethodMatcher) other; return (this.mm1.equals(that.mm1) && this.mm2.equals(that.mm2)); } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java index 847f1bb86220..40530db71895 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java @@ -72,10 +72,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof AnnotationClassFilter)) { + if (!(other instanceof AnnotationClassFilter otherCf)) { return false; } - AnnotationClassFilter otherCf = (AnnotationClassFilter) other; return (this.annotationType.equals(otherCf.annotationType) && this.checkInherited == otherCf.checkInherited); } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java index d734fbc0f147..f17a78f6ecb6 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java @@ -125,10 +125,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof AnnotationMatchingPointcut)) { + if (!(other instanceof AnnotationMatchingPointcut otherPointcut)) { return false; } - AnnotationMatchingPointcut otherPointcut = (AnnotationMatchingPointcut) other; return (this.classFilter.equals(otherPointcut.classFilter) && this.methodMatcher.equals(otherPointcut.methodMatcher)); } @@ -189,10 +188,9 @@ public boolean equals(Object obj) { if (this == obj) { return true; } - if (!(obj instanceof AnnotationCandidateClassFilter)) { + if (!(obj instanceof AnnotationCandidateClassFilter that)) { return false; } - AnnotationCandidateClassFilter that = (AnnotationCandidateClassFilter) obj; return this.annotationType.equals(that.annotationType); } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java index 720c7b889bbb..b65661bb4b74 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java @@ -92,10 +92,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof AnnotationMethodMatcher)) { + if (!(other instanceof AnnotationMethodMatcher otherMm)) { return false; } - AnnotationMethodMatcher otherMm = (AnnotationMethodMatcher) other; return (this.annotationType.equals(otherMm.annotationType) && this.checkInherited == otherMm.checkInherited); } diff --git a/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java index 2ebcc216dce7..cf3afa032c7d 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java @@ -135,10 +135,9 @@ public boolean equals(Object other) { if (this == other) { return true; } - if (!(other instanceof EmptyTargetSource)) { + if (!(other instanceof EmptyTargetSource otherTs)) { return false; } - EmptyTargetSource otherTs = (EmptyTargetSource) other; return (ObjectUtils.nullSafeEquals(this.targetClass, otherTs.targetClass) && this.isStatic == otherTs.isStatic); } diff --git a/spring-aop/src/main/java/org/springframework/aop/target/SingletonTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/SingletonTargetSource.java index 24ae9865a6db..52115fbf45fb 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/SingletonTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/SingletonTargetSource.java @@ -85,10 +85,9 @@ public boolean equals(Object other) { if (this == other) { return true; } - if (!(other instanceof SingletonTargetSource)) { + if (!(other instanceof SingletonTargetSource otherTargetSource)) { return false; } - SingletonTargetSource otherTargetSource = (SingletonTargetSource) other; return this.target.equals(otherTargetSource.target); } From 63c6a7e15efe741adc38a4bccaef389468bb808b Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 16:26:21 +0200 Subject: [PATCH 252/735] Update copyright date --- .../org/springframework/aop/aspectj/AbstractAspectJAdvice.java | 2 +- .../org/springframework/aop/aspectj/AspectJAroundAdvice.java | 2 +- .../org/springframework/aop/aspectj/AspectJPointcutAdvisor.java | 2 +- .../aop/config/AspectJAutoProxyBeanDefinitionParser.java | 2 +- .../springframework/aop/config/ConfigBeanDefinitionParser.java | 2 +- .../aop/config/ScopedProxyBeanDefinitionDecorator.java | 2 +- .../java/org/springframework/aop/framework/AdvisedSupport.java | 2 +- .../org/springframework/aop/framework/ProxyFactoryBean.java | 2 +- .../aop/framework/adapter/DefaultAdvisorAdapterRegistry.java | 2 +- .../springframework/aop/interceptor/ExposeBeanNameAdvisors.java | 2 +- .../org/springframework/aop/scope/ScopedProxyFactoryBean.java | 2 +- .../springframework/aop/support/AbstractPointcutAdvisor.java | 2 +- .../aop/support/AbstractRegexpMethodPointcut.java | 2 +- .../src/main/java/org/springframework/aop/support/AopUtils.java | 2 +- .../org/springframework/aop/support/ComposablePointcut.java | 2 +- .../support/DelegatePerTargetObjectIntroductionInterceptor.java | 2 +- .../java/org/springframework/aop/support/MethodMatchers.java | 2 +- .../aop/support/annotation/AnnotationClassFilter.java | 2 +- .../aop/support/annotation/AnnotationMatchingPointcut.java | 2 +- .../aop/support/annotation/AnnotationMethodMatcher.java | 2 +- .../java/org/springframework/aop/target/EmptyTargetSource.java | 2 +- .../org/springframework/aop/target/SingletonTargetSource.java | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java index 5beb29f55b5e..fdede934f586 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java index e3530a11a5ac..d1584c54af8a 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java index 17fc3422a966..442df0808f26 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/config/AspectJAutoProxyBeanDefinitionParser.java b/spring-aop/src/main/java/org/springframework/aop/config/AspectJAutoProxyBeanDefinitionParser.java index 1f23b5ecb7e4..70b9762006b0 100644 --- a/spring-aop/src/main/java/org/springframework/aop/config/AspectJAutoProxyBeanDefinitionParser.java +++ b/spring-aop/src/main/java/org/springframework/aop/config/AspectJAutoProxyBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/config/ConfigBeanDefinitionParser.java b/spring-aop/src/main/java/org/springframework/aop/config/ConfigBeanDefinitionParser.java index 70b6870f75c1..fff18c0a4e42 100644 --- a/spring-aop/src/main/java/org/springframework/aop/config/ConfigBeanDefinitionParser.java +++ b/spring-aop/src/main/java/org/springframework/aop/config/ConfigBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/config/ScopedProxyBeanDefinitionDecorator.java b/spring-aop/src/main/java/org/springframework/aop/config/ScopedProxyBeanDefinitionDecorator.java index 0e51956f940a..e116ec85947a 100644 --- a/spring-aop/src/main/java/org/springframework/aop/config/ScopedProxyBeanDefinitionDecorator.java +++ b/spring-aop/src/main/java/org/springframework/aop/config/ScopedProxyBeanDefinitionDecorator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java b/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java index 65ca054410eb..7bd772a29060 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java b/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java index d14f8008eddd..5f3d3d17e416 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/adapter/DefaultAdvisorAdapterRegistry.java b/spring-aop/src/main/java/org/springframework/aop/framework/adapter/DefaultAdvisorAdapterRegistry.java index da24c8017cff..9335a1f5a012 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/adapter/DefaultAdvisorAdapterRegistry.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/adapter/DefaultAdvisorAdapterRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/ExposeBeanNameAdvisors.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/ExposeBeanNameAdvisors.java index 17aa3bfaf527..1f095ed89e9e 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/ExposeBeanNameAdvisors.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/ExposeBeanNameAdvisors.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java b/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java index 2a77bf6b54b7..fe7934b0ca0c 100644 --- a/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java +++ b/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java b/spring-aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java index 9c515e8ed04f..c032db69e90b 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/support/AbstractRegexpMethodPointcut.java b/spring-aop/src/main/java/org/springframework/aop/support/AbstractRegexpMethodPointcut.java index 8add9103caa1..9587e1164612 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/AbstractRegexpMethodPointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/AbstractRegexpMethodPointcut.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java b/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java index 1260627ff3f8..a40218231b10 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/support/ComposablePointcut.java b/spring-aop/src/main/java/org/springframework/aop/support/ComposablePointcut.java index b73c40bd4c10..9a259b16a23e 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/ComposablePointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/ComposablePointcut.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/support/DelegatePerTargetObjectIntroductionInterceptor.java b/spring-aop/src/main/java/org/springframework/aop/support/DelegatePerTargetObjectIntroductionInterceptor.java index a212e8983c4f..299a474a64e0 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/DelegatePerTargetObjectIntroductionInterceptor.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/DelegatePerTargetObjectIntroductionInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. 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 6fbd38279dc5..893986f6a9a2 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-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java index 40530db71895..5ed1ae5f8b1e 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java index f17a78f6ecb6..539e5820b12b 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java index b65661bb4b74..ce6ec2e29afe 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java index cf3afa032c7d..da63c2bb2f8c 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-aop/src/main/java/org/springframework/aop/target/SingletonTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/SingletonTargetSource.java index 52115fbf45fb..216b7c0648b5 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/SingletonTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/SingletonTargetSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 401c0d220a8e6f89b7707530005ce802c67729e8 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 16:45:08 +0200 Subject: [PATCH 253/735] Apply "instanceof pattern matching" Eclipse clean-up in spring-beans This commit also applies additional clean-up tasks such as the following. - final fields - diamond operator (<>) for anonymous inner classes - Comparator.comparing This has only been applied to `src/main/java`. --- .../beans/BeanMetadataAttribute.java | 5 +- .../beans/ExtendedBeanInfo.java | 10 ++- .../GenericTypeAwarePropertyDescriptor.java | 3 +- .../beans/MutablePropertyValues.java | 5 +- .../springframework/beans/PropertyValue.java | 5 +- .../beans/factory/BeanFactoryUtils.java | 23 +++---- .../BeanFactoryAnnotationUtils.java | 5 +- .../annotation/CustomAutowireConfigurer.java | 8 +-- ...nitDestroyAnnotationBeanPostProcessor.java | 3 +- .../factory/annotation/InjectionMetadata.java | 5 +- .../factory/config/BeanDefinitionHolder.java | 5 +- .../factory/config/BeanDefinitionVisitor.java | 11 ++- .../factory/config/BeanExpressionContext.java | 5 +- .../config/ConstructorArgumentValues.java | 3 +- .../config/RuntimeBeanNameReference.java | 5 +- .../factory/config/RuntimeBeanReference.java | 5 +- .../factory/config/TypedStringValue.java | 5 +- .../groovy/GroovyBeanDefinitionReader.java | 2 +- .../parsing/BeanComponentDefinition.java | 6 +- .../AbstractAutowireCapableBeanFactory.java | 7 +- .../support/AbstractBeanDefinition.java | 9 +-- .../factory/support/AbstractBeanFactory.java | 6 +- .../beans/factory/support/AutowireUtils.java | 11 ++- .../support/BeanDefinitionValueResolver.java | 68 +++++++++---------- .../factory/support/ChildBeanDefinition.java | 5 +- .../support/DefaultListableBeanFactory.java | 7 +- .../support/GenericBeanDefinition.java | 5 +- ...ricTypeAwareAutowireCandidateResolver.java | 5 +- .../beans/factory/support/LookupOverride.java | 3 +- .../beans/factory/support/MethodOverride.java | 5 +- .../factory/support/MethodOverrides.java | 5 +- .../PropertiesBeanDefinitionReader.java | 8 +-- .../factory/support/ReplaceOverride.java | 3 +- .../support/StaticListableBeanFactory.java | 4 +- .../xml/BeanDefinitionParserDelegate.java | 5 +- .../DefaultBeanDefinitionDocumentReader.java | 5 +- .../SimpleConstructorNamespaceHandler.java | 5 +- .../xml/SimplePropertyNamespaceHandler.java | 5 +- .../factory/xml/XmlBeanDefinitionReader.java | 4 +- .../beans/support/MutableSortDefinition.java | 5 +- 40 files changed, 120 insertions(+), 179 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanMetadataAttribute.java b/spring-beans/src/main/java/org/springframework/beans/BeanMetadataAttribute.java index db6435d5c0e4..57662a952b1a 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanMetadataAttribute.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanMetadataAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,10 +85,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof BeanMetadataAttribute)) { + if (!(other instanceof BeanMetadataAttribute otherMa)) { return false; } - BeanMetadataAttribute otherMa = (BeanMetadataAttribute) other; return (this.name.equals(otherMa.name) && ObjectUtils.nullSafeEquals(this.value, otherMa.value) && ObjectUtils.nullSafeEquals(this.source, otherMa.source)); diff --git a/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java b/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java index 21ce57cf6add..a338b7cde609 100644 --- a/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java +++ b/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -139,7 +139,7 @@ private List findCandidateWriteMethods(MethodDescriptor[] methodDescript // Sort non-void returning write methods to guard against the ill effects of // non-deterministic sorting of methods returned from Class#getDeclaredMethods // under JDK 7. See https://bugs.java.com/view_bug.do?bug_id=7023180 - matches.sort((m1, m2) -> m2.toString().compareTo(m1.toString())); + matches.sort(Comparator.comparing(Method::toString).reversed()); return matches; } @@ -188,8 +188,7 @@ private PropertyDescriptor findExistingPropertyDescriptor(String propertyName, C for (PropertyDescriptor pd : this.propertyDescriptors) { final Class candidateType; final String candidateName = pd.getName(); - if (pd instanceof IndexedPropertyDescriptor) { - IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd; + if (pd instanceof IndexedPropertyDescriptor ipd) { candidateType = ipd.getIndexedPropertyType(); if (candidateName.equals(propertyName) && (candidateType.equals(propertyType) || candidateType.equals(propertyType.getComponentType()))) { @@ -494,10 +493,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof IndexedPropertyDescriptor)) { + if (!(other instanceof IndexedPropertyDescriptor otherPd)) { return false; } - IndexedPropertyDescriptor otherPd = (IndexedPropertyDescriptor) other; return (ObjectUtils.nullSafeEquals(getIndexedReadMethod(), otherPd.getIndexedReadMethod()) && ObjectUtils.nullSafeEquals(getIndexedWriteMethod(), otherPd.getIndexedWriteMethod()) && ObjectUtils.nullSafeEquals(getIndexedPropertyType(), otherPd.getIndexedPropertyType()) && diff --git a/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java b/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java index b4052b7b84e9..fb5d4d15ae1d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java +++ b/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java @@ -168,10 +168,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof GenericTypeAwarePropertyDescriptor)) { + if (!(other instanceof GenericTypeAwarePropertyDescriptor otherPd)) { return false; } - GenericTypeAwarePropertyDescriptor otherPd = (GenericTypeAwarePropertyDescriptor) other; return (getBeanClass().equals(otherPd.getBeanClass()) && PropertyDescriptorUtils.equals(this, otherPd)); } diff --git a/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java b/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java index 97c0a0ab05b9..1c978059ef1e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java +++ b/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -221,8 +221,7 @@ public void setPropertyValueAt(PropertyValue pv, int i) { */ private PropertyValue mergeIfRequired(PropertyValue newPv, PropertyValue currentPv) { Object value = newPv.getValue(); - if (value instanceof Mergeable) { - Mergeable mergeable = (Mergeable) value; + if (value instanceof Mergeable mergeable) { if (mergeable.isMergeEnabled()) { Object merged = mergeable.merge(currentPv.getValue()); return new PropertyValue(newPv.getName(), merged); diff --git a/spring-beans/src/main/java/org/springframework/beans/PropertyValue.java b/spring-beans/src/main/java/org/springframework/beans/PropertyValue.java index 16c6bae560a4..93b97042b010 100644 --- a/spring-beans/src/main/java/org/springframework/beans/PropertyValue.java +++ b/spring-beans/src/main/java/org/springframework/beans/PropertyValue.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -192,10 +192,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof PropertyValue)) { + if (!(other instanceof PropertyValue otherPv)) { return false; } - PropertyValue otherPv = (PropertyValue) other; return (this.name.equals(otherPv.name) && ObjectUtils.nullSafeEquals(this.value, otherPv.value) && ObjectUtils.nullSafeEquals(getSource(), otherPv.getSource())); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java index 17a5d70460de..fbc7cb4751d0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -161,8 +161,7 @@ public static String[] beanNamesIncludingAncestors(ListableBeanFactory lbf) { public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, ResolvableType type) { Assert.notNull(lbf, "ListableBeanFactory must not be null"); String[] result = lbf.getBeanNamesForType(type); - if (lbf instanceof HierarchicalBeanFactory) { - HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf; + if (lbf instanceof HierarchicalBeanFactory hbf) { if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) { String[] parentResult = beanNamesForTypeIncludingAncestors( (ListableBeanFactory) hbf.getParentBeanFactory(), type); @@ -199,8 +198,7 @@ public static String[] beanNamesForTypeIncludingAncestors( Assert.notNull(lbf, "ListableBeanFactory must not be null"); String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit); - if (lbf instanceof HierarchicalBeanFactory) { - HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf; + if (lbf instanceof HierarchicalBeanFactory hbf) { if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) { String[] parentResult = beanNamesForTypeIncludingAncestors( (ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit); @@ -226,8 +224,7 @@ public static String[] beanNamesForTypeIncludingAncestors( public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, Class type) { Assert.notNull(lbf, "ListableBeanFactory must not be null"); String[] result = lbf.getBeanNamesForType(type); - if (lbf instanceof HierarchicalBeanFactory) { - HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf; + if (lbf instanceof HierarchicalBeanFactory hbf) { if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) { String[] parentResult = beanNamesForTypeIncludingAncestors( (ListableBeanFactory) hbf.getParentBeanFactory(), type); @@ -263,8 +260,7 @@ public static String[] beanNamesForTypeIncludingAncestors( Assert.notNull(lbf, "ListableBeanFactory must not be null"); String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit); - if (lbf instanceof HierarchicalBeanFactory) { - HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf; + if (lbf instanceof HierarchicalBeanFactory hbf) { if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) { String[] parentResult = beanNamesForTypeIncludingAncestors( (ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit); @@ -289,8 +285,7 @@ public static String[] beanNamesForAnnotationIncludingAncestors( Assert.notNull(lbf, "ListableBeanFactory must not be null"); String[] result = lbf.getBeanNamesForAnnotation(annotationType); - if (lbf instanceof HierarchicalBeanFactory) { - HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf; + if (lbf instanceof HierarchicalBeanFactory hbf) { if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) { String[] parentResult = beanNamesForAnnotationIncludingAncestors( (ListableBeanFactory) hbf.getParentBeanFactory(), annotationType); @@ -327,8 +322,7 @@ public static Map beansOfTypeIncludingAncestors(ListableBeanFacto Assert.notNull(lbf, "ListableBeanFactory must not be null"); Map result = new LinkedHashMap<>(4); result.putAll(lbf.getBeansOfType(type)); - if (lbf instanceof HierarchicalBeanFactory) { - HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf; + if (lbf instanceof HierarchicalBeanFactory hbf) { if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) { Map parentResult = beansOfTypeIncludingAncestors( (ListableBeanFactory) hbf.getParentBeanFactory(), type); @@ -376,8 +370,7 @@ public static Map beansOfTypeIncludingAncestors( Assert.notNull(lbf, "ListableBeanFactory must not be null"); Map result = new LinkedHashMap<>(4); result.putAll(lbf.getBeansOfType(type, includeNonSingletons, allowEagerInit)); - if (lbf instanceof HierarchicalBeanFactory) { - HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf; + if (lbf instanceof HierarchicalBeanFactory hbf) { if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) { Map parentResult = beansOfTypeIncludingAncestors( (ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationUtils.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationUtils.java index 58e04c4c032d..722995aabec4 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -166,8 +166,7 @@ public static boolean isQualifierMatch( if (beanFactory instanceof ConfigurableBeanFactory) { BeanDefinition bd = ((ConfigurableBeanFactory) beanFactory).getMergedBeanDefinition(beanName); // Explicit qualifier metadata on bean definition? (typically in XML definition) - if (bd instanceof AbstractBeanDefinition) { - AbstractBeanDefinition abd = (AbstractBeanDefinition) bd; + if (bd instanceof AbstractBeanDefinition abd) { AutowireCandidateQualifier candidate = abd.getQualifier(Qualifier.class.getName()); if (candidate != null) { Object value = candidate.getAttribute(AutowireCandidateQualifier.VALUE_KEY); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.java index d43329a0f626..86fe4482b2ee 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -91,11 +91,10 @@ public void setCustomQualifierTypes(Set customQualifierTypes) { @SuppressWarnings("unchecked") public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { if (this.customQualifierTypes != null) { - if (!(beanFactory instanceof DefaultListableBeanFactory)) { + if (!(beanFactory instanceof DefaultListableBeanFactory dlbf)) { throw new IllegalStateException( "CustomAutowireConfigurer needs to operate on a DefaultListableBeanFactory"); } - DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory; if (!(dlbf.getAutowireCandidateResolver() instanceof QualifierAnnotationAutowireCandidateResolver)) { dlbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver()); } @@ -106,8 +105,7 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) if (value instanceof Class) { customType = (Class) value; } - else if (value instanceof String) { - String className = (String) value; + else if (value instanceof String className) { customType = (Class) ClassUtils.resolveClassName(className, this.beanClassLoader); } else { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java index 2f1bd7763b2c..804c89a4455d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java @@ -394,10 +394,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof LifecycleElement)) { + if (!(other instanceof LifecycleElement otherElement)) { return false; } - LifecycleElement otherElement = (LifecycleElement) other; return (this.identifier.equals(otherElement.identifier)); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java index f7dcb8d18cf1..4e205558523d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -304,10 +304,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof InjectedElement)) { + if (!(other instanceof InjectedElement otherElement)) { return false; } - InjectedElement otherElement = (InjectedElement) other; return this.member.equals(otherElement.member); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionHolder.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionHolder.java index d6767f7dcf7e..0b25ad6144a1 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionHolder.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionHolder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -168,10 +168,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof BeanDefinitionHolder)) { + if (!(other instanceof BeanDefinitionHolder otherHolder)) { return false; } - BeanDefinitionHolder otherHolder = (BeanDefinitionHolder) other; return this.beanDefinition.equals(otherHolder.beanDefinition) && this.beanName.equals(otherHolder.beanName) && ObjectUtils.nullSafeEquals(this.aliases, otherHolder.aliases); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionVisitor.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionVisitor.java index 7b826c50d7cd..d3d83c71ca93 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionVisitor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -178,8 +178,7 @@ protected Object resolveValue(@Nullable Object value) { else if (value instanceof BeanDefinitionHolder) { visitBeanDefinition(((BeanDefinitionHolder) value).getBeanDefinition()); } - else if (value instanceof RuntimeBeanReference) { - RuntimeBeanReference ref = (RuntimeBeanReference) value; + else if (value instanceof RuntimeBeanReference ref) { String newBeanName = resolveStringValue(ref.getBeanName()); if (newBeanName == null) { return null; @@ -188,8 +187,7 @@ else if (value instanceof RuntimeBeanReference) { return new RuntimeBeanReference(newBeanName); } } - else if (value instanceof RuntimeBeanNameReference) { - RuntimeBeanNameReference ref = (RuntimeBeanNameReference) value; + else if (value instanceof RuntimeBeanNameReference ref) { String newBeanName = resolveStringValue(ref.getBeanName()); if (newBeanName == null) { return null; @@ -210,8 +208,7 @@ else if (value instanceof Set) { else if (value instanceof Map) { visitMap((Map) value); } - else if (value instanceof TypedStringValue) { - TypedStringValue typedStringValue = (TypedStringValue) value; + else if (value instanceof TypedStringValue typedStringValue) { String stringValue = typedStringValue.getValue(); if (stringValue != null) { String visitedString = resolveStringValue(stringValue); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionContext.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionContext.java index e6e383935e78..e50e9346587e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionContext.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,10 +73,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof BeanExpressionContext)) { + if (!(other instanceof BeanExpressionContext otherContext)) { return false; } - BeanExpressionContext otherContext = (BeanExpressionContext) other; return (this.beanFactory == otherContext.beanFactory && this.scope == otherContext.scope); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java index c4d779e697b8..a90e57094530 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java @@ -392,10 +392,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ConstructorArgumentValues)) { + if (!(other instanceof ConstructorArgumentValues that)) { return false; } - ConstructorArgumentValues that = (ConstructorArgumentValues) other; if (this.genericArgumentValues.size() != that.genericArgumentValues.size() || this.indexedArgumentValues.size() != that.indexedArgumentValues.size()) { return false; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/RuntimeBeanNameReference.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/RuntimeBeanNameReference.java index 805f6bbd61bc..90a59c2ac7f5 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/RuntimeBeanNameReference.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/RuntimeBeanNameReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,10 +71,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof RuntimeBeanNameReference)) { + if (!(other instanceof RuntimeBeanNameReference that)) { return false; } - RuntimeBeanNameReference that = (RuntimeBeanNameReference) other; return this.beanName.equals(that.beanName); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/RuntimeBeanReference.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/RuntimeBeanReference.java index 11b4f1ac79b6..a414c3e78297 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/RuntimeBeanReference.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/RuntimeBeanReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -135,10 +135,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof RuntimeBeanReference)) { + if (!(other instanceof RuntimeBeanReference that)) { return false; } - RuntimeBeanReference that = (RuntimeBeanReference) other; return (this.beanName.equals(that.beanName) && this.beanType == that.beanType && this.toParent == that.toParent); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java index 70d4ab2ff09c..bd27173a3f88 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -219,10 +219,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof TypedStringValue)) { + if (!(other instanceof TypedStringValue otherValue)) { return false; } - TypedStringValue otherValue = (TypedStringValue) other; return (ObjectUtils.nullSafeEquals(this.value, otherValue.value) && ObjectUtils.nullSafeEquals(this.targetType, otherValue.targetType)); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java b/spring-beans/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java index 9ef7aa3799f3..56dd8580e9f8 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java @@ -244,7 +244,7 @@ public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefin } @SuppressWarnings("serial") - Closure beans = new Closure(this) { + Closure beans = new Closure<>(this) { @Override public Object call(Object... args) { invokeBeanDefiningClosure((Closure) args[0]); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/parsing/BeanComponentDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/parsing/BeanComponentDefinition.java index 32305abbacc3..cb7720f85c9a 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/parsing/BeanComponentDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/parsing/BeanComponentDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,9 +36,9 @@ */ public class BeanComponentDefinition extends BeanDefinitionHolder implements ComponentDefinition { - private BeanDefinition[] innerBeanDefinitions; + private final BeanDefinition[] innerBeanDefinitions; - private BeanReference[] beanReferences; + private final BeanReference[] beanReferences; /** diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 77abc22fce61..5ab6fb085a27 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -303,9 +303,7 @@ public void ignoreDependencyInterface(Class ifc) { @Override public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) { super.copyConfigurationFrom(otherFactory); - if (otherFactory instanceof AbstractAutowireCapableBeanFactory) { - AbstractAutowireCapableBeanFactory otherAutowireFactory = - (AbstractAutowireCapableBeanFactory) otherFactory; + if (otherFactory instanceof AbstractAutowireCapableBeanFactory otherAutowireFactory) { this.instantiationStrategy = otherAutowireFactory.instantiationStrategy; this.allowCircularReferences = otherAutowireFactory.allowCircularReferences; this.ignoredDependencyTypes.addAll(otherAutowireFactory.ignoredDependencyTypes); @@ -344,8 +342,7 @@ public Object configureBean(Object existingBean, String beanName) throws BeansEx markBeanAsCreated(beanName); BeanDefinition mbd = getMergedBeanDefinition(beanName); RootBeanDefinition bd = null; - if (mbd instanceof RootBeanDefinition) { - RootBeanDefinition rbd = (RootBeanDefinition) mbd; + if (mbd instanceof RootBeanDefinition rbd) { bd = (rbd.isPrototype() ? rbd : rbd.cloneBeanDefinition()); } if (bd == null) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java index 2ceff658dbce..09bbf79d1943 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java @@ -236,8 +236,7 @@ protected AbstractBeanDefinition(BeanDefinition original) { setSource(original.getSource()); copyAttributesFrom(original); - if (original instanceof AbstractBeanDefinition) { - AbstractBeanDefinition originalAbd = (AbstractBeanDefinition) original; + if (original instanceof AbstractBeanDefinition originalAbd) { if (originalAbd.hasBeanClass()) { setBeanClass(originalAbd.getBeanClass()); } @@ -313,8 +312,7 @@ public void overrideFrom(BeanDefinition other) { setSource(other.getSource()); copyAttributesFrom(other); - if (other instanceof AbstractBeanDefinition) { - AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other; + if (other instanceof AbstractBeanDefinition otherAbd) { if (otherAbd.hasBeanClass()) { setBeanClass(otherAbd.getBeanClass()); } @@ -1178,10 +1176,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof AbstractBeanDefinition)) { + if (!(other instanceof AbstractBeanDefinition that)) { return false; } - AbstractBeanDefinition that = (AbstractBeanDefinition) other; return (ObjectUtils.nullSafeEquals(getBeanClassName(), that.getBeanClassName()) && ObjectUtils.nullSafeEquals(this.scope, that.scope) && this.abstractFlag == that.abstractFlag && diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index 921b46c38533..b33651f186d3 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -1054,8 +1054,7 @@ public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) { setCacheBeanMetadata(otherFactory.isCacheBeanMetadata()); setBeanExpressionResolver(otherFactory.getBeanExpressionResolver()); setConversionService(otherFactory.getConversionService()); - if (otherFactory instanceof AbstractBeanFactory) { - AbstractBeanFactory otherAbstractFactory = (AbstractBeanFactory) otherFactory; + if (otherFactory instanceof AbstractBeanFactory otherAbstractFactory) { this.propertyEditorRegistrars.addAll(otherAbstractFactory.propertyEditorRegistrars); this.customEditors.putAll(otherAbstractFactory.customEditors); this.typeConverter = otherAbstractFactory.typeConverter; @@ -1512,8 +1511,7 @@ private Class doResolveBeanClass(RootBeanDefinition mbd, Class... typesToM if (tempClassLoader != null) { dynamicLoader = tempClassLoader; freshResolve = true; - if (tempClassLoader instanceof DecoratingClassLoader) { - DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader; + if (tempClassLoader instanceof DecoratingClassLoader dcl) { for (Class typeToMatch : typesToMatch) { dcl.excludeClass(typeToMatch.getName()); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java index d807cc4dc2fe..c91508cb1810 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -198,8 +198,7 @@ public static Class resolveReturnTypeForFactoryMethod( Type methodParameterType = methodParameterTypes[i]; Object arg = args[i]; if (methodParameterType.equals(genericReturnType)) { - if (arg instanceof TypedStringValue) { - TypedStringValue typedValue = ((TypedStringValue) arg); + if (arg instanceof TypedStringValue typedValue) { if (typedValue.hasTargetType()) { return typedValue.getTargetType(); } @@ -220,8 +219,7 @@ else if (arg != null && !(arg instanceof BeanMetadataElement)) { } return method.getReturnType(); } - else if (methodParameterType instanceof ParameterizedType) { - ParameterizedType parameterizedType = (ParameterizedType) methodParameterType; + else if (methodParameterType instanceof ParameterizedType parameterizedType) { Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); for (Type typeArg : actualTypeArguments) { if (typeArg.equals(genericReturnType)) { @@ -233,8 +231,7 @@ else if (methodParameterType instanceof ParameterizedType) { if (arg instanceof String) { className = (String) arg; } - else if (arg instanceof TypedStringValue) { - TypedStringValue typedValue = ((TypedStringValue) arg); + else if (arg instanceof TypedStringValue typedValue) { String targetTypeName = typedValue.getTargetTypeName(); if (targetTypeName == null || Class.class.getName().equals(targetTypeName)) { className = typedValue.getValue(); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java index be9667b19a38..0468bc4aadd1 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,6 +55,7 @@ * Used by {@link AbstractAutowireCapableBeanFactory}. * * @author Juergen Hoeller + * @author Sam Brannen * @since 1.2 * @see AbstractAutowireCapableBeanFactory */ @@ -108,12 +109,11 @@ public BeanDefinitionValueResolver(AbstractAutowireCapableBeanFactory beanFactor public Object resolveValueIfNecessary(Object argName, @Nullable Object value) { // We must check each value to see whether it requires a runtime reference // to another bean to be resolved. - if (value instanceof RuntimeBeanReference) { - RuntimeBeanReference ref = (RuntimeBeanReference) value; + if (value instanceof RuntimeBeanReference ref) { return resolveReference(argName, ref); } - else if (value instanceof RuntimeBeanNameReference) { - String refName = ((RuntimeBeanNameReference) value).getBeanName(); + else if (value instanceof RuntimeBeanNameReference ref) { + String refName = ref.getBeanName(); refName = String.valueOf(doEvaluate(refName)); if (!this.beanFactory.containsBean(refName)) { throw new BeanDefinitionStoreException( @@ -121,22 +121,20 @@ else if (value instanceof RuntimeBeanNameReference) { } return refName; } - else if (value instanceof BeanDefinitionHolder) { + else if (value instanceof BeanDefinitionHolder bdHolder) { // Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases. - BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value; return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition()); } - else if (value instanceof BeanDefinition) { + else if (value instanceof BeanDefinition bd) { // Resolve plain BeanDefinition, without contained name: use dummy name. - BeanDefinition bd = (BeanDefinition) value; String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(bd); return resolveInnerBean(argName, innerBeanName, bd); } - else if (value instanceof DependencyDescriptor) { + else if (value instanceof DependencyDescriptor dependencyDescriptor) { Set autowiredBeanNames = new LinkedHashSet<>(4); Object result = this.beanFactory.resolveDependency( - (DependencyDescriptor) value, this.beanName, autowiredBeanNames, this.typeConverter); + dependencyDescriptor, this.beanName, autowiredBeanNames, this.typeConverter); for (String autowiredBeanName : autowiredBeanNames) { if (this.beanFactory.containsBean(autowiredBeanName)) { this.beanFactory.registerDependentBean(autowiredBeanName, this.beanName); @@ -144,16 +142,15 @@ else if (value instanceof DependencyDescriptor) { } return result; } - else if (value instanceof ManagedArray) { + else if (value instanceof ManagedArray managedArray) { // May need to resolve contained runtime references. - ManagedArray array = (ManagedArray) value; - Class elementType = array.resolvedElementType; + Class elementType = managedArray.resolvedElementType; if (elementType == null) { - String elementTypeName = array.getElementTypeName(); + String elementTypeName = managedArray.getElementTypeName(); if (StringUtils.hasText(elementTypeName)) { try { elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader()); - array.resolvedElementType = elementType; + managedArray.resolvedElementType = elementType; } catch (Throwable ex) { // Improve the message by showing the context. @@ -168,27 +165,27 @@ else if (value instanceof ManagedArray) { } return resolveManagedArray(argName, (List) value, elementType); } - else if (value instanceof ManagedList) { + else if (value instanceof ManagedList managedList) { // May need to resolve contained runtime references. - return resolveManagedList(argName, (List) value); + return resolveManagedList(argName, managedList); } - else if (value instanceof ManagedSet) { + else if (value instanceof ManagedSet managedSet) { // May need to resolve contained runtime references. - return resolveManagedSet(argName, (Set) value); + return resolveManagedSet(argName, managedSet); } - else if (value instanceof ManagedMap) { + else if (value instanceof ManagedMap managedMap) { // May need to resolve contained runtime references. - return resolveManagedMap(argName, (Map) value); + return resolveManagedMap(argName, managedMap); } - else if (value instanceof ManagedProperties) { - Properties original = (Properties) value; + else if (value instanceof ManagedProperties original) { + // Properties original = managedProperties; Properties copy = new Properties(); original.forEach((propKey, propValue) -> { - if (propKey instanceof TypedStringValue) { - propKey = evaluate((TypedStringValue) propKey); + if (propKey instanceof TypedStringValue typedStringValue) { + propKey = evaluate(typedStringValue); } - if (propValue instanceof TypedStringValue) { - propValue = evaluate((TypedStringValue) propValue); + if (propValue instanceof TypedStringValue typedStringValue) { + propValue = evaluate(typedStringValue); } if (propKey == null || propValue == null) { throw new BeanCreationException( @@ -199,9 +196,8 @@ else if (value instanceof ManagedProperties) { }); return copy; } - else if (value instanceof TypedStringValue) { + else if (value instanceof TypedStringValue typedStringValue) { // Convert value to target type here. - TypedStringValue typedStringValue = (TypedStringValue) value; Object valueObject = evaluate(typedStringValue); try { Class resolvedTargetType = resolveTargetType(typedStringValue); @@ -248,11 +244,10 @@ protected Object evaluate(TypedStringValue value) { */ @Nullable protected Object evaluate(@Nullable Object value) { - if (value instanceof String) { - return doEvaluate((String) value); + if (value instanceof String str) { + return doEvaluate(str); } - else if (value instanceof String[]) { - String[] values = (String[]) value; + else if (value instanceof String[] values) { boolean actuallyResolved = false; Object[] resolvedValues = new Object[values.length]; for (int i = 0; i < values.length; i++) { @@ -372,10 +367,9 @@ private Object resolveInnerBean(Object argName, String innerBeanName, BeanDefini } // Actually create the inner bean instance now... Object innerBean = this.beanFactory.createBean(actualInnerBeanName, mbd, null); - if (innerBean instanceof FactoryBean) { + if (innerBean instanceof FactoryBean factoryBean) { boolean synthetic = mbd.isSynthetic(); - innerBean = this.beanFactory.getObjectFromFactoryBean( - (FactoryBean) innerBean, actualInnerBeanName, !synthetic); + innerBean = this.beanFactory.getObjectFromFactoryBean(factoryBean, actualInnerBeanName, !synthetic); } if (innerBean instanceof NullBean) { innerBean = null; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java index 51b981f6193c..bab5f2118faa 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -160,10 +160,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ChildBeanDefinition)) { + if (!(other instanceof ChildBeanDefinition that)) { return false; } - ChildBeanDefinition that = (ChildBeanDefinition) other; return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other)); } 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 7c16748e1414..6848c7347745 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 @@ -310,8 +310,7 @@ public AutowireCandidateResolver getAutowireCandidateResolver() { @Override public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) { super.copyConfigurationFrom(otherFactory); - if (otherFactory instanceof DefaultListableBeanFactory) { - DefaultListableBeanFactory otherListableFactory = (DefaultListableBeanFactory) otherFactory; + if (otherFactory instanceof DefaultListableBeanFactory otherListableFactory) { this.allowBeanDefinitionOverriding = otherListableFactory.allowBeanDefinitionOverriding; this.allowEagerClassLoading = otherListableFactory.allowEagerClassLoading; this.dependencyComparator = otherListableFactory.dependencyComparator; @@ -389,7 +388,7 @@ public ObjectProvider getBeanProvider(Class requiredType, boolean allo @Override public ObjectProvider getBeanProvider(ResolvableType requiredType, boolean allowEagerInit) { - return new BeanObjectProvider() { + return new BeanObjectProvider<>() { @Override public T getObject() throws BeansException { T resolved = resolveBean(requiredType, null, false); @@ -1248,7 +1247,7 @@ private NamedBeanHolder resolveNamedBean( if (bean instanceof NullBean) { return null; } - return new NamedBeanHolder(beanName, adaptBeanInstance(beanName, bean, requiredType.toClass())); + return new NamedBeanHolder<>(beanName, adaptBeanInstance(beanName, bean, requiredType.toClass())); } @Override diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java index ca779d1e66e9..b0a40b332ae3 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,10 +88,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof GenericBeanDefinition)) { + if (!(other instanceof GenericBeanDefinition that)) { return false; } - GenericBeanDefinition that = (GenericBeanDefinition) other; return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other)); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java index 01b81450903d..8fe5a854ffeb 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -142,8 +142,7 @@ protected boolean checkGenericTypeMatch(BeanDefinitionHolder bdHolder, Dependenc @Nullable protected RootBeanDefinition getResolvedDecoratedDefinition(RootBeanDefinition rbd) { BeanDefinitionHolder decDef = rbd.getDecoratedDefinition(); - if (decDef != null && this.beanFactory instanceof ConfigurableListableBeanFactory) { - ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) this.beanFactory; + if (decDef != null && this.beanFactory instanceof ConfigurableListableBeanFactory clbf) { if (clbf.containsBeanDefinition(decDef.getBeanName())) { BeanDefinition dbd = clbf.getMergedBeanDefinition(decDef.getBeanName()); if (dbd instanceof RootBeanDefinition) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/LookupOverride.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/LookupOverride.java index c441bf7e9cc3..faa7478a8198 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/LookupOverride.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/LookupOverride.java @@ -102,10 +102,9 @@ public boolean matches(Method method) { @Override public boolean equals(@Nullable Object other) { - if (!(other instanceof LookupOverride) || !super.equals(other)) { + if (!(other instanceof LookupOverride that) || !super.equals(other)) { return false; } - LookupOverride that = (LookupOverride) other; return (ObjectUtils.nullSafeEquals(this.method, that.method) && ObjectUtils.nullSafeEquals(this.beanName, that.beanName)); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java index 24a2056cf195..0107e104c213 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -109,10 +109,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof MethodOverride)) { + if (!(other instanceof MethodOverride that)) { return false; } - MethodOverride that = (MethodOverride) other; return (ObjectUtils.nullSafeEquals(this.methodName, that.methodName) && ObjectUtils.nullSafeEquals(this.source, that.source)); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverrides.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverrides.java index a84a15f83020..07dc3a6b0db9 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverrides.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverrides.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -107,10 +107,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof MethodOverrides)) { + if (!(other instanceof MethodOverrides that)) { return false; } - MethodOverrides that = (MethodOverrides) other; return this.overrides.equals(that.overrides); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java index 617a13be564b..01d901048d00 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -363,10 +363,9 @@ public int registerBeanDefinitions(Map map, @Nullable String prefix, Strin int beanCount = 0; for (Object key : map.keySet()) { - if (!(key instanceof String)) { + if (!(key instanceof String keyString)) { throw new IllegalArgumentException("Illegal key [" + key + "]: only Strings allowed"); } - String keyString = (String) key; if (keyString.startsWith(prefix)) { // Key is of form: prefix.property String nameAndProperty = keyString.substring(prefix.length()); @@ -519,8 +518,7 @@ else if (property.endsWith(REF_SUFFIX)) { */ private Object readValue(Map.Entry entry) { Object val = entry.getValue(); - if (val instanceof String) { - String strVal = (String) val; + if (val instanceof String strVal) { // If it starts with a reference prefix... if (strVal.startsWith(REF_PREFIX)) { // Expand the reference. diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ReplaceOverride.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ReplaceOverride.java index 80f866d21cc7..a702b7d7af1a 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ReplaceOverride.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ReplaceOverride.java @@ -97,10 +97,9 @@ public boolean matches(Method method) { @Override public boolean equals(@Nullable Object other) { - if (!(other instanceof ReplaceOverride) || !super.equals(other)) { + if (!(other instanceof ReplaceOverride that) || !super.equals(other)) { return false; } - ReplaceOverride that = (ReplaceOverride) other; return (ObjectUtils.nullSafeEquals(this.methodReplacerBeanName, that.methodReplacerBeanName) && ObjectUtils.nullSafeEquals(this.typeIdentifiers, that.typeIdentifiers)); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java index a5430120dfdb..b9994f6f7633 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -284,7 +284,7 @@ public ObjectProvider getBeanProvider(Class requiredType, boolean allo @SuppressWarnings("unchecked") @Override public ObjectProvider getBeanProvider(ResolvableType requiredType, boolean allowEagerInit) { - return new ObjectProvider() { + return new ObjectProvider<>() { @Override public T getObject() throws BeansException { String[] beanNames = getBeanNamesForType(requiredType); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java index 6be311eb1efe..fd5f4ad64527 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1186,8 +1186,7 @@ public Map parseMapElement(Element mapEle, @Nullable BeanDefinit Element valueEle = null; for (int j = 0; j < entrySubNodes.getLength(); j++) { Node node = entrySubNodes.item(j); - if (node instanceof Element) { - Element candidateEle = (Element) node; + if (node instanceof Element candidateEle) { if (nodeNameEquals(candidateEle, KEY_ELEMENT)) { if (keyEle != null) { error(" element is only allowed to contain one sub-element", entryEle); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultBeanDefinitionDocumentReader.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultBeanDefinitionDocumentReader.java index af5026dce346..b8e2935a9c46 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultBeanDefinitionDocumentReader.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultBeanDefinitionDocumentReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -170,8 +170,7 @@ protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate d NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); - if (node instanceof Element) { - Element ele = (Element) node; + if (node instanceof Element ele) { if (delegate.isDefaultNamespace(ele)) { parseDefaultElement(ele, delegate); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/SimpleConstructorNamespaceHandler.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/SimpleConstructorNamespaceHandler.java index ddffb17d5175..f30852f97b6c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/SimpleConstructorNamespaceHandler.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/SimpleConstructorNamespaceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,8 +78,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { @Override public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) { - if (node instanceof Attr) { - Attr attr = (Attr) node; + if (node instanceof Attr attr) { String argName = StringUtils.trimWhitespace(parserContext.getDelegate().getLocalName(attr)); String argValue = StringUtils.trimWhitespace(attr.getValue()); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/SimplePropertyNamespaceHandler.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/SimplePropertyNamespaceHandler.java index 9cecef4eed47..ec3c1512d8a8 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/SimplePropertyNamespaceHandler.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/SimplePropertyNamespaceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,8 +67,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { @Override public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) { - if (node instanceof Attr) { - Attr attr = (Attr) node; + if (node instanceof Attr attr) { String propertyName = parserContext.getDelegate().getLocalName(attr); String propertyValue = attr.getValue(); MutablePropertyValues pvs = definition.getBeanDefinition().getPropertyValues(); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/XmlBeanDefinitionReader.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/XmlBeanDefinitionReader.java index 589208a4d3af..25cef22bd011 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/XmlBeanDefinitionReader.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/XmlBeanDefinitionReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -128,7 +128,7 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { private final XmlValidationModeDetector validationModeDetector = new XmlValidationModeDetector(); private final ThreadLocal> resourcesCurrentlyBeingLoaded = - new NamedThreadLocal>("XML bean definition resources currently being loaded"){ + new NamedThreadLocal<>("XML bean definition resources currently being loaded"){ @Override protected Set initialValue() { return new HashSet<>(4); diff --git a/spring-beans/src/main/java/org/springframework/beans/support/MutableSortDefinition.java b/spring-beans/src/main/java/org/springframework/beans/support/MutableSortDefinition.java index 2a428fc9d077..096b0d6a2cde 100644 --- a/spring-beans/src/main/java/org/springframework/beans/support/MutableSortDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/support/MutableSortDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -159,10 +159,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof SortDefinition)) { + if (!(other instanceof SortDefinition otherSd)) { return false; } - SortDefinition otherSd = (SortDefinition) other; return (getProperty().equals(otherSd.getProperty()) && isAscending() == otherSd.isAscending() && isIgnoreCase() == otherSd.isIgnoreCase()); From 67333a3f94b5ad3ab828988932f4a75759d0c53c Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 17:09:30 +0200 Subject: [PATCH 254/735] Apply "instanceof pattern matching" Eclipse clean-up in spring-context This commit also applies additional clean-up tasks such as the following. - final fields - diamond operator (<>) for anonymous inner classes - Comparator.comparing - convert to switch expression This has only been applied to `src/main/java`. --- .../AnnotationCacheOperationSource.java | 5 +-- .../cache/config/CacheAdviceParser.java | 12 ++--- .../cache/interceptor/CacheAspectSupport.java | 3 +- .../CacheOperationSourcePointcut.java | 5 +-- .../NameMatchCacheOperationSource.java | 7 ++- .../AnnotationBeanNameGenerator.java | 5 +-- .../AnnotationScopeMetadataResolver.java | 5 +-- .../CommonAnnotationBeanPostProcessor.java | 26 +++++------ ...onfigurationClassBeanDefinitionReader.java | 8 ++-- .../ConfigurationClassEnhancer.java | 6 +-- .../ConfigurationClassPostProcessor.java | 45 +++++++++---------- .../Jsr330ScopeMetadataResolver.java | 5 +-- .../AbstractApplicationEventMulticaster.java | 3 +- .../ApplicationListenerMethodAdapter.java | 3 +- .../expression/AnnotatedElementKey.java | 5 +-- .../expression/CachedExpressionEvaluator.java | 5 +-- .../support/AbstractApplicationContext.java | 5 +-- .../DefaultMessageSourceResolvable.java | 5 +-- .../PostProcessorRegistrationDelegate.java | 10 ++--- .../PropertySourcesPlaceholderConfigurer.java | 2 +- .../context/support/SimpleThreadScope.java | 4 +- .../standard/DateTimeFormatterFactory.java | 9 ++++ .../format/number/NumberStyleFormatter.java | 5 +-- .../support/FormattingConversionService.java | 5 +-- ...esourceOverridingShadowingClassLoader.java | 6 +-- .../jmx/access/MBeanClientInterceptor.java | 15 +++---- .../jmx/export/MBeanExporter.java | 4 +- ...bstractConfigurableMBeanInfoAssembler.java | 8 ++-- .../support/ConnectorServerFactoryBean.java | 4 +- .../MBeanServerConnectionFactoryBean.java | 4 +- .../support/NotificationListenerHolder.java | 5 +-- .../jndi/support/SimpleJndiBeanFactory.java | 4 +- .../annotation/AsyncAnnotationAdvisor.java | 4 +- .../DefaultManagedAwareThreadFactory.java | 4 +- .../concurrent/ThreadPoolTaskScheduler.java | 3 +- .../scheduling/support/BitsCronField.java | 3 +- .../support/CompositeCronField.java | 3 +- .../scheduling/support/CronExpression.java | 3 +- .../support/CronSequenceGenerator.java | 5 +-- .../scheduling/support/PeriodicTrigger.java | 5 +-- .../scheduling/support/QuartzCronField.java | 3 +- .../support/StandardScriptFactory.java | 5 +-- .../support/UiApplicationContextUtils.java | 5 +-- .../validation/AbstractBindingResult.java | 8 ++-- .../SpringValidatorAdapter.java | 12 ++--- .../support/BindingAwareModelMap.java | 3 +- 46 files changed, 137 insertions(+), 172 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java b/spring-context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java index 5d34d0e1031f..230a36d18766 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -168,10 +168,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof AnnotationCacheOperationSource)) { + if (!(other instanceof AnnotationCacheOperationSource otherCos)) { return false; } - AnnotationCacheOperationSource otherCos = (AnnotationCacheOperationSource) other; return (this.annotationParsers.equals(otherCos.annotationParsers) && this.publicMethodsOnly == otherCos.publicMethodsOnly); } diff --git a/spring-context/src/main/java/org/springframework/cache/config/CacheAdviceParser.java b/spring-context/src/main/java/org/springframework/cache/config/CacheAdviceParser.java index 2d75593e50da..c85dcad9065d 100644 --- a/spring-context/src/main/java/org/springframework/cache/config/CacheAdviceParser.java +++ b/spring-context/src/main/java/org/springframework/cache/config/CacheAdviceParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -175,15 +175,15 @@ private static String getAttributeValue(Element element, String attributeName, S */ private static class Props { - private String key; + private final String key; - private String keyGenerator; + private final String keyGenerator; - private String cacheManager; + private final String cacheManager; - private String condition; + private final String condition; - private String method; + private final String method; @Nullable private String[] caches; 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 c528a83206bd..f29dfe3395ff 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 @@ -857,10 +857,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof CacheOperationCacheKey)) { + if (!(other instanceof CacheOperationCacheKey otherKey)) { return false; } - CacheOperationCacheKey otherKey = (CacheOperationCacheKey) other; return (this.cacheOperation.equals(otherKey.cacheOperation) && this.methodCacheKey.equals(otherKey.methodCacheKey)); } diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperationSourcePointcut.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperationSourcePointcut.java index 5cf286faf637..d555d802a234 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperationSourcePointcut.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperationSourcePointcut.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,10 +53,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof CacheOperationSourcePointcut)) { + if (!(other instanceof CacheOperationSourcePointcut otherPc)) { return false; } - CacheOperationSourcePointcut otherPc = (CacheOperationSourcePointcut) other; return ObjectUtils.nullSafeEquals(getCacheOperationSource(), otherPc.getCacheOperationSource()); } 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 ac23ae7e9fd2..d916e3f89c76 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,7 +47,7 @@ public class NameMatchCacheOperationSource implements CacheOperationSource, Seri /** Keys are method names; values are TransactionAttributes. */ - private Map> nameMap = new LinkedHashMap<>(); + private final Map> nameMap = new LinkedHashMap<>(); /** @@ -114,10 +114,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof NameMatchCacheOperationSource)) { + if (!(other instanceof NameMatchCacheOperationSource otherTas)) { return false; } - NameMatchCacheOperationSource otherTas = (NameMatchCacheOperationSource) other; return ObjectUtils.nullSafeEquals(this.nameMap, otherTas.nameMap); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java index d686b5f29921..e690e76d86ea 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -107,8 +107,7 @@ protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotat }); if (isStereotypeWithNameValue(type, metaTypes, attributes)) { Object value = attributes.get("value"); - if (value instanceof String) { - String strVal = (String) value; + if (value instanceof String strVal) { if (StringUtils.hasLength(strVal)) { if (beanName != null && !strVal.equals(beanName)) { throw new IllegalStateException("Stereotype annotations suggest inconsistent " + diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationScopeMetadataResolver.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationScopeMetadataResolver.java index fec4fb3e0780..867d8d17e2b4 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationScopeMetadataResolver.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationScopeMetadataResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,8 +77,7 @@ public void setScopeAnnotationType(Class scopeAnnotationTy @Override public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) { ScopeMetadata metadata = new ScopeMetadata(); - if (definition instanceof AnnotatedBeanDefinition) { - AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition; + if (definition instanceof AnnotatedBeanDefinition annDef) { AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor( annDef.getMetadata(), this.scopeAnnotationType); if (attributes != null) { diff --git a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java index c3efdfbed261..81b77e5e6a41 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java @@ -266,8 +266,8 @@ public void setBeanFactory(BeanFactory beanFactory) { if (this.resourceFactory == null) { this.resourceFactory = beanFactory; } - if (beanFactory instanceof ConfigurableBeanFactory) { - this.embeddedValueResolver = new EmbeddedValueResolver((ConfigurableBeanFactory) beanFactory); + if (beanFactory instanceof ConfigurableBeanFactory configurableBeanFactory) { + this.embeddedValueResolver = new EmbeddedValueResolver(configurableBeanFactory); } } @@ -437,8 +437,8 @@ public void releaseTarget(Object target) { if (element.lookupType.isInterface()) { pf.addInterface(element.lookupType); } - ClassLoader classLoader = (this.beanFactory instanceof ConfigurableBeanFactory ? - ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() : null); + ClassLoader classLoader = (this.beanFactory instanceof ConfigurableBeanFactory configurableBeanFactory ? + configurableBeanFactory.getBeanClassLoader() : null); return pf.getProxy(classLoader); } @@ -492,18 +492,17 @@ protected Object autowireResource(BeanFactory factory, LookupElement element, @N Set autowiredBeanNames; String name = element.name; - if (factory instanceof AutowireCapableBeanFactory) { - AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory; + if (factory instanceof AutowireCapableBeanFactory autowireCapableBeanFactory) { DependencyDescriptor descriptor = element.getDependencyDescriptor(); if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) { autowiredBeanNames = new LinkedHashSet<>(); - resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null); + resource = autowireCapableBeanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null); if (resource == null) { throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object"); } } else { - resource = beanFactory.resolveBeanByName(name, descriptor); + resource = autowireCapableBeanFactory.resolveBeanByName(name, descriptor); autowiredBeanNames = Collections.singleton(name); } } @@ -512,11 +511,10 @@ protected Object autowireResource(BeanFactory factory, LookupElement element, @N autowiredBeanNames = Collections.singleton(name); } - if (factory instanceof ConfigurableBeanFactory) { - ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory; + if (factory instanceof ConfigurableBeanFactory configurableBeanFactory) { for (String autowiredBeanName : autowiredBeanNames) { - if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) { - beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName); + if (requestingBeanName != null && configurableBeanFactory.containsBean(autowiredBeanName)) { + configurableBeanFactory.registerDependentBean(autowiredBeanName, requestingBeanName); } } } @@ -671,8 +669,8 @@ protected Object getResourceToInject(Object target, @Nullable String requestingB if (beanFactory != null && beanFactory.containsBean(this.beanName)) { // Local match found for explicitly specified local bean name. Object bean = beanFactory.getBean(this.beanName, this.lookupType); - if (requestingBeanName != null && beanFactory instanceof ConfigurableBeanFactory) { - ((ConfigurableBeanFactory) beanFactory).registerDependentBean(this.beanName, requestingBeanName); + if (requestingBeanName != null && beanFactory instanceof ConfigurableBeanFactory configurableBeanFactory) { + configurableBeanFactory.registerDependentBean(this.beanName, requestingBeanName); } return bean; } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java index 427e2bec83b2..85b45e1574f1 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -305,8 +305,7 @@ protected boolean isOverriddenByExistingDefinition(BeanMethod beanMethod, String // -> allow the current bean method to override, since both are at second-pass level. // However, if the bean method is an overloaded case on the same configuration class, // preserve the existing bean definition. - if (existingBeanDef instanceof ConfigurationClassBeanDefinition) { - ConfigurationClassBeanDefinition ccbd = (ConfigurationClassBeanDefinition) existingBeanDef; + if (existingBeanDef instanceof ConfigurationClassBeanDefinition ccbd) { if (ccbd.getMetadata().getClassName().equals( beanMethod.getConfigurationClass().getMetadata().getClassName())) { if (ccbd.getFactoryMethodMetadata().getMethodName().equals(ccbd.getFactoryMethodName())) { @@ -373,8 +372,7 @@ else if (shouldIgnoreXml) { // Instantiate the specified BeanDefinitionReader reader = readerClass.getConstructor(BeanDefinitionRegistry.class).newInstance(this.registry); // Delegate the current ResourceLoader to it if possible - if (reader instanceof AbstractBeanDefinitionReader) { - AbstractBeanDefinitionReader abdr = ((AbstractBeanDefinitionReader) reader); + if (reader instanceof AbstractBeanDefinitionReader abdr) { abdr.setResourceLoader(this.resourceLoader); abdr.setEnvironment(this.environment); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java index 17079522c7f6..eb53d63fbf84 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.aop.scope.ScopedProxyFactoryBean; +import org.springframework.asm.Opcodes; import org.springframework.asm.Type; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -36,7 +37,6 @@ import org.springframework.beans.factory.support.SimpleInstantiationStrategy; import org.springframework.cglib.core.ClassGenerator; import org.springframework.cglib.core.ClassLoaderAwareGeneratorStrategy; -import org.springframework.cglib.core.Constants; import org.springframework.cglib.core.SpringNamingPolicy; import org.springframework.cglib.proxy.Callback; import org.springframework.cglib.proxy.CallbackFilter; @@ -219,7 +219,7 @@ protected ClassGenerator transform(ClassGenerator cg) throws Exception { ClassEmitterTransformer transformer = new ClassEmitterTransformer() { @Override public void end_class() { - declare_field(Constants.ACC_PUBLIC, BEAN_FACTORY_FIELD, Type.getType(BeanFactory.class), null); + declare_field(Opcodes.ACC_PUBLIC, BEAN_FACTORY_FIELD, Type.getType(BeanFactory.class), null); super.end_class(); } }; diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java index 7913e61f56b2..e5da4c44c794 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java @@ -371,10 +371,10 @@ else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this. sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); } - if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) { + if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory cachingMetadataReaderFactory) { // Clear cache in externally provided MetadataReaderFactory; this is a no-op // for a shared cache since it'll be cleared by the ApplicationContext. - ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache(); + cachingMetadataReaderFactory.clearCache(); } } @@ -392,33 +392,30 @@ public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFact Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE); AnnotationMetadata annotationMetadata = null; MethodMetadata methodMetadata = null; - if (beanDef instanceof AnnotatedBeanDefinition) { - AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) beanDef; + if (beanDef instanceof AnnotatedBeanDefinition annotatedBeanDefinition) { annotationMetadata = annotatedBeanDefinition.getMetadata(); methodMetadata = annotatedBeanDefinition.getFactoryMethodMetadata(); } - if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) { + if ((configClassAttr != null || methodMetadata != null) && + (beanDef instanceof AbstractBeanDefinition abd) && !abd.hasBeanClass()) { // Configuration class (full or lite) or a configuration-derived @Bean method // -> eagerly resolve bean class at this point, unless it's a 'lite' configuration // or component class without @Bean methods. - AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef; - if (!abd.hasBeanClass()) { - boolean liteConfigurationCandidateWithoutBeanMethods = - (ConfigurationClassUtils.CONFIGURATION_CLASS_LITE.equals(configClassAttr) && - annotationMetadata != null && !ConfigurationClassUtils.hasBeanMethods(annotationMetadata)); - if (!liteConfigurationCandidateWithoutBeanMethods) { - try { - abd.resolveBeanClass(this.beanClassLoader); - } - catch (Throwable ex) { - throw new IllegalStateException( - "Cannot load configuration class: " + beanDef.getBeanClassName(), ex); - } + boolean liteConfigurationCandidateWithoutBeanMethods = + (ConfigurationClassUtils.CONFIGURATION_CLASS_LITE.equals(configClassAttr) && + annotationMetadata != null && !ConfigurationClassUtils.hasBeanMethods(annotationMetadata)); + if (!liteConfigurationCandidateWithoutBeanMethods) { + try { + abd.resolveBeanClass(this.beanClassLoader); + } + catch (Throwable ex) { + throw new IllegalStateException( + "Cannot load configuration class: " + beanDef.getBeanClassName(), ex); } } } if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) { - if (!(beanDef instanceof AbstractBeanDefinition)) { + if (!(beanDef instanceof AbstractBeanDefinition abd)) { throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" + beanName + "' since it is not stored in an AbstractBeanDefinition subclass"); } @@ -428,7 +425,7 @@ else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) { "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " + "return type: Consider declaring such methods as 'static'."); } - configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef); + configBeanDefs.put(beanName, abd); } } if (configBeanDefs.isEmpty() || NativeDetector.inNativeImage()) { @@ -469,19 +466,19 @@ public ImportAwareBeanPostProcessor(BeanFactory beanFactory) { public PropertyValues postProcessProperties(@Nullable PropertyValues pvs, Object bean, String beanName) { // Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's // postProcessProperties method attempts to autowire other configuration beans. - if (bean instanceof EnhancedConfiguration) { - ((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory); + if (bean instanceof EnhancedConfiguration enhancedConfiguration) { + enhancedConfiguration.setBeanFactory(this.beanFactory); } return pvs; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { - if (bean instanceof ImportAware) { + if (bean instanceof ImportAware importAware) { ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class); AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName()); if (importingClass != null) { - ((ImportAware) bean).setImportMetadata(importingClass); + importAware.setImportMetadata(importingClass); } } return bean; diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Jsr330ScopeMetadataResolver.java b/spring-context/src/main/java/org/springframework/context/annotation/Jsr330ScopeMetadataResolver.java index 7dc65574f4cd..b3e1c6736ef1 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/Jsr330ScopeMetadataResolver.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/Jsr330ScopeMetadataResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -87,8 +87,7 @@ protected String resolveScopeName(String annotationType) { public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) { ScopeMetadata metadata = new ScopeMetadata(); metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE); - if (definition instanceof AnnotatedBeanDefinition) { - AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition; + if (definition instanceof AnnotatedBeanDefinition annDef) { Set annTypes = annDef.getMetadata().getAnnotationTypes(); String found = null; for (String annType : annTypes) { diff --git a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java index d765539d0ada..26147f825acc 100644 --- a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java +++ b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java @@ -400,10 +400,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ListenerCacheKey)) { + if (!(other instanceof ListenerCacheKey otherKey)) { return false; } - ListenerCacheKey otherKey = (ListenerCacheKey) other; return (this.eventType.equals(otherKey.eventType) && ObjectUtils.nullSafeEquals(this.sourceType, otherKey.sourceType)); } diff --git a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java index bc7e1f939899..748fa55b3938 100644 --- a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java +++ b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java @@ -293,8 +293,7 @@ private void publishEvents(Object result) { publishEvent(event); } } - else if (result instanceof Collection) { - Collection events = (Collection) result; + else if (result instanceof Collection events) { for (Object event : events) { publishEvent(event); } diff --git a/spring-context/src/main/java/org/springframework/context/expression/AnnotatedElementKey.java b/spring-context/src/main/java/org/springframework/context/expression/AnnotatedElementKey.java index 582e823ee0b3..6476217f3203 100644 --- a/spring-context/src/main/java/org/springframework/context/expression/AnnotatedElementKey.java +++ b/spring-context/src/main/java/org/springframework/context/expression/AnnotatedElementKey.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,10 +55,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof AnnotatedElementKey)) { + if (!(other instanceof AnnotatedElementKey otherKey)) { return false; } - AnnotatedElementKey otherKey = (AnnotatedElementKey) other; return (this.element.equals(otherKey.element) && ObjectUtils.nullSafeEquals(this.targetClass, otherKey.targetClass)); } diff --git a/spring-context/src/main/java/org/springframework/context/expression/CachedExpressionEvaluator.java b/spring-context/src/main/java/org/springframework/context/expression/CachedExpressionEvaluator.java index 7b868fc9871e..e24511d6e1c3 100644 --- a/spring-context/src/main/java/org/springframework/context/expression/CachedExpressionEvaluator.java +++ b/spring-context/src/main/java/org/springframework/context/expression/CachedExpressionEvaluator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -118,10 +118,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ExpressionKey)) { + if (!(other instanceof ExpressionKey otherKey)) { return false; } - ExpressionKey otherKey = (ExpressionKey) other; return (this.element.equals(otherKey.element) && ObjectUtils.nullSafeEquals(this.expression, otherKey.expression)); } diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index aca706e82c1f..dae989caa666 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -211,7 +211,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader private Thread shutdownHook; /** ResourcePatternResolver used by this context. */ - private ResourcePatternResolver resourcePatternResolver; + private final ResourcePatternResolver resourcePatternResolver; /** LifecycleProcessor for managing the lifecycle of beans within this context. */ @Nullable @@ -771,8 +771,7 @@ protected void initMessageSource() { if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); // Make MessageSource aware of parent MessageSource. - if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { - HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; + if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource hms) { if (hms.getParentMessageSource() == null) { // Only set parent context as parent MessageSource if no parent MessageSource // registered already. diff --git a/spring-context/src/main/java/org/springframework/context/support/DefaultMessageSourceResolvable.java b/spring-context/src/main/java/org/springframework/context/support/DefaultMessageSourceResolvable.java index 334204465fb0..e8297a5bcf06 100644 --- a/spring-context/src/main/java/org/springframework/context/support/DefaultMessageSourceResolvable.java +++ b/spring-context/src/main/java/org/springframework/context/support/DefaultMessageSourceResolvable.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -174,10 +174,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof MessageSourceResolvable)) { + if (!(other instanceof MessageSourceResolvable otherResolvable)) { return false; } - MessageSourceResolvable otherResolvable = (MessageSourceResolvable) other; return (ObjectUtils.nullSafeEquals(getCodes(), otherResolvable.getCodes()) && ObjectUtils.nullSafeEquals(getArguments(), otherResolvable.getArguments()) && ObjectUtils.nullSafeEquals(getDefaultMessage(), otherResolvable.getDefaultMessage())); 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 493eb3789428..ebf935ab51cf 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 @@ -35,7 +35,6 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor; -import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.core.OrderComparator; import org.springframework.core.Ordered; import org.springframework.core.PriorityOrdered; @@ -75,15 +74,12 @@ public static void invokeBeanFactoryPostProcessors( // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set processedBeans = new HashSet<>(); - if (beanFactory instanceof BeanDefinitionRegistry) { - BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; + if (beanFactory instanceof BeanDefinitionRegistry registry) { List regularPostProcessors = new ArrayList<>(); List registryProcessors = new ArrayList<>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { - if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { - BeanDefinitionRegistryPostProcessor registryProcessor = - (BeanDefinitionRegistryPostProcessor) postProcessor; + if (postProcessor instanceof BeanDefinitionRegistryPostProcessor registryProcessor) { registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } @@ -384,7 +380,7 @@ public Object postProcessAfterInitialization(Object bean, String beanName) { private boolean isInfrastructureBean(@Nullable String beanName) { if (beanName != null && this.beanFactory.containsBeanDefinition(beanName)) { BeanDefinition bd = this.beanFactory.getBeanDefinition(beanName); - return (bd.getRole() == RootBeanDefinition.ROLE_INFRASTRUCTURE); + return (bd.getRole() == BeanDefinition.ROLE_INFRASTRUCTURE); } return false; } diff --git a/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java b/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java index a0907a1f3a15..c2d5e65d583c 100644 --- a/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java +++ b/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java @@ -130,7 +130,7 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) this.propertySources = new MutablePropertySources(); if (this.environment != null) { this.propertySources.addLast( - new PropertySource(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) { + new PropertySource<>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) { @Override @Nullable public String getProperty(String key) { diff --git a/spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java b/spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java index a1750518a42d..0b237eb0b1c2 100644 --- a/spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java +++ b/spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,7 +56,7 @@ public class SimpleThreadScope implements Scope { private static final Log logger = LogFactory.getLog(SimpleThreadScope.class); private final ThreadLocal> threadScope = - new NamedThreadLocal>("SimpleThreadScope") { + new NamedThreadLocal<>("SimpleThreadScope") { @Override protected Map initialValue() { return new HashMap<>(); diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterFactory.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterFactory.java index c2fc3148dbc3..df4f277e5de9 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterFactory.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterFactory.java @@ -183,6 +183,15 @@ public DateTimeFormatter createDateTimeFormatter(DateTimeFormatter fallbackForma dateTimeFormatter = DateTimeFormatterUtils.createStrictDateTimeFormatter(this.pattern); } else if (this.iso != null && this.iso != ISO.NONE) { + // TODO Use switch expression once spring-javaformat 0.0.30 has been released. + // See https://github.com/spring-io/spring-javaformat/issues/300 + // + // dateTimeFormatter = switch (this.iso) { + // case DATE -> DateTimeFormatter.ISO_DATE; + // case TIME -> DateTimeFormatter.ISO_TIME; + // case DATE_TIME -> DateTimeFormatter.ISO_DATE_TIME; + // default -> throw new IllegalStateException("Unsupported ISO format: " + this.iso); + // }; switch (this.iso) { case DATE: dateTimeFormatter = DateTimeFormatter.ISO_DATE; diff --git a/spring-context/src/main/java/org/springframework/format/number/NumberStyleFormatter.java b/spring-context/src/main/java/org/springframework/format/number/NumberStyleFormatter.java index 2ebbe36ce383..1597180306a6 100644 --- a/spring-context/src/main/java/org/springframework/format/number/NumberStyleFormatter.java +++ b/spring-context/src/main/java/org/springframework/format/number/NumberStyleFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,13 +71,12 @@ public void setPattern(String pattern) { @Override public NumberFormat getNumberFormat(Locale locale) { NumberFormat format = NumberFormat.getInstance(locale); - if (!(format instanceof DecimalFormat)) { + if (!(format instanceof DecimalFormat decimalFormat)) { if (this.pattern != null) { throw new IllegalStateException("Cannot support pattern for non-DecimalFormat: " + format); } return format; } - DecimalFormat decimalFormat = (DecimalFormat) format; decimalFormat.setParseBigDecimal(true); if (this.pattern != null) { decimalFormat.applyPattern(this.pattern); diff --git a/spring-context/src/main/java/org/springframework/format/support/FormattingConversionService.java b/spring-context/src/main/java/org/springframework/format/support/FormattingConversionService.java index 661c198fd498..9f502e1f9e42 100644 --- a/spring-context/src/main/java/org/springframework/format/support/FormattingConversionService.java +++ b/spring-context/src/main/java/org/springframework/format/support/FormattingConversionService.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -370,10 +370,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof AnnotationConverterKey)) { + if (!(other instanceof AnnotationConverterKey otherKey)) { return false; } - AnnotationConverterKey otherKey = (AnnotationConverterKey) other; return (this.fieldType == otherKey.fieldType && this.annotation.equals(otherKey.annotation)); } diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/ResourceOverridingShadowingClassLoader.java b/spring-context/src/main/java/org/springframework/instrument/classloading/ResourceOverridingShadowingClassLoader.java index 4e68ab9fe527..21b75d9c2f2b 100644 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/ResourceOverridingShadowingClassLoader.java +++ b/spring-context/src/main/java/org/springframework/instrument/classloading/ResourceOverridingShadowingClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ */ public class ResourceOverridingShadowingClassLoader extends ShadowingClassLoader { - private static final Enumeration EMPTY_URL_ENUMERATION = new Enumeration() { + private static final Enumeration EMPTY_URL_ENUMERATION = new Enumeration<>() { @Override public boolean hasMoreElements() { return false; @@ -51,7 +51,7 @@ public URL nextElement() { /** * Key is asked for value: value is actual value. */ - private Map overrides = new HashMap<>(); + private final Map overrides = new HashMap<>(); /** diff --git a/spring-context/src/main/java/org/springframework/jmx/access/MBeanClientInterceptor.java b/spring-context/src/main/java/org/springframework/jmx/access/MBeanClientInterceptor.java index 816459b3e54c..e60e6bacd8b3 100644 --- a/spring-context/src/main/java/org/springframework/jmx/access/MBeanClientInterceptor.java +++ b/spring-context/src/main/java/org/springframework/jmx/access/MBeanClientInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -566,8 +566,7 @@ protected Object convertResultValueIfNecessary(@Nullable Object result, MethodPa Method fromMethod = targetClass.getMethod("from", CompositeData.class); return ReflectionUtils.invokeMethod(fromMethod, null, result); } - else if (result instanceof CompositeData[]) { - CompositeData[] array = (CompositeData[]) result; + else if (result instanceof CompositeData[] array) { if (targetClass.isArray()) { return convertDataArrayToTargetArray(array, targetClass); } @@ -583,8 +582,7 @@ else if (result instanceof TabularData) { Method fromMethod = targetClass.getMethod("from", TabularData.class); return ReflectionUtils.invokeMethod(fromMethod, null, result); } - else if (result instanceof TabularData[]) { - TabularData[] array = (TabularData[]) result; + else if (result instanceof TabularData[] array) { if (targetClass.isArray()) { return convertDataArrayToTargetArray(array, targetClass); } @@ -621,8 +619,8 @@ private Collection convertDataArrayToTargetCollection(Object[] array, Class resultColl = CollectionFactory.createCollection(collectionType, Array.getLength(array)); - for (int i = 0; i < array.length; i++) { - resultColl.add(ReflectionUtils.invokeMethod(fromMethod, null, array[i])); + for (Object element : array) { + resultColl.add(ReflectionUtils.invokeMethod(fromMethod, null, element)); } return resultColl; } @@ -660,10 +658,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof MethodCacheKey)) { + if (!(other instanceof MethodCacheKey otherKey)) { return false; } - MethodCacheKey otherKey = (MethodCacheKey) other; return (this.name.equals(otherKey.name) && Arrays.equals(this.parameterTypes, otherKey.parameterTypes)); } diff --git a/spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java b/spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java index 98090fca6ce1..fce9739404df 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -165,7 +165,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo private boolean exposeManagedResourceClassLoader = true; /** A set of bean names that should be excluded from autodetection. */ - private Set excludedBeans = new HashSet<>(); + private final Set excludedBeans = new HashSet<>(); /** The MBeanExporterListeners registered with this exporter. */ @Nullable diff --git a/spring-context/src/main/java/org/springframework/jmx/export/assembler/AbstractConfigurableMBeanInfoAssembler.java b/spring-context/src/main/java/org/springframework/jmx/export/assembler/AbstractConfigurableMBeanInfoAssembler.java index 4ebcbc4749dc..525a27432656 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/assembler/AbstractConfigurableMBeanInfoAssembler.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/assembler/AbstractConfigurableMBeanInfoAssembler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,19 +73,17 @@ protected ModelMBeanNotificationInfo[] getNotificationInfo(Object managedBean, S } private ModelMBeanNotificationInfo[] extractNotificationMetadata(Object mapValue) { - if (mapValue instanceof ManagedNotification) { - ManagedNotification mn = (ManagedNotification) mapValue; + if (mapValue instanceof ManagedNotification mn) { return new ModelMBeanNotificationInfo[] {JmxMetadataUtils.convertToModelMBeanNotificationInfo(mn)}; } else if (mapValue instanceof Collection) { Collection col = (Collection) mapValue; List result = new ArrayList<>(); for (Object colValue : col) { - if (!(colValue instanceof ManagedNotification)) { + if (!(colValue instanceof ManagedNotification mn)) { throw new IllegalArgumentException( "Property 'notificationInfoMappings' only accepts ManagedNotifications for Map values"); } - ManagedNotification mn = (ManagedNotification) colValue; result.add(JmxMetadataUtils.convertToModelMBeanNotificationInfo(mn)); } return result.toArray(new ModelMBeanNotificationInfo[0]); diff --git a/spring-context/src/main/java/org/springframework/jmx/support/ConnectorServerFactoryBean.java b/spring-context/src/main/java/org/springframework/jmx/support/ConnectorServerFactoryBean.java index c02f5fbca10a..799c5c8cbb3c 100644 --- a/spring-context/src/main/java/org/springframework/jmx/support/ConnectorServerFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/jmx/support/ConnectorServerFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +63,7 @@ public class ConnectorServerFactoryBean extends MBeanRegistrationSupport private String serviceUrl = DEFAULT_SERVICE_URL; - private Map environment = new HashMap<>(); + private final Map environment = new HashMap<>(); @Nullable private MBeanServerForwarder forwarder; diff --git a/spring-context/src/main/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBean.java b/spring-context/src/main/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBean.java index 64258d71192e..dfaf6d7afcaa 100644 --- a/spring-context/src/main/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,7 +58,7 @@ public class MBeanServerConnectionFactoryBean @Nullable private JMXServiceURL serviceUrl; - private Map environment = new HashMap<>(); + private final Map environment = new HashMap<>(); private boolean connectOnStartup = true; diff --git a/spring-context/src/main/java/org/springframework/jmx/support/NotificationListenerHolder.java b/spring-context/src/main/java/org/springframework/jmx/support/NotificationListenerHolder.java index ac573bb1fa70..29df6edf539d 100644 --- a/spring-context/src/main/java/org/springframework/jmx/support/NotificationListenerHolder.java +++ b/spring-context/src/main/java/org/springframework/jmx/support/NotificationListenerHolder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -161,10 +161,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof NotificationListenerHolder)) { + if (!(other instanceof NotificationListenerHolder otherNlh)) { return false; } - NotificationListenerHolder otherNlh = (NotificationListenerHolder) other; return (ObjectUtils.nullSafeEquals(this.notificationListener, otherNlh.notificationListener) && ObjectUtils.nullSafeEquals(this.notificationFilter, otherNlh.notificationFilter) && ObjectUtils.nullSafeEquals(this.handback, otherNlh.handback) && diff --git a/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java b/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java index 25249087720f..186f546c6115 100644 --- a/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java +++ b/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -155,7 +155,7 @@ public T getBean(Class requiredType, @Nullable Object... args) throws Bea @Override public ObjectProvider getBeanProvider(Class requiredType) { - return new ObjectProvider() { + return new ObjectProvider<>() { @Override public T getObject() throws BeansException { return getBean(requiredType); diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java index 43326b427971..371c34333446 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,7 +55,7 @@ @SuppressWarnings("serial") public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware { - private Advice advice; + private final Advice advice; private Pointcut pointcut; diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedAwareThreadFactory.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedAwareThreadFactory.java index d52b92ed7597..417a542c6862 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedAwareThreadFactory.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/DefaultManagedAwareThreadFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +51,7 @@ public class DefaultManagedAwareThreadFactory extends CustomizableThreadFactory protected final Log logger = LogFactory.getLog(getClass()); - private JndiLocatorDelegate jndiLocator = new JndiLocatorDelegate(); + private final JndiLocatorDelegate jndiLocator = new JndiLocatorDelegate(); @Nullable private String jndiName = "java:comp/DefaultManagedThreadFactory"; diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java index 718c5833929e..f1f0df514782 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java @@ -169,8 +169,7 @@ protected ExecutorService initializeExecutor( this.scheduledExecutor = createExecutor(this.poolSize, threadFactory, rejectedExecutionHandler); - if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) { - ScheduledThreadPoolExecutor scheduledPoolExecutor = (ScheduledThreadPoolExecutor) this.scheduledExecutor; + if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor scheduledPoolExecutor) { if (this.removeOnCancelPolicy) { scheduledPoolExecutor.setRemoveOnCancelPolicy(true); } diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/BitsCronField.java b/spring-context/src/main/java/org/springframework/scheduling/support/BitsCronField.java index 8ea07d5ba854..9619c12ca5c3 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/BitsCronField.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/BitsCronField.java @@ -260,10 +260,9 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof BitsCronField)) { + if (!(o instanceof BitsCronField other)) { return false; } - BitsCronField other = (BitsCronField) o; return type() == other.type() && this.bits == other.bits; } diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/CompositeCronField.java b/spring-context/src/main/java/org/springframework/scheduling/support/CompositeCronField.java index 97f808fc4c5c..a3bf6eced060 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/CompositeCronField.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/CompositeCronField.java @@ -81,10 +81,9 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof CompositeCronField)) { + if (!(o instanceof CompositeCronField other)) { return false; } - CompositeCronField other = (CompositeCronField) o; return type() == other.type() && this.value.equals(other.value); } diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/CronExpression.java b/spring-context/src/main/java/org/springframework/scheduling/support/CronExpression.java index e2e6687055e3..93e65bf9c54a 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/CronExpression.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/CronExpression.java @@ -280,8 +280,7 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (o instanceof CronExpression) { - CronExpression other = (CronExpression) o; + if (o instanceof CronExpression other) { return Arrays.equals(this.fields, other.fields); } else { diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/CronSequenceGenerator.java b/spring-context/src/main/java/org/springframework/scheduling/support/CronSequenceGenerator.java index 1f2b90f7cf1f..e9c74387b2b4 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/CronSequenceGenerator.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/CronSequenceGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -438,10 +438,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof CronSequenceGenerator)) { + if (!(other instanceof CronSequenceGenerator otherCron)) { return false; } - CronSequenceGenerator otherCron = (CronSequenceGenerator) other; return (this.months.equals(otherCron.months) && this.daysOfMonth.equals(otherCron.daysOfMonth) && this.daysOfWeek.equals(otherCron.daysOfWeek) && this.hours.equals(otherCron.hours) && this.minutes.equals(otherCron.minutes) && this.seconds.equals(otherCron.seconds)); diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/PeriodicTrigger.java b/spring-context/src/main/java/org/springframework/scheduling/support/PeriodicTrigger.java index 8e19a265f04b..9292c0086212 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/PeriodicTrigger.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/PeriodicTrigger.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -148,10 +148,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof PeriodicTrigger)) { + if (!(other instanceof PeriodicTrigger otherTrigger)) { return false; } - PeriodicTrigger otherTrigger = (PeriodicTrigger) other; return (this.fixedRate == otherTrigger.fixedRate && this.initialDelay == otherTrigger.initialDelay && this.period == otherTrigger.period); } diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/QuartzCronField.java b/spring-context/src/main/java/org/springframework/scheduling/support/QuartzCronField.java index 0b72a273ab2c..db1f20a7cb79 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/QuartzCronField.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/QuartzCronField.java @@ -360,10 +360,9 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof QuartzCronField)) { + if (!(o instanceof QuartzCronField other)) { return false; } - QuartzCronField other = (QuartzCronField) o; return type() == other.type() && this.value.equals(other.value); } diff --git a/spring-context/src/main/java/org/springframework/scripting/support/StandardScriptFactory.java b/spring-context/src/main/java/org/springframework/scripting/support/StandardScriptFactory.java index 80a1a8fb6fac..3a14dcb33a5d 100644 --- a/spring-context/src/main/java/org/springframework/scripting/support/StandardScriptFactory.java +++ b/spring-context/src/main/java/org/springframework/scripting/support/StandardScriptFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -241,11 +241,10 @@ protected Object adaptToInterfaces( if (adaptedIfc != null) { ScriptEngine scriptEngine = this.scriptEngine; - if (!(scriptEngine instanceof Invocable)) { + if (!(scriptEngine instanceof Invocable invocable)) { throw new ScriptCompilationException(scriptSource, "ScriptEngine must implement Invocable in order to adapt it to an interface: " + scriptEngine); } - Invocable invocable = (Invocable) scriptEngine; if (script != null) { script = invocable.getInterface(script, adaptedIfc); } diff --git a/spring-context/src/main/java/org/springframework/ui/context/support/UiApplicationContextUtils.java b/spring-context/src/main/java/org/springframework/ui/context/support/UiApplicationContextUtils.java index bd842c419a76..675c705fb374 100644 --- a/spring-context/src/main/java/org/springframework/ui/context/support/UiApplicationContextUtils.java +++ b/spring-context/src/main/java/org/springframework/ui/context/support/UiApplicationContextUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,8 +57,7 @@ public static ThemeSource initThemeSource(ApplicationContext context) { if (context.containsLocalBean(THEME_SOURCE_BEAN_NAME)) { ThemeSource themeSource = context.getBean(THEME_SOURCE_BEAN_NAME, ThemeSource.class); // Make ThemeSource aware of parent ThemeSource. - if (context.getParent() instanceof ThemeSource && themeSource instanceof HierarchicalThemeSource) { - HierarchicalThemeSource hts = (HierarchicalThemeSource) themeSource; + if (context.getParent() instanceof ThemeSource && themeSource instanceof HierarchicalThemeSource hts) { if (hts.getParentThemeSource() == null) { // Only set parent context as parent ThemeSource if no parent ThemeSource // registered already. diff --git a/spring-context/src/main/java/org/springframework/validation/AbstractBindingResult.java b/spring-context/src/main/java/org/springframework/validation/AbstractBindingResult.java index b8857b15b50b..2ef8f10ae0fe 100644 --- a/spring-context/src/main/java/org/springframework/validation/AbstractBindingResult.java +++ b/spring-context/src/main/java/org/springframework/validation/AbstractBindingResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -204,8 +204,7 @@ public List getFieldErrors(String field) { public FieldError getFieldError(String field) { String fixedField = fixedField(field); for (ObjectError objectError : this.errors) { - if (objectError instanceof FieldError) { - FieldError fieldError = (FieldError) objectError; + if (objectError instanceof FieldError fieldError) { if (isMatchingFieldError(fixedField, fieldError)) { return fieldError; } @@ -364,10 +363,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof BindingResult)) { + if (!(other instanceof BindingResult otherResult)) { return false; } - BindingResult otherResult = (BindingResult) other; return (getObjectName().equals(otherResult.getObjectName()) && ObjectUtils.nullSafeEquals(getTarget(), otherResult.getTarget()) && getAllErrors().equals(otherResult.getAllErrors())); diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java index de02082dffe7..ef6d19b3afb8 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java @@ -58,6 +58,7 @@ * Bean Validation 1.1 as well as 2.0. * * @author Juergen Hoeller + * @author Sam Brannen * @since 3.0 * @see SmartValidator * @see CustomValidatorBean @@ -136,8 +137,8 @@ public void validateValue( private Class[] asValidationGroups(Object... validationHints) { Set> groups = new LinkedHashSet<>(4); for (Object hint : validationHints) { - if (hint instanceof Class) { - groups.add((Class) hint); + if (hint instanceof Class clazz) { + groups.add(clazz); } } return ClassUtils.toClassArray(groups); @@ -159,10 +160,9 @@ protected void processConstraintViolations(Set> viol ConstraintDescriptor cd = violation.getConstraintDescriptor(); String errorCode = determineErrorCode(cd); Object[] errorArgs = getArgumentsForConstraint(errors.getObjectName(), field, cd); - if (errors instanceof BindingResult) { + if (errors instanceof BindingResult bindingResult) { // Can do custom FieldError registration with invalid value from ConstraintViolation, // as necessary for Hibernate Validator compatibility (non-indexed set path in field) - BindingResult bindingResult = (BindingResult) errors; String nestedField = bindingResult.getNestedPath() + field; if (nestedField.isEmpty()) { String[] errorCodes = bindingResult.resolveMessageCodes(errorCode); @@ -269,8 +269,8 @@ protected Object[] getArgumentsForConstraint(String objectName, String field, Co Map attributesToExpose = new TreeMap<>(); descriptor.getAttributes().forEach((attributeName, attributeValue) -> { if (!internalAnnotationAttributes.contains(attributeName)) { - if (attributeValue instanceof String) { - attributeValue = new ResolvableAttribute(attributeValue.toString()); + if (attributeValue instanceof String str) { + attributeValue = new ResolvableAttribute(str); } attributesToExpose.put(attributeName, attributeValue); } diff --git a/spring-context/src/main/java/org/springframework/validation/support/BindingAwareModelMap.java b/spring-context/src/main/java/org/springframework/validation/support/BindingAwareModelMap.java index 9ac97145bafd..c37eca8a7a0e 100644 --- a/spring-context/src/main/java/org/springframework/validation/support/BindingAwareModelMap.java +++ b/spring-context/src/main/java/org/springframework/validation/support/BindingAwareModelMap.java @@ -52,8 +52,7 @@ public void putAll(Map map) { } private void removeBindingResultIfNecessary(Object key, @Nullable Object value) { - if (key instanceof String) { - String attributeName = (String) key; + if (key instanceof String attributeName) { if (!attributeName.startsWith(BindingResult.MODEL_KEY_PREFIX)) { String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + attributeName; BindingResult bindingResult = (BindingResult) get(bindingResultKey); From 0eb73c130c4006b631edb6df6adebe1330fc07a7 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 17:33:42 +0200 Subject: [PATCH 255/735] Apply "instanceof pattern matching" Eclipse clean-up in spring-context-indexer --- .../springframework/context/index/processor/TypeHelper.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spring-context-indexer/src/main/java/org/springframework/context/index/processor/TypeHelper.java b/spring-context-indexer/src/main/java/org/springframework/context/index/processor/TypeHelper.java index 470c0398a235..f24fd21df42a 100644 --- a/spring-context-indexer/src/main/java/org/springframework/context/index/processor/TypeHelper.java +++ b/spring-context-indexer/src/main/java/org/springframework/context/index/processor/TypeHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,8 +60,7 @@ public String getType(TypeMirror type) { if (type == null) { return null; } - if (type instanceof DeclaredType) { - DeclaredType declaredType = (DeclaredType) type; + if (type instanceof DeclaredType declaredType) { Element enclosingElement = declaredType.asElement().getEnclosingElement(); if (enclosingElement instanceof TypeElement) { return getQualifiedName(enclosingElement) + "$" + declaredType.asElement().getSimpleName().toString(); From b3473a3e810fc0ebe6d6d1a63e5ec281de31fa51 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 17:45:56 +0200 Subject: [PATCH 256/735] Apply "instanceof pattern matching" Eclipse clean-up in spring-context-support This has only been applied to `src/main/java`. --- .../interceptor/CacheResolverAdapter.java | 5 ++--- .../JCacheOperationSourcePointcut.java | 5 ++--- .../SimpleExceptionCacheResolver.java | 5 ++--- .../mail/SimpleMailMessage.java | 5 ++--- .../mail/javamail/MimeMessageHelper.java | 20 ++++++++++--------- .../quartz/SchedulerAccessorBean.java | 5 ++--- 6 files changed, 21 insertions(+), 24 deletions(-) diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResolverAdapter.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResolverAdapter.java index 88724adc12c2..041d9aea0ef7 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResolverAdapter.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResolverAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,10 +59,9 @@ protected javax.cache.annotation.CacheResolver getTarget() { @Override public Collection resolveCaches(CacheOperationInvocationContext context) { - if (!(context instanceof CacheInvocationContext)) { + if (!(context instanceof CacheInvocationContext cacheInvocationContext)) { throw new IllegalStateException("Unexpected context " + context); } - CacheInvocationContext cacheInvocationContext = (CacheInvocationContext) context; javax.cache.Cache cache = this.target.resolveCache(cacheInvocationContext); if (cache == null) { throw new IllegalStateException("Could not resolve cache for " + context + " using " + this.target); diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperationSourcePointcut.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperationSourcePointcut.java index 4b6d7e0fb940..1dbb4210894c 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperationSourcePointcut.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperationSourcePointcut.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,10 +52,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof JCacheOperationSourcePointcut)) { + if (!(other instanceof JCacheOperationSourcePointcut otherPc)) { return false; } - JCacheOperationSourcePointcut otherPc = (JCacheOperationSourcePointcut) other; return ObjectUtils.nullSafeEquals(getCacheOperationSource(), otherPc.getCacheOperationSource()); } diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleExceptionCacheResolver.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleExceptionCacheResolver.java index f2091ab1fb31..1aa569546131 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleExceptionCacheResolver.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleExceptionCacheResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,10 +43,9 @@ public SimpleExceptionCacheResolver(CacheManager cacheManager) { @Override protected Collection getCacheNames(CacheOperationInvocationContext context) { BasicOperation operation = context.getOperation(); - if (!(operation instanceof CacheResultOperation)) { + if (!(operation instanceof CacheResultOperation cacheResultOperation)) { throw new IllegalStateException("Could not extract exception cache name from " + operation); } - CacheResultOperation cacheResultOperation = (CacheResultOperation) operation; String exceptionCacheName = cacheResultOperation.getExceptionCacheName(); if (exceptionCacheName != null) { return Collections.singleton(exceptionCacheName); diff --git a/spring-context-support/src/main/java/org/springframework/mail/SimpleMailMessage.java b/spring-context-support/src/main/java/org/springframework/mail/SimpleMailMessage.java index 95268a2993e0..4e8295f70d31 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/SimpleMailMessage.java +++ b/spring-context-support/src/main/java/org/springframework/mail/SimpleMailMessage.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -226,10 +226,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof SimpleMailMessage)) { + if (!(other instanceof SimpleMailMessage otherMessage)) { return false; } - SimpleMailMessage otherMessage = (SimpleMailMessage) other; return (ObjectUtils.nullSafeEquals(this.from, otherMessage.from) && ObjectUtils.nullSafeEquals(this.replyTo, otherMessage.replyTo) && ObjectUtils.nullSafeEquals(this.to, otherMessage.to) && diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java index c056ec623d27..3d7bf4c7b0dc 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import jakarta.mail.BodyPart; import jakarta.mail.Message; import jakarta.mail.MessagingException; +import jakarta.mail.Part; import jakarta.mail.internet.AddressException; import jakarta.mail.internet.InternetAddress; import jakarta.mail.internet.MimeBodyPart; @@ -91,6 +92,7 @@ * on the MULTIPART_MODE constants contains more detailed information. * * @author Juergen Hoeller + * @author Sam Brannen * @since 19.01.2004 * @see #setText(String, boolean) * @see #setText(String, String) @@ -427,8 +429,8 @@ public final MimeMultipart getMimeMultipart() throws IllegalStateException { */ @Nullable protected String getDefaultEncoding(MimeMessage mimeMessage) { - if (mimeMessage instanceof SmartMimeMessage) { - return ((SmartMimeMessage) mimeMessage).getDefaultEncoding(); + if (mimeMessage instanceof SmartMimeMessage smartMimeMessage) { + return smartMimeMessage.getDefaultEncoding(); } return null; } @@ -449,8 +451,8 @@ public String getEncoding() { * @see ConfigurableMimeFileTypeMap */ protected FileTypeMap getDefaultFileTypeMap(MimeMessage mimeMessage) { - if (mimeMessage instanceof SmartMimeMessage) { - FileTypeMap fileTypeMap = ((SmartMimeMessage) mimeMessage).getDefaultFileTypeMap(); + if (mimeMessage instanceof SmartMimeMessage smartMimeMessage) { + FileTypeMap fileTypeMap = smartMimeMessage.getDefaultFileTypeMap(); if (fileTypeMap != null) { return fileTypeMap; } @@ -908,7 +910,7 @@ public void addInline(String contentId, DataSource dataSource) throws MessagingE Assert.notNull(contentId, "Content ID must not be null"); Assert.notNull(dataSource, "DataSource must not be null"); MimeBodyPart mimeBodyPart = new MimeBodyPart(); - mimeBodyPart.setDisposition(MimeBodyPart.INLINE); + mimeBodyPart.setDisposition(Part.INLINE); mimeBodyPart.setContentID("<" + contentId + ">"); mimeBodyPart.setDataHandler(new DataHandler(dataSource)); getMimeMultipart().addBodyPart(mimeBodyPart); @@ -990,7 +992,7 @@ public void addInline(String contentId, InputStreamSource inputStreamSource, Str throws MessagingException { Assert.notNull(inputStreamSource, "InputStreamSource must not be null"); - if (inputStreamSource instanceof Resource && ((Resource) inputStreamSource).isOpen()) { + if (inputStreamSource instanceof Resource resource && resource.isOpen()) { throw new IllegalArgumentException( "Passed-in Resource contains an open stream: invalid argument. " + "JavaMail requires an InputStreamSource that creates a fresh stream for every call."); @@ -1018,7 +1020,7 @@ public void addAttachment(String attachmentFilename, DataSource dataSource) thro Assert.notNull(dataSource, "DataSource must not be null"); try { MimeBodyPart mimeBodyPart = new MimeBodyPart(); - mimeBodyPart.setDisposition(MimeBodyPart.ATTACHMENT); + mimeBodyPart.setDisposition(Part.ATTACHMENT); mimeBodyPart.setFileName(isEncodeFilenames() ? MimeUtility.encodeText(attachmentFilename) : attachmentFilename); mimeBodyPart.setDataHandler(new DataHandler(dataSource)); @@ -1095,7 +1097,7 @@ public void addAttachment( throws MessagingException { Assert.notNull(inputStreamSource, "InputStreamSource must not be null"); - if (inputStreamSource instanceof Resource && ((Resource) inputStreamSource).isOpen()) { + if (inputStreamSource instanceof Resource resource && resource.isOpen()) { throw new IllegalArgumentException( "Passed-in Resource contains an open stream: invalid argument. " + "JavaMail requires an InputStreamSource that creates a fresh stream for every call."); diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerAccessorBean.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerAccessorBean.java index 42a80e2a33bf..ea136c6e4fb1 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerAccessorBean.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerAccessorBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -99,8 +99,7 @@ public void afterPropertiesSet() throws SchedulerException { } protected Scheduler findScheduler(String schedulerName) throws SchedulerException { - if (this.beanFactory instanceof ListableBeanFactory) { - ListableBeanFactory lbf = (ListableBeanFactory) this.beanFactory; + if (this.beanFactory instanceof ListableBeanFactory lbf) { String[] beanNames = lbf.getBeanNamesForType(Scheduler.class); for (String beanName : beanNames) { Scheduler schedulerBean = (Scheduler) lbf.getBean(beanName); From 76c9306dda572ab1be9b888feeb7b56ceb989d85 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 14 Oct 2021 17:18:34 +0100 Subject: [PATCH 257/735] Adjust logging of resource locations --- .../reactive/resource/ResourceWebHandler.java | 32 +++++++------------ .../resource/ResourceHttpRequestHandler.java | 22 +++++++------ 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java index 2361d1532895..75ac8ddd320e 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java @@ -304,11 +304,6 @@ public void setUseLastModified(boolean useLastModified) { public void afterPropertiesSet() throws Exception { resolveResourceLocations(); - if (logger.isWarnEnabled() && CollectionUtils.isEmpty(getLocations())) { - logger.warn("Locations list is empty. No resources will be served unless a " + - "custom ResourceResolver is configured as an alternative to PathResourceResolver."); - } - if (this.resourceResolvers.isEmpty()) { this.resourceResolvers.add(new PathResourceResolver()); } @@ -341,6 +336,12 @@ private void resolveResourceLocations() { this.locationsToUse.clear(); this.locationsToUse.addAll(result); + + if (logger.isInfoEnabled()) { + logger.info(!this.locationsToUse.isEmpty() ? + "Locations in use: " + locationToString(this.locationsToUse) : + "0 locations in use."); + } } /** @@ -350,10 +351,6 @@ private void resolveResourceLocations() { */ protected void initAllowedLocations() { if (CollectionUtils.isEmpty(getLocations())) { - if (logger.isInfoEnabled()) { - logger.info("Locations list is empty. No resources will be served unless a " + - "custom ResourceResolver is configured as an alternative to PathResourceResolver."); - } return; } for (int i = getResourceResolvers().size() - 1; i >= 0; i--) { @@ -621,18 +618,13 @@ protected void setHeaders(ServerWebExchange exchange, Resource resource, @Nullab @Override public String toString() { - return "ResourceWebHandler " + formatLocations(); + return "ResourceWebHandler " + locationToString(getLocations()); } - private Object formatLocations() { - if (!this.locationValues.isEmpty()) { - return this.locationValues.stream().collect(Collectors.joining("\", \"", "[\"", "\"]")); - } - if (!getLocations().isEmpty()) { - return "[" + getLocations().toString() - .replaceAll("class path resource", "Classpath") - .replaceAll("ServletContext resource", "ServletContext") + "]"; - } - return Collections.emptyList(); + private String locationToString(List locations) { + return locations.toString() + .replaceAll("class path resource", "classpath") + .replaceAll("ServletContext resource", "ServletContext"); } + } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index 6e556e9af5fa..7456f37f0318 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -392,11 +392,6 @@ public void setUseLastModified(boolean useLastModified) { public void afterPropertiesSet() throws Exception { resolveResourceLocations(); - if (logger.isWarnEnabled() && CollectionUtils.isEmpty(getLocations())) { - logger.warn("Locations list is empty. No resources will be served unless a " + - "custom ResourceResolver is configured as an alternative to PathResourceResolver."); - } - if (this.resourceResolvers.isEmpty()) { this.resourceResolvers.add(new PathResourceResolver()); } @@ -472,6 +467,12 @@ private void resolveResourceLocations() { this.locationsToUse.clear(); this.locationsToUse.addAll(result); + + if (logger.isInfoEnabled()) { + logger.info(!this.locationsToUse.isEmpty() ? + "Locations in use: " + locationToString(this.locationsToUse) : + "0 locations in use."); + } } /** @@ -810,10 +811,13 @@ protected void setHeaders(HttpServletResponse response, Resource resource, @Null @Override public String toString() { - return "ResourceHttpRequestHandler " + - getLocations().toString() - .replaceAll("class path resource", "Classpath") - .replaceAll("ServletContext resource", "ServletContext"); + return "ResourceHttpRequestHandler " + locationToString(getLocations()); + } + + private String locationToString(List locations) { + return locations.toString() + .replaceAll("class path resource", "classpath") + .replaceAll("ServletContext resource", "ServletContext"); } } From cb17441780eee8489a26b7772b70cdc77aecacff Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 18:12:27 +0200 Subject: [PATCH 258/735] Apply "instanceof pattern matching" Eclipse clean-up in spring-core This commit also applies additional clean-up tasks such as the following. - final fields - diamond operator (<>) for anonymous inner classes This has only been applied to `src/main/java`. --- .../core/CollectionFactory.java | 32 +++++----- .../springframework/core/MethodClassKey.java | 5 +- .../springframework/core/MethodParameter.java | 5 +- .../core/ParameterizedTypeReference.java | 4 +- .../springframework/core/ResolvableType.java | 14 ++-- .../core/annotation/AnnotationUtils.java | 8 +-- .../core/annotation/AnnotationsScanner.java | 5 +- .../MergedAnnotationsCollection.java | 4 +- .../core/annotation/TypeMappedAnnotation.java | 5 +- .../core/convert/Property.java | 5 +- .../core/convert/TypeDescriptor.java | 3 +- .../convert/support/ByteBufferConverter.java | 3 +- .../support/GenericConversionService.java | 5 +- .../support/ObjectToObjectConverter.java | 8 +-- .../io/AbstractFileResolvingResource.java | 3 +- .../core/io/ClassPathResource.java | 3 +- .../core/io/buffer/DataBufferUtils.java | 3 +- .../core/io/buffer/DefaultDataBuffer.java | 3 +- .../core/io/support/EncodedResource.java | 5 +- .../PathMatchingResourcePatternResolver.java | 9 ++- .../springframework/core/log/LogMessage.java | 4 +- .../core/style/DefaultValueStyler.java | 5 +- .../AnnotationReadingVisitorUtils.java | 8 +-- .../ClassMetadataReadingVisitor.java | 4 +- ...impleAnnotationMetadataReadingVisitor.java | 8 +-- .../objenesis/SpringObjenesis.java | 4 +- .../util/ConcurrentReferenceHashMap.java | 9 +-- .../util/LinkedCaseInsensitiveMap.java | 2 +- .../org/springframework/util/MimeType.java | 5 +- .../org/springframework/util/TypeUtils.java | 64 +++++++++---------- .../util/xml/XMLEventStreamReader.java | 5 +- 31 files changed, 108 insertions(+), 142 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/CollectionFactory.java b/spring-core/src/main/java/org/springframework/core/CollectionFactory.java index 4f90a3bff18e..a9321e0a34bf 100644 --- a/spring-core/src/main/java/org/springframework/core/CollectionFactory.java +++ b/spring-core/src/main/java/org/springframework/core/CollectionFactory.java @@ -119,7 +119,7 @@ public static boolean isApproximableCollectionType(@Nullable Class collection * @see java.util.TreeSet * @see java.util.LinkedHashSet */ - @SuppressWarnings({"rawtypes", "unchecked", "cast"}) + @SuppressWarnings({"rawtypes", "unchecked"}) public static Collection createApproximateCollection(@Nullable Object collection, int capacity) { if (collection instanceof LinkedList) { return new LinkedList<>(); @@ -127,14 +127,13 @@ public static Collection createApproximateCollection(@Nullable Object col else if (collection instanceof List) { return new ArrayList<>(capacity); } - else if (collection instanceof EnumSet) { - // Cast is necessary for compilation in Eclipse 4.4.1. - Collection enumSet = (Collection) EnumSet.copyOf((EnumSet) collection); - enumSet.clear(); - return enumSet; + else if (collection instanceof EnumSet enumSet) { + Collection copy = EnumSet.copyOf(enumSet); + copy.clear(); + return copy; } - else if (collection instanceof SortedSet) { - return new TreeSet<>(((SortedSet) collection).comparator()); + else if (collection instanceof SortedSet sortedSet) { + return new TreeSet<>(sortedSet.comparator()); } else { return new LinkedHashSet<>(capacity); @@ -178,7 +177,7 @@ public static Collection createCollection(Class collectionType, int ca * @see java.util.TreeSet * @see java.util.EnumSet */ - @SuppressWarnings({"unchecked", "cast"}) + @SuppressWarnings("unchecked") public static Collection createCollection(Class collectionType, @Nullable Class elementType, int capacity) { Assert.notNull(collectionType, "Collection type must not be null"); if (collectionType.isInterface()) { @@ -197,8 +196,7 @@ else if (SortedSet.class == collectionType || NavigableSet.class == collectionTy } else if (EnumSet.class.isAssignableFrom(collectionType)) { Assert.notNull(elementType, "Cannot create EnumSet for unknown element type"); - // Cast is necessary for compilation in Eclipse 4.4.1. - return (Collection) EnumSet.noneOf(asEnumType(elementType)); + return EnumSet.noneOf(asEnumType(elementType)); } else { if (!Collection.class.isAssignableFrom(collectionType)) { @@ -243,13 +241,13 @@ public static boolean isApproximableMapType(@Nullable Class mapType) { */ @SuppressWarnings({"rawtypes", "unchecked"}) public static Map createApproximateMap(@Nullable Object map, int capacity) { - if (map instanceof EnumMap) { - EnumMap enumMap = new EnumMap((EnumMap) map); - enumMap.clear(); - return enumMap; + if (map instanceof EnumMap enumMap) { + EnumMap copy = new EnumMap(enumMap); + copy.clear(); + return copy; } - else if (map instanceof SortedMap) { - return new TreeMap<>(((SortedMap) map).comparator()); + else if (map instanceof SortedMap sortedMap) { + return new TreeMap<>(sortedMap.comparator()); } else { return new LinkedHashMap<>(capacity); diff --git a/spring-core/src/main/java/org/springframework/core/MethodClassKey.java b/spring-core/src/main/java/org/springframework/core/MethodClassKey.java index 62ca1ea04f48..60e28be1e092 100644 --- a/spring-core/src/main/java/org/springframework/core/MethodClassKey.java +++ b/spring-core/src/main/java/org/springframework/core/MethodClassKey.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,10 +54,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof MethodClassKey)) { + if (!(other instanceof MethodClassKey otherKey)) { return false; } - MethodClassKey otherKey = (MethodClassKey) other; return (this.method.equals(otherKey.method) && ObjectUtils.nullSafeEquals(this.targetClass, otherKey.targetClass)); } diff --git a/spring-core/src/main/java/org/springframework/core/MethodParameter.java b/spring-core/src/main/java/org/springframework/core/MethodParameter.java index 3ec9549cb60f..3bbe10d5d4c6 100644 --- a/spring-core/src/main/java/org/springframework/core/MethodParameter.java +++ b/spring-core/src/main/java/org/springframework/core/MethodParameter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -753,10 +753,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof MethodParameter)) { + if (!(other instanceof MethodParameter otherParam)) { return false; } - MethodParameter otherParam = (MethodParameter) other; return (getContainingClass() == otherParam.getContainingClass() && ObjectUtils.nullSafeEquals(this.typeIndexesPerLevel, otherParam.typeIndexesPerLevel) && this.nestingLevel == otherParam.nestingLevel && diff --git a/spring-core/src/main/java/org/springframework/core/ParameterizedTypeReference.java b/spring-core/src/main/java/org/springframework/core/ParameterizedTypeReference.java index c10dd89aee9e..2cb589eb74c6 100644 --- a/spring-core/src/main/java/org/springframework/core/ParameterizedTypeReference.java +++ b/spring-core/src/main/java/org/springframework/core/ParameterizedTypeReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -92,7 +92,7 @@ public String toString() { * @since 4.3.12 */ public static ParameterizedTypeReference forType(Type type) { - return new ParameterizedTypeReference(type) { + return new ParameterizedTypeReference<>(type) { }; } diff --git a/spring-core/src/main/java/org/springframework/core/ResolvableType.java b/spring-core/src/main/java/org/springframework/core/ResolvableType.java index ae6fe4f0846b..17a9572ccd03 100644 --- a/spring-core/src/main/java/org/springframework/core/ResolvableType.java +++ b/spring-core/src/main/java/org/springframework/core/ResolvableType.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -594,8 +594,7 @@ private boolean isUnresolvableTypeVariable() { * without specific bounds (i.e., equal to {@code ? extends Object}). */ private boolean isWildcardWithoutBounds() { - if (this.type instanceof WildcardType) { - WildcardType wt = (WildcardType) this.type; + if (this.type instanceof WildcardType wt) { if (wt.getLowerBounds().length == 0) { Type[] upperBounds = wt.getUpperBounds(); if (upperBounds.length == 0 || (upperBounds.length == 1 && Object.class == upperBounds[0])) { @@ -870,8 +869,7 @@ private ResolvableType resolveVariable(TypeVariable variable) { if (this.type instanceof TypeVariable) { return resolveType().resolveVariable(variable); } - if (this.type instanceof ParameterizedType) { - ParameterizedType parameterizedType = (ParameterizedType) this.type; + if (this.type instanceof ParameterizedType parameterizedType) { Class resolved = resolve(); if (resolved == null) { return null; @@ -906,11 +904,10 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ResolvableType)) { + if (!(other instanceof ResolvableType otherType)) { return false; } - ResolvableType otherType = (ResolvableType) other; if (!ObjectUtils.nullSafeEquals(this.type, otherType.type)) { return false; } @@ -1573,10 +1570,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ParameterizedType)) { + if (!(other instanceof ParameterizedType otherType)) { return false; } - ParameterizedType otherType = (ParameterizedType) other; return (otherType.getOwnerType() == null && this.rawType.equals(otherType.getRawType()) && Arrays.equals(this.typeArguments, otherType.getActualTypeArguments())); } diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java index edd099624154..2009d848b8cd 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1006,12 +1006,10 @@ private static Object adaptValue( return names; } } - if (value instanceof Annotation) { - Annotation annotation = (Annotation) value; + if (value instanceof Annotation annotation) { return MergedAnnotation.from(annotatedElement, annotation).synthesize(); } - if (value instanceof Annotation[]) { - Annotation[] annotations = (Annotation[]) value; + if (value instanceof Annotation[] annotations) { Annotation[] synthesized = (Annotation[]) Array.newInstance( annotations.getClass().getComponentType(), annotations.length); for (int i = 0; i < annotations.length; i++) { diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java index 626413838c9b..19d520c3c14a 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -521,8 +521,7 @@ private static boolean isWithoutHierarchy(AnnotatedElement source, SearchStrateg return (searchStrategy == SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES ? noSuperTypes && sourceClass.getEnclosingClass() == null : noSuperTypes); } - if (source instanceof Method) { - Method sourceMethod = (Method) source; + if (source instanceof Method sourceMethod) { return (Modifier.isPrivate(sourceMethod.getModifiers()) || isWithoutHierarchy(sourceMethod.getDeclaringClass(), searchStrategy)); } diff --git a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationsCollection.java b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationsCollection.java index 9fc6cb53671d..0d2e8372d078 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationsCollection.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationsCollection.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -221,7 +221,7 @@ static MergedAnnotations of(Collection> annotations) { private class AnnotationsSpliterator implements Spliterator> { @Nullable - private Object requiredType; + private final Object requiredType; private final int[] mappingCursors; 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 06aa93d7d5a3..660e43b86951 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -439,8 +439,7 @@ else if (value instanceof Class[] && type == String[].class) { } value = names; } - else if (value instanceof String[] && type == Class[].class) { - String[] names = (String[]) value; + else if (value instanceof String[] names && type == Class[].class) { Class[] classes = new Class[names.length]; for (int i = 0; i < names.length; i++) { classes[i] = ClassUtils.resolveClassName(names[i], getClassLoader()); diff --git a/spring-core/src/main/java/org/springframework/core/convert/Property.java b/spring-core/src/main/java/org/springframework/core/convert/Property.java index 5cddaea8769f..afabd528fb02 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/Property.java +++ b/spring-core/src/main/java/org/springframework/core/convert/Property.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -263,10 +263,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof Property)) { + if (!(other instanceof Property otherProperty)) { return false; } - Property otherProperty = (Property) other; return (ObjectUtils.nullSafeEquals(this.objectType, otherProperty.objectType) && ObjectUtils.nullSafeEquals(this.name, otherProperty.name) && ObjectUtils.nullSafeEquals(this.readMethod, otherProperty.readMethod) && diff --git a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java index 1bc8cb281b1f..064579c82f86 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java +++ b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java @@ -458,10 +458,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof TypeDescriptor)) { + if (!(other instanceof TypeDescriptor otherDesc)) { return false; } - TypeDescriptor otherDesc = (TypeDescriptor) other; if (getType() != otherDesc.getType()) { return false; } diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java index 0a230ef076c7..64e49717974c 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java @@ -88,8 +88,7 @@ private boolean matchesToByteBuffer(TypeDescriptor sourceType) { @Nullable public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { boolean byteBufferTarget = targetType.isAssignableTo(BYTE_BUFFER_TYPE); - if (source instanceof ByteBuffer) { - ByteBuffer buffer = (ByteBuffer) source; + if (source instanceof ByteBuffer buffer) { return (byteBufferTarget ? buffer.duplicate() : convertFromByteBuffer(buffer, targetType)); } if (byteBufferTarget) { diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java b/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java index 1134483e88a8..0c0e9c036474 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -463,10 +463,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ConverterCacheKey)) { + if (!(other instanceof ConverterCacheKey otherKey)) { return false; } - ConverterCacheKey otherKey = (ConverterCacheKey) other; return (this.sourceType.equals(otherKey.sourceType)) && this.targetType.equals(otherKey.targetType); } diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/ObjectToObjectConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/ObjectToObjectConverter.java index 802e09700804..145e28806fb3 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/ObjectToObjectConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/ObjectToObjectConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -92,8 +92,7 @@ public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDe Member member = getValidatedMember(targetClass, sourceClass); try { - if (member instanceof Method) { - Method method = (Method) member; + if (member instanceof Method method) { ReflectionUtils.makeAccessible(method); if (!Modifier.isStatic(method.getModifiers())) { return method.invoke(source); @@ -152,8 +151,7 @@ private static Member getValidatedMember(Class targetClass, Class sourceCl } private static boolean isApplicable(Member member, Class sourceClass) { - if (member instanceof Method) { - Method method = (Method) member; + if (member instanceof Method method) { return (!Modifier.isStatic(method.getModifiers()) ? ClassUtils.isAssignable(method.getDeclaringClass(), sourceClass) : method.getParameterTypes()[0] == sourceClass); 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 ac9ea29a5dca..5369b2fdea9f 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 @@ -106,8 +106,7 @@ boolean checkReadable(URL url) { // Try InputStream resolution for jar resources URLConnection con = url.openConnection(); customizeConnection(con); - if (con instanceof HttpURLConnection) { - HttpURLConnection httpCon = (HttpURLConnection) con; + if (con instanceof HttpURLConnection httpCon) { int code = httpCon.getResponseCode(); if (code != HttpURLConnection.HTTP_OK) { httpCon.disconnect(); diff --git a/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java b/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java index f99adce06ce4..cbaad7001b8c 100644 --- a/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java @@ -267,10 +267,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ClassPathResource)) { + if (!(other instanceof ClassPathResource otherRes)) { return false; } - ClassPathResource otherRes = (ClassPathResource) other; return (this.path.equals(otherRes.path) && ObjectUtils.nullSafeEquals(this.classLoader, otherRes.classLoader) && ObjectUtils.nullSafeEquals(this.clazz, otherRes.clazz)); diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java index ad0419ee4b77..d97a59fe45e0 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java @@ -513,8 +513,7 @@ public static T touch(T dataBuffer, Object hint) { * @return {@code true} if the buffer was released; {@code false} otherwise. */ public static boolean release(@Nullable DataBuffer dataBuffer) { - if (dataBuffer instanceof PooledDataBuffer) { - PooledDataBuffer pooledDataBuffer = (PooledDataBuffer) dataBuffer; + if (dataBuffer instanceof PooledDataBuffer pooledDataBuffer) { if (pooledDataBuffer.isAllocated()) { try { return pooledDataBuffer.release(); diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java index ab6c80a25f45..2efc753ab6c7 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java @@ -431,10 +431,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof DefaultDataBuffer)) { + if (!(other instanceof DefaultDataBuffer otherBuffer)) { return false; } - DefaultDataBuffer otherBuffer = (DefaultDataBuffer) other; return (this.readPosition == otherBuffer.readPosition && this.writePosition == otherBuffer.writePosition && this.byteBuffer.equals(otherBuffer.byteBuffer)); diff --git a/spring-core/src/main/java/org/springframework/core/io/support/EncodedResource.java b/spring-core/src/main/java/org/springframework/core/io/support/EncodedResource.java index f718fe73cfa2..ed4eb169da6d 100644 --- a/spring-core/src/main/java/org/springframework/core/io/support/EncodedResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/support/EncodedResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -165,10 +165,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof EncodedResource)) { + if (!(other instanceof EncodedResource otherResource)) { return false; } - EncodedResource otherResource = (EncodedResource) other; return (this.resource.equals(otherResource.resource) && ObjectUtils.nullSafeEquals(this.charset, otherResource.charset) && ObjectUtils.nullSafeEquals(this.encoding, otherResource.encoding)); diff --git a/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java b/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java index 69cd66134883..aef2476b0a55 100644 --- a/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java +++ b/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -368,9 +368,9 @@ protected Resource convertClassLoaderURL(URL url) { * @since 4.1.1 */ protected void addAllClassLoaderJarRoots(@Nullable ClassLoader classLoader, Set result) { - if (classLoader instanceof URLClassLoader) { + if (classLoader instanceof URLClassLoader urlClassLoader) { try { - for (URL url : ((URLClassLoader) classLoader).getURLs()) { + for (URL url : urlClassLoader.getURLs()) { try { UrlResource jarResource = (ResourceUtils.URL_PROTOCOL_JAR.equals(url.getProtocol()) ? new UrlResource(url) : @@ -597,9 +597,8 @@ protected Set doFindPathMatchingJarResources(Resource rootDirResource, String rootEntryPath; boolean closeJarFile; - if (con instanceof JarURLConnection) { + if (con instanceof JarURLConnection jarCon) { // Should usually be the case for traditional JAR files. - JarURLConnection jarCon = (JarURLConnection) con; ResourceUtils.useCachesIfNecessary(jarCon); jarFile = jarCon.getJarFile(); jarFileUrl = jarCon.getJarFileURL().toExternalForm(); diff --git a/spring-core/src/main/java/org/springframework/core/log/LogMessage.java b/spring-core/src/main/java/org/springframework/core/log/LogMessage.java index ee7dd65f2814..4546f7a76ab8 100644 --- a/spring-core/src/main/java/org/springframework/core/log/LogMessage.java +++ b/spring-core/src/main/java/org/springframework/core/log/LogMessage.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -143,7 +143,7 @@ public static LogMessage format(String format, Object... args) { private static final class SupplierMessage extends LogMessage { - private Supplier supplier; + private final Supplier supplier; SupplierMessage(Supplier supplier) { Assert.notNull(supplier, "Supplier must not be null"); diff --git a/spring-core/src/main/java/org/springframework/core/style/DefaultValueStyler.java b/spring-core/src/main/java/org/springframework/core/style/DefaultValueStyler.java index f56ac82af9cb..2b968d113068 100644 --- a/spring-core/src/main/java/org/springframework/core/style/DefaultValueStyler.java +++ b/spring-core/src/main/java/org/springframework/core/style/DefaultValueStyler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,8 +61,7 @@ else if (value instanceof String) { else if (value instanceof Class) { return ClassUtils.getShortName((Class) value); } - else if (value instanceof Method) { - Method method = (Method) value; + else if (value instanceof Method method) { return method.getName() + "@" + ClassUtils.getShortName(method.getDeclaringClass()); } else if (value instanceof Map) { diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationReadingVisitorUtils.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationReadingVisitorUtils.java index d7c47ea2660a..98bb301ba40b 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationReadingVisitorUtils.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationReadingVisitorUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,8 +61,7 @@ public static AnnotationAttributes convertClassValues(Object annotatedElement, value = convertClassValues( annotatedElement, classLoader, (AnnotationAttributes) value, classValuesAsString); } - else if (value instanceof AnnotationAttributes[]) { - AnnotationAttributes[] values = (AnnotationAttributes[]) value; + else if (value instanceof AnnotationAttributes[] values) { for (int i = 0; i < values.length; i++) { values[i] = convertClassValues(annotatedElement, classLoader, values[i], classValuesAsString); } @@ -72,8 +71,7 @@ else if (value instanceof Type) { value = (classValuesAsString ? ((Type) value).getClassName() : ClassUtils.forName(((Type) value).getClassName(), classLoader)); } - else if (value instanceof Type[]) { - Type[] array = (Type[]) value; + else if (value instanceof Type[] array) { Object[] convArray = (classValuesAsString ? new String[array.length] : new Class[array.length]); for (int i = 0; i < array.length; i++) { diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java index aca2ecd8b7d1..c80520cb5e77 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -69,7 +69,7 @@ class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata private String[] interfaces = new String[0]; - private Set memberClassNames = new LinkedHashSet<>(4); + private final Set memberClassNames = new LinkedHashSet<>(4); public ClassMetadataReadingVisitor() { diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataReadingVisitor.java index 6422cda99105..2875b1e263b1 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataReadingVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,11 +59,11 @@ final class SimpleAnnotationMetadataReadingVisitor extends ClassVisitor { private boolean independentInnerClass; - private Set memberClassNames = new LinkedHashSet<>(4); + private final Set memberClassNames = new LinkedHashSet<>(4); - private List> annotations = new ArrayList<>(); + private final List> annotations = new ArrayList<>(); - private List annotatedMethods = new ArrayList<>(); + private final List annotatedMethods = new ArrayList<>(); @Nullable private SimpleAnnotationMetadata metadata; diff --git a/spring-core/src/main/java/org/springframework/objenesis/SpringObjenesis.java b/spring-core/src/main/java/org/springframework/objenesis/SpringObjenesis.java index 9984211efcd4..031ef027f03c 100644 --- a/spring-core/src/main/java/org/springframework/objenesis/SpringObjenesis.java +++ b/spring-core/src/main/java/org/springframework/objenesis/SpringObjenesis.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -102,10 +102,12 @@ public T newInstance(Class clazz, boolean useCache) { return getInstantiatorOf(clazz).newInstance(); } + @Override public T newInstance(Class clazz) { return getInstantiatorOf(clazz).newInstance(); } + @Override @SuppressWarnings("unchecked") public ObjectInstantiator getInstantiatorOf(Class clazz) { ObjectInstantiator instantiator = this.cache.get(clazz); diff --git a/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java b/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java index 3291ca6e079a..47f44b188c09 100644 --- a/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java +++ b/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java @@ -762,10 +762,9 @@ public final boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof Map.Entry)) { + if (!(other instanceof Map.Entry otherEntry)) { return false; } - Map.Entry otherEntry = (Map.Entry) other; return (ObjectUtils.nullSafeEquals(getKey(), otherEntry.getKey()) && ObjectUtils.nullSafeEquals(getValue(), otherEntry.getValue())); } @@ -853,8 +852,7 @@ public Iterator> iterator() { @Override public boolean contains(@Nullable Object o) { - if (o instanceof Map.Entry) { - Map.Entry entry = (Map.Entry) o; + if (o instanceof Map.Entry entry) { Reference ref = ConcurrentReferenceHashMap.this.getReference(entry.getKey(), Restructure.NEVER); Entry otherEntry = (ref != null ? ref.get() : null); if (otherEntry != null) { @@ -866,8 +864,7 @@ public boolean contains(@Nullable Object o) { @Override public boolean remove(Object o) { - if (o instanceof Map.Entry) { - Map.Entry entry = (Map.Entry) o; + if (o instanceof Map.Entry entry) { return ConcurrentReferenceHashMap.this.remove(entry.getKey(), entry.getValue()); } return false; diff --git a/spring-core/src/main/java/org/springframework/util/LinkedCaseInsensitiveMap.java b/spring-core/src/main/java/org/springframework/util/LinkedCaseInsensitiveMap.java index 4689d53ee1e6..8deb9bf9c02e 100644 --- a/spring-core/src/main/java/org/springframework/util/LinkedCaseInsensitiveMap.java +++ b/spring-core/src/main/java/org/springframework/util/LinkedCaseInsensitiveMap.java @@ -110,7 +110,7 @@ public LinkedCaseInsensitiveMap(int expectedSize) { * @see #convertKey(String) */ public LinkedCaseInsensitiveMap(int expectedSize, @Nullable Locale locale) { - this.targetMap = new LinkedHashMap( + this.targetMap = new LinkedHashMap<>( (int) (expectedSize / CollectionUtils.DEFAULT_LOAD_FACTOR), CollectionUtils.DEFAULT_LOAD_FACTOR) { @Override public boolean containsKey(Object key) { diff --git a/spring-core/src/main/java/org/springframework/util/MimeType.java b/spring-core/src/main/java/org/springframework/util/MimeType.java index aa4ef6f53a31..d77b2f5711be 100644 --- a/spring-core/src/main/java/org/springframework/util/MimeType.java +++ b/spring-core/src/main/java/org/springframework/util/MimeType.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -453,10 +453,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof MimeType)) { + if (!(other instanceof MimeType otherType)) { return false; } - MimeType otherType = (MimeType) other; return (this.type.equalsIgnoreCase(otherType.type) && this.subtype.equalsIgnoreCase(otherType.subtype) && parametersAreEqual(otherType)); diff --git a/spring-core/src/main/java/org/springframework/util/TypeUtils.java b/spring-core/src/main/java/org/springframework/util/TypeUtils.java index 4a959aef52f0..0b770779550b 100644 --- a/spring-core/src/main/java/org/springframework/util/TypeUtils.java +++ b/spring-core/src/main/java/org/springframework/util/TypeUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,11 +25,12 @@ /** * Utility to work with Java 5 generic type parameters. - * Mainly for internal use within the framework. + *

    Mainly for internal use within the framework. * * @author Ramnivas Laddad * @author Juergen Hoeller * @author Chris Beams + * @author Sam Brannen * @since 2.0.7 */ public abstract class TypeUtils { @@ -50,62 +51,56 @@ public static boolean isAssignable(Type lhsType, Type rhsType) { return true; } - if (lhsType instanceof Class) { - Class lhsClass = (Class) lhsType; - + if (lhsType instanceof Class lhsClass) { // just comparing two classes - if (rhsType instanceof Class) { - return ClassUtils.isAssignable(lhsClass, (Class) rhsType); + if (rhsType instanceof Class rhsClass) { + return ClassUtils.isAssignable(lhsClass, rhsClass); } - if (rhsType instanceof ParameterizedType) { - Type rhsRaw = ((ParameterizedType) rhsType).getRawType(); + if (rhsType instanceof ParameterizedType rhsParameterizedType) { + Type rhsRaw = rhsParameterizedType.getRawType(); // a parameterized type is always assignable to its raw class type - if (rhsRaw instanceof Class) { - return ClassUtils.isAssignable(lhsClass, (Class) rhsRaw); + if (rhsRaw instanceof Class rhRawClass) { + return ClassUtils.isAssignable(lhsClass, rhRawClass); } } - else if (lhsClass.isArray() && rhsType instanceof GenericArrayType) { - Type rhsComponent = ((GenericArrayType) rhsType).getGenericComponentType(); + else if (lhsClass.isArray() && rhsType instanceof GenericArrayType rhsGenericArrayType) { + Type rhsComponent = rhsGenericArrayType.getGenericComponentType(); return isAssignable(lhsClass.getComponentType(), rhsComponent); } } // parameterized types are only assignable to other parameterized types and class types - if (lhsType instanceof ParameterizedType) { - if (rhsType instanceof Class) { - Type lhsRaw = ((ParameterizedType) lhsType).getRawType(); + if (lhsType instanceof ParameterizedType lhsParameterizedType) { + if (rhsType instanceof Class rhsClass) { + Type lhsRaw = lhsParameterizedType.getRawType(); - if (lhsRaw instanceof Class) { - return ClassUtils.isAssignable((Class) lhsRaw, (Class) rhsType); + if (lhsRaw instanceof Class lhsClass) { + return ClassUtils.isAssignable(lhsClass, rhsClass); } } - else if (rhsType instanceof ParameterizedType) { - return isAssignable((ParameterizedType) lhsType, (ParameterizedType) rhsType); + else if (rhsType instanceof ParameterizedType rhsParameterizedType) { + return isAssignable(lhsParameterizedType, rhsParameterizedType); } } - if (lhsType instanceof GenericArrayType) { - Type lhsComponent = ((GenericArrayType) lhsType).getGenericComponentType(); - - if (rhsType instanceof Class) { - Class rhsClass = (Class) rhsType; + if (lhsType instanceof GenericArrayType lhsGenericArrayType) { + Type lhsComponent = lhsGenericArrayType.getGenericComponentType(); - if (rhsClass.isArray()) { - return isAssignable(lhsComponent, rhsClass.getComponentType()); - } + if (rhsType instanceof Class rhsClass && rhsClass.isArray()) { + return isAssignable(lhsComponent, rhsClass.getComponentType()); } - else if (rhsType instanceof GenericArrayType) { - Type rhsComponent = ((GenericArrayType) rhsType).getGenericComponentType(); + else if (rhsType instanceof GenericArrayType rhsGenericArrayType) { + Type rhsComponent = rhsGenericArrayType.getGenericComponentType(); return isAssignable(lhsComponent, rhsComponent); } } - if (lhsType instanceof WildcardType) { - return isAssignable((WildcardType) lhsType, rhsType); + if (lhsType instanceof WildcardType lhsWildcardType) { + return isAssignable(lhsWildcardType, rhsType); } return false; @@ -128,7 +123,7 @@ private static boolean isAssignable(ParameterizedType lhsType, ParameterizedType Type rhsArg = rhsTypeArguments[i]; if (!lhsArg.equals(rhsArg) && - !(lhsArg instanceof WildcardType && isAssignable((WildcardType) lhsArg, rhsArg))) { + !(lhsArg instanceof WildcardType wildcardType && isAssignable(wildcardType, rhsArg))) { return false; } } @@ -151,11 +146,10 @@ private static boolean isAssignable(WildcardType lhsType, Type rhsType) { lLowerBounds = new Type[] { null }; } - if (rhsType instanceof WildcardType) { + if (rhsType instanceof WildcardType rhsWcType) { // both the upper and lower bounds of the right-hand side must be // completely enclosed in the upper and lower bounds of the left- // hand side. - WildcardType rhsWcType = (WildcardType) rhsType; Type[] rUpperBounds = rhsWcType.getUpperBounds(); if (rUpperBounds.length == 0) { diff --git a/spring-core/src/main/java/org/springframework/util/xml/XMLEventStreamReader.java b/spring-core/src/main/java/org/springframework/util/xml/XMLEventStreamReader.java index 7a27d683c297..7b1ba92bfb40 100644 --- a/spring-core/src/main/java/org/springframework/util/xml/XMLEventStreamReader.java +++ b/spring-core/src/main/java/org/springframework/util/xml/XMLEventStreamReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import javax.xml.namespace.QName; import javax.xml.stream.Location; import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Attribute; import javax.xml.stream.events.Comment; @@ -155,7 +156,7 @@ public String getText() { if (this.event.isCharacters()) { return this.event.asCharacters().getData(); } - else if (this.event.getEventType() == XMLEvent.COMMENT) { + else if (this.event.getEventType() == XMLStreamConstants.COMMENT) { return ((Comment) this.event).getText(); } else { From 4e6ef82d8f3ae7c587e0f1900ca263fd5d7b7f02 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 19:46:21 +0200 Subject: [PATCH 259/735] Apply "instanceof pattern matching" in spring-expression This commit also applies additional clean-up tasks such as the following. - final fields This commit also makes use of java.lang.String.repeat(int) in OptMultiply. This has only been applied to `src/main/java`. --- .../expression/TypedValue.java | 5 +- .../spel/ast/ConstructorReference.java | 11 ++-- .../expression/spel/ast/Indexer.java | 36 ++++++------- .../expression/spel/ast/InlineList.java | 18 +++---- .../expression/spel/ast/InlineMap.java | 30 +++++------ .../expression/spel/ast/OpDec.java | 14 ++--- .../expression/spel/ast/OpDivide.java | 8 ++- .../expression/spel/ast/OpGE.java | 7 +-- .../expression/spel/ast/OpGT.java | 7 +-- .../expression/spel/ast/OpInc.java | 14 ++--- .../expression/spel/ast/OpLE.java | 7 +-- .../expression/spel/ast/OpLT.java | 7 +-- .../expression/spel/ast/OpMinus.java | 52 +++++++++---------- .../expression/spel/ast/OpModulus.java | 9 ++-- .../expression/spel/ast/OpMultiply.java | 16 ++---- .../expression/spel/ast/OpPlus.java | 14 ++--- .../expression/spel/ast/Operator.java | 6 +-- .../expression/spel/ast/OperatorMatches.java | 8 +-- .../expression/spel/ast/OperatorPower.java | 7 +-- .../spel/ast/PropertyOrFieldReference.java | 20 ++++--- .../expression/spel/standard/Tokenizer.java | 10 ++-- .../support/ReflectivePropertyAccessor.java | 42 +++++++-------- .../spel/support/StandardTypeComparator.java | 9 ++-- 23 files changed, 151 insertions(+), 206 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/TypedValue.java b/spring-expression/src/main/java/org/springframework/expression/TypedValue.java index d2d470b72d70..a4f2427cc0ad 100644 --- a/spring-expression/src/main/java/org/springframework/expression/TypedValue.java +++ b/spring-expression/src/main/java/org/springframework/expression/TypedValue.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,10 +85,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof TypedValue)) { + if (!(other instanceof TypedValue otherTv)) { return false; } - TypedValue otherTv = (TypedValue) other; // Avoid TypeDescriptor initialization if not necessary return (ObjectUtils.nullSafeEquals(this.value, otherTv.value) && ((this.typeDescriptor == null && otherTv.typeDescriptor == null) || diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java index d42a375410f6..9841cee9ba98 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java @@ -136,8 +136,8 @@ private TypedValue createNewInstance(ExpressionState state) throws EvaluationExc if (ex.getCause() instanceof InvocationTargetException) { // User exception was the root cause - exit now Throwable rootCause = ex.getCause().getCause(); - if (rootCause instanceof RuntimeException) { - throw (RuntimeException) rootCause; + if (rootCause instanceof RuntimeException runtimeException) { + throw runtimeException; } else { String typeName = (String) this.children[0].getValueInternal(state).getValue(); @@ -158,9 +158,9 @@ private TypedValue createNewInstance(ExpressionState state) throws EvaluationExc executorToUse = findExecutorForConstructor(typeName, argumentTypes, state); try { this.cachedExecutor = executorToUse; - if (executorToUse instanceof ReflectiveConstructorExecutor) { + if (executorToUse instanceof ReflectiveConstructorExecutor reflectiveConstructorExecutor) { this.exitTypeDescriptor = CodeFlow.toDescriptor( - ((ReflectiveConstructorExecutor) executorToUse).getConstructor().getDeclaringClass()); + reflectiveConstructorExecutor.getConstructor().getDeclaringClass()); } return executorToUse.execute(state.getEvaluationContext(), arguments); @@ -228,14 +228,13 @@ public String toStringAST() { private TypedValue createArray(ExpressionState state) throws EvaluationException { // First child gives us the array type which will either be a primitive or reference type Object intendedArrayType = getChild(0).getValue(state); - if (!(intendedArrayType instanceof String)) { + if (!(intendedArrayType instanceof String type)) { throw new SpelEvaluationException(getChild(0).getStartPosition(), SpelMessage.TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION, FormatHelper.formatClassNameForMessage( intendedArrayType != null ? intendedArrayType.getClass() : null)); } - String type = (String) intendedArrayType; Class componentType; TypeCode arrayTypeCode = TypeCode.forName(type); if (arrayTypeCode == TypeCode.OBJECT) { diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java index 04b502816169..7a9d277ac027 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,6 +50,7 @@ * @author Andy Clement * @author Phillip Webb * @author Stephane Nicoll + * @author Sam Brannen * @since 3.0 */ // TODO support multidimensional arrays @@ -121,8 +122,7 @@ protected ValueRef getValueRef(ExpressionState state) throws EvaluationException Object index; // This first part of the if clause prevents a 'double dereference' of the property (SPR-5847) - if (target instanceof Map && (this.children[0] instanceof PropertyOrFieldReference)) { - PropertyOrFieldReference reference = (PropertyOrFieldReference) this.children[0]; + if (target instanceof Map && (this.children[0] instanceof PropertyOrFieldReference reference)) { index = reference.getName(); indexValue = new TypedValue(index); } @@ -148,13 +148,13 @@ protected ValueRef getValueRef(ExpressionState state) throws EvaluationException Assert.state(targetDescriptor != null, "No type descriptor"); // Indexing into a Map - if (target instanceof Map) { + if (target instanceof Map map) { Object key = index; if (targetDescriptor.getMapKeyTypeDescriptor() != null) { key = state.convertValue(key, targetDescriptor.getMapKeyTypeDescriptor()); } this.indexedType = IndexedType.MAP; - return new MapIndexingValueRef(state.getTypeConverter(), (Map) target, key, targetDescriptor); + return new MapIndexingValueRef(state.getTypeConverter(), map, key, targetDescriptor); } // If the object is something that looks indexable by an integer, @@ -275,8 +275,7 @@ else if (this.indexedType == IndexedType.MAP) { mv.visitTypeInsn(CHECKCAST, "java/util/Map"); // Special case when the key is an unquoted string literal that will be parsed as // a property/field reference - if ((this.children[0] instanceof PropertyOrFieldReference)) { - PropertyOrFieldReference reference = (PropertyOrFieldReference) this.children[0]; + if ((this.children[0] instanceof PropertyOrFieldReference reference)) { String mapKeyName = reference.getName(); mv.visitLdcInsn(mapKeyName); } @@ -306,9 +305,9 @@ else if (this.indexedType == IndexedType.OBJECT) { } } - if (member instanceof Method) { + if (member instanceof Method method) { mv.visitMethodInsn((isStatic? INVOKESTATIC : INVOKEVIRTUAL), classDesc, member.getName(), - CodeFlow.createSignatureDescriptor((Method) member), false); + CodeFlow.createSignatureDescriptor(method), false); } else { mv.visitFieldInsn((isStatic ? GETSTATIC : GETFIELD), classDesc, member.getName(), @@ -572,19 +571,17 @@ public TypedValue getValue() { targetObjectRuntimeClass, this.evaluationContext.getPropertyAccessors()); for (PropertyAccessor accessor : accessorsToTry) { if (accessor.canRead(this.evaluationContext, this.targetObject, this.name)) { - if (accessor instanceof ReflectivePropertyAccessor) { - accessor = ((ReflectivePropertyAccessor) accessor).createOptimalAccessor( + if (accessor instanceof ReflectivePropertyAccessor reflectivePropertyAccessor) { + accessor = reflectivePropertyAccessor.createOptimalAccessor( this.evaluationContext, this.targetObject, this.name); } Indexer.this.cachedReadAccessor = accessor; Indexer.this.cachedReadName = this.name; Indexer.this.cachedReadTargetType = targetObjectRuntimeClass; - if (accessor instanceof ReflectivePropertyAccessor.OptimalPropertyAccessor) { - ReflectivePropertyAccessor.OptimalPropertyAccessor optimalAccessor = - (ReflectivePropertyAccessor.OptimalPropertyAccessor) accessor; + if (accessor instanceof ReflectivePropertyAccessor.OptimalPropertyAccessor optimalAccessor) { Member member = optimalAccessor.member; - Indexer.this.exitTypeDescriptor = CodeFlow.toDescriptor(member instanceof Method ? - ((Method) member).getReturnType() : ((Field) member).getType()); + Indexer.this.exitTypeDescriptor = CodeFlow.toDescriptor(member instanceof Method method ? + method.getReturnType() : ((Field) member).getType()); } return accessor.read(this.evaluationContext, this.targetObject, this.name); } @@ -665,8 +662,8 @@ public CollectionIndexingValueRef(Collection collection, int index, TypeDescript @Override public TypedValue getValue() { growCollectionIfNecessary(); - if (this.collection instanceof List) { - Object o = ((List) this.collection).get(this.index); + if (this.collection instanceof List list) { + Object o = list.get(this.index); exitTypeDescriptor = CodeFlow.toDescriptor(Object.class); return new TypedValue(o, this.collectionEntryDescriptor.elementTypeDescriptor(o)); } @@ -683,8 +680,7 @@ public TypedValue getValue() { @Override public void setValue(@Nullable Object newValue) { growCollectionIfNecessary(); - if (this.collection instanceof List) { - List list = (List) this.collection; + if (this.collection instanceof List list) { if (this.collectionEntryDescriptor.getElementTypeDescriptor() != null) { newValue = this.typeConverter.convertValue(newValue, TypeDescriptor.forObject(newValue), this.collectionEntryDescriptor.getElementTypeDescriptor()); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineList.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineList.java index 4fa298eb5a3d..8abf63ec6ddf 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineList.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineList.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ * Represent a list in an expression, e.g. '{1,2,3}' * * @author Andy Clement + * @author Sam Brannen * @since 3.0.4 */ public class InlineList extends SpelNodeImpl { @@ -59,8 +60,7 @@ private void checkIfConstant() { for (int c = 0, max = getChildCount(); c < max; c++) { SpelNode child = getChild(c); if (!(child instanceof Literal)) { - if (child instanceof InlineList) { - InlineList inlineList = (InlineList) child; + if (child instanceof InlineList inlineList) { if (!inlineList.isConstant()) { isConstant = false; } @@ -75,11 +75,11 @@ private void checkIfConstant() { int childcount = getChildCount(); for (int c = 0; c < childcount; c++) { SpelNode child = getChild(c); - if ((child instanceof Literal)) { - constantList.add(((Literal) child).getLiteralValue().getValue()); + if (child instanceof Literal literal) { + constantList.add(literal.getLiteralValue().getValue()); } - else if (child instanceof InlineList) { - constantList.add(((InlineList) child).getConstantValue()); + else if (child instanceof InlineList inlineList) { + constantList.add(inlineList.getConstantValue()); } } this.constant = new TypedValue(Collections.unmodifiableList(constantList)); @@ -164,8 +164,8 @@ void generateClinitCode(String clazzname, String constantFieldName, MethodVisito // The children might be further lists if they are not constants. In this // situation do not call back into generateCode() because it will register another clinit adder. // Instead, directly build the list here: - if (this.children[c] instanceof InlineList) { - ((InlineList)this.children[c]).generateClinitCode(clazzname, constantFieldName, mv, codeflow, true); + if (this.children[c] instanceof InlineList inlineList) { + inlineList.generateClinitCode(clazzname, constantFieldName, mv, codeflow, true); } else { this.children[c].generateCode(mv, codeflow); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineMap.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineMap.java index c70759b03fe1..7f63c356885b 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineMap.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineMap.java @@ -31,6 +31,7 @@ * Represent a map in an expression, e.g. '{name:'foo',age:12}' * * @author Andy Clement + * @author Sam Brannen * @since 4.1 */ public class InlineMap extends SpelNodeImpl { @@ -56,15 +57,13 @@ private void checkIfConstant() { for (int c = 0, max = getChildCount(); c < max; c++) { SpelNode child = getChild(c); if (!(child instanceof Literal)) { - if (child instanceof InlineList) { - InlineList inlineList = (InlineList) child; + if (child instanceof InlineList inlineList) { if (!inlineList.isConstant()) { isConstant = false; break; } } - else if (child instanceof InlineMap) { - InlineMap inlineMap = (InlineMap) child; + else if (child instanceof InlineMap inlineMap) { if (!inlineMap.isConstant()) { isConstant = false; break; @@ -84,23 +83,23 @@ else if (!(c % 2 == 0 && child instanceof PropertyOrFieldReference)) { SpelNode valueChild = getChild(c); Object key = null; Object value = null; - if (keyChild instanceof Literal) { - key = ((Literal) keyChild).getLiteralValue().getValue(); + if (keyChild instanceof Literal literal) { + key = literal.getLiteralValue().getValue(); } - else if (keyChild instanceof PropertyOrFieldReference) { - key = ((PropertyOrFieldReference) keyChild).getName(); + else if (keyChild instanceof PropertyOrFieldReference propertyOrFieldReference) { + key = propertyOrFieldReference.getName(); } else { return; } - if (valueChild instanceof Literal) { - value = ((Literal) valueChild).getLiteralValue().getValue(); + if (valueChild instanceof Literal literal) { + value = literal.getLiteralValue().getValue(); } - else if (valueChild instanceof InlineList) { - value = ((InlineList) valueChild).getConstantValue(); + else if (valueChild instanceof InlineList inlineList) { + value = inlineList.getConstantValue(); } - else if (valueChild instanceof InlineMap) { - value = ((InlineMap) valueChild).getConstantValue(); + else if (valueChild instanceof InlineMap inlineMap) { + value = inlineMap.getConstantValue(); } constantMap.put(key, value); } @@ -120,8 +119,7 @@ public TypedValue getValueInternal(ExpressionState expressionState) throws Evalu // TODO allow for key being PropertyOrFieldReference like Indexer on maps SpelNode keyChild = getChild(c++); Object key = null; - if (keyChild instanceof PropertyOrFieldReference) { - PropertyOrFieldReference reference = (PropertyOrFieldReference) keyChild; + if (keyChild instanceof PropertyOrFieldReference reference) { key = reference.getName(); } else { diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDec.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDec.java index 9bab5a1e381b..d61e8d641062 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDec.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDec.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ * @author Andy Clement * @author Juergen Hoeller * @author Giovanni Dall'Oglio Risso + * @author Sam Brannen * @since 3.2 */ public class OpDec extends Operator { @@ -60,10 +61,9 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep TypedValue returnValue = operandTypedValue; TypedValue newValue = null; - if (operandValue instanceof Number) { - Number op1 = (Number) operandValue; - if (op1 instanceof BigDecimal) { - newValue = new TypedValue(((BigDecimal) op1).subtract(BigDecimal.ONE), operandTypedValue.getTypeDescriptor()); + if (operandValue instanceof Number op1) { + if (op1 instanceof BigDecimal bigDecimal) { + newValue = new TypedValue(bigDecimal.subtract(BigDecimal.ONE), operandTypedValue.getTypeDescriptor()); } else if (op1 instanceof Double) { newValue = new TypedValue(op1.doubleValue() - 1.0d, operandTypedValue.getTypeDescriptor()); @@ -71,8 +71,8 @@ else if (op1 instanceof Double) { else if (op1 instanceof Float) { newValue = new TypedValue(op1.floatValue() - 1.0f, operandTypedValue.getTypeDescriptor()); } - else if (op1 instanceof BigInteger) { - newValue = new TypedValue(((BigInteger) op1).subtract(BigInteger.ONE), operandTypedValue.getTypeDescriptor()); + else if (op1 instanceof BigInteger bigInteger) { + newValue = new TypedValue(bigInteger.subtract(BigInteger.ONE), operandTypedValue.getTypeDescriptor()); } else if (op1 instanceof Long) { newValue = new TypedValue(op1.longValue() - 1L, operandTypedValue.getTypeDescriptor()); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java index 02eae2f48c85..f555d75f3209 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ * @author Andy Clement * @author Juergen Hoeller * @author Giovanni Dall'Oglio Risso + * @author Sam Brannen * @since 3.0 */ public class OpDivide extends Operator { @@ -49,10 +50,7 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep Object leftOperand = getLeftOperand().getValueInternal(state).getValue(); Object rightOperand = getRightOperand().getValueInternal(state).getValue(); - if (leftOperand instanceof Number && rightOperand instanceof Number) { - Number leftNumber = (Number) leftOperand; - Number rightNumber = (Number) rightOperand; - + if (leftOperand instanceof Number leftNumber && rightOperand instanceof Number rightNumber) { if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) { BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGE.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGE.java index 708e1b89c593..8dea989339f8 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGE.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGE.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,10 +50,7 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati this.leftActualDescriptor = CodeFlow.toDescriptorFromObject(left); this.rightActualDescriptor = CodeFlow.toDescriptorFromObject(right); - if (left instanceof Number && right instanceof Number) { - Number leftNumber = (Number) left; - Number rightNumber = (Number) right; - + if (left instanceof Number leftNumber && right instanceof Number rightNumber) { if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) { BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGT.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGT.java index 3a4b2fd70889..7823bf888a57 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGT.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGT.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,10 +50,7 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati this.leftActualDescriptor = CodeFlow.toDescriptorFromObject(left); this.rightActualDescriptor = CodeFlow.toDescriptorFromObject(right); - if (left instanceof Number && right instanceof Number) { - Number leftNumber = (Number) left; - Number rightNumber = (Number) right; - + if (left instanceof Number leftNumber && right instanceof Number rightNumber) { if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) { BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpInc.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpInc.java index ee19b59988ca..f6dc184c0f5e 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpInc.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpInc.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ * @author Andy Clement * @author Juergen Hoeller * @author Giovanni Dall'Oglio Risso + * @author Sam Brannen * @since 3.2 */ public class OpInc extends Operator { @@ -58,10 +59,9 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep TypedValue returnValue = typedValue; TypedValue newValue = null; - if (value instanceof Number) { - Number op1 = (Number) value; - if (op1 instanceof BigDecimal) { - newValue = new TypedValue(((BigDecimal) op1).add(BigDecimal.ONE), typedValue.getTypeDescriptor()); + if (value instanceof Number op1) { + if (op1 instanceof BigDecimal bigDecimal) { + newValue = new TypedValue(bigDecimal.add(BigDecimal.ONE), typedValue.getTypeDescriptor()); } else if (op1 instanceof Double) { newValue = new TypedValue(op1.doubleValue() + 1.0d, typedValue.getTypeDescriptor()); @@ -69,8 +69,8 @@ else if (op1 instanceof Double) { else if (op1 instanceof Float) { newValue = new TypedValue(op1.floatValue() + 1.0f, typedValue.getTypeDescriptor()); } - else if (op1 instanceof BigInteger) { - newValue = new TypedValue(((BigInteger) op1).add(BigInteger.ONE), typedValue.getTypeDescriptor()); + else if (op1 instanceof BigInteger bigInteger) { + newValue = new TypedValue(bigInteger.add(BigInteger.ONE), typedValue.getTypeDescriptor()); } else if (op1 instanceof Long) { newValue = new TypedValue(op1.longValue() + 1L, typedValue.getTypeDescriptor()); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLE.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLE.java index adbc29916405..1fa2e2025308 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLE.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLE.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,10 +50,7 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati this.leftActualDescriptor = CodeFlow.toDescriptorFromObject(left); this.rightActualDescriptor = CodeFlow.toDescriptorFromObject(right); - if (left instanceof Number && right instanceof Number) { - Number leftNumber = (Number) left; - Number rightNumber = (Number) right; - + if (left instanceof Number leftNumber && right instanceof Number rightNumber) { if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) { BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLT.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLT.java index 8101dee8b31f..fc6d91705c8d 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLT.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLT.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,10 +50,7 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati this.leftActualDescriptor = CodeFlow.toDescriptorFromObject(left); this.rightActualDescriptor = CodeFlow.toDescriptorFromObject(right); - if (left instanceof Number && right instanceof Number) { - Number leftNumber = (Number) left; - Number rightNumber = (Number) right; - + if (left instanceof Number leftNumber && right instanceof Number rightNumber) { if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) { BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java index 54d6b689d8e1..ddbc9c7d6f67 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,6 +43,7 @@ * @author Andy Clement * @author Juergen Hoeller * @author Giovanni Dall'Oglio Risso + * @author Sam Brannen * @since 3.0 */ public class OpMinus extends Operator { @@ -58,38 +59,38 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep if (this.children.length < 2) { // if only one operand, then this is unary minus Object operand = leftOp.getValueInternal(state).getValue(); - if (operand instanceof Number) { - if (operand instanceof BigDecimal) { - return new TypedValue(((BigDecimal) operand).negate()); + if (operand instanceof Number number) { + if (number instanceof BigDecimal bigDecimal) { + return new TypedValue(bigDecimal.negate()); } - else if (operand instanceof Double) { + else if (number instanceof BigInteger bigInteger) { + return new TypedValue(bigInteger.negate()); + } + else if (number instanceof Double) { this.exitTypeDescriptor = "D"; - return new TypedValue(0 - ((Number) operand).doubleValue()); + return new TypedValue(0 - number.doubleValue()); } - else if (operand instanceof Float) { + else if (number instanceof Float) { this.exitTypeDescriptor = "F"; - return new TypedValue(0 - ((Number) operand).floatValue()); - } - else if (operand instanceof BigInteger) { - return new TypedValue(((BigInteger) operand).negate()); + return new TypedValue(0 - number.floatValue()); } - else if (operand instanceof Long) { + else if (number instanceof Long) { this.exitTypeDescriptor = "J"; - return new TypedValue(0 - ((Number) operand).longValue()); + return new TypedValue(0 - number.longValue()); } - else if (operand instanceof Integer) { + else if (number instanceof Integer) { this.exitTypeDescriptor = "I"; - return new TypedValue(0 - ((Number) operand).intValue()); + return new TypedValue(0 - number.intValue()); } - else if (operand instanceof Short) { - return new TypedValue(0 - ((Number) operand).shortValue()); + else if (number instanceof Short) { + return new TypedValue(0 - number.shortValue()); } - else if (operand instanceof Byte) { - return new TypedValue(0 - ((Number) operand).byteValue()); + else if (number instanceof Byte) { + return new TypedValue(0 - number.byteValue()); } else { - // Unknown Number subtypes -> best guess is double subtraction - return new TypedValue(0 - ((Number) operand).doubleValue()); + // Unknown Number subtype -> best guess is double subtraction + return new TypedValue(0 - number.doubleValue()); } } return state.operate(Operation.SUBTRACT, operand, null); @@ -98,10 +99,7 @@ else if (operand instanceof Byte) { Object left = leftOp.getValueInternal(state).getValue(); Object right = getRightOperand().getValueInternal(state).getValue(); - if (left instanceof Number && right instanceof Number) { - Number leftNumber = (Number) left; - Number rightNumber = (Number) right; - + if (left instanceof Number leftNumber && right instanceof Number rightNumber) { if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) { BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class); @@ -134,9 +132,7 @@ else if (CodeFlow.isIntegerForNumericOp(leftNumber) || CodeFlow.isIntegerForNume } } - if (left instanceof String && right instanceof Integer && ((String) left).length() == 1) { - String theString = (String) left; - Integer theInteger = (Integer) right; + if (left instanceof String theString && right instanceof Integer theInteger && theString.length() == 1) { // Implements character - int (ie. b - 1 = a) return new TypedValue(Character.toString((char) (theString.charAt(0) - theInteger))); } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java index eadd9a960d1f..51385a3603ea 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,10 +48,7 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep Object leftOperand = getLeftOperand().getValueInternal(state).getValue(); Object rightOperand = getRightOperand().getValueInternal(state).getValue(); - if (leftOperand instanceof Number && rightOperand instanceof Number) { - Number leftNumber = (Number) leftOperand; - Number rightNumber = (Number) rightOperand; - + if (leftOperand instanceof Number leftNumber && rightOperand instanceof Number rightNumber) { if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) { BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class); @@ -79,7 +76,7 @@ else if (CodeFlow.isIntegerForNumericOp(leftNumber) || CodeFlow.isIntegerForNume return new TypedValue(leftNumber.intValue() % rightNumber.intValue()); } else { - // Unknown Number subtypes -> best guess is double division + // Unknown Number subtype -> best guess is double division return new TypedValue(leftNumber.doubleValue() % rightNumber.doubleValue()); } } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java index fbf28317b32b..83c406e01d09 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,10 +72,7 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep Object leftOperand = getLeftOperand().getValueInternal(state).getValue(); Object rightOperand = getRightOperand().getValueInternal(state).getValue(); - if (leftOperand instanceof Number && rightOperand instanceof Number) { - Number leftNumber = (Number) leftOperand; - Number rightNumber = (Number) rightOperand; - + if (leftOperand instanceof Number leftNumber && rightOperand instanceof Number rightNumber) { if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) { BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class); @@ -108,13 +105,8 @@ else if (CodeFlow.isIntegerForNumericOp(leftNumber) || CodeFlow.isIntegerForNume } } - if (leftOperand instanceof String && rightOperand instanceof Integer) { - int repeats = (Integer) rightOperand; - StringBuilder result = new StringBuilder(); - for (int i = 0; i < repeats; i++) { - result.append(leftOperand); - } - return new TypedValue(result.toString()); + if (leftOperand instanceof String text && rightOperand instanceof Integer repeats) { + return new TypedValue(text.repeat(repeats)); } return state.operate(Operation.MULTIPLY, leftOperand, rightOperand); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java index d128f56b2deb..098f96dca123 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,10 +85,7 @@ else if (operandOne instanceof Integer) { TypedValue operandTwoValue = getRightOperand().getValueInternal(state); Object rightOperand = operandTwoValue.getValue(); - if (leftOperand instanceof Number && rightOperand instanceof Number) { - Number leftNumber = (Number) leftOperand; - Number rightNumber = (Number) rightOperand; - + if (leftOperand instanceof Number leftNumber && rightOperand instanceof Number rightNumber) { if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) { BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class); @@ -121,9 +118,9 @@ else if (CodeFlow.isIntegerForNumericOp(leftNumber) || CodeFlow.isIntegerForNume } } - if (leftOperand instanceof String && rightOperand instanceof String) { + if (leftOperand instanceof String leftString && rightOperand instanceof String rightString) { this.exitTypeDescriptor = "Ljava/lang/String"; - return new TypedValue((String) leftOperand + rightOperand); + return new TypedValue(leftString + rightString); } if (leftOperand instanceof String) { @@ -190,8 +187,7 @@ public boolean isCompilable() { * them all to the same (on stack) StringBuilder. */ private void walk(MethodVisitor mv, CodeFlow cf, @Nullable SpelNodeImpl operand) { - if (operand instanceof OpPlus) { - OpPlus plus = (OpPlus)operand; + if (operand instanceof OpPlus plus) { walk(mv, cf, plus.getLeftOperand()); walk(mv, cf, plus.getRightOperand()); } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java index ec31559e379f..11150a7c9bf6 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java @@ -36,6 +36,7 @@ * @author Andy Clement * @author Juergen Hoeller * @author Giovanni Dall'Oglio Risso + * @author Sam Brannen * @since 3.0 */ public abstract class Operator extends SpelNodeImpl { @@ -261,10 +262,7 @@ else if (targetType == 'I') { * @param right the right-hand operand value */ public static boolean equalityCheck(EvaluationContext context, @Nullable Object left, @Nullable Object right) { - if (left instanceof Number && right instanceof Number) { - Number leftNumber = (Number) left; - Number rightNumber = (Number) right; - + if (left instanceof Number leftNumber && right instanceof Number rightNumber) { if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) { BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorMatches.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorMatches.java index 22795a928796..6c9bfbaf3ed5 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorMatches.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorMatches.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,7 @@ * * @author Andy Clement * @author Juergen Hoeller + * @author Sam Brannen * @since 3.0 */ public class OperatorMatches extends Operator { @@ -69,13 +70,12 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati throw new SpelEvaluationException(leftOp.getStartPosition(), SpelMessage.INVALID_FIRST_OPERAND_FOR_MATCHES_OPERATOR, (Object) null); } - if (!(right instanceof String)) { + if (!(right instanceof String rightString)) { throw new SpelEvaluationException(rightOp.getStartPosition(), SpelMessage.INVALID_SECOND_OPERAND_FOR_MATCHES_OPERATOR, right); } try { - String rightString = (String) right; Pattern pattern = this.patternCache.get(rightString); if (pattern == null) { pattern = Pattern.compile(rightString); @@ -111,7 +111,7 @@ private static class MatcherInput implements CharSequence { private final CharSequence value; - private AccessCount access; + private final AccessCount access; public MatcherInput(CharSequence value, AccessCount access) { this.value = value; diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorPower.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorPower.java index 2a256ea4371e..cd90af1effff 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorPower.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorPower.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,10 +47,7 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep Object leftOperand = leftOp.getValueInternal(state).getValue(); Object rightOperand = rightOp.getValueInternal(state).getValue(); - if (leftOperand instanceof Number && rightOperand instanceof Number) { - Number leftNumber = (Number) leftOperand; - Number rightNumber = (Number) rightOperand; - + if (leftOperand instanceof Number leftNumber && rightOperand instanceof Number rightNumber) { if (leftNumber instanceof BigDecimal) { BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); return new TypedValue(leftBigDecimal.pow(rightNumber.intValue())); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java index 476fb4c9b7a2..769376c9fa50 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +46,7 @@ * @author Andy Clement * @author Juergen Hoeller * @author Clark Duplichien + * @author Sam Brannen * @since 3.0 */ public class PropertyOrFieldReference extends SpelNodeImpl { @@ -91,8 +92,7 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep TypedValue tv = getValueInternal(state.getActiveContextObject(), state.getEvaluationContext(), state.getConfiguration().isAutoGrowNullReferences()); PropertyAccessor accessorToUse = this.cachedReadAccessor; - if (accessorToUse instanceof CompilablePropertyAccessor) { - CompilablePropertyAccessor accessor = (CompilablePropertyAccessor) accessorToUse; + if (accessorToUse instanceof CompilablePropertyAccessor accessor) { setExitTypeDescriptor(CodeFlow.toDescriptor(accessor.getPropertyType())); } return tv; @@ -196,8 +196,8 @@ private TypedValue readProperty(TypedValue contextObject, EvaluationContext eval try { for (PropertyAccessor accessor : accessorsToTry) { if (accessor.canRead(evalContext, contextObject.getValue(), name)) { - if (accessor instanceof ReflectivePropertyAccessor) { - accessor = ((ReflectivePropertyAccessor) accessor).createOptimalAccessor( + if (accessor instanceof ReflectivePropertyAccessor reflectivePropertyAccessor) { + accessor = reflectivePropertyAccessor.createOptimalAccessor( evalContext, contextObject.getValue(), name); } this.cachedReadAccessor = accessor; @@ -330,9 +330,8 @@ else if (clazz.isAssignableFrom(targetType)) { @Override public boolean isCompilable() { - PropertyAccessor accessorToUse = this.cachedReadAccessor; - return (accessorToUse instanceof CompilablePropertyAccessor && - ((CompilablePropertyAccessor) accessorToUse).isCompilable()); + return (this.cachedReadAccessor instanceof CompilablePropertyAccessor compilablePropertyAccessor && + compilablePropertyAccessor.isCompilable()); } @Override @@ -404,9 +403,8 @@ public AccessorLValue(PropertyOrFieldReference propertyOrFieldReference, TypedVa public TypedValue getValue() { TypedValue value = this.ref.getValueInternal(this.contextObject, this.evalContext, this.autoGrowNullReferences); - PropertyAccessor accessorToUse = this.ref.cachedReadAccessor; - if (accessorToUse instanceof CompilablePropertyAccessor) { - this.ref.setExitTypeDescriptor(CodeFlow.toDescriptor(((CompilablePropertyAccessor) accessorToUse).getPropertyType())); + if (this.ref.cachedReadAccessor instanceof CompilablePropertyAccessor compilablePropertyAccessor) { + this.ref.setExitTypeDescriptor(CodeFlow.toDescriptor(compilablePropertyAccessor.getPropertyType())); } return value; } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/standard/Tokenizer.java b/spring-expression/src/main/java/org/springframework/expression/spel/standard/Tokenizer.java index 5034c960ec61..2726fa53fb3c 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/standard/Tokenizer.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/standard/Tokenizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,15 +65,15 @@ class Tokenizer { } - private String expressionString; + private final String expressionString; - private char[] charsToProcess; + private final char[] charsToProcess; private int pos; - private int max; + private final int max; - private List tokens = new ArrayList<>(); + private final List tokens = new ArrayList<>(); public Tokenizer(String inputData) { diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java index 5fd48cdad88a..fae62e1d3791 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -123,7 +123,7 @@ public boolean canRead(EvaluationContext context, @Nullable Object target, Strin return false; } - Class type = (target instanceof Class ? (Class) target : target.getClass()); + Class type = (target instanceof Class clazz ? clazz : target.getClass()); if (type.isArray() && name.equals("length")) { return true; } @@ -160,7 +160,7 @@ public boolean canRead(EvaluationContext context, @Nullable Object target, Strin @Override public TypedValue read(EvaluationContext context, @Nullable Object target, String name) throws AccessException { Assert.state(target != null, "Target must not be null"); - Class type = (target instanceof Class ? (Class) target : target.getClass()); + Class type = (target instanceof Class clazz ? clazz : target.getClass()); if (type.isArray() && name.equals("length")) { if (target instanceof Class) { @@ -231,7 +231,7 @@ public boolean canWrite(EvaluationContext context, @Nullable Object target, Stri return false; } - Class type = (target instanceof Class ? (Class) target : target.getClass()); + Class type = (target instanceof Class clazz ? clazz : target.getClass()); PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class); if (this.writerCache.containsKey(cacheKey)) { return true; @@ -269,7 +269,7 @@ public void write(EvaluationContext context, @Nullable Object target, String nam } Assert.state(target != null, "Target must not be null"); - Class type = (target instanceof Class ? (Class) target : target.getClass()); + Class type = (target instanceof Class clazz ? clazz : target.getClass()); Object possiblyConvertedNewValue = newValue; TypeDescriptor typeDescriptor = getTypeDescriptor(context, target, name); @@ -346,7 +346,7 @@ public Member getLastReadInvokerPair() { @Nullable private TypeDescriptor getTypeDescriptor(EvaluationContext context, Object target, String name) { - Class type = (target instanceof Class ? (Class) target : target.getClass()); + Class type = (target instanceof Class clazz ? clazz : target.getClass()); if (type.isArray() && name.equals("length")) { return TypeDescriptor.valueOf(Integer.TYPE); @@ -533,18 +533,18 @@ public PropertyAccessor createOptimalAccessor(EvaluationContext context, @Nullab if (target == null) { return this; } - Class clazz = (target instanceof Class ? (Class) target : target.getClass()); - if (clazz.isArray()) { + Class type = (target instanceof Class clazz ? clazz : target.getClass()); + if (type.isArray()) { return this; } - PropertyCacheKey cacheKey = new PropertyCacheKey(clazz, name, target instanceof Class); + PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class); InvokerPair invocationTarget = this.readerCache.get(cacheKey); if (invocationTarget == null || invocationTarget.member instanceof Method) { Method method = (Method) (invocationTarget != null ? invocationTarget.member : null); if (method == null) { - method = findGetterForProperty(name, clazz, target); + method = findGetterForProperty(name, type, target); if (method != null) { TypeDescriptor typeDescriptor = new TypeDescriptor(new MethodParameter(method, -1)); method = ClassUtils.getInterfaceMethodIfPossible(method); @@ -561,7 +561,7 @@ public PropertyAccessor createOptimalAccessor(EvaluationContext context, @Nullab if (invocationTarget == null || invocationTarget.member instanceof Field) { Field field = (invocationTarget != null ? (Field) invocationTarget.member : null); if (field == null) { - field = findField(name, clazz, target instanceof Class); + field = findField(name, type, target instanceof Class); if (field != null) { invocationTarget = new InvokerPair(field, new TypeDescriptor(field)); ReflectionUtils.makeAccessible(field); @@ -600,7 +600,7 @@ private static final class PropertyCacheKey implements Comparable clazz, String name, boolean targetIsClass) { this.clazz = clazz; @@ -613,10 +613,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof PropertyCacheKey)) { + if (!(other instanceof PropertyCacheKey otherKey)) { return false; } - PropertyCacheKey otherKey = (PropertyCacheKey) other; return (this.clazz == otherKey.clazz && this.property.equals(otherKey.property) && this.targetIsClass == otherKey.targetIsClass); } @@ -676,13 +675,12 @@ public boolean canRead(EvaluationContext context, @Nullable Object target, Strin if (target == null) { return false; } - Class type = (target instanceof Class ? (Class) target : target.getClass()); + Class type = (target instanceof Class clazz ? clazz : target.getClass()); if (type.isArray()) { return false; } - if (this.member instanceof Method) { - Method method = (Method) this.member; + if (this.member instanceof Method method) { String getterName = "get" + StringUtils.capitalize(name); if (getterName.equals(method.getName())) { return true; @@ -697,8 +695,7 @@ public boolean canRead(EvaluationContext context, @Nullable Object target, Strin @Override public TypedValue read(EvaluationContext context, @Nullable Object target, String name) throws AccessException { - if (this.member instanceof Method) { - Method method = (Method) this.member; + if (this.member instanceof Method method) { try { ReflectionUtils.makeAccessible(method); Object value = method.invoke(target); @@ -739,8 +736,8 @@ public boolean isCompilable() { @Override public Class getPropertyType() { - if (this.member instanceof Method) { - return ((Method) this.member).getReturnType(); + if (this.member instanceof Method method) { + return method.getReturnType(); } else { return ((Field) this.member).getType(); @@ -769,8 +766,7 @@ public void generateCode(String propertyName, MethodVisitor mv, CodeFlow cf) { } } - if (this.member instanceof Method) { - Method method = (Method) this.member; + if (this.member instanceof Method method) { boolean isInterface = method.getDeclaringClass().isInterface(); int opcode = (isStatic ? INVOKESTATIC : isInterface ? INVOKEINTERFACE : INVOKEVIRTUAL); mv.visitMethodInsn(opcode, classDesc, method.getName(), diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeComparator.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeComparator.java index 8e48aa878c8f..fc15f6b3ec0e 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeComparator.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeComparator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,10 +62,7 @@ else if (right == null) { } // Basic number comparisons - if (left instanceof Number && right instanceof Number) { - Number leftNumber = (Number) left; - Number rightNumber = (Number) right; - + if (left instanceof Number leftNumber && right instanceof Number rightNumber) { if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) { BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class); @@ -95,7 +92,7 @@ else if (leftNumber instanceof Byte || rightNumber instanceof Byte) { return Byte.compare(leftNumber.byteValue(), rightNumber.byteValue()); } else { - // Unknown Number subtypes -> best guess is double multiplication + // Unknown Number subtype -> best guess is double multiplication return Double.compare(leftNumber.doubleValue(), rightNumber.doubleValue()); } } From 971f665eb1e8cd9e8a0c788a8f5612f815894082 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 19:53:40 +0200 Subject: [PATCH 260/735] Apply "instanceof pattern matching" in spring-jdbc This commit also applies additional clean-up tasks such as the following. - final fields This has only been applied to `src/main/java`. --- .../core/ArgumentPreparedStatementSetter.java | 5 ++--- .../ArgumentTypePreparedStatementSetter.java | 5 ++--- .../jdbc/core/BatchUpdateUtils.java | 5 ++--- .../springframework/jdbc/core/JdbcTemplate.java | 8 +++----- .../core/PreparedStatementCreatorFactory.java | 11 +++++------ .../jdbc/core/StatementCreatorUtils.java | 17 ++++++----------- .../metadata/GenericTableMetaDataProvider.java | 6 +++--- .../core/namedparam/NamedParameterUtils.java | 3 +-- .../jdbc/datasource/DataSourceUtils.java | 2 +- .../embedded/EmbeddedDatabaseFactory.java | 5 ++--- .../lookup/IsolationLevelDataSourceRouter.java | 5 ++--- .../springframework/jdbc/support/JdbcUtils.java | 8 +++----- .../jdbc/support/lob/PassThroughBlob.java | 4 ++-- .../jdbc/support/lob/PassThroughClob.java | 4 ++-- 14 files changed, 36 insertions(+), 52 deletions(-) diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/ArgumentPreparedStatementSetter.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/ArgumentPreparedStatementSetter.java index 4f92385be8d4..915c602e6bc0 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/ArgumentPreparedStatementSetter.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/ArgumentPreparedStatementSetter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,8 +61,7 @@ public void setValues(PreparedStatement ps) throws SQLException { * @throws SQLException if thrown by PreparedStatement methods */ protected void doSetValue(PreparedStatement ps, int parameterPosition, Object argValue) throws SQLException { - if (argValue instanceof SqlParameterValue) { - SqlParameterValue paramValue = (SqlParameterValue) argValue; + if (argValue instanceof SqlParameterValue paramValue) { StatementCreatorUtils.setParameterValue(ps, parameterPosition, paramValue, paramValue.getValue()); } else { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/ArgumentTypePreparedStatementSetter.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/ArgumentTypePreparedStatementSetter.java index 7e102efe31dc..3d89d8abe775 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/ArgumentTypePreparedStatementSetter.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/ArgumentTypePreparedStatementSetter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,8 +64,7 @@ public void setValues(PreparedStatement ps) throws SQLException { if (arg instanceof Collection && this.argTypes[i] != Types.ARRAY) { Collection entries = (Collection) arg; for (Object entry : entries) { - if (entry instanceof Object[]) { - Object[] valueArray = ((Object[]) entry); + if (entry instanceof Object[] valueArray) { for (Object argValue : valueArray) { doSetValue(ps, parameterPosition, this.argTypes[i], argValue); parameterPosition++; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java index 8f1fcef395a3..dcab3b2ca9b8 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,8 +62,7 @@ protected static void setStatementParameters(Object[] values, PreparedStatement int colIndex = 0; for (Object value : values) { colIndex++; - if (value instanceof SqlParameterValue) { - SqlParameterValue paramValue = (SqlParameterValue) value; + if (value instanceof SqlParameterValue paramValue) { StatementCreatorUtils.setParameterValue(ps, colIndex, paramValue, paramValue.getValue()); } else { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index f41390c2c439..179a6b79e166 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1094,8 +1094,7 @@ public void setValues(PreparedStatement ps, int i) throws SQLException { int colIndex = 0; for (Object value : values) { colIndex++; - if (value instanceof SqlParameterValue) { - SqlParameterValue paramValue = (SqlParameterValue) value; + if (value instanceof SqlParameterValue paramValue) { StatementCreatorUtils.setParameterValue(ps, colIndex, paramValue, paramValue.getValue()); } else { @@ -1337,8 +1336,7 @@ protected Map extractOutputParameters(CallableStatement cs, List Map results = CollectionUtils.newLinkedHashMap(parameters.size()); int sqlColIndex = 1; for (SqlParameter param : parameters) { - if (param instanceof SqlOutParameter) { - SqlOutParameter outParam = (SqlOutParameter) param; + if (param instanceof SqlOutParameter outParam) { Assert.state(outParam.getName() != null, "Anonymous parameters not allowed"); SqlReturnType returnType = outParam.getSqlReturnType(); if (returnType != null) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.java index e6083f8be0f5..ecf784e4c63e 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; import java.sql.Types; import java.util.ArrayList; import java.util.Arrays; @@ -228,7 +229,7 @@ public PreparedStatement createPreparedStatement(Connection con) throws SQLExcep ps = con.prepareStatement(this.actualSql, generatedKeysColumnNames); } else { - ps = con.prepareStatement(this.actualSql, PreparedStatement.RETURN_GENERATED_KEYS); + ps = con.prepareStatement(this.actualSql, Statement.RETURN_GENERATED_KEYS); } } else if (resultSetType == ResultSet.TYPE_FORWARD_ONLY && !updatableResults) { @@ -251,8 +252,7 @@ public void setValues(PreparedStatement ps) throws SQLException { SqlParameter declaredParameter; // SqlParameterValue overrides declared parameter meta-data, in particular for // independence from the declared parameter position in case of named parameters. - if (in instanceof SqlParameterValue) { - SqlParameterValue paramValue = (SqlParameterValue) in; + if (in instanceof SqlParameterValue paramValue) { in = paramValue.getValue(); declaredParameter = paramValue; } @@ -268,8 +268,7 @@ public void setValues(PreparedStatement ps) throws SQLException { if (in instanceof Iterable && declaredParameter.getSqlType() != Types.ARRAY) { Iterable entries = (Iterable) in; for (Object entry : entries) { - if (entry instanceof Object[]) { - Object[] valueArray = (Object[]) entry; + if (entry instanceof Object[] valueArray) { for (Object argValue : valueArray) { StatementCreatorUtils.setParameterValue(ps, sqlColIndx++, declaredParameter, argValue); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java index 5c6c1d859d22..3d7edf0e8e25 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -202,8 +202,7 @@ private static void setParameterValueInternal(PreparedStatement ps, int paramInd Object inValueToUse = inValue; // override type info? - if (inValue instanceof SqlParameterValue) { - SqlParameterValue parameterValue = (SqlParameterValue) inValue; + if (inValue instanceof SqlParameterValue parameterValue) { if (logger.isDebugEnabled()) { logger.debug("Overriding type info with runtime info from SqlParameterValue: column index " + paramIndex + ", SQL type " + parameterValue.getSqlType() + ", type name " + parameterValue.getTypeName()); @@ -350,8 +349,7 @@ else if (sqlType == Types.DATE) { ps.setDate(paramIndex, new java.sql.Date(((java.util.Date) inValue).getTime())); } } - else if (inValue instanceof Calendar) { - Calendar cal = (Calendar) inValue; + else if (inValue instanceof Calendar cal) { ps.setDate(paramIndex, new java.sql.Date(cal.getTime().getTime()), cal); } else { @@ -367,8 +365,7 @@ else if (sqlType == Types.TIME) { ps.setTime(paramIndex, new java.sql.Time(((java.util.Date) inValue).getTime())); } } - else if (inValue instanceof Calendar) { - Calendar cal = (Calendar) inValue; + else if (inValue instanceof Calendar cal) { ps.setTime(paramIndex, new java.sql.Time(cal.getTime().getTime()), cal); } else { @@ -384,8 +381,7 @@ else if (sqlType == Types.TIMESTAMP) { ps.setTimestamp(paramIndex, new java.sql.Timestamp(((java.util.Date) inValue).getTime())); } } - else if (inValue instanceof Calendar) { - Calendar cal = (Calendar) inValue; + else if (inValue instanceof Calendar cal) { ps.setTimestamp(paramIndex, new java.sql.Timestamp(cal.getTime().getTime()), cal); } else { @@ -400,8 +396,7 @@ else if (sqlType == SqlTypeValue.TYPE_UNKNOWN || (sqlType == Types.OTHER && else if (isDateValue(inValue.getClass())) { ps.setTimestamp(paramIndex, new java.sql.Timestamp(((java.util.Date) inValue).getTime())); } - else if (inValue instanceof Calendar) { - Calendar cal = (Calendar) inValue; + else if (inValue instanceof Calendar cal) { ps.setTimestamp(paramIndex, new java.sql.Timestamp(cal.getTime().getTime()), cal); } else { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java index 5228cb9b05cd..85c3bc65fcc6 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java @@ -56,7 +56,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { /** the name of the user currently connected. */ @Nullable - private String userName; + private final String userName; /** indicates whether the identifiers are uppercased. */ private boolean storesUpperCaseIdentifiers = true; @@ -71,11 +71,11 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { private boolean generatedKeysColumnNameArraySupported = true; /** database products we know not supporting the use of a String[] for generated keys. */ - private List productsNotSupportingGeneratedKeysColumnNameArray = + private final List productsNotSupportingGeneratedKeysColumnNameArray = Arrays.asList("Apache Derby", "HSQL Database Engine"); /** Collection of TableParameterMetaData objects. */ - private List tableParameterMetaData = new ArrayList<>(); + private final List tableParameterMetaData = new ArrayList<>(); /** diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java index 1325cdedf5e7..981dfc22e7fb 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java @@ -293,8 +293,7 @@ public static String substituteNamedParameters(ParsedSql parsedSql, @Nullable Sq } k++; Object entryItem = entryIter.next(); - if (entryItem instanceof Object[]) { - Object[] expressionList = (Object[]) entryItem; + if (entryItem instanceof Object[] expressionList) { actualSql.append('('); for (int m = 0; m < expressionList.length; m++) { if (m > 0) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java index ae708030bcc1..6f14c748e0d9 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java @@ -474,7 +474,7 @@ private static class ConnectionSynchronization implements TransactionSynchroniza private final DataSource dataSource; - private int order; + private final int order; private boolean holderActive = true; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.java index 52b66888b968..afc49cadd8fb 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -185,8 +185,7 @@ protected void initDatabase() { this.dataSource = this.dataSourceFactory.getDataSource(); if (logger.isInfoEnabled()) { - if (this.dataSource instanceof SimpleDriverDataSource) { - SimpleDriverDataSource simpleDriverDataSource = (SimpleDriverDataSource) this.dataSource; + if (this.dataSource instanceof SimpleDriverDataSource simpleDriverDataSource) { logger.info(String.format("Starting embedded database: url='%s', username='%s'", simpleDriverDataSource.getUrl(), simpleDriverDataSource.getUsername())); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/IsolationLevelDataSourceRouter.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/IsolationLevelDataSourceRouter.java index b008aabf3d54..6e5cd3c67b81 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/IsolationLevelDataSourceRouter.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/IsolationLevelDataSourceRouter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -106,8 +106,7 @@ protected Object resolveSpecifiedLookupKey(Object lookupKey) { if (lookupKey instanceof Integer) { return lookupKey; } - else if (lookupKey instanceof String) { - String constantName = (String) lookupKey; + else if (lookupKey instanceof String constantName) { if (!constantName.startsWith(DefaultTransactionDefinition.PREFIX_ISOLATION)) { throw new IllegalArgumentException("Only isolation constants allowed"); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java index 6fe7e9ea125a..1fbeb253708e 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -285,12 +285,10 @@ public static Object getResultSetValue(ResultSet rs, int index) throws SQLExcept if (obj != null) { className = obj.getClass().getName(); } - if (obj instanceof Blob) { - Blob blob = (Blob) obj; + if (obj instanceof Blob blob) { obj = blob.getBytes(1, (int) blob.length()); } - else if (obj instanceof Clob) { - Clob clob = (Clob) obj; + else if (obj instanceof Clob clob) { obj = clob.getSubString(1, (int) clob.length()); } else if ("oracle.sql.TIMESTAMP".equals(className) || "oracle.sql.TIMESTAMPTZ".equals(className)) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughBlob.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughBlob.java index ad50eeb94e65..099bd27391cc 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughBlob.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughBlob.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ class PassThroughBlob implements Blob { @Nullable private InputStream binaryStream; - private long contentLength; + private final long contentLength; public PassThroughBlob(byte[] content) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughClob.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughClob.java index 0f4d25a12d2d..b9a27afe922e 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughClob.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughClob.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,7 +50,7 @@ class PassThroughClob implements Clob { @Nullable private InputStream asciiStream; - private long contentLength; + private final long contentLength; public PassThroughClob(String content) { From d70a610a0d2794d53110064b76c749ed45d3059a Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 19:58:22 +0200 Subject: [PATCH 261/735] Apply "instanceof pattern matching" in spring-jms This commit also applies additional clean-up tasks such as the following. - final fields This has only been applied to `src/main/java`. --- .../jms/connection/CachingConnectionFactory.java | 3 +-- .../UserCredentialsConnectionFactoryAdapter.java | 8 +++----- .../listener/AbstractPollingMessageListenerContainer.java | 4 ++-- .../adapter/AbstractAdaptableMessageListener.java | 5 ++--- .../springframework/jms/listener/adapter/JmsResponse.java | 5 ++--- .../java/org/springframework/jms/support/QosSettings.java | 5 ++--- .../converter/MappingJackson2MessageConverter.java | 5 ++--- .../support/converter/MarshallingMessageConverter.java | 8 +++----- .../jms/support/converter/MessagingMessageConverter.java | 6 +++--- 9 files changed, 20 insertions(+), 29 deletions(-) diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java b/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java index 109762e0888d..3ad92bf33cb1 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java @@ -598,10 +598,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ConsumerCacheKey)) { + if (!(other instanceof ConsumerCacheKey otherKey)) { return false; } - ConsumerCacheKey otherKey = (ConsumerCacheKey) other; return (destinationEquals(otherKey) && ObjectUtils.nullSafeEquals(this.selector, otherKey.selector) && ObjectUtils.nullSafeEquals(this.noLocal, otherKey.noLocal) && diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java b/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java index d781e30997a6..657c0862f8a5 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -232,10 +232,9 @@ protected QueueConnection doCreateQueueConnection( @Nullable String username, @Nullable String password) throws JMSException { ConnectionFactory target = obtainTargetConnectionFactory(); - if (!(target instanceof QueueConnectionFactory)) { + if (!(target instanceof QueueConnectionFactory queueFactory)) { throw new jakarta.jms.IllegalStateException("'targetConnectionFactory' is not a QueueConnectionFactory"); } - QueueConnectionFactory queueFactory = (QueueConnectionFactory) target; if (StringUtils.hasLength(username)) { return queueFactory.createQueueConnection(username, password); } @@ -284,10 +283,9 @@ protected TopicConnection doCreateTopicConnection( @Nullable String username, @Nullable String password) throws JMSException { ConnectionFactory target = obtainTargetConnectionFactory(); - if (!(target instanceof TopicConnectionFactory)) { + if (!(target instanceof TopicConnectionFactory queueFactory)) { throw new jakarta.jms.IllegalStateException("'targetConnectionFactory' is not a TopicConnectionFactory"); } - TopicConnectionFactory queueFactory = (TopicConnectionFactory) target; if (StringUtils.hasLength(username)) { return queueFactory.createTopicConnection(username, password); } diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractPollingMessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractPollingMessageListenerContainer.java index e681aaef1b19..7d5de80078e1 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractPollingMessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractPollingMessageListenerContainer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -90,7 +90,7 @@ public abstract class AbstractPollingMessageListenerContainer extends AbstractMe @Nullable private PlatformTransactionManager transactionManager; - private DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition(); + private final DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition(); private long receiveTimeout = DEFAULT_RECEIVE_TIMEOUT; diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java index 0bfec3872626..0cd9bf2bd8e6 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -411,8 +411,7 @@ protected Destination resolveDefaultResponseDestination(Session session) throws if (this.defaultResponseDestination instanceof Destination) { return (Destination) this.defaultResponseDestination; } - if (this.defaultResponseDestination instanceof DestinationNameHolder) { - DestinationNameHolder nameHolder = (DestinationNameHolder) this.defaultResponseDestination; + if (this.defaultResponseDestination instanceof DestinationNameHolder nameHolder) { return getDestinationResolver().resolveDestinationName(session, nameHolder.name, nameHolder.isTopic); } return null; diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/JmsResponse.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/JmsResponse.java index 16564a3b6c2e..2fdaca138416 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/JmsResponse.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/JmsResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -94,8 +94,7 @@ public Destination resolveDestination(DestinationResolver destinationResolver, S if (this.destination instanceof Destination) { return (Destination) this.destination; } - if (this.destination instanceof DestinationNameHolder) { - DestinationNameHolder nameHolder = (DestinationNameHolder) this.destination; + if (this.destination instanceof DestinationNameHolder nameHolder) { return destinationResolver.resolveDestinationName(session, nameHolder.destinationName, nameHolder.pubSubDomain); } diff --git a/spring-jms/src/main/java/org/springframework/jms/support/QosSettings.java b/spring-jms/src/main/java/org/springframework/jms/support/QosSettings.java index 2cd329fff708..9f627cf08999 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/QosSettings.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/QosSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -114,11 +114,10 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof QosSettings)) { + if (!(other instanceof QosSettings otherSettings)) { return false; } - QosSettings otherSettings = (QosSettings) other; return (this.deliveryMode == otherSettings.deliveryMode && this.priority == otherSettings.priority && this.timeToLive == otherSettings.timeToLive); diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java index 7b6c3370aed1..429343f6b235 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java @@ -85,7 +85,7 @@ public class MappingJackson2MessageConverter implements SmartMessageConverter, B private Map> idClassMappings = new HashMap<>(); - private Map, String> classIdMappings = new HashMap<>(); + private final Map, String> classIdMappings = new HashMap<>(); @Nullable private ClassLoader beanClassLoader; @@ -476,8 +476,7 @@ protected JavaType getJavaTypeForMessage(Message message) throws JMSException { */ @Nullable protected Class getSerializationView(@Nullable Object conversionHint) { - if (conversionHint instanceof MethodParameter) { - MethodParameter methodParam = (MethodParameter) conversionHint; + if (conversionHint instanceof MethodParameter methodParam) { JsonView annotation = methodParam.getParameterAnnotation(JsonView.class); if (annotation == null) { annotation = methodParam.getMethodAnnotation(JsonView.class); diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java index b420ec92c6b0..e8524239e9e4 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -178,12 +178,10 @@ public Message toMessage(Object object, Session session) throws JMSException, Me public Object fromMessage(Message message) throws JMSException, MessageConversionException { Assert.state(this.unmarshaller != null, "No Unmarshaller set"); try { - if (message instanceof TextMessage) { - TextMessage textMessage = (TextMessage) message; + if (message instanceof TextMessage textMessage) { return unmarshalFromTextMessage(textMessage, this.unmarshaller); } - else if (message instanceof BytesMessage) { - BytesMessage bytesMessage = (BytesMessage) message; + else if (message instanceof BytesMessage bytesMessage) { return unmarshalFromBytesMessage(bytesMessage, this.unmarshaller); } else { diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MessagingMessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MessagingMessageConverter.java index 98e8ad026395..70daf59e493d 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MessagingMessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MessagingMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ import org.springframework.lang.Nullable; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; -import org.springframework.messaging.core.AbstractMessagingTemplate; +import org.springframework.messaging.core.AbstractMessageSendingTemplate; import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.Assert; @@ -107,7 +107,7 @@ public jakarta.jms.Message toMessage(Object object, Session session) throws JMSE } Message input = (Message) object; MessageHeaders headers = input.getHeaders(); - Object conversionHint = headers.get(AbstractMessagingTemplate.CONVERSION_HINT_HEADER); + Object conversionHint = headers.get(AbstractMessageSendingTemplate.CONVERSION_HINT_HEADER); jakarta.jms.Message reply = createMessageForPayload(input.getPayload(), session, conversionHint); this.headerMapper.fromHeaders(headers, reply); return reply; From 1cd70bbe6b25b01d185a5283a223795395f33e27 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 20:15:10 +0200 Subject: [PATCH 262/735] Apply "instanceof pattern matching" in spring-messaging This commit also applies additional clean-up tasks such as the following. - final fields - diamond operator (<>) for anonymous inner classes - for-each loop This has only been applied to `src/main/java`. --- .../converter/AbstractMessageConverter.java | 5 ++--- .../converter/MappingJackson2MessageConverter.java | 3 +-- .../handler/CompositeMessageCondition.java | 5 ++--- .../messaging/handler/HandlerMethod.java | 3 +-- .../support/MessageMethodArgumentResolver.java | 5 ++--- .../support/PayloadMethodArgumentResolver.java | 5 ++--- .../invocation/AbstractMethodMessageHandler.java | 3 +-- .../HandlerMethodReturnValueHandlerComposite.java | 5 ++--- .../reactive/AbstractMethodMessageHandler.java | 2 +- .../HandlerMethodReturnValueHandlerComposite.java | 5 ++--- .../reactive/InvocableHandlerMethod.java | 5 ++--- .../rsocket/DefaultRSocketRequesterBuilder.java | 6 +++--- .../support/SendToMethodReturnValueHandler.java | 8 ++++---- .../SubscriptionMethodReturnValueHandler.java | 6 +++--- .../simp/broker/AbstractBrokerMessageHandler.java | 4 ++-- .../simp/broker/DefaultSubscriptionRegistry.java | 8 ++++---- .../broker/OrderedMessageChannelDecorator.java | 5 ++--- .../simp/stomp/StompBrokerRelayMessageHandler.java | 2 ++ .../messaging/simp/stomp/StompEncoder.java | 10 ++++++---- .../simp/user/MultiServerUserRegistry.java | 7 +++---- .../simp/user/UserDestinationMessageHandler.java | 8 +++++--- .../messaging/support/MessageHeaderAccessor.java | 14 +++++--------- 22 files changed, 57 insertions(+), 67 deletions(-) diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/AbstractMessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/AbstractMessageConverter.java index b8400e046c89..6a8386fbb439 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/AbstractMessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/AbstractMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -314,8 +314,7 @@ protected Object convertToInternal( static Type getResolvedType(Class targetClass, @Nullable Object conversionHint) { - if (conversionHint instanceof MethodParameter) { - MethodParameter param = (MethodParameter) conversionHint; + if (conversionHint instanceof MethodParameter param) { param = param.nestedIfOptional(); if (Message.class.isAssignableFrom(param.getParameterType())) { param = param.nested(); 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 9bb32eebd942..008d0b5ba759 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 @@ -285,8 +285,7 @@ protected Object convertToInternal(Object payload, @Nullable MessageHeaders head */ @Nullable protected Class getSerializationView(@Nullable Object conversionHint) { - if (conversionHint instanceof MethodParameter) { - MethodParameter param = (MethodParameter) conversionHint; + if (conversionHint instanceof MethodParameter param) { JsonView annotation = (param.getParameterIndex() >= 0 ? param.getParameterAnnotation(JsonView.class) : param.getMethodAnnotation(JsonView.class)); if (annotation != null) { diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/CompositeMessageCondition.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/CompositeMessageCondition.java index 4a70d4f6a91e..4d4d21614b99 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/CompositeMessageCondition.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/CompositeMessageCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -131,10 +131,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof CompositeMessageCondition)) { + if (!(other instanceof CompositeMessageCondition otherComposite)) { return false; } - CompositeMessageCondition otherComposite = (CompositeMessageCondition) other; checkCompatible(otherComposite); List> otherConditions = otherComposite.getMessageConditions(); for (int i = 0; i < this.messageConditions.size(); i++) { 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 4ace844929fb..d254f5d5c0d2 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 @@ -308,10 +308,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof HandlerMethod)) { + if (!(other instanceof HandlerMethod otherMethod)) { return false; } - HandlerMethod otherMethod = (HandlerMethod) other; return (this.bean.equals(otherMethod.bean) && this.method.equals(otherMethod.method)); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java index fcbe59313223..8b0e23fb7edf 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -134,8 +134,7 @@ else if (payload instanceof String) { private Object convertPayload(Message message, MethodParameter parameter, Class targetPayloadType) { Object result = null; - if (this.converter instanceof SmartMessageConverter) { - SmartMessageConverter smartConverter = (SmartMessageConverter) this.converter; + if (this.converter instanceof SmartMessageConverter smartConverter) { result = smartConverter.fromMessage(message, targetPayloadType, parameter); } else if (this.converter != null) { diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java index 92e5d5ecc9f5..9e14cb324eee 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -133,8 +133,7 @@ public Object resolveArgument(MethodParameter parameter, Message message) thr return payload; } else { - if (this.converter instanceof SmartMessageConverter) { - SmartMessageConverter smartConverter = (SmartMessageConverter) this.converter; + if (this.converter instanceof SmartMessageConverter smartConverter) { payload = smartConverter.fromMessage(message, targetClass, parameter); } else { diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java index f160d506eed7..b1b0da1f7f3a 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java @@ -478,8 +478,7 @@ protected String getLookupDestination(@Nullable String destination) { if (CollectionUtils.isEmpty(this.destinationPrefixes)) { return destination; } - for (int i = 0; i < this.destinationPrefixes.size(); i++) { - String prefix = this.destinationPrefixes.get(i); + for (String prefix : this.destinationPrefixes) { if (destination.startsWith(prefix)) { return destination.substring(prefix.length()); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/HandlerMethodReturnValueHandlerComposite.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/HandlerMethodReturnValueHandlerComposite.java index 645538e8273b..af3efda05c66 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/HandlerMethodReturnValueHandlerComposite.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/HandlerMethodReturnValueHandlerComposite.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -104,8 +104,7 @@ public boolean supportsReturnType(MethodParameter returnType) { @SuppressWarnings("ForLoopReplaceableByForEach") @Nullable private HandlerMethodReturnValueHandler getReturnValueHandler(MethodParameter returnType) { - for (int i = 0; i < this.returnValueHandlers.size(); i++) { - HandlerMethodReturnValueHandler handler = this.returnValueHandlers.get(i); + for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) { if (handler.supportsReturnType(returnType)) { return handler; } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java index a240f4d8efa0..f59fde59ec48 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java @@ -512,7 +512,7 @@ private void addMatchesToCollection( for (T mapping : mappingsToCheck) { T match = getMatchingMapping(mapping, message); if (match != null) { - matches.add(new Match(match, this.handlerMethods.get(mapping))); + matches.add(new Match<>(match, this.handlerMethods.get(mapping))); } } } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/HandlerMethodReturnValueHandlerComposite.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/HandlerMethodReturnValueHandlerComposite.java index c9347256b0e5..724fc8b650d0 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/HandlerMethodReturnValueHandlerComposite.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/HandlerMethodReturnValueHandlerComposite.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -95,8 +95,7 @@ public Mono handleReturnValue(@Nullable Object returnValue, MethodParamete @SuppressWarnings("ForLoopReplaceableByForEach") @Nullable private HandlerMethodReturnValueHandler getReturnValueHandler(MethodParameter returnType) { - for (int i = 0; i < this.returnValueHandlers.size(); i++) { - HandlerMethodReturnValueHandler handler = this.returnValueHandlers.get(i); + for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) { if (handler.supportsReturnType(returnType)) { return handler; } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/InvocableHandlerMethod.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/InvocableHandlerMethod.java index aad9384af251..3156c66a824f 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/InvocableHandlerMethod.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/InvocableHandlerMethod.java @@ -54,7 +54,7 @@ public class InvocableHandlerMethod extends HandlerMethod { private static final Object NO_ARG_VALUE = new Object(); - private HandlerMethodArgumentResolverComposite resolvers = new HandlerMethodArgumentResolverComposite(); + private final HandlerMethodArgumentResolverComposite resolvers = new HandlerMethodArgumentResolverComposite(); private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer(); @@ -206,8 +206,7 @@ private boolean isAsyncVoidReturnType(MethodParameter returnType, @Nullable Reac return true; } Type parameterType = returnType.getGenericParameterType(); - if (parameterType instanceof ParameterizedType) { - ParameterizedType type = (ParameterizedType) parameterType; + if (parameterType instanceof ParameterizedType type) { if (type.getActualTypeArguments().length == 1) { return Void.class.equals(type.getActualTypeArguments()[0]); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/DefaultRSocketRequesterBuilder.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/DefaultRSocketRequesterBuilder.java index 3c3ff332a976..c251b7dbcd1f 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/DefaultRSocketRequesterBuilder.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/DefaultRSocketRequesterBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -90,9 +90,9 @@ final class DefaultRSocketRequesterBuilder implements RSocketRequester.Builder { @Nullable private RSocketStrategies strategies; - private List> strategiesConfigurers = new ArrayList<>(); + private final List> strategiesConfigurers = new ArrayList<>(); - private List rsocketConnectorConfigurers = new ArrayList<>(); + private final List rsocketConnectorConfigurers = new ArrayList<>(); @Override diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java index 8a150a572f1d..f91f47bc5e7e 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.core.AbstractMessageSendingTemplate; import org.springframework.messaging.handler.DestinationPatternsMessageCondition; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.messaging.handler.annotation.support.DestinationVariableMethodArgumentResolver; @@ -35,7 +36,6 @@ import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.messaging.simp.SimpMessageSendingOperations; import org.springframework.messaging.simp.SimpMessageType; -import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.messaging.simp.annotation.SendToUser; import org.springframework.messaging.simp.user.DestinationUserNameProvider; import org.springframework.messaging.support.MessageHeaderInitializer; @@ -68,7 +68,7 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH private String defaultUserDestinationPrefix = "/queue"; - private PropertyPlaceholderHelper placeholderHelper = new PropertyPlaceholderHelper("{", "}", null, false); + private final PropertyPlaceholderHelper placeholderHelper = new PropertyPlaceholderHelper("{", "}", null, false); @Nullable private MessageHeaderInitializer headerInitializer; @@ -244,7 +244,7 @@ private MessageHeaders createHeaders(@Nullable String sessionId, MethodParameter if (sessionId != null) { headerAccessor.setSessionId(sessionId); } - headerAccessor.setHeader(SimpMessagingTemplate.CONVERSION_HINT_HEADER, returnType); + headerAccessor.setHeader(AbstractMessageSendingTemplate.CONVERSION_HINT_HEADER, returnType); headerAccessor.setLeaveMutable(true); return headerAccessor.getMessageHeaders(); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java index 5e2be5c3e971..8ff4d521a2fe 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,13 +22,13 @@ import org.springframework.lang.Nullable; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.core.AbstractMessageSendingTemplate; import org.springframework.messaging.core.MessageSendingOperations; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.messaging.handler.invocation.HandlerMethodReturnValueHandler; import org.springframework.messaging.simp.SimpLogging; import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.messaging.simp.SimpMessageType; -import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.messaging.simp.annotation.SendToUser; import org.springframework.messaging.simp.annotation.SubscribeMapping; import org.springframework.messaging.support.MessageHeaderInitializer; @@ -141,7 +141,7 @@ private MessageHeaders createHeaders(@Nullable String sessionId, String subscrip accessor.setSessionId(sessionId); } accessor.setSubscriptionId(subscriptionId); - accessor.setHeader(SimpMessagingTemplate.CONVERSION_HINT_HEADER, returnType); + accessor.setHeader(AbstractMessageSendingTemplate.CONVERSION_HINT_HEADER, returnType); accessor.setLeaveMutable(true); return accessor.getMessageHeaders(); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractBrokerMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractBrokerMessageHandler.java index 1babc663ebf5..19896834a929 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractBrokerMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractBrokerMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +67,7 @@ public abstract class AbstractBrokerMessageHandler @Nullable private ApplicationEventPublisher eventPublisher; - private AtomicBoolean brokerAvailable = new AtomicBoolean(); + private final AtomicBoolean brokerAvailable = new AtomicBoolean(); private final BrokerAvailabilityEvent availableEvent = new BrokerAvailabilityEvent(true, this); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistry.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistry.java index 709f88e4db1f..e46e34de6737 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistry.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,6 +41,7 @@ import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.messaging.support.MessageHeaderAccessor; +import org.springframework.messaging.support.NativeMessageHeaderAccessor; import org.springframework.util.AntPathMatcher; import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; @@ -162,7 +163,7 @@ private Expression getSelectorExpression(MessageHeaders headers) { if (getSelectorHeaderName() == null) { return null; } - String selector = SimpMessageHeaderAccessor.getFirstNativeHeader(getSelectorHeaderName(), headers); + String selector = NativeMessageHeaderAccessor.getFirstNativeHeader(getSelectorHeaderName(), headers); if (selector == null) { return null; } @@ -509,8 +510,7 @@ public TypedValue read(EvaluationContext context, @Nullable Object target, Strin if (target instanceof Message) { value = name.equals("headers") ? ((Message) target).getHeaders() : null; } - else if (target instanceof MessageHeaders) { - MessageHeaders headers = (MessageHeaders) target; + else if (target instanceof MessageHeaders headers) { SimpMessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(headers, SimpMessageHeaderAccessor.class); Assert.state(accessor != null, "No SimpMessageHeaderAccessor"); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/OrderedMessageChannelDecorator.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/OrderedMessageChannelDecorator.java index 7a55adde7c35..15fd1063eb7a 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/OrderedMessageChannelDecorator.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/OrderedMessageChannelDecorator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -154,8 +154,7 @@ public static void configureInterceptor(MessageChannel channel, boolean preserve execChannel.addInterceptor(0, new CallbackInterceptor()); } } - else if (channel instanceof ExecutorSubscribableChannel) { - ExecutorSubscribableChannel execChannel = (ExecutorSubscribableChannel) channel; + else if (channel instanceof ExecutorSubscribableChannel execChannel) { execChannel.getInterceptors().stream().filter(i -> i instanceof CallbackInterceptor) .findFirst().map(execChannel::removeInterceptor); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java index f756b0b1f9ea..343ef8696ee2 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java @@ -657,6 +657,7 @@ private RelayConnectionHandler(String sessionId, StompHeaderAccessor connectHead } + @Override public String getSessionId() { return this.sessionId; } @@ -984,6 +985,7 @@ protected void afterStompConnected(StompHeaderAccessor connectedHeaders) { sendSystemSubscriptions(); } + @Override protected void initHeartbeats(StompHeaderAccessor connectedHeaders) { TcpConnection con = getTcpConnection(); Assert.state(con != null, "No TcpConnection available"); 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 175043f586db..c4480b6fc2a7 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,7 +58,7 @@ public class StompEncoder { @SuppressWarnings("serial") private final Map headerKeyUpdateCache = - new LinkedHashMap(HEADER_KEY_CACHE_LIMIT, 0.75f, true) { + new LinkedHashMap<>(HEADER_KEY_CACHE_LIMIT, 0.75f, true) { @Override protected boolean removeEldestEntry(Map.Entry eldest) { if (size() > HEADER_KEY_CACHE_LIMIT) { @@ -236,22 +236,24 @@ private static class DefaultResult extends ArrayList implements Result { private int size; + @Override public void add(byte[] bytes) { this.size += bytes.length; super.add(bytes); } + @Override public void add(byte b) { this.size++; super.add(b); } + @Override public byte[] toByteArray() { byte[] result = new byte[this.size]; int position = 0; for (Object o : this) { - if (o instanceof byte[]) { - byte[] src = (byte[]) o; + if (o instanceof byte[] src) { System.arraycopy(src, 0, result, position, src.length); position += src.length; } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java index 5bc331d666af..c6f32b9f3cd5 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -275,7 +275,7 @@ private static class TransferSimpUser implements SimpUser { private String name = ""; // User sessions from "this" registry only (i.e. one server) - private Set sessions; + private final Set sessions; // Cross-server session lookup (e.g. user connected to multiple servers) @Nullable @@ -535,10 +535,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof SimpSubscription)) { + if (!(other instanceof SimpSubscription otherSubscription)) { return false; } - SimpSubscription otherSubscription = (SimpSubscription) other; return (getId().equals(otherSubscription.getId()) && ObjectUtils.nullSafeEquals(getSession(), otherSubscription.getSession())); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java index 4b80d09cde68..f6d0db3dd32b 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,9 @@ import org.springframework.messaging.simp.SimpMessageType; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.messaging.support.MessageBuilder; +import org.springframework.messaging.support.MessageHeaderAccessor; import org.springframework.messaging.support.MessageHeaderInitializer; +import org.springframework.messaging.support.NativeMessageHeaderAccessor; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -258,7 +260,7 @@ public Message preHandle(Message message) throws MessagingException { return message; } SimpMessageHeaderAccessor accessor = - SimpMessageHeaderAccessor.getAccessor(message, SimpMessageHeaderAccessor.class); + MessageHeaderAccessor.getAccessor(message, SimpMessageHeaderAccessor.class); Assert.state(accessor != null, "No SimpMessageHeaderAccessor"); if (accessor.getSessionId() == null) { // Our own broadcast @@ -284,7 +286,7 @@ public Message preHandle(Message message) throws MessagingException { public void handleUnresolved(Message message) { MessageHeaders headers = message.getHeaders(); - if (SimpMessageHeaderAccessor.getFirstNativeHeader( + if (NativeMessageHeaderAccessor.getFirstNativeHeader( SimpMessageHeaderAccessor.ORIGINAL_DESTINATION, headers) != null) { // Re-broadcast return; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java b/spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java index 95e04b63f489..a1f93eb7a403 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -495,14 +495,12 @@ public String getDetailedLogMessage(@Nullable Object payload) { } protected String getShortPayloadLogMessage(Object payload) { - if (payload instanceof String) { - String payloadText = (String) payload; + if (payload instanceof String payloadText) { return (payloadText.length() < 80) ? " payload=" + payloadText : " payload=" + payloadText.substring(0, 80) + "...(truncated)"; } - else if (payload instanceof byte[]) { - byte[] bytes = (byte[]) payload; + else if (payload instanceof byte[] bytes) { if (isReadableContentType()) { return (bytes.length < 80) ? " payload=" + new String(bytes, getCharset()) : @@ -524,8 +522,7 @@ protected String getDetailedPayloadLogMessage(@Nullable Object payload) { if (payload instanceof String) { return " payload=" + payload; } - else if (payload instanceof byte[]) { - byte[] bytes = (byte[]) payload; + else if (payload instanceof byte[] bytes) { if (isReadableContentType()) { return " payload=" + new String(bytes, getCharset()); } @@ -601,8 +598,7 @@ public static T getAccessor(Message message public static T getAccessor( MessageHeaders messageHeaders, @Nullable Class requiredType) { - if (messageHeaders instanceof MutableMessageHeaders) { - MutableMessageHeaders mutableHeaders = (MutableMessageHeaders) messageHeaders; + if (messageHeaders instanceof MutableMessageHeaders mutableHeaders) { MessageHeaderAccessor headerAccessor = mutableHeaders.getAccessor(); if (requiredType == null || requiredType.isInstance(headerAccessor)) { return (T) headerAccessor; From 40ead013fa9b33e5264338975142c0a0491b729e Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 21:53:47 +0200 Subject: [PATCH 263/735] Apply "instanceof pattern matching" in spring-orm This has only been applied to `src/main/java`. --- .../HibernateExceptionTranslator.java | 5 ++-- .../orm/hibernate5/SessionFactoryUtils.java | 23 +++++--------- .../orm/hibernate5/SpringSessionContext.java | 13 ++++---- .../jpa/AbstractEntityManagerFactoryBean.java | 13 ++++---- .../orm/jpa/EntityManagerFactoryAccessor.java | 5 ++-- .../orm/jpa/EntityManagerFactoryUtils.java | 6 ++-- .../orm/jpa/ExtendedEntityManagerCreator.java | 5 ++-- .../orm/jpa/JpaTransactionManager.java | 5 ++-- .../orm/jpa/SharedEntityManagerCreator.java | 8 ++--- ...ersistenceAnnotationBeanPostProcessor.java | 28 ++++++++--------- .../jpa/support/SharedEntityManagerBean.java | 5 ++-- .../orm/jpa/vendor/HibernateJpaDialect.java | 30 +++++++------------ 12 files changed, 58 insertions(+), 88 deletions(-) diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateExceptionTranslator.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateExceptionTranslator.java index 2f69163421f6..6b66360c22fc 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateExceptionTranslator.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateExceptionTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -90,8 +90,7 @@ public DataAccessException translateExceptionIfPossible(RuntimeException ex) { * @see SessionFactoryUtils#convertHibernateAccessException */ protected DataAccessException convertHibernateAccessException(HibernateException ex) { - if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException) { - JDBCException jdbcEx = (JDBCException) ex; + if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException jdbcEx) { DataAccessException dae = this.jdbcExceptionTranslator.translate( "Hibernate operation: " + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException()); if (dae != null) { diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java index 32cf2bc90e72..ce92d686ce55 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -159,8 +159,7 @@ public static DataSource getDataSource(SessionFactory sessionFactory) { } } } - if (sessionFactory instanceof SessionFactoryImplementor) { - SessionFactoryImplementor sfi = (SessionFactoryImplementor) sessionFactory; + if (sessionFactory instanceof SessionFactoryImplementor sfi) { try { ConnectionProvider cp = sfi.getServiceRegistry().getService(ConnectionProvider.class); if (cp != null) { @@ -188,29 +187,23 @@ public static DataAccessException convertHibernateAccessException(HibernateExcep if (ex instanceof JDBCConnectionException) { return new DataAccessResourceFailureException(ex.getMessage(), ex); } - if (ex instanceof SQLGrammarException) { - SQLGrammarException jdbcEx = (SQLGrammarException) ex; + if (ex instanceof SQLGrammarException jdbcEx) { return new InvalidDataAccessResourceUsageException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); } - if (ex instanceof QueryTimeoutException) { - QueryTimeoutException jdbcEx = (QueryTimeoutException) ex; + if (ex instanceof QueryTimeoutException jdbcEx) { return new org.springframework.dao.QueryTimeoutException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); } - if (ex instanceof LockAcquisitionException) { - LockAcquisitionException jdbcEx = (LockAcquisitionException) ex; + if (ex instanceof LockAcquisitionException jdbcEx) { return new CannotAcquireLockException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); } - if (ex instanceof PessimisticLockException) { - PessimisticLockException jdbcEx = (PessimisticLockException) ex; + if (ex instanceof PessimisticLockException jdbcEx) { return new PessimisticLockingFailureException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); } - if (ex instanceof ConstraintViolationException) { - ConstraintViolationException jdbcEx = (ConstraintViolationException) ex; + if (ex instanceof ConstraintViolationException jdbcEx) { return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]; constraint [" + jdbcEx.getConstraintName() + "]", ex); } - if (ex instanceof DataException) { - DataException jdbcEx = (DataException) ex; + if (ex instanceof DataException jdbcEx) { return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); } if (ex instanceof JDBCException) { diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java index a7a5e2f3d26a..ea814641ca2a 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -81,12 +81,11 @@ public SpringSessionContext(SessionFactoryImplementor sessionFactory) { @Override public Session currentSession() throws HibernateException { Object value = TransactionSynchronizationManager.getResource(this.sessionFactory); - if (value instanceof Session) { - return (Session) value; + if (value instanceof Session session) { + return session; } - else if (value instanceof SessionHolder) { + else if (value instanceof SessionHolder sessionHolder) { // HibernateTransactionManager - SessionHolder sessionHolder = (SessionHolder) value; Session session = sessionHolder.getSession(); if (!sessionHolder.isSynchronizedWithTransaction() && TransactionSynchronizationManager.isSynchronizationActive()) { @@ -104,9 +103,9 @@ else if (value instanceof SessionHolder) { } return session; } - else if (value instanceof EntityManagerHolder) { + else if (value instanceof EntityManagerHolder entityManagerHolder) { // JpaTransactionManager - return ((EntityManagerHolder) value).getEntityManager().unwrap(Session.class); + return entityManagerHolder.getEntityManager().unwrap(Session.class); } if (this.transactionManager != null && this.jtaSessionContext != null) { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java index 1a7328254610..1c85df6d06b8 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -501,12 +501,12 @@ else if (method.getName().equals("createEntityManager") && args != null && args. if (args != null) { for (int i = 0; i < args.length; i++) { Object arg = args[i]; - if (arg instanceof Query && Proxy.isProxyClass(arg.getClass())) { + if (arg instanceof Query query && Proxy.isProxyClass(arg.getClass())) { // Assumably a Spring-generated proxy from SharedEntityManagerCreator: // since we're passing it back to the native EntityManagerFactory, // let's unwrap it to the original Query object from the provider. try { - args[i] = ((Query) arg).unwrap(null); + args[i] = query.unwrap(null); } catch (RuntimeException ex) { // Ignore - simply proceed with given Query object then @@ -517,9 +517,8 @@ else if (method.getName().equals("createEntityManager") && args != null && args. // Standard delegation to the native factory, just post-processing EntityManager return values Object retVal = method.invoke(getNativeEntityManagerFactory(), args); - if (retVal instanceof EntityManager) { + if (retVal instanceof EntityManager rawEntityManager) { // Any other createEntityManager variant - expecting non-synchronized semantics - EntityManager rawEntityManager = (EntityManager) retVal; postProcessEntityManager(rawEntityManager); retVal = ExtendedEntityManagerCreator.createApplicationManagedEntityManager(rawEntityManager, this, false); } @@ -568,9 +567,9 @@ public EntityManagerFactory getNativeEntityManagerFactory() { } catch (ExecutionException ex) { Throwable cause = ex.getCause(); - if (cause instanceof PersistenceException) { + if (cause instanceof PersistenceException persistenceException) { // Rethrow a provider configuration exception (possibly with a nested cause) directly - throw (PersistenceException) cause; + throw persistenceException; } throw new IllegalStateException("Failed to asynchronously initialize native EntityManagerFactory: " + ex.getMessage(), cause); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryAccessor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryAccessor.java index 5f73add85814..045559a02f52 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryAccessor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -146,11 +146,10 @@ public Map getJpaPropertyMap() { @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { if (getEntityManagerFactory() == null) { - if (!(beanFactory instanceof ListableBeanFactory)) { + if (!(beanFactory instanceof ListableBeanFactory lbf)) { throw new IllegalStateException("Cannot retrieve EntityManagerFactory by persistence unit name " + "in a non-listable BeanFactory: " + beanFactory); } - ListableBeanFactory lbf = (ListableBeanFactory) beanFactory; setEntityManagerFactory(EntityManagerFactoryUtils.findEntityManagerFactory(lbf, getPersistenceUnitName())); } } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java index ceb470a9ea04..d8e515c16361 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java @@ -302,8 +302,7 @@ else if (!TransactionSynchronizationManager.isSynchronizationActive()) { */ @Nullable private static Object prepareTransaction(EntityManager em, EntityManagerFactory emf) { - if (emf instanceof EntityManagerFactoryInfo) { - EntityManagerFactoryInfo emfInfo = (EntityManagerFactoryInfo) emf; + if (emf instanceof EntityManagerFactoryInfo emfInfo) { JpaDialect jpaDialect = emfInfo.getJpaDialect(); if (jpaDialect != null) { return jpaDialect.prepareTransaction(em, @@ -322,8 +321,7 @@ private static Object prepareTransaction(EntityManager em, EntityManagerFactory * @see JpaDialect#cleanupTransaction */ private static void cleanupTransaction(@Nullable Object transactionData, EntityManagerFactory emf) { - if (emf instanceof EntityManagerFactoryInfo) { - EntityManagerFactoryInfo emfInfo = (EntityManagerFactoryInfo) emf; + if (emf instanceof EntityManagerFactoryInfo emfInfo) { JpaDialect jpaDialect = emfInfo.getJpaDialect(); if (jpaDialect != null) { jpaDialect.cleanupTransaction(transactionData); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java b/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java index 29b7a008ca93..452eb81b9678 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -169,8 +169,7 @@ public static EntityManager createContainerManagedEntityManager( EntityManagerFactory emf, @Nullable Map properties, boolean synchronizedWithTransaction) { Assert.notNull(emf, "EntityManagerFactory must not be null"); - if (emf instanceof EntityManagerFactoryInfo) { - EntityManagerFactoryInfo emfInfo = (EntityManagerFactoryInfo) emf; + if (emf instanceof EntityManagerFactoryInfo emfInfo) { EntityManager rawEntityManager = emfInfo.createNativeEntityManager(properties); return createProxy(rawEntityManager, emfInfo, true, synchronizedWithTransaction); } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaTransactionManager.java b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaTransactionManager.java index 79e48b7d0f32..3c02cc2d11ef 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaTransactionManager.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaTransactionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -326,11 +326,10 @@ public void setEntityManagerInitializer(Consumer entityManagerIni @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { if (getEntityManagerFactory() == null) { - if (!(beanFactory instanceof ListableBeanFactory)) { + if (!(beanFactory instanceof ListableBeanFactory lbf)) { throw new IllegalStateException("Cannot retrieve EntityManagerFactory by persistence unit name " + "in a non-listable BeanFactory: " + beanFactory); } - ListableBeanFactory lbf = (ListableBeanFactory) beanFactory; setEntityManagerFactory(EntityManagerFactoryUtils.findEntityManagerFactory(lbf, getPersistenceUnitName())); } } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java index 26add517b036..0fb6acc3bab5 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -308,8 +308,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl // Invoke method on current EntityManager. try { Object result = method.invoke(target, args); - if (result instanceof Query) { - Query query = (Query) result; + if (result instanceof Query query) { if (isNewEm) { Class[] ifcs = cachedQueryInterfaces.computeIfAbsent(query.getClass(), key -> ClassUtils.getAllInterfacesForClass(key, this.proxyClassLoader)); @@ -419,8 +418,7 @@ else if (targetClass.isInstance(proxy)) { if (queryTerminatingMethods.contains(method.getName())) { // Actual execution of the query: close the EntityManager right // afterwards, since that was the only reason we kept it open. - if (this.outputParameters != null && this.target instanceof StoredProcedureQuery) { - StoredProcedureQuery storedProc = (StoredProcedureQuery) this.target; + if (this.outputParameters != null && this.target instanceof StoredProcedureQuery storedProc) { for (Map.Entry entry : this.outputParameters.entrySet()) { try { Object key = entry.getKey(); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java index 20747130ac71..3f8171c84b60 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -324,8 +324,8 @@ public int getOrder() { @Override public void setBeanFactory(BeanFactory beanFactory) { - if (beanFactory instanceof ListableBeanFactory) { - this.beanFactory = (ListableBeanFactory) beanFactory; + if (beanFactory instanceof ListableBeanFactory lbf) { + this.beanFactory = lbf; } } @@ -543,8 +543,8 @@ protected EntityManagerFactory findNamedEntityManagerFactory(String unitName, @N Assert.state(this.beanFactory != null, "ListableBeanFactory required for EntityManagerFactory bean lookup"); EntityManagerFactory emf = EntityManagerFactoryUtils.findEntityManagerFactory(this.beanFactory, unitName); - if (requestingBeanName != null && this.beanFactory instanceof ConfigurableBeanFactory) { - ((ConfigurableBeanFactory) this.beanFactory).registerDependentBean(unitName, requestingBeanName); + if (requestingBeanName != null && this.beanFactory instanceof ConfigurableBeanFactory cbf) { + cbf.registerDependentBean(unitName, requestingBeanName); } return emf; } @@ -559,9 +559,8 @@ protected EntityManagerFactory findDefaultEntityManagerFactory(@Nullable String Assert.state(this.beanFactory != null, "ListableBeanFactory required for EntityManagerFactory bean lookup"); - if (this.beanFactory instanceof ConfigurableListableBeanFactory) { + if (this.beanFactory instanceof ConfigurableListableBeanFactory clbf) { // Fancy variant with dependency registration - ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) this.beanFactory; NamedBeanHolder emfHolder = clbf.resolveNamedBean(EntityManagerFactory.class); if (requestingBeanName != null) { clbf.registerDependentBean(emfHolder.getBeanName(), requestingBeanName); @@ -596,11 +595,11 @@ private class LocatorDelegate { public T lookup(String jndiName, Class requiredType) throws Exception { JndiLocatorDelegate locator = new JndiLocatorDelegate(); - if (jndiEnvironment instanceof JndiTemplate) { - locator.setJndiTemplate((JndiTemplate) jndiEnvironment); + if (jndiEnvironment instanceof JndiTemplate jndiTemplate) { + locator.setJndiTemplate(jndiTemplate); } - else if (jndiEnvironment instanceof Properties) { - locator.setJndiEnvironment((Properties) jndiEnvironment); + else if (jndiEnvironment instanceof Properties properties) { + locator.setJndiEnvironment(properties); } else if (jndiEnvironment != null) { throw new IllegalStateException("Illegal 'jndiEnvironment' type: " + jndiEnvironment.getClass()); @@ -696,8 +695,7 @@ private EntityManager resolveEntityManager(@Nullable String requestingBeanName) emf = findEntityManagerFactory(this.unitName, requestingBeanName); } // Inject a shared transactional EntityManager proxy. - if (emf instanceof EntityManagerFactoryInfo && - ((EntityManagerFactoryInfo) emf).getEntityManagerInterface() != null) { + if (emf instanceof EntityManagerFactoryInfo emfInfo && emfInfo.getEntityManagerInterface() != null) { // Create EntityManager based on the info's vendor-specific type // (which might be more specific than the field's type). em = SharedEntityManagerCreator.createSharedEntityManager( @@ -727,9 +725,9 @@ private EntityManager resolveExtendedEntityManager(Object target, @Nullable Stri em = ExtendedEntityManagerCreator.createContainerManagedEntityManager( emf, this.properties, this.synchronizedWithTransaction); } - if (em instanceof EntityManagerProxy && beanFactory != null && requestingBeanName != null && + if (em instanceof EntityManagerProxy emp && beanFactory != null && requestingBeanName != null && beanFactory.containsBean(requestingBeanName) && !beanFactory.isPrototype(requestingBeanName)) { - extendedEntityManagersToClose.put(target, ((EntityManagerProxy) em).getTargetEntityManager()); + extendedEntityManagersToClose.put(target, emp.getTargetEntityManager()); } return em; } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/SharedEntityManagerBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/SharedEntityManagerBean.java index a3f465dc68d9..0b460b000014 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/SharedEntityManagerBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/SharedEntityManagerBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -89,8 +89,7 @@ public final void afterPropertiesSet() { if (emf == null) { throw new IllegalArgumentException("'entityManagerFactory' or 'persistenceUnitName' is required"); } - if (emf instanceof EntityManagerFactoryInfo) { - EntityManagerFactoryInfo emfInfo = (EntityManagerFactoryInfo) emf; + if (emf instanceof EntityManagerFactoryInfo emfInfo) { if (this.entityManagerInterface == null) { this.entityManagerInterface = emfInfo.getEntityManagerInterface(); if (this.entityManagerInterface == null) { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java index a87bf44b6519..acf70e0909c5 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java @@ -241,8 +241,7 @@ public DataAccessException translateExceptionIfPossible(RuntimeException ex) { * @return the corresponding DataAccessException instance */ protected DataAccessException convertHibernateAccessException(HibernateException ex) { - if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException) { - JDBCException jdbcEx = (JDBCException) ex; + if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException jdbcEx) { DataAccessException dae = this.jdbcExceptionTranslator.translate( "Hibernate operation: " + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException()); if (dae != null) { @@ -253,29 +252,23 @@ protected DataAccessException convertHibernateAccessException(HibernateException if (ex instanceof JDBCConnectionException) { return new DataAccessResourceFailureException(ex.getMessage(), ex); } - if (ex instanceof SQLGrammarException) { - SQLGrammarException jdbcEx = (SQLGrammarException) ex; + if (ex instanceof SQLGrammarException jdbcEx) { return new InvalidDataAccessResourceUsageException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); } - if (ex instanceof QueryTimeoutException) { - QueryTimeoutException jdbcEx = (QueryTimeoutException) ex; + if (ex instanceof QueryTimeoutException jdbcEx) { return new org.springframework.dao.QueryTimeoutException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); } - if (ex instanceof LockAcquisitionException) { - LockAcquisitionException jdbcEx = (LockAcquisitionException) ex; + if (ex instanceof LockAcquisitionException jdbcEx) { return new CannotAcquireLockException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); } - if (ex instanceof PessimisticLockException) { - PessimisticLockException jdbcEx = (PessimisticLockException) ex; + if (ex instanceof PessimisticLockException jdbcEx) { return new PessimisticLockingFailureException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); } - if (ex instanceof ConstraintViolationException) { - ConstraintViolationException jdbcEx = (ConstraintViolationException) ex; + if (ex instanceof ConstraintViolationException jdbcEx) { return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]; constraint [" + jdbcEx.getConstraintName() + "]", ex); } - if (ex instanceof DataException) { - DataException jdbcEx = (DataException) ex; + if (ex instanceof DataException jdbcEx) { return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex); } // end of JDBCException subclass handling @@ -301,16 +294,13 @@ protected DataAccessException convertHibernateAccessException(HibernateException if (ex instanceof ObjectDeletedException) { return new InvalidDataAccessApiUsageException(ex.getMessage(), ex); } - if (ex instanceof UnresolvableObjectException) { - UnresolvableObjectException hibEx = (UnresolvableObjectException) ex; + if (ex instanceof UnresolvableObjectException hibEx) { return new ObjectRetrievalFailureException(hibEx.getEntityName(), hibEx.getIdentifier(), ex.getMessage(), ex); } - if (ex instanceof WrongClassException) { - WrongClassException hibEx = (WrongClassException) ex; + if (ex instanceof WrongClassException hibEx) { return new ObjectRetrievalFailureException(hibEx.getEntityName(), hibEx.getIdentifier(), ex.getMessage(), ex); } - if (ex instanceof StaleObjectStateException) { - StaleObjectStateException hibEx = (StaleObjectStateException) ex; + if (ex instanceof StaleObjectStateException hibEx) { return new ObjectOptimisticLockingFailureException(hibEx.getEntityName(), hibEx.getIdentifier(), ex); } if (ex instanceof StaleStateException) { From 9b4f3880b3a0090ecaa78a6e9ffab37d8e2ae7fc Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 22:06:55 +0200 Subject: [PATCH 264/735] Apply "instanceof pattern matching" in spring-oxm This has only been applied to `src/main/java`. --- .../oxm/jaxb/Jaxb2Marshaller.java | 19 +++--- .../oxm/xstream/XStreamMarshaller.java | 61 ++++++++----------- 2 files changed, 34 insertions(+), 46 deletions(-) diff --git a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java index 7267f311cc08..4b30aad1e06d 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java @@ -111,6 +111,7 @@ * @author Arjen Poutsma * @author Juergen Hoeller * @author Rossen Stoyanchev + * @author Sam Brannen * @since 3.0 * @see #setContextPath * @see #setClassesToBeBound @@ -607,25 +608,21 @@ public boolean supports(Class clazz) { @Override public boolean supports(Type genericType) { - if (genericType instanceof ParameterizedType) { - ParameterizedType parameterizedType = (ParameterizedType) genericType; + if (genericType instanceof ParameterizedType parameterizedType) { if (JAXBElement.class == parameterizedType.getRawType() && parameterizedType.getActualTypeArguments().length == 1) { Type typeArgument = parameterizedType.getActualTypeArguments()[0]; - if (typeArgument instanceof Class) { - Class classArgument = (Class) typeArgument; + if (typeArgument instanceof Class classArgument) { return ((classArgument.isArray() && Byte.TYPE == classArgument.getComponentType()) || isPrimitiveWrapper(classArgument) || isStandardClass(classArgument) || supportsInternal(classArgument, false)); } - else if (typeArgument instanceof GenericArrayType) { - GenericArrayType arrayType = (GenericArrayType) typeArgument; + else if (typeArgument instanceof GenericArrayType arrayType) { return (Byte.TYPE == arrayType.getGenericComponentType()); } } } - else if (genericType instanceof Class) { - Class clazz = (Class) genericType; + else if (genericType instanceof Class clazz) { return supportsInternal(clazz, this.checkForXmlRootElement); } return false; @@ -866,13 +863,11 @@ private Source processSource(Source source) { XMLReader xmlReader = null; InputSource inputSource = null; - if (source instanceof SAXSource) { - SAXSource saxSource = (SAXSource) source; + if (source instanceof SAXSource saxSource) { xmlReader = saxSource.getXMLReader(); inputSource = saxSource.getInputSource(); } - else if (source instanceof StreamSource) { - StreamSource streamSource = (StreamSource) source; + else if (source instanceof StreamSource streamSource) { if (streamSource.getInputStream() != null) { inputSource = new InputSource(streamSource.getInputStream()); } diff --git a/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java index 342f9a41edac..3a3356d485cb 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java @@ -253,8 +253,8 @@ public void setMapperWrappers(Class... mapperWrappers) */ public void setConverterLookup(ConverterLookup converterLookup) { this.converterLookup = converterLookup; - if (converterLookup instanceof ConverterRegistry) { - this.converterRegistry = (ConverterRegistry) converterLookup; + if (converterLookup instanceof ConverterRegistry registry) { + this.converterRegistry = registry; } } @@ -491,11 +491,11 @@ protected MapperWrapper wrapMapper(MapperWrapper next) { protected void configureXStream(XStream xstream) { if (this.converters != null) { for (int i = 0; i < this.converters.length; i++) { - if (this.converters[i] instanceof Converter) { - xstream.registerConverter((Converter) this.converters[i], i); + if (this.converters[i] instanceof Converter converter) { + xstream.registerConverter(converter, i); } - else if (this.converters[i] instanceof SingleValueConverter) { - xstream.registerConverter((SingleValueConverter) this.converters[i], i); + else if (this.converters[i] instanceof SingleValueConverter converter) { + xstream.registerConverter(converter, i); } else { throw new IllegalArgumentException("Invalid ConverterMatcher [" + this.converters[i] + "]"); @@ -553,26 +553,23 @@ else if (this.converters[i] instanceof SingleValueConverter) { } if (this.useAttributeFor != null) { for (Map.Entry entry : this.useAttributeFor.entrySet()) { - if (entry.getKey() instanceof String) { - if (entry.getValue() instanceof Class) { - xstream.useAttributeFor((String) entry.getKey(), (Class) entry.getValue()); + if (entry.getKey() instanceof String key) { + if (entry.getValue() instanceof Class clazz) { + xstream.useAttributeFor(key, clazz); } else { throw new IllegalArgumentException( "'useAttributesFor' takes Map when using a map key of type String"); } } - else if (entry.getKey() instanceof Class) { - Class key = (Class) entry.getKey(); - if (entry.getValue() instanceof String) { - xstream.useAttributeFor(key, (String) entry.getValue()); + else if (entry.getKey() instanceof Class key) { + if (entry.getValue() instanceof String value) { + xstream.useAttributeFor(key, value); } - else if (entry.getValue() instanceof List) { - @SuppressWarnings("unchecked") - List listValue = (List) entry.getValue(); + else if (entry.getValue() instanceof List listValue) { for (Object element : listValue) { - if (element instanceof String) { - xstream.useAttributeFor(key, (String) element); + if (element instanceof String value) { + xstream.useAttributeFor(key, value); } } } @@ -619,11 +616,10 @@ private Map> toClassMap(Map map) throws ClassNotFoun String key = entry.getKey(); Object value = entry.getValue(); Class type; - if (value instanceof Class) { - type = (Class) value; + if (value instanceof Class clazz) { + type = clazz; } - else if (value instanceof String) { - String className = (String) value; + else if (value instanceof String className) { type = ClassUtils.forName(className, this.beanClassLoader); } else { @@ -676,11 +672,11 @@ public boolean supports(Class clazz) { @Override protected void marshalDomNode(Object graph, Node node) throws XmlMappingException { HierarchicalStreamWriter streamWriter; - if (node instanceof Document) { - streamWriter = new DomWriter((Document) node, this.nameCoder); + if (node instanceof Document document) { + streamWriter = new DomWriter(document, this.nameCoder); } - else if (node instanceof Element) { - streamWriter = new DomWriter((Element) node, node.getOwnerDocument(), this.nameCoder); + else if (node instanceof Element element) { + streamWriter = new DomWriter(element, node.getOwnerDocument(), this.nameCoder); } else { throw new IllegalArgumentException("DOMResult contains neither Document nor Element"); @@ -691,10 +687,7 @@ else if (node instanceof Element) { @Override protected void marshalXmlEventWriter(Object graph, XMLEventWriter eventWriter) throws XmlMappingException { ContentHandler contentHandler = StaxUtils.createContentHandler(eventWriter); - LexicalHandler lexicalHandler = null; - if (contentHandler instanceof LexicalHandler) { - lexicalHandler = (LexicalHandler) contentHandler; - } + LexicalHandler lexicalHandler = (contentHandler instanceof LexicalHandler handler ? handler : null); marshalSaxHandlers(graph, contentHandler, lexicalHandler); } @@ -789,11 +782,11 @@ else if (streamSource.getReader() != null) { @Override protected Object unmarshalDomNode(Node node) throws XmlMappingException { HierarchicalStreamReader streamReader; - if (node instanceof Document) { - streamReader = new DomReader((Document) node, this.nameCoder); + if (node instanceof Document document) { + streamReader = new DomReader(document, this.nameCoder); } - else if (node instanceof Element) { - streamReader = new DomReader((Element) node, this.nameCoder); + else if (node instanceof Element element) { + streamReader = new DomReader(element, this.nameCoder); } else { throw new IllegalArgumentException("DOMSource contains neither Document nor Element"); From b8fc79543dd1a445aaf6f0e0daaa6dd28421f003 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 22:12:23 +0200 Subject: [PATCH 265/735] Polish tests and test fixtures in spring-test --- .../springframework/mock/web/MockHttpSessionTests.java | 2 +- .../test/context/TestContextConcurrencyTests.java | 2 +- .../test/context/cache/ContextCacheTests.java | 2 +- .../junit4/statements/SpringFailOnTimeoutTests.java | 2 +- .../springframework/test/util/subpackage/Component.java | 8 ++++---- .../test/java/org/springframework/test/web/Person.java | 3 +-- .../test/web/reactive/server/samples/Person.java | 8 ++++++-- .../web/servlet/result/PrintingResultHandlerTests.java | 2 +- .../test/web/servlet/samples/spr/EncodedUriTests.java | 4 +--- .../test/web/servlet/samples/spr/HttpOptionsTests.java | 2 +- .../samples/standalone/FrameworkExtensionTests.java | 2 +- 11 files changed, 19 insertions(+), 18 deletions(-) diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockHttpSessionTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockHttpSessionTests.java index d20693b2d204..602290d5597a 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockHttpSessionTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockHttpSessionTests.java @@ -34,7 +34,7 @@ */ class MockHttpSessionTests { - private MockHttpSession session = new MockHttpSession(); + private final MockHttpSession session = new MockHttpSession(); @Test diff --git a/spring-test/src/test/java/org/springframework/test/context/TestContextConcurrencyTests.java b/spring-test/src/test/java/org/springframework/test/context/TestContextConcurrencyTests.java index 80548d015c4f..4194f243b3e2 100644 --- a/spring-test/src/test/java/org/springframework/test/context/TestContextConcurrencyTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/TestContextConcurrencyTests.java @@ -118,7 +118,7 @@ void test_010() { private static class TrackingListener implements TestExecutionListener { - private ThreadLocal methodName = new ThreadLocal<>(); + private final ThreadLocal methodName = new ThreadLocal<>(); @Override diff --git a/spring-test/src/test/java/org/springframework/test/context/cache/ContextCacheTests.java b/spring-test/src/test/java/org/springframework/test/context/cache/ContextCacheTests.java index 202af4bb4b1b..c454e72ad9c5 100644 --- a/spring-test/src/test/java/org/springframework/test/context/cache/ContextCacheTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/cache/ContextCacheTests.java @@ -47,7 +47,7 @@ */ class ContextCacheTests { - private ContextCache contextCache = new DefaultContextCache(); + private final ContextCache contextCache = new DefaultContextCache(); @BeforeEach diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/statements/SpringFailOnTimeoutTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/statements/SpringFailOnTimeoutTests.java index 59f037e199e7..2c6627c0c672 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/statements/SpringFailOnTimeoutTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/statements/SpringFailOnTimeoutTests.java @@ -38,7 +38,7 @@ */ public class SpringFailOnTimeoutTests { - private Statement statement = mock(Statement.class); + private final Statement statement = mock(Statement.class); @Test diff --git a/spring-test/src/test/java/org/springframework/test/util/subpackage/Component.java b/spring-test/src/test/java/org/springframework/test/util/subpackage/Component.java index 676592741381..7260f3182da6 100644 --- a/spring-test/src/test/java/org/springframework/test/util/subpackage/Component.java +++ b/spring-test/src/test/java/org/springframework/test/util/subpackage/Component.java @@ -68,16 +68,16 @@ int subtract(int a, int b) { int add(int... args) { int sum = 0; - for (int i = 0; i < args.length; i++) { - sum += args[i]; + for (int arg : args) { + sum += arg; } return sum; } int multiply(Integer... args) { int product = 1; - for (int i = 0; i < args.length; i++) { - product *= args[i]; + for (Integer arg : args) { + product *= arg; } return product; } 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 2282b70dc304..5184cd0a9cd3 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 @@ -70,10 +70,9 @@ public boolean equals(Object other) { if (this == other) { return true; } - if (!(other instanceof Person)) { + if (!(other instanceof Person otherPerson)) { return false; } - Person otherPerson = (Person) other; return (ObjectUtils.nullSafeEquals(this.name, otherPerson.name) && ObjectUtils.nullSafeEquals(this.someDouble, otherPerson.someDouble) && ObjectUtils.nullSafeEquals(this.someBoolean, otherPerson.someBoolean)); diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/Person.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/Person.java index d99265f36a06..b56aebe8ebf0 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/Person.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/Person.java @@ -45,8 +45,12 @@ public String getName() { @Override public boolean equals(Object other) { - if (this == other) return true; - if (other == null || getClass() != other.getClass()) return false; + if (this == other) { + return true; + } + if (other == null || getClass() != other.getClass()) { + return false; + } Person person = (Person) other; return getName().equals(person.getName()); } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/result/PrintingResultHandlerTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/result/PrintingResultHandlerTests.java index c7c3cab6772f..e7ff36a4cf15 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/result/PrintingResultHandlerTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/result/PrintingResultHandlerTests.java @@ -347,7 +347,7 @@ private static class TestResultValuePrinter implements ResultValuePrinter { private String printedHeading; - private Map> printedValues = new HashMap<>(); + private final Map> printedValues = new HashMap<>(); @Override public void printHeading(String heading) { diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/EncodedUriTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/EncodedUriTests.java index aac7d7985be9..b67aeb493e2f 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/EncodedUriTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/EncodedUriTests.java @@ -117,9 +117,7 @@ private static class HandlerMappingConfigurer implements BeanPostProcessor, Prio @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof RequestMappingHandlerMapping) { - RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) bean; - + if (bean instanceof RequestMappingHandlerMapping requestMappingHandlerMapping) { // URL decode after request mapping, not before. requestMappingHandlerMapping.setUrlDecode(false); } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/HttpOptionsTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/HttpOptionsTests.java index 508c697c67b7..97f8f5a457bb 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/HttpOptionsTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/HttpOptionsTests.java @@ -86,7 +86,7 @@ public MyController myController() { @Controller private static class MyController { - private AtomicInteger counter = new AtomicInteger(); + private final AtomicInteger counter = new AtomicInteger(); @RequestMapping(value = "/myUrl", method = RequestMethod.OPTIONS) diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/FrameworkExtensionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/FrameworkExtensionTests.java index a18759bba83b..e98278f98c4b 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/FrameworkExtensionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/FrameworkExtensionTests.java @@ -85,7 +85,7 @@ private static TestRequestPostProcessor headers() { */ private static class TestRequestPostProcessor implements RequestPostProcessor { - private HttpHeaders headers = new HttpHeaders(); + private final HttpHeaders headers = new HttpHeaders(); public TestRequestPostProcessor foo(String value) { From e9cf645b86c39c66759492435e6d44b70736cee5 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 14 Oct 2021 22:18:01 +0200 Subject: [PATCH 266/735] Apply "instanceof pattern matching" in spring-tx This commit also applies additional clean-up tasks such as the following. - final fields This has only been applied to `src/main/java`. --- .../jca/support/SimpleBootstrapContext.java | 4 ++-- .../AnnotationTransactionAttributeSource.java | 5 ++--- .../AbstractFallbackTransactionAttributeSource.java | 5 ++--- .../MatchAlwaysTransactionAttributeSource.java | 9 ++++----- .../MethodMapTransactionAttributeSource.java | 9 ++++----- .../NameMatchTransactionAttributeSource.java | 13 ++++++------- .../interceptor/RollbackRuleAttribute.java | 5 ++--- .../TransactionAttributeSourcePointcut.java | 5 ++--- 8 files changed, 24 insertions(+), 31 deletions(-) diff --git a/spring-tx/src/main/java/org/springframework/jca/support/SimpleBootstrapContext.java b/spring-tx/src/main/java/org/springframework/jca/support/SimpleBootstrapContext.java index c607a6f2660a..fac8e45d5abe 100644 --- a/spring-tx/src/main/java/org/springframework/jca/support/SimpleBootstrapContext.java +++ b/spring-tx/src/main/java/org/springframework/jca/support/SimpleBootstrapContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ public class SimpleBootstrapContext implements BootstrapContext { @Nullable - private WorkManager workManager; + private final WorkManager workManager; @Nullable private XATerminator xaTerminator; diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java index 13f16a20e93e..5d4e2e939559 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java +++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -194,10 +194,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof AnnotationTransactionAttributeSource)) { + if (!(other instanceof AnnotationTransactionAttributeSource otherTas)) { return false; } - AnnotationTransactionAttributeSource otherTas = (AnnotationTransactionAttributeSource) other; return (this.annotationParsers.equals(otherTas.annotationParsers) && this.publicMethodsOnly == otherTas.publicMethodsOnly); } diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/AbstractFallbackTransactionAttributeSource.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/AbstractFallbackTransactionAttributeSource.java index 80983806eded..e50c9b52319a 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/AbstractFallbackTransactionAttributeSource.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/AbstractFallbackTransactionAttributeSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -128,8 +128,7 @@ public TransactionAttribute getTransactionAttribute(Method method, @Nullable Cla } else { String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass); - if (txAttr instanceof DefaultTransactionAttribute) { - DefaultTransactionAttribute dta = (DefaultTransactionAttribute) txAttr; + if (txAttr instanceof DefaultTransactionAttribute dta) { dta.setDescriptor(methodIdentification); dta.resolveAttributeStrings(this.embeddedValueResolver); } diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/MatchAlwaysTransactionAttributeSource.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/MatchAlwaysTransactionAttributeSource.java index c5698a7cb131..d1f068dbf4a4 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/MatchAlwaysTransactionAttributeSource.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/MatchAlwaysTransactionAttributeSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,8 +49,8 @@ public class MatchAlwaysTransactionAttributeSource implements TransactionAttribu * @see org.springframework.transaction.interceptor.TransactionAttributeEditor */ public void setTransactionAttribute(TransactionAttribute transactionAttribute) { - if (transactionAttribute instanceof DefaultTransactionAttribute) { - ((DefaultTransactionAttribute) transactionAttribute).resolveAttributeStrings(null); + if (transactionAttribute instanceof DefaultTransactionAttribute dta) { + dta.resolveAttributeStrings(null); } this.transactionAttribute = transactionAttribute; } @@ -68,10 +68,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof MatchAlwaysTransactionAttributeSource)) { + if (!(other instanceof MatchAlwaysTransactionAttributeSource otherTas)) { return false; } - MatchAlwaysTransactionAttributeSource otherTas = (MatchAlwaysTransactionAttributeSource) other; return ObjectUtils.nullSafeEquals(this.transactionAttribute, otherTas.transactionAttribute); } diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/MethodMapTransactionAttributeSource.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/MethodMapTransactionAttributeSource.java index 9407b1881a6c..e328a88a2eca 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/MethodMapTransactionAttributeSource.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/MethodMapTransactionAttributeSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -199,8 +199,8 @@ public void addTransactionalMethod(Method method, TransactionAttribute attr) { if (logger.isDebugEnabled()) { logger.debug("Adding transactional method [" + method + "] with attribute [" + attr + "]"); } - if (this.embeddedValueResolver != null && attr instanceof DefaultTransactionAttribute) { - ((DefaultTransactionAttribute) attr).resolveAttributeStrings(this.embeddedValueResolver); + if (this.embeddedValueResolver != null && attr instanceof DefaultTransactionAttribute dta) { + dta.resolveAttributeStrings(this.embeddedValueResolver); } this.transactionAttributeMap.put(method, attr); } @@ -242,10 +242,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof MethodMapTransactionAttributeSource)) { + if (!(other instanceof MethodMapTransactionAttributeSource otherTas)) { return false; } - MethodMapTransactionAttributeSource otherTas = (MethodMapTransactionAttributeSource) other; return ObjectUtils.nullSafeEquals(this.methodMap, otherTas.methodMap); } diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/NameMatchTransactionAttributeSource.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/NameMatchTransactionAttributeSource.java index b9c8996424cf..a0f4e15bf4b4 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/NameMatchTransactionAttributeSource.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/NameMatchTransactionAttributeSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -101,8 +101,8 @@ public void addTransactionalMethod(String methodName, TransactionAttribute attr) if (logger.isDebugEnabled()) { logger.debug("Adding transactional method [" + methodName + "] with attribute [" + attr + "]"); } - if (this.embeddedValueResolver != null && attr instanceof DefaultTransactionAttribute) { - ((DefaultTransactionAttribute) attr).resolveAttributeStrings(this.embeddedValueResolver); + if (this.embeddedValueResolver != null && attr instanceof DefaultTransactionAttribute dta) { + dta.resolveAttributeStrings(this.embeddedValueResolver); } this.nameMap.put(methodName, attr); } @@ -115,8 +115,8 @@ public void setEmbeddedValueResolver(StringValueResolver resolver) { @Override public void afterPropertiesSet() { for (TransactionAttribute attr : this.nameMap.values()) { - if (attr instanceof DefaultTransactionAttribute) { - ((DefaultTransactionAttribute) attr).resolveAttributeStrings(this.embeddedValueResolver); + if (attr instanceof DefaultTransactionAttribute dta) { + dta.resolveAttributeStrings(this.embeddedValueResolver); } } } @@ -167,10 +167,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof NameMatchTransactionAttributeSource)) { + if (!(other instanceof NameMatchTransactionAttributeSource otherTas)) { return false; } - NameMatchTransactionAttributeSource otherTas = (NameMatchTransactionAttributeSource) other; return ObjectUtils.nullSafeEquals(this.nameMap, otherTas.nameMap); } diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/RollbackRuleAttribute.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/RollbackRuleAttribute.java index e0552d41f21a..f9defeecd4b6 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/RollbackRuleAttribute.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/RollbackRuleAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -129,10 +129,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof RollbackRuleAttribute)) { + if (!(other instanceof RollbackRuleAttribute rhs)) { return false; } - RollbackRuleAttribute rhs = (RollbackRuleAttribute) other; return this.exceptionName.equals(rhs.exceptionName); } diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSourcePointcut.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSourcePointcut.java index ceef2bd82f94..a7cdc8867d02 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSourcePointcut.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSourcePointcut.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,10 +52,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof TransactionAttributeSourcePointcut)) { + if (!(other instanceof TransactionAttributeSourcePointcut otherPc)) { return false; } - TransactionAttributeSourcePointcut otherPc = (TransactionAttributeSourcePointcut) other; return ObjectUtils.nullSafeEquals(getTransactionAttributeSource(), otherPc.getTransactionAttributeSource()); } From 785212d67655119a71d3ad700e90c6e09e7c6361 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 17 Oct 2021 12:58:25 +0200 Subject: [PATCH 267/735] Apply "instanceof pattern matching" in spring-web This commit also applies additional clean-up tasks such as the following. - final fields - diamond operator (<>) for anonymous inner classes - try with resources This has only been applied to `src/main/java`. --- .../http/ContentDisposition.java | 3 +- .../org/springframework/http/HttpCookie.java | 5 +-- .../org/springframework/http/HttpRange.java | 8 ++-- .../org/springframework/http/MediaType.java | 6 +-- .../springframework/http/ResponseCookie.java | 3 +- .../HttpComponentsClientHttpRequest.java | 5 +-- ...pComponentsStreamingClientHttpRequest.java | 5 +-- .../client/InterceptingClientHttpRequest.java | 9 ++--- .../http/client/MultipartBodyBuilder.java | 22 +++++------ .../HttpComponentsHeadersAdapter.java | 12 +++--- .../client/reactive/JettyHeadersAdapter.java | 39 ++++++++++--------- .../client/reactive/NettyHeadersAdapter.java | 13 ++++--- .../reactive/ReactorClientHttpResponse.java | 13 +++---- .../codec/json/AbstractJackson2Encoder.java | 9 ++--- .../AbstractGenericHttpMessageConverter.java | 7 ++-- .../AbstractHttpMessageConverter.java | 5 +-- .../BufferedImageHttpMessageConverter.java | 5 +-- .../converter/FormHttpMessageConverter.java | 16 +++----- .../ResourceRegionHttpMessageConverter.java | 30 +++++++------- .../AbstractJackson2HttpMessageConverter.java | 28 ++++++------- .../Jaxb2CollectionHttpMessageConverter.java | 12 +++--- .../Jaxb2RootElementHttpMessageConverter.java | 3 +- .../ServletServerHttpAsyncRequestControl.java | 4 +- .../http/server/ServletServerHttpRequest.java | 3 +- .../DefaultServerHttpRequestBuilder.java | 6 +-- .../reactive/JettyHttpHandlerAdapter.java | 14 +++---- .../server/reactive/NettyHeadersAdapter.java | 12 +++--- .../server/reactive/TomcatHeadersAdapter.java | 21 +++++----- .../reactive/TomcatHttpHandlerAdapter.java | 21 +++++----- .../reactive/UndertowHeadersAdapter.java | 20 +++++----- .../reactive/UndertowServerHttpRequest.java | 5 +-- .../ContentNegotiationManagerFactoryBean.java | 4 +- .../web/bind/EscapedErrors.java | 11 +++--- .../bind/support/WebRequestDataBinder.java | 3 +- .../web/context/ContextLoader.java | 31 +++++++-------- .../async/StandardServletAsyncWebRequest.java | 4 +- .../context/support/RequestHandledEvent.java | 6 +-- .../support/ServletContextResource.java | 5 +-- ...ServletContextResourcePatternResolver.java | 5 +-- .../web/filter/DelegatingFilterProxy.java | 11 ++---- .../web/filter/FormContentFilter.java | 4 +- .../web/filter/HttpPutFormContentFilter.java | 4 +- .../web/filter/OncePerRequestFilter.java | 7 +--- .../web/jsf/DecoratingNavigationHandler.java | 5 +-- .../WebApplicationContextFacesELResolver.java | 8 ++-- .../web/method/ControllerAdviceBean.java | 20 +++++----- .../web/method/HandlerMethod.java | 6 +-- .../CompositeUriComponentsContributor.java | 16 ++++---- .../support/ByteArrayMultipartFileEditor.java | 3 +- .../support/StringMultipartFileEditor.java | 5 +-- .../AbstractReactiveWebInitializer.java | 16 +++----- .../web/util/HierarchicalUriComponents.java | 12 +++--- .../web/util/OpaqueUriComponents.java | 5 +-- .../springframework/web/util/WebUtils.java | 20 +++++----- .../web/util/pattern/PathPattern.java | 8 +--- 55 files changed, 262 insertions(+), 321 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/ContentDisposition.java b/spring-web/src/main/java/org/springframework/http/ContentDisposition.java index 1d5254e336a8..63149ae9e018 100644 --- a/spring-web/src/main/java/org/springframework/http/ContentDisposition.java +++ b/spring-web/src/main/java/org/springframework/http/ContentDisposition.java @@ -212,10 +212,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ContentDisposition)) { + if (!(other instanceof ContentDisposition otherCd)) { return false; } - ContentDisposition otherCd = (ContentDisposition) other; return (ObjectUtils.nullSafeEquals(this.type, otherCd.type) && ObjectUtils.nullSafeEquals(this.name, otherCd.name) && ObjectUtils.nullSafeEquals(this.filename, otherCd.filename) && diff --git a/spring-web/src/main/java/org/springframework/http/HttpCookie.java b/spring-web/src/main/java/org/springframework/http/HttpCookie.java index e09070c9bf79..c09cdc947f15 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpCookie.java +++ b/spring-web/src/main/java/org/springframework/http/HttpCookie.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,10 +66,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof HttpCookie)) { + if (!(other instanceof HttpCookie otherCookie)) { return false; } - HttpCookie otherCookie = (HttpCookie) other; return (this.name.equalsIgnoreCase(otherCookie.getName())); } diff --git a/spring-web/src/main/java/org/springframework/http/HttpRange.java b/spring-web/src/main/java/org/springframework/http/HttpRange.java index ae591cd33529..25159745e574 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpRange.java +++ b/spring-web/src/main/java/org/springframework/http/HttpRange.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -272,10 +272,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ByteRange)) { + if (!(other instanceof ByteRange otherRange)) { return false; } - ByteRange otherRange = (ByteRange) other; return (this.firstPos == otherRange.firstPos && ObjectUtils.nullSafeEquals(this.lastPos, otherRange.lastPos)); } @@ -335,10 +334,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof SuffixByteRange)) { + if (!(other instanceof SuffixByteRange otherRange)) { return false; } - SuffixByteRange otherRange = (SuffixByteRange) other; return (this.suffixLength == otherRange.suffixLength); } diff --git a/spring-web/src/main/java/org/springframework/http/MediaType.java b/spring-web/src/main/java/org/springframework/http/MediaType.java index ec57d77a5ac2..dfd68464b433 100644 --- a/spring-web/src/main/java/org/springframework/http/MediaType.java +++ b/spring-web/src/main/java/org/springframework/http/MediaType.java @@ -691,8 +691,8 @@ public static List asMediaTypes(List mimeTypes) { * @since 5.0 */ public static MediaType asMediaType(MimeType mimeType) { - if (mimeType instanceof MediaType) { - return (MediaType) mimeType; + if (mimeType instanceof MediaType mediaType) { + return mediaType; } return new MediaType(mimeType.getType(), mimeType.getSubtype(), mimeType.getParameters()); } @@ -817,7 +817,7 @@ else if (mediaType2.isWildcardSubtype() && !mediaType1.isWildcardSubtype()) { / /** * Comparator used by {@link #sortBySpecificity(List)}. */ - public static final Comparator SPECIFICITY_COMPARATOR = new SpecificityComparator() { + public static final Comparator SPECIFICITY_COMPARATOR = new SpecificityComparator<>() { @Override protected int compareParameters(MediaType mediaType1, MediaType mediaType2) { diff --git a/spring-web/src/main/java/org/springframework/http/ResponseCookie.java b/spring-web/src/main/java/org/springframework/http/ResponseCookie.java index bada6e559885..cd0a19f0b5d0 100644 --- a/spring-web/src/main/java/org/springframework/http/ResponseCookie.java +++ b/spring-web/src/main/java/org/springframework/http/ResponseCookie.java @@ -134,10 +134,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ResponseCookie)) { + if (!(other instanceof ResponseCookie otherCookie)) { return false; } - ResponseCookie otherCookie = (ResponseCookie) other; return (getName().equalsIgnoreCase(otherCookie.getName()) && ObjectUtils.nullSafeEquals(this.path, otherCookie.getPath()) && ObjectUtils.nullSafeEquals(this.domain, otherCookie.getDomain())); diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequest.java index e1b328df0ffd..5803e19f92a1 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,8 +79,7 @@ HttpContext getHttpContext() { protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException { addHeaders(this.httpRequest, headers); - if (this.httpRequest instanceof HttpEntityEnclosingRequest) { - HttpEntityEnclosingRequest entityEnclosingRequest = (HttpEntityEnclosingRequest) this.httpRequest; + if (this.httpRequest instanceof HttpEntityEnclosingRequest entityEnclosingRequest) { HttpEntity requestEntity = new ByteArrayEntity(bufferedOutput); entityEnclosingRequest.setEntity(requestEntity); } diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsStreamingClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsStreamingClientHttpRequest.java index 7b145e2a306f..ed0cc19fa79d 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsStreamingClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsStreamingClientHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -90,8 +90,7 @@ protected OutputStream getBodyInternal(HttpHeaders headers) throws IOException { protected ClientHttpResponse executeInternal(HttpHeaders headers) throws IOException { HttpComponentsClientHttpRequest.addHeaders(this.httpRequest, headers); - if (this.httpRequest instanceof HttpEntityEnclosingRequest && this.body != null) { - HttpEntityEnclosingRequest entityEnclosingRequest = (HttpEntityEnclosingRequest) this.httpRequest; + if (this.httpRequest instanceof HttpEntityEnclosingRequest entityEnclosingRequest && this.body != null) { HttpEntity requestEntity = new StreamingHttpEntity(getHeaders(), this.body); entityEnclosingRequest.setEntity(requestEntity); } diff --git a/spring-web/src/main/java/org/springframework/http/client/InterceptingClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/InterceptingClientHttpRequest.java index 8b75f7e31a76..57198a5e697a 100644 --- a/spring-web/src/main/java/org/springframework/http/client/InterceptingClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/InterceptingClientHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,9 +41,9 @@ class InterceptingClientHttpRequest extends AbstractBufferingClientHttpRequest { private final List interceptors; - private HttpMethod method; + private final HttpMethod method; - private URI uri; + private final URI uri; protected InterceptingClientHttpRequest(ClientHttpRequestFactory requestFactory, @@ -98,8 +98,7 @@ public ClientHttpResponse execute(HttpRequest request, byte[] body) throws IOExc ClientHttpRequest delegate = requestFactory.createRequest(request.getURI(), method); request.getHeaders().forEach((key, value) -> delegate.getHeaders().addAll(key, value)); if (body.length > 0) { - if (delegate instanceof StreamingHttpOutputMessage) { - StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) delegate; + if (delegate instanceof StreamingHttpOutputMessage streamingOutputMessage) { streamingOutputMessage.setBody(outputStream -> StreamUtils.copy(body, outputStream)); } else { diff --git a/spring-web/src/main/java/org/springframework/http/client/MultipartBodyBuilder.java b/spring-web/src/main/java/org/springframework/http/client/MultipartBodyBuilder.java index 9d76f72f15b1..c80e3c56e23f 100644 --- a/spring-web/src/main/java/org/springframework/http/client/MultipartBodyBuilder.java +++ b/spring-web/src/main/java/org/springframework/http/client/MultipartBodyBuilder.java @@ -83,6 +83,7 @@ * * @author Arjen Poutsma * @author Rossen Stoyanchev + * @author Sam Brannen * @since 5.0.2 * @see RFC 7578 */ @@ -127,8 +128,7 @@ public PartBuilder part(String name, Object part, @Nullable MediaType contentTyp Assert.hasLength(name, "'name' must not be empty"); Assert.notNull(part, "'part' must not be null"); - if (part instanceof Part) { - Part partObject = (Part) part; + if (part instanceof Part partObject) { PartBuilder builder = asyncPart(name, partObject.content(), DataBuffer.class); if (!partObject.headers().isEmpty()) { builder.headers(headers -> { @@ -144,8 +144,8 @@ public PartBuilder part(String name, Object part, @Nullable MediaType contentTyp return builder; } - if (part instanceof PublisherEntity) { - PublisherPartBuilder builder = new PublisherPartBuilder<>(name, (PublisherEntity) part); + if (part instanceof PublisherEntity publisherEntity) { + PublisherPartBuilder builder = new PublisherPartBuilder<>(name, publisherEntity); if (contentType != null) { builder.contentType(contentType); } @@ -155,20 +155,20 @@ public PartBuilder part(String name, Object part, @Nullable MediaType contentTyp Object partBody; HttpHeaders partHeaders = null; - if (part instanceof HttpEntity) { - partBody = ((HttpEntity) part).getBody(); + if (part instanceof HttpEntity httpEntity) { + partBody = httpEntity.getBody(); partHeaders = new HttpHeaders(); - partHeaders.putAll(((HttpEntity) part).getHeaders()); + partHeaders.putAll(httpEntity.getHeaders()); } else { partBody = part; } if (partBody instanceof Publisher) { - throw new IllegalArgumentException( - "Use asyncPart(String, Publisher, Class)" + - " or asyncPart(String, Publisher, ParameterizedTypeReference) or" + - " or MultipartBodyBuilder.PublisherEntity"); + throw new IllegalArgumentException(""" + Use asyncPart(String, Publisher, Class) \ + or asyncPart(String, Publisher, ParameterizedTypeReference) \ + or MultipartBodyBuilder.PublisherEntity"""); } DefaultPartBuilder builder = new DefaultPartBuilder(name, partHeaders, partBody); diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/HttpComponentsHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/client/reactive/HttpComponentsHeadersAdapter.java index f24d77cb86d6..9b914c1a4e21 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/HttpComponentsHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/HttpComponentsHeadersAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -102,7 +102,7 @@ public boolean isEmpty() { @Override public boolean containsKey(Object key) { - return (key instanceof String && this.response.containsHeader((String) key)); + return (key instanceof String headerName && this.response.containsHeader(headerName)); } @Override @@ -136,9 +136,9 @@ public List put(String key, List values) { @Nullable @Override public List remove(Object key) { - if (key instanceof String) { + if (key instanceof String headerName) { List oldValues = get(key); - this.response.removeHeaders((String) key); + this.response.removeHeaders(headerName); return oldValues; } return null; @@ -174,7 +174,7 @@ public Collection> values() { @Override public Set>> entrySet() { - return new AbstractSet>>() { + return new AbstractSet<>() { @Override public Iterator>> iterator() { return new EntryIterator(); @@ -196,7 +196,7 @@ public String toString() { private class EntryIterator implements Iterator>> { - private Iterator
    iterator = response.headerIterator(); + private final Iterator
    iterator = response.headerIterator(); @Override public boolean hasNext() { diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyHeadersAdapter.java index 6d42dc76204e..b1c01aa88225 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyHeadersAdapter.java @@ -40,6 +40,7 @@ * * @author Rossen Stoyanchev * @author Juergen Hoeller + * @author Sam Brannen * @since 5.3 */ class JettyHeadersAdapter implements MultiValueMap { @@ -59,10 +60,10 @@ public String getFirst(String key) { @Override public void add(String key, @Nullable String value) { - if (!(this.headers instanceof HttpFields.Mutable)) { + if (!(this.headers instanceof HttpFields.Mutable mutableHttpFields)) { throw new IllegalStateException("Immutable headers"); } - ((HttpFields.Mutable) this.headers).add(key, value); + mutableHttpFields.add(key, value); } @Override @@ -77,10 +78,10 @@ public void addAll(MultiValueMap values) { @Override public void set(String key, @Nullable String value) { - if (!(this.headers instanceof HttpFields.Mutable)) { + if (!(this.headers instanceof HttpFields.Mutable mutableHttpFields)) { throw new IllegalStateException("Immutable headers"); } - ((HttpFields.Mutable) this.headers).put(key, value); + mutableHttpFields.put(key, value); } @Override @@ -112,13 +113,13 @@ public boolean isEmpty() { @Override public boolean containsKey(Object key) { - return (key instanceof String && this.headers.contains((String) key)); + return (key instanceof String headerName && this.headers.contains(headerName)); } @Override public boolean containsValue(Object value) { - return (value instanceof String && - this.headers.stream().anyMatch(field -> field.contains((String) value))); + return (value instanceof String searchString && + this.headers.stream().anyMatch(field -> field.contains(searchString))); } @Nullable @@ -133,23 +134,23 @@ public List get(Object key) { @Nullable @Override public List put(String key, List value) { - if (!(this.headers instanceof HttpFields.Mutable)) { + if (!(this.headers instanceof HttpFields.Mutable mutableHttpFields)) { throw new IllegalStateException("Immutable headers"); } List oldValues = get(key); - ((HttpFields.Mutable) this.headers).put(key, value); + mutableHttpFields.put(key, value); return oldValues; } @Nullable @Override public List remove(Object key) { - if (!(this.headers instanceof HttpFields.Mutable)) { + if (!(this.headers instanceof HttpFields.Mutable mutableHttpFields)) { throw new IllegalStateException("Immutable headers"); } - if (key instanceof String) { + if (key instanceof String name) { List oldValues = get(key); - ((HttpFields.Mutable) this.headers).remove((String) key); + mutableHttpFields.remove(name); return oldValues; } return null; @@ -162,10 +163,10 @@ public void putAll(Map> map) { @Override public void clear() { - if (!(this.headers instanceof HttpFields.Mutable)) { + if (!(this.headers instanceof HttpFields.Mutable mutableHttpFields)) { throw new IllegalStateException("Immutable headers"); } - ((HttpFields.Mutable) this.headers).clear(); + mutableHttpFields.clear(); } @Override @@ -181,7 +182,7 @@ public Collection> values() { @Override public Set>> entrySet() { - return new AbstractSet>>() { + return new AbstractSet<>() { @Override public Iterator>> iterator() { return new EntryIterator(); @@ -237,11 +238,11 @@ public List getValue() { @Override public List setValue(List value) { - if (!(headers instanceof HttpFields.Mutable)) { + if (!(headers instanceof HttpFields.Mutable mutableHttpFields)) { throw new IllegalStateException("Immutable headers"); } List previousValues = headers.getValuesList(this.key); - ((HttpFields.Mutable) headers).put(this.key, value); + mutableHttpFields.put(this.key, value); return previousValues; } } @@ -285,7 +286,7 @@ public String next() { @Override public void remove() { - if (!(headers instanceof HttpFields.Mutable)) { + if (!(headers instanceof HttpFields.Mutable mutableHttpFields)) { throw new IllegalStateException("Immutable headers"); } if (this.currentName == null) { @@ -294,7 +295,7 @@ public void remove() { if (!headers.contains(this.currentName)) { throw new IllegalStateException("Header not present: " + this.currentName); } - ((HttpFields.Mutable) headers).remove(this.currentName); + mutableHttpFields.remove(this.currentName); } } diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/NettyHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/client/reactive/NettyHeadersAdapter.java index 382203b34b99..b35fa91ed902 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/NettyHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/NettyHeadersAdapter.java @@ -36,6 +36,7 @@ *

    There is a duplicate of this class in the server package! * * @author Rossen Stoyanchev + * @author Sam Brannen * @since 5.3 */ class NettyHeadersAdapter implements MultiValueMap { @@ -107,7 +108,7 @@ public boolean isEmpty() { @Override public boolean containsKey(Object key) { - return (key instanceof String && this.headers.contains((String) key)); + return (key instanceof String headerName && this.headers.contains(headerName)); } @Override @@ -137,9 +138,9 @@ public List put(String key, @Nullable List value) { @Nullable @Override public List remove(Object key) { - if (key instanceof String) { - List previousValues = this.headers.getAll((String) key); - this.headers.remove((String) key); + if (key instanceof String headerName) { + List previousValues = this.headers.getAll(headerName); + this.headers.remove(headerName); return previousValues; } return null; @@ -168,7 +169,7 @@ public Collection> values() { @Override public Set>> entrySet() { - return new AbstractSet>>() { + return new AbstractSet<>() { @Override public Iterator>> iterator() { return new EntryIterator(); @@ -190,7 +191,7 @@ public String toString() { private class EntryIterator implements Iterator>> { - private Iterator names = headers.names().iterator(); + private final Iterator names = headers.names().iterator(); @Override public boolean hasNext() { diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/ReactorClientHttpResponse.java b/spring-web/src/main/java/org/springframework/http/client/reactive/ReactorClientHttpResponse.java index 26903c4481aa..5139d9e3ae90 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/ReactorClientHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/ReactorClientHttpResponse.java @@ -105,8 +105,8 @@ public String getId() { if (reactorNettyRequestChannelOperationsIdPresent) { id = ChannelOperationsIdHelper.getId(this.response); } - if (id == null && this.response instanceof Connection) { - id = ((Connection) this.response).channel().id().asShortText(); + if (id == null && this.response instanceof Connection connection) { + id = connection.channel().id().asShortText(); } return (id != null ? id : ObjectUtils.getIdentityHexString(this)); } @@ -163,8 +163,7 @@ public MultiValueMap getCookies() { @Nullable private static String getSameSite(Cookie cookie) { - if (cookie instanceof DefaultCookie) { - DefaultCookie defaultCookie = (DefaultCookie) cookie; + if (cookie instanceof DefaultCookie defaultCookie) { if (defaultCookie.sameSite() != null) { return defaultCookie.sameSite().name(); } @@ -206,10 +205,8 @@ private static class ChannelOperationsIdHelper { @Nullable public static String getId(HttpClientResponse response) { - if (response instanceof reactor.netty.ChannelOperationsId) { - return (logger.isDebugEnabled() ? - ((reactor.netty.ChannelOperationsId) response).asLongText() : - ((reactor.netty.ChannelOperationsId) response).asShortText()); + if (response instanceof reactor.netty.ChannelOperationsId id) { + return (logger.isDebugEnabled() ? id.asLongText() : id.asShortText()); } return null; } diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java b/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java index 89644fecff9d..0eeaf5832e18 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java @@ -202,11 +202,10 @@ public DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory, } Class jsonView = null; FilterProvider filters = null; - if (value instanceof MappingJacksonValue) { - MappingJacksonValue container = (MappingJacksonValue) value; - value = container.getValue(); - jsonView = container.getSerializationView(); - filters = container.getFilters(); + if (value instanceof MappingJacksonValue mappingJacksonValue) { + value = mappingJacksonValue.getValue(); + jsonView = mappingJacksonValue.getSerializationView(); + filters = mappingJacksonValue.getFilters(); } ObjectWriter writer = createObjectWriter(mapper, valueType, mimeType, jsonView, hints); if (filters != null) { diff --git a/spring-web/src/main/java/org/springframework/http/converter/AbstractGenericHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/AbstractGenericHttpMessageConverter.java index 3b34625e5a24..ce3eadc42bb8 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/AbstractGenericHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/AbstractGenericHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,7 +68,7 @@ protected boolean supports(Class clazz) { @Override public boolean canRead(Type type, @Nullable Class contextClass, @Nullable MediaType mediaType) { - return (type instanceof Class ? canRead((Class) type, mediaType) : canRead(mediaType)); + return (type instanceof Class clazz ? canRead(clazz, mediaType) : canRead(mediaType)); } @Override @@ -87,8 +87,7 @@ public final void write(final T t, @Nullable final Type type, @Nullable MediaTyp final HttpHeaders headers = outputMessage.getHeaders(); addDefaultHeaders(headers, t, contentType); - if (outputMessage instanceof StreamingHttpOutputMessage) { - StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage; + if (outputMessage instanceof StreamingHttpOutputMessage streamingOutputMessage) { streamingOutputMessage.setBody(outputStream -> writeInternal(t, type, new HttpOutputMessage() { @Override public OutputStream getBody() { diff --git a/spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java index cf0674e06a1a..644be4f36e3b 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -210,8 +210,7 @@ public final void write(final T t, @Nullable MediaType contentType, HttpOutputMe final HttpHeaders headers = outputMessage.getHeaders(); addDefaultHeaders(headers, t, contentType); - if (outputMessage instanceof StreamingHttpOutputMessage) { - StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage; + if (outputMessage instanceof StreamingHttpOutputMessage streamingOutputMessage) { streamingOutputMessage.setBody(outputStream -> writeInternal(t, new HttpOutputMessage() { @Override public OutputStream getBody() { diff --git a/spring-web/src/main/java/org/springframework/http/converter/BufferedImageHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/BufferedImageHttpMessageConverter.java index cdfa5781c99d..c1cf744b808a 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/BufferedImageHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/BufferedImageHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -221,8 +221,7 @@ public void write(final BufferedImage image, @Nullable final MediaType contentTy final MediaType selectedContentType = getContentType(contentType); outputMessage.getHeaders().setContentType(selectedContentType); - if (outputMessage instanceof StreamingHttpOutputMessage) { - StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage; + if (outputMessage instanceof StreamingHttpOutputMessage streamingOutputMessage) { streamingOutputMessage.setBody(outputStream -> writeInternal(image, selectedContentType, outputStream)); } else { 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 c113194183e6..680da1ae2a10 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-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -274,8 +274,7 @@ public void setCharset(@Nullable Charset charset) { */ private void applyDefaultCharset() { for (HttpMessageConverter candidate : this.partConverters) { - if (candidate instanceof AbstractHttpMessageConverter) { - AbstractHttpMessageConverter converter = (AbstractHttpMessageConverter) candidate; + if (candidate instanceof AbstractHttpMessageConverter converter) { // Only override default charset if the converter operates with a charset to begin with... if (converter.getDefaultCharset() != null) { converter.setDefaultCharset(this.charset); @@ -400,8 +399,7 @@ private void writeForm(MultiValueMap formData, @Nullable MediaTy byte[] bytes = serializeForm(formData, charset).getBytes(charset); outputMessage.getHeaders().setContentLength(bytes.length); - if (outputMessage instanceof StreamingHttpOutputMessage) { - StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage; + if (outputMessage instanceof StreamingHttpOutputMessage streamingOutputMessage) { streamingOutputMessage.setBody(outputStream -> StreamUtils.copy(bytes, outputStream)); } else { @@ -486,8 +484,7 @@ private void writeMultipart( contentType = new MediaType(contentType, parameters); outputMessage.getHeaders().setContentType(contentType); - if (outputMessage instanceof StreamingHttpOutputMessage) { - StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage; + if (outputMessage instanceof StreamingHttpOutputMessage streamingOutputMessage) { streamingOutputMessage.setBody(outputStream -> { writeParts(outputStream, parts, boundary); writeEnd(outputStream, boundary); @@ -562,7 +559,7 @@ protected byte[] generateMultipartBoundary() { * or a newly built {@link HttpEntity} wrapper for that part */ protected HttpEntity getHttpEntity(Object part) { - return (part instanceof HttpEntity ? (HttpEntity) part : new HttpEntity<>(part)); + return (part instanceof HttpEntity httpEntity ? httpEntity : new HttpEntity<>(part)); } /** @@ -575,8 +572,7 @@ protected HttpEntity getHttpEntity(Object part) { */ @Nullable protected String getFilename(Object part) { - if (part instanceof Resource) { - Resource resource = (Resource) part; + if (part instanceof Resource resource) { String filename = resource.getFilename(); if (filename != null && this.multipartCharset != null) { filename = MimeDelegate.encode(filename, this.multipartCharset.name()); diff --git a/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java index b9dca7220413..08e0a55bded7 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,11 +37,12 @@ import org.springframework.util.StreamUtils; /** - * Implementation of {@link HttpMessageConverter} that can write a single {@link ResourceRegion}, - * or Collections of {@link ResourceRegion ResourceRegions}. + * Implementation of {@link HttpMessageConverter} that can write a single + * {@link ResourceRegion} or Collections of {@link ResourceRegion ResourceRegions}. * * @author Brian Clozel * @author Juergen Hoeller + * @author Sam Brannen * @since 4.3 */ public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessageConverter { @@ -55,8 +56,8 @@ public ResourceRegionHttpMessageConverter() { @SuppressWarnings("unchecked") protected MediaType getDefaultContentType(Object object) { Resource resource = null; - if (object instanceof ResourceRegion) { - resource = ((ResourceRegion) object).getResource(); + if (object instanceof ResourceRegion resourceRegion) { + resource = resourceRegion.getResource(); } else { Collection regions = (Collection) object; @@ -98,15 +99,12 @@ public boolean canWrite(Class clazz, @Nullable MediaType mediaType) { @Override public boolean canWrite(@Nullable Type type, @Nullable Class clazz, @Nullable MediaType mediaType) { - if (!(type instanceof ParameterizedType)) { - return (type instanceof Class && ResourceRegion.class.isAssignableFrom((Class) type)); + if (!(type instanceof ParameterizedType parameterizedType)) { + return (type instanceof Class c && ResourceRegion.class.isAssignableFrom(c)); } - - ParameterizedType parameterizedType = (ParameterizedType) type; - if (!(parameterizedType.getRawType() instanceof Class)) { + if (!(parameterizedType.getRawType() instanceof Class rawType)) { return false; } - Class rawType = (Class) parameterizedType.getRawType(); if (!(Collection.class.isAssignableFrom(rawType))) { return false; } @@ -114,11 +112,9 @@ public boolean canWrite(@Nullable Type type, @Nullable Class clazz, @Nullable return false; } Type typeArgument = parameterizedType.getActualTypeArguments()[0]; - if (!(typeArgument instanceof Class)) { + if (!(typeArgument instanceof Class typeArgumentClass)) { return false; } - - Class typeArgumentClass = (Class) typeArgument; return ResourceRegion.class.isAssignableFrom(typeArgumentClass); } @@ -127,8 +123,8 @@ public boolean canWrite(@Nullable Type type, @Nullable Class clazz, @Nullable protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { - if (object instanceof ResourceRegion) { - writeResourceRegion((ResourceRegion) object, outputMessage); + if (object instanceof ResourceRegion resourceRegion) { + writeResourceRegion(resourceRegion, outputMessage); } else { Collection regions = (Collection) object; @@ -136,7 +132,7 @@ protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessa writeResourceRegion(regions.iterator().next(), outputMessage); } else { - writeResourceRegionCollection((Collection) object, outputMessage); + writeResourceRegionCollection(regions, outputMessage); } } } diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java index 19b22fef2c81..3a547e62c59d 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java @@ -74,6 +74,7 @@ * @author Rossen Stoyanchev * @author Juergen Hoeller * @author Sebastien Deleuze + * @author Sam Brannen * @since 4.1 * @see MappingJackson2HttpMessageConverter */ @@ -107,7 +108,7 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener private Boolean prettyPrint; @Nullable - private PrettyPrinter ssePrettyPrinter; + private final PrettyPrinter ssePrettyPrinter; protected AbstractJackson2HttpMessageConverter(ObjectMapper objectMapper) { @@ -361,8 +362,8 @@ private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage) th "UTF-16".equals(charset.name()) || "UTF-32".equals(charset.name()); try { - if (inputMessage instanceof MappingJacksonInputMessage) { - Class deserializationView = ((MappingJacksonInputMessage) inputMessage).getDeserializationView(); + if (inputMessage instanceof MappingJacksonInputMessage mappingJacksonInputMessage) { + Class deserializationView = mappingJacksonInputMessage.getDeserializationView(); if (deserializationView != null) { ObjectReader objectReader = objectMapper.readerWithView(deserializationView).forType(javaType); if (isUnicode) { @@ -414,8 +415,8 @@ protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessa MediaType contentType = outputMessage.getHeaders().getContentType(); JsonEncoding encoding = getJsonEncoding(contentType); - Class clazz = (object instanceof MappingJacksonValue ? - ((MappingJacksonValue) object).getValue().getClass() : object.getClass()); + Class clazz = (object instanceof MappingJacksonValue mappingJacksonValue ? + mappingJacksonValue.getValue().getClass() : object.getClass()); ObjectMapper objectMapper = selectObjectMapper(clazz, contentType); Assert.state(objectMapper != null, "No ObjectMapper for " + clazz.getName()); @@ -428,11 +429,10 @@ protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessa FilterProvider filters = null; JavaType javaType = null; - if (object instanceof MappingJacksonValue) { - MappingJacksonValue container = (MappingJacksonValue) object; - value = container.getValue(); - serializationView = container.getSerializationView(); - filters = container.getFilters(); + if (object instanceof MappingJacksonValue mappingJacksonValue) { + value = mappingJacksonValue.getValue(); + serializationView = mappingJacksonValue.getSerializationView(); + filters = mappingJacksonValue.getFilters(); } if (type != null && TypeUtils.isAssignable(type, value.getClass())) { javaType = getJavaType(type, null); @@ -510,16 +510,16 @@ protected JsonEncoding getJsonEncoding(@Nullable MediaType contentType) { @Override @Nullable protected MediaType getDefaultContentType(Object object) throws IOException { - if (object instanceof MappingJacksonValue) { - object = ((MappingJacksonValue) object).getValue(); + if (object instanceof MappingJacksonValue mappingJacksonValue) { + object = mappingJacksonValue.getValue(); } return super.getDefaultContentType(object); } @Override protected Long getContentLength(Object object, @Nullable MediaType contentType) throws IOException { - if (object instanceof MappingJacksonValue) { - object = ((MappingJacksonValue) object).getValue(); + if (object instanceof MappingJacksonValue mappingJacksonValue) { + object = mappingJacksonValue.getValue(); } return super.getContentLength(object, contentType); } diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java index c2e3bfdc10ad..e1acb3a833b1 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,6 +59,7 @@ * * @author Arjen Poutsma * @author Rossen Stoyanchev + * @author Sam Brannen * @since 3.2 * @param the converted object type */ @@ -86,14 +87,12 @@ public boolean canRead(Class clazz, @Nullable MediaType mediaType) { */ @Override public boolean canRead(Type type, @Nullable Class contextClass, @Nullable MediaType mediaType) { - if (!(type instanceof ParameterizedType)) { + if (!(type instanceof ParameterizedType parameterizedType)) { return false; } - ParameterizedType parameterizedType = (ParameterizedType) type; - if (!(parameterizedType.getRawType() instanceof Class)) { + if (!(parameterizedType.getRawType() instanceof Class rawType)) { return false; } - Class rawType = (Class) parameterizedType.getRawType(); if (!(Collection.class.isAssignableFrom(rawType))) { return false; } @@ -101,10 +100,9 @@ public boolean canRead(Type type, @Nullable Class contextClass, @Nullable Med return false; } Type typeArgument = parameterizedType.getActualTypeArguments()[0]; - if (!(typeArgument instanceof Class)) { + if (!(typeArgument instanceof Class typeArgumentClass)) { return false; } - Class typeArgumentClass = (Class) typeArgument; return (typeArgumentClass.isAnnotationPresent(XmlRootElement.class) || typeArgumentClass.isAnnotationPresent(XmlType.class)) && canRead(mediaType); } diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java index c41fb18b8545..a1acfda553e3 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java @@ -151,8 +151,7 @@ protected Object readFromSource(Class clazz, HttpHeaders headers, Source sour @SuppressWarnings("deprecation") protected Source processSource(Source source) { - if (source instanceof StreamSource) { - StreamSource streamSource = (StreamSource) source; + if (source instanceof StreamSource streamSource) { InputSource inputSource = new InputSource(streamSource.getInputStream()); try { XMLReader xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); diff --git a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java index 0a0d1b4fa39a..7833b92bbb1d 100644 --- a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java +++ b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,7 @@ public class ServletServerHttpAsyncRequestControl implements ServerHttpAsyncRequ @Nullable private AsyncContext asyncContext; - private AtomicBoolean asyncCompleted = new AtomicBoolean(); + private final AtomicBoolean asyncCompleted = new AtomicBoolean(); /** diff --git a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java index f7b3e9e99f0d..7bac4b70a94e 100644 --- a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java @@ -216,11 +216,10 @@ public InputStream getBody() throws IOException { @Override public ServerHttpAsyncRequestControl getAsyncRequestControl(ServerHttpResponse response) { if (this.asyncRequestControl == null) { - if (!(response instanceof ServletServerHttpResponse)) { + if (!(response instanceof ServletServerHttpResponse servletServerResponse)) { throw new IllegalArgumentException( "Response must be a ServletServerHttpResponse: " + response.getClass()); } - ServletServerHttpResponse servletServerResponse = (ServletServerHttpResponse) response; this.asyncRequestControl = new ServletServerHttpAsyncRequestControl(this, servletServerResponse); } return this.asyncRequestControl; diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java b/spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java index d4398d76091b..956808e57ae1 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java @@ -45,7 +45,7 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder { private URI uri; - private HttpHeaders headers; + private final HttpHeaders headers; private String httpMethodValue; @@ -61,7 +61,7 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder { @Nullable private InetSocketAddress remoteAddress; - private Flux body; + private final Flux body; private final ServerHttpRequest originalRequest; @@ -182,7 +182,7 @@ private static class MutatedServerHttpRequest extends AbstractServerHttpRequest private final SslInfo sslInfo; @Nullable - private InetSocketAddress remoteAddress; + private final InetSocketAddress remoteAddress; private final Flux body; diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java index 8c1615e6d281..2862ce8e7a2f 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java @@ -89,11 +89,10 @@ private static MultiValueMap createHeaders(HttpServletRequest se } private static Request getRequest(HttpServletRequest request) { - if (request instanceof Request) { - return (Request) request; + if (request instanceof Request jettyRequest) { + return jettyRequest; } - else if (request instanceof HttpServletRequestWrapper) { - HttpServletRequestWrapper wrapper = (HttpServletRequestWrapper) request; + else if (request instanceof HttpServletRequestWrapper wrapper) { HttpServletRequest wrappedRequest = (HttpServletRequest) wrapper.getRequest(); return getRequest(wrappedRequest); } @@ -121,11 +120,10 @@ private static HttpHeaders createHeaders(HttpServletResponse servletResponse) { } private static Response getResponse(HttpServletResponse response) { - if (response instanceof Response) { - return (Response) response; + if (response instanceof Response jettyResponse) { + return jettyResponse; } - else if (response instanceof HttpServletResponseWrapper) { - HttpServletResponseWrapper wrapper = (HttpServletResponseWrapper) response; + else if (response instanceof HttpServletResponseWrapper wrapper) { HttpServletResponse wrappedResponse = (HttpServletResponse) wrapper.getResponse(); return getResponse(wrappedResponse); } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/NettyHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/NettyHeadersAdapter.java index 08ae3207f91b..fdbdcacf5147 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/NettyHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/NettyHeadersAdapter.java @@ -107,7 +107,7 @@ public boolean isEmpty() { @Override public boolean containsKey(Object key) { - return (key instanceof String && this.headers.contains((String) key)); + return (key instanceof String headerName && this.headers.contains(headerName)); } @Override @@ -137,9 +137,9 @@ public List put(String key, @Nullable List value) { @Nullable @Override public List remove(Object key) { - if (key instanceof String) { - List previousValues = this.headers.getAll((String) key); - this.headers.remove((String) key); + if (key instanceof String headerName) { + List previousValues = this.headers.getAll(headerName); + this.headers.remove(headerName); return previousValues; } return null; @@ -168,7 +168,7 @@ public Collection> values() { @Override public Set>> entrySet() { - return new AbstractSet>>() { + return new AbstractSet<>() { @Override public Iterator>> iterator() { return new EntryIterator(); @@ -190,7 +190,7 @@ public String toString() { private class EntryIterator implements Iterator>> { - private Iterator names = headers.names().iterator(); + private final Iterator names = headers.names().iterator(); @Override public boolean hasNext() { diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHeadersAdapter.java index 6bde8a98a3cc..baaf0788c473 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHeadersAdapter.java @@ -38,6 +38,7 @@ * {@code MultiValueMap} implementation for wrapping Tomcat HTTP headers. * * @author Brian Clozel + * @author Sam Brannen * @since 5.1.1 */ class TomcatHeadersAdapter implements MultiValueMap { @@ -105,19 +106,19 @@ public boolean isEmpty() { @Override public boolean containsKey(Object key) { - if (key instanceof String) { - return (this.headers.findHeader((String) key, 0) != -1); + if (key instanceof String headerName) { + return (this.headers.findHeader(headerName, 0) != -1); } return false; } @Override public boolean containsValue(Object value) { - if (value instanceof String) { - MessageBytes needle = MessageBytes.newInstance(); - needle.setString((String) value); + if (value instanceof String text) { + MessageBytes messageBytes = MessageBytes.newInstance(); + messageBytes.setString(text); for (int i = 0; i < this.headers.size(); i++) { - if (this.headers.getValue(i).equals(needle)) { + if (this.headers.getValue(i).equals(messageBytes)) { return true; } } @@ -146,9 +147,9 @@ public List put(String key, List value) { @Override @Nullable public List remove(Object key) { - if (key instanceof String) { + if (key instanceof String headerName) { List previousValues = get(key); - this.headers.removeHeader((String) key); + this.headers.removeHeader(headerName); return previousValues; } return null; @@ -176,7 +177,7 @@ public Collection> values() { @Override public Set>> entrySet() { - return new AbstractSet>>() { + return new AbstractSet<>() { @Override public Iterator>> iterator() { return new EntryIterator(); @@ -198,7 +199,7 @@ public String toString() { private class EntryIterator implements Iterator>> { - private Enumeration names = headers.names(); + private final Enumeration names = headers.names(); @Override public boolean hasNext() { diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java index f9a8e7277c5c..b34723afa013 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,6 +52,7 @@ * * @author Violeta Georgieva * @author Brian Clozel + * @author Sam Brannen * @since 5.0 * @see org.springframework.web.server.adapter.AbstractReactiveWebInitializer */ @@ -115,11 +116,10 @@ private static MultiValueMap createTomcatHttpHeaders(HttpServlet } private static RequestFacade getRequestFacade(HttpServletRequest request) { - if (request instanceof RequestFacade) { - return (RequestFacade) request; + if (request instanceof RequestFacade facade) { + return facade; } - else if (request instanceof HttpServletRequestWrapper) { - HttpServletRequestWrapper wrapper = (HttpServletRequestWrapper) request; + else if (request instanceof HttpServletRequestWrapper wrapper) { HttpServletRequest wrappedRequest = (HttpServletRequest) wrapper.getRequest(); return getRequestFacade(wrappedRequest); } @@ -132,7 +132,7 @@ else if (request instanceof HttpServletRequestWrapper) { @Override protected DataBuffer readFromInputStream() throws IOException { ServletInputStream inputStream = ((ServletRequest) getNativeRequest()).getInputStream(); - if (!(inputStream instanceof CoyoteInputStream)) { + if (!(inputStream instanceof CoyoteInputStream coyoteInputStream)) { // It's possible InputStream can be wrapped, preventing use of CoyoteInputStream return super.readFromInputStream(); } @@ -141,7 +141,7 @@ protected DataBuffer readFromInputStream() throws IOException { DataBuffer dataBuffer = this.factory.allocateBuffer(capacity); try { ByteBuffer byteBuffer = dataBuffer.asByteBuffer(0, capacity); - int read = ((CoyoteInputStream) inputStream).read(byteBuffer); + int read = coyoteInputStream.read(byteBuffer); logBytesRead(read); if (read > 0) { dataBuffer.writePosition(read); @@ -192,11 +192,10 @@ private static HttpHeaders createTomcatHttpHeaders(HttpServletResponse response) } private static ResponseFacade getResponseFacade(HttpServletResponse response) { - if (response instanceof ResponseFacade) { - return (ResponseFacade) response; + if (response instanceof ResponseFacade facade) { + return facade; } - else if (response instanceof HttpServletResponseWrapper) { - HttpServletResponseWrapper wrapper = (HttpServletResponseWrapper) response; + else if (response instanceof HttpServletResponseWrapper wrapper) { HttpServletResponse wrappedResponse = (HttpServletResponse) wrapper.getResponse(); return getResponseFacade(wrappedResponse); } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHeadersAdapter.java index fa197aa0c208..9e249031872b 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHeadersAdapter.java @@ -17,6 +17,7 @@ package org.springframework.http.server.reactive; import java.util.AbstractSet; +import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -36,6 +37,7 @@ * {@code MultiValueMap} implementation for wrapping Undertow HTTP headers. * * @author Brian Clozel + * @author Sam Brannen * @since 5.1.1 */ class UndertowHeadersAdapter implements MultiValueMap { @@ -99,7 +101,7 @@ public boolean isEmpty() { @Override public boolean containsKey(Object key) { - return (key instanceof String && this.headers.contains((String) key)); + return (key instanceof String headerName && this.headers.contains(headerName)); } @Override @@ -113,10 +115,7 @@ public boolean containsValue(Object value) { @Override @Nullable public List get(Object key) { - if (key instanceof String) { - return this.headers.get((String) key); - } - return null; + return (key instanceof String headerName ? this.headers.get(headerName) : null); } @Override @@ -130,8 +129,11 @@ public List put(String key, List value) { @Override @Nullable public List remove(Object key) { - if (key instanceof String) { - this.headers.remove((String) key); + if (key instanceof String headerName) { + Collection removed = this.headers.remove(headerName); + if (removed != null) { + return new ArrayList<>(removed); + } } return null; } @@ -161,7 +163,7 @@ public Collection> values() { @Override public Set>> entrySet() { - return new AbstractSet>>() { + return new AbstractSet<>() { @Override public Iterator>> iterator() { return new EntryIterator(); @@ -183,7 +185,7 @@ public String toString() { private class EntryIterator implements Iterator>> { - private Iterator names = headers.getHeaderNames().iterator(); + private final Iterator names = headers.getHeaderNames().iterator(); @Override public boolean hasNext() { diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java index 4d87fa5f38e1..6de7dfb39996 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java @@ -175,7 +175,7 @@ protected void readingPaused() { @Nullable protected DataBuffer read() throws IOException { PooledByteBuffer pooledByteBuffer = this.byteBufferPool.allocate(); - try { + try (pooledByteBuffer) { ByteBuffer byteBuffer = pooledByteBuffer.getBuffer(); int read = this.channel.read(byteBuffer); @@ -194,9 +194,6 @@ else if (read == -1) { } return null; } - finally { - pooledByteBuffer.close(); - } } @Override diff --git a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java index a7c2358dd5e9..a9fcb4d8dc90 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -110,7 +110,7 @@ public class ContentNegotiationManagerFactoryBean private boolean favorPathExtension = false; - private Map mediaTypes = new HashMap<>(); + private final Map mediaTypes = new HashMap<>(); private boolean ignoreUnknownPathExtensions = true; diff --git a/spring-web/src/main/java/org/springframework/web/bind/EscapedErrors.java b/spring-web/src/main/java/org/springframework/web/bind/EscapedErrors.java index a2cb47e4787a..eb1166f9adea 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/EscapedErrors.java +++ b/spring-web/src/main/java/org/springframework/web/bind/EscapedErrors.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -204,7 +204,7 @@ public FieldError getFieldError(String field) { @Nullable public Object getFieldValue(String field) { Object value = this.source.getFieldValue(field); - return (value instanceof String ? HtmlUtils.htmlEscape((String) value) : value); + return (value instanceof String text ? HtmlUtils.htmlEscape(text) : value); } @Override @@ -223,11 +223,10 @@ private T escapeObjectError(@Nullable T source) { if (defaultMessage != null) { defaultMessage = HtmlUtils.htmlEscape(defaultMessage); } - if (source instanceof FieldError) { - FieldError fieldError = (FieldError) source; + if (source instanceof FieldError fieldError) { Object value = fieldError.getRejectedValue(); - if (value instanceof String) { - value = HtmlUtils.htmlEscape((String) value); + if (value instanceof String text) { + value = HtmlUtils.htmlEscape(text); } return (T) new FieldError( fieldError.getObjectName(), fieldError.getField(), value, fieldError.isBindingFailure(), diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java b/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java index 23e747a17c88..7be21a3db4ad 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java +++ b/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java @@ -109,8 +109,7 @@ public WebRequestDataBinder(@Nullable Object target, String objectName) { */ public void bind(WebRequest request) { MutablePropertyValues mpvs = new MutablePropertyValues(request.getParameterMap()); - if (request instanceof NativeWebRequest) { - NativeWebRequest nativeRequest = (NativeWebRequest) request; + if (request instanceof NativeWebRequest nativeRequest) { MultipartRequest multipartRequest = nativeRequest.getNativeRequest(MultipartRequest.class); if (multipartRequest != null) { bindMultipart(multipartRequest.getMultiFileMap(), mpvs); diff --git a/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java b/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java index 722fb7a17000..45a4bb69a928 100644 --- a/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java +++ b/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -277,19 +277,16 @@ public WebApplicationContext initWebApplicationContext(ServletContext servletCon if (this.context == null) { this.context = createWebApplicationContext(servletContext); } - if (this.context instanceof ConfigurableWebApplicationContext) { - ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context; - if (!cwac.isActive()) { - // The context has not yet been refreshed -> provide services such as - // setting the parent context, setting the application context id, etc - if (cwac.getParent() == null) { - // The context instance was injected without an explicit parent -> - // determine parent for root web application context, if any. - ApplicationContext parent = loadParentContext(servletContext); - cwac.setParent(parent); - } - configureAndRefreshWebApplicationContext(cwac, servletContext); + if (this.context instanceof ConfigurableWebApplicationContext cwac && !cwac.isActive()) { + // The context has not yet been refreshed -> provide services such as + // setting the parent context, setting the application context id, etc + if (cwac.getParent() == null) { + // The context instance was injected without an explicit parent -> + // determine parent for root web application context, if any. + ApplicationContext parent = loadParentContext(servletContext); + cwac.setParent(parent); } + configureAndRefreshWebApplicationContext(cwac, servletContext); } servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); @@ -392,8 +389,8 @@ protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicati // is refreshed; do it eagerly here to ensure servlet property sources are in place for // use in any post-processing or initialization that occurs below prior to #refresh ConfigurableEnvironment env = wac.getEnvironment(); - if (env instanceof ConfigurableWebEnvironment) { - ((ConfigurableWebEnvironment) env).initPropertySources(sc, null); + if (env instanceof ConfigurableWebEnvironment cwe) { + cwe.initPropertySources(sc, null); } customizeContext(sc, wac); @@ -512,8 +509,8 @@ protected ApplicationContext loadParentContext(ServletContext servletContext) { public void closeWebApplicationContext(ServletContext servletContext) { servletContext.log("Closing Spring root WebApplicationContext"); try { - if (this.context instanceof ConfigurableWebApplicationContext) { - ((ConfigurableWebApplicationContext) this.context).close(); + if (this.context instanceof ConfigurableWebApplicationContext cwac) { + cwac.close(); } } finally { diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequest.java b/spring-web/src/main/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequest.java index 18d29550bfd8..395166f84e92 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequest.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,7 +48,7 @@ public class StandardServletAsyncWebRequest extends ServletWebRequest implements private AsyncContext asyncContext; - private AtomicBoolean asyncCompleted = new AtomicBoolean(); + private final AtomicBoolean asyncCompleted = new AtomicBoolean(); private final List timeoutHandlers = new ArrayList<>(); diff --git a/spring-web/src/main/java/org/springframework/web/context/support/RequestHandledEvent.java b/spring-web/src/main/java/org/springframework/web/context/support/RequestHandledEvent.java index 30d32153ebb0..4ee3ec2367a0 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/RequestHandledEvent.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/RequestHandledEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,11 +38,11 @@ public class RequestHandledEvent extends ApplicationEvent { /** Session id that applied to the request, if any. */ @Nullable - private String sessionId; + private final String sessionId; /** Usually the UserPrincipal. */ @Nullable - private String userName; + private final String userName; /** Request processing time. */ private final long processingTimeMillis; diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java index 3942fa0deab7..bf498cda8587 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -241,10 +241,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ServletContextResource)) { + if (!(other instanceof ServletContextResource otherRes)) { return false; } - ServletContextResource otherRes = (ServletContextResource) other; return (this.servletContext.equals(otherRes.servletContext) && this.path.equals(otherRes.path)); } diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResourcePatternResolver.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResourcePatternResolver.java index c9bd0c447e9a..e452d222ecc9 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResourcePatternResolver.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResourcePatternResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -80,8 +80,7 @@ public ServletContextResourcePatternResolver(ResourceLoader resourceLoader) { protected Set doFindPathMatchingFileResources(Resource rootDirResource, String subPattern) throws IOException { - if (rootDirResource instanceof ServletContextResource) { - ServletContextResource scResource = (ServletContextResource) rootDirResource; + if (rootDirResource instanceof ServletContextResource scResource) { ServletContext sc = scResource.getServletContext(); String fullPattern = scResource.getPath() + subPattern; Set result = new LinkedHashSet<>(8); diff --git a/spring-web/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java b/spring-web/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java index dff469446ad2..8a85966ed353 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java +++ b/spring-web/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -300,12 +300,9 @@ public void destroy() { protected WebApplicationContext findWebApplicationContext() { if (this.webApplicationContext != null) { // The user has injected a context at construction time -> use it... - if (this.webApplicationContext instanceof ConfigurableApplicationContext) { - ConfigurableApplicationContext cac = (ConfigurableApplicationContext) this.webApplicationContext; - if (!cac.isActive()) { - // The context has not yet been refreshed -> do so before returning it... - cac.refresh(); - } + if (this.webApplicationContext instanceof ConfigurableApplicationContext cac && !cac.isActive()) { + // The context has not yet been refreshed -> do so before returning it... + cac.refresh(); } return this.webApplicationContext; } diff --git a/spring-web/src/main/java/org/springframework/web/filter/FormContentFilter.java b/spring-web/src/main/java/org/springframework/web/filter/FormContentFilter.java index a66a2ba49eca..bad214fb5d59 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/FormContentFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/FormContentFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -126,7 +126,7 @@ private boolean shouldParse(HttpServletRequest request) { private static class FormContentRequestWrapper extends HttpServletRequestWrapper { - private MultiValueMap formParams; + private final MultiValueMap formParams; public FormContentRequestWrapper(HttpServletRequest request, MultiValueMap params) { super(request); diff --git a/spring-web/src/main/java/org/springframework/web/filter/HttpPutFormContentFilter.java b/spring-web/src/main/java/org/springframework/web/filter/HttpPutFormContentFilter.java index acb0c0fbfe23..66745fc0cb1d 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/HttpPutFormContentFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/HttpPutFormContentFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -132,7 +132,7 @@ private boolean isFormContentType(HttpServletRequest request) { private static class HttpPutFormContentRequestWrapper extends HttpServletRequestWrapper { - private MultiValueMap formParameters; + private final MultiValueMap formParameters; public HttpPutFormContentRequestWrapper(HttpServletRequest request, MultiValueMap parameters) { super(request); diff --git a/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java b/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java index 953bda7f8692..6f505363829f 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java @@ -64,6 +64,7 @@ * * @author Juergen Hoeller * @author Rossen Stoyanchev + * @author Sam Brannen * @since 06.12.2003 */ public abstract class OncePerRequestFilter extends GenericFilterBean { @@ -88,22 +89,18 @@ public abstract class OncePerRequestFilter extends GenericFilterBean { public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { - if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) { + if (!((request instanceof HttpServletRequest httpRequest) && (response instanceof HttpServletResponse httpResponse))) { throw new ServletException("OncePerRequestFilter just supports HTTP requests"); } - HttpServletRequest httpRequest = (HttpServletRequest) request; - HttpServletResponse httpResponse = (HttpServletResponse) response; String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName(); boolean hasAlreadyFilteredAttribute = request.getAttribute(alreadyFilteredAttributeName) != null; if (skipDispatch(httpRequest) || shouldNotFilter(httpRequest)) { - // Proceed without invoking this filter... filterChain.doFilter(request, response); } else if (hasAlreadyFilteredAttribute) { - if (DispatcherType.ERROR.equals(request.getDispatcherType())) { doFilterNestedErrorDispatch(httpRequest, httpResponse, filterChain); return; diff --git a/spring-web/src/main/java/org/springframework/web/jsf/DecoratingNavigationHandler.java b/spring-web/src/main/java/org/springframework/web/jsf/DecoratingNavigationHandler.java index 98dd6cce8a61..f80280f2234c 100644 --- a/spring-web/src/main/java/org/springframework/web/jsf/DecoratingNavigationHandler.java +++ b/spring-web/src/main/java/org/springframework/web/jsf/DecoratingNavigationHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -135,10 +135,9 @@ protected final void callNextHandlerInChain(FacesContext facesContext, @Nullable NavigationHandler decoratedNavigationHandler = getDecoratedNavigationHandler(); - if (decoratedNavigationHandler instanceof DecoratingNavigationHandler) { + if (decoratedNavigationHandler instanceof DecoratingNavigationHandler decHandler) { // DecoratingNavigationHandler specified through constructor argument: // Call it with original NavigationHandler passed in. - DecoratingNavigationHandler decHandler = (DecoratingNavigationHandler) decoratedNavigationHandler; decHandler.handleNavigation(facesContext, fromAction, outcome, originalNavigationHandler); } else if (decoratedNavigationHandler != null) { diff --git a/spring-web/src/main/java/org/springframework/web/jsf/el/WebApplicationContextFacesELResolver.java b/spring-web/src/main/java/org/springframework/web/jsf/el/WebApplicationContextFacesELResolver.java index 86babdf0a48b..a991ed8a1c42 100644 --- a/spring-web/src/main/java/org/springframework/web/jsf/el/WebApplicationContextFacesELResolver.java +++ b/spring-web/src/main/java/org/springframework/web/jsf/el/WebApplicationContextFacesELResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,8 +70,7 @@ public class WebApplicationContextFacesELResolver extends ELResolver { @Nullable public Object getValue(ELContext elContext, @Nullable Object base, Object property) throws ELException { if (base != null) { - if (base instanceof WebApplicationContext) { - WebApplicationContext wac = (WebApplicationContext) base; + if (base instanceof WebApplicationContext wac) { String beanName = property.toString(); if (logger.isTraceEnabled()) { logger.trace("Attempting to resolve property '" + beanName + "' in root WebApplicationContext"); @@ -108,8 +107,7 @@ public Object getValue(ELContext elContext, @Nullable Object base, Object proper @Nullable public Class getType(ELContext elContext, @Nullable Object base, Object property) throws ELException { if (base != null) { - if (base instanceof WebApplicationContext) { - WebApplicationContext wac = (WebApplicationContext) base; + if (base instanceof WebApplicationContext wac) { String beanName = property.toString(); if (logger.isDebugEnabled()) { logger.debug("Attempting to resolve property '" + beanName + "' in root WebApplicationContext"); diff --git a/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java b/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java index b8e2436d5160..f9b353ac0c2a 100644 --- a/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java +++ b/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -176,16 +176,15 @@ public int getOrder() { resolvedBean = resolveBean(); } - if (resolvedBean instanceof Ordered) { - this.order = ((Ordered) resolvedBean).getOrder(); + if (resolvedBean instanceof Ordered ordered) { + this.order = ordered.getOrder(); } else { - if (beanName != null && this.beanFactory instanceof ConfigurableBeanFactory) { - ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) this.beanFactory; + if (beanName != null && this.beanFactory instanceof ConfigurableBeanFactory cbf) { try { BeanDefinition bd = cbf.getMergedBeanDefinition(beanName); - if (bd instanceof RootBeanDefinition) { - Method factoryMethod = ((RootBeanDefinition) bd).getResolvedFactoryMethod(); + if (bd instanceof RootBeanDefinition rbd) { + Method factoryMethod = rbd.getResolvedFactoryMethod(); if (factoryMethod != null) { this.order = OrderUtils.getOrder(factoryMethod); } @@ -261,10 +260,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ControllerAdviceBean)) { + if (!(other instanceof ControllerAdviceBean otherAdvice)) { return false; } - ControllerAdviceBean otherAdvice = (ControllerAdviceBean) other; return (this.beanOrName.equals(otherAdvice.beanOrName) && this.beanFactory == otherAdvice.beanFactory); } @@ -291,9 +289,9 @@ public String toString() { */ public static List findAnnotatedBeans(ApplicationContext context) { ListableBeanFactory beanFactory = context; - if (context instanceof ConfigurableApplicationContext) { + if (context instanceof ConfigurableApplicationContext cac) { // Use internal BeanFactory for potential downcast to ConfigurableBeanFactory above - beanFactory = ((ConfigurableApplicationContext) context).getBeanFactory(); + beanFactory = cac.getBeanFactory(); } List adviceBeans = new ArrayList<>(); for (String name : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Object.class)) { diff --git a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java index 80d6e7999eb4..541592c3363e 100644 --- a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java @@ -370,9 +370,8 @@ public HandlerMethod getResolvedFromHandlerMethod() { */ public HandlerMethod createWithResolvedBean() { Object handler = this.bean; - if (this.bean instanceof String) { + if (this.bean instanceof String beanName) { Assert.state(this.beanFactory != null, "Cannot resolve bean name without BeanFactory"); - String beanName = (String) this.bean; handler = this.beanFactory.getBean(beanName); } return new HandlerMethod(this, handler); @@ -428,10 +427,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof HandlerMethod)) { + if (!(other instanceof HandlerMethod otherMethod)) { return false; } - HandlerMethod otherMethod = (HandlerMethod) other; return (this.bean.equals(otherMethod.bean) && this.method.equals(otherMethod.method)); } diff --git a/spring-web/src/main/java/org/springframework/web/method/support/CompositeUriComponentsContributor.java b/spring-web/src/main/java/org/springframework/web/method/support/CompositeUriComponentsContributor.java index 9c20b6f3bbd4..2e2ffaf8fb48 100644 --- a/spring-web/src/main/java/org/springframework/web/method/support/CompositeUriComponentsContributor.java +++ b/spring-web/src/main/java/org/springframework/web/method/support/CompositeUriComponentsContributor.java @@ -36,6 +36,7 @@ * * @author Rossen Stoyanchev * @author Juergen Hoeller + * @author Sam Brannen * @since 4.0 */ public class CompositeUriComponentsContributor implements UriComponentsContributor { @@ -104,13 +105,13 @@ public boolean hasContributors() { @Override public boolean supportsParameter(MethodParameter parameter) { for (Object contributor : this.contributors) { - if (contributor instanceof UriComponentsContributor) { - if (((UriComponentsContributor) contributor).supportsParameter(parameter)) { + if (contributor instanceof UriComponentsContributor ucc) { + if (ucc.supportsParameter(parameter)) { return true; } } - else if (contributor instanceof HandlerMethodArgumentResolver) { - if (((HandlerMethodArgumentResolver) contributor).supportsParameter(parameter)) { + else if (contributor instanceof HandlerMethodArgumentResolver resolver) { + if (resolver.supportsParameter(parameter)) { return false; } } @@ -123,15 +124,14 @@ public void contributeMethodArgument(MethodParameter parameter, Object value, UriComponentsBuilder builder, Map uriVariables, ConversionService conversionService) { for (Object contributor : this.contributors) { - if (contributor instanceof UriComponentsContributor) { - UriComponentsContributor ucc = (UriComponentsContributor) contributor; + if (contributor instanceof UriComponentsContributor ucc) { if (ucc.supportsParameter(parameter)) { ucc.contributeMethodArgument(parameter, value, builder, uriVariables, conversionService); break; } } - else if (contributor instanceof HandlerMethodArgumentResolver) { - if (((HandlerMethodArgumentResolver) contributor).supportsParameter(parameter)) { + else if (contributor instanceof HandlerMethodArgumentResolver resolver) { + if (resolver.supportsParameter(parameter)) { break; } } diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/ByteArrayMultipartFileEditor.java b/spring-web/src/main/java/org/springframework/web/multipart/support/ByteArrayMultipartFileEditor.java index b5439e55899a..71068c296042 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/ByteArrayMultipartFileEditor.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/ByteArrayMultipartFileEditor.java @@ -33,8 +33,7 @@ public class ByteArrayMultipartFileEditor extends ByteArrayPropertyEditor { @Override public void setValue(@Nullable Object value) { - if (value instanceof MultipartFile) { - MultipartFile multipartFile = (MultipartFile) value; + if (value instanceof MultipartFile multipartFile) { try { super.setValue(multipartFile.getBytes()); } diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/StringMultipartFileEditor.java b/spring-web/src/main/java/org/springframework/web/multipart/support/StringMultipartFileEditor.java index 015663c274df..32bb903a9780 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/StringMultipartFileEditor.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/StringMultipartFileEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,8 +61,7 @@ public void setAsText(String text) { @Override public void setValue(Object value) { - if (value instanceof MultipartFile) { - MultipartFile multipartFile = (MultipartFile) value; + if (value instanceof MultipartFile multipartFile) { try { super.setValue(this.charsetName != null ? new String(multipartFile.getBytes(), this.charsetName) : diff --git a/spring-web/src/main/java/org/springframework/web/server/adapter/AbstractReactiveWebInitializer.java b/spring-web/src/main/java/org/springframework/web/server/adapter/AbstractReactiveWebInitializer.java index 93db78699c2c..6e18bec9bbeb 100644 --- a/spring-web/src/main/java/org/springframework/web/server/adapter/AbstractReactiveWebInitializer.java +++ b/spring-web/src/main/java/org/springframework/web/server/adapter/AbstractReactiveWebInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,6 +41,7 @@ * the {@link ServletHttpHandlerAdapter}. * * @author Rossen Stoyanchev + * @author Sam Brannen * @since 5.0.2 */ public abstract class AbstractReactiveWebInitializer implements WebApplicationInitializer { @@ -108,11 +109,8 @@ protected ApplicationContext createApplicationContext() { * Refresh the given application context, if necessary. */ protected void refreshApplicationContext(ApplicationContext context) { - if (context instanceof ConfigurableApplicationContext) { - ConfigurableApplicationContext cac = (ConfigurableApplicationContext) context; - if (!cac.isActive()) { - cac.refresh(); - } + if (context instanceof ConfigurableApplicationContext cac && !cac.isActive()) { + cac.refresh(); } } @@ -124,10 +122,8 @@ protected void refreshApplicationContext(ApplicationContext context) { * closed when {@code servletContext} is destroyed */ protected void registerCloseListener(ServletContext servletContext, ApplicationContext applicationContext) { - if (applicationContext instanceof ConfigurableApplicationContext) { - ConfigurableApplicationContext cac = (ConfigurableApplicationContext) applicationContext; - ServletContextDestroyedListener listener = new ServletContextDestroyedListener(cac); - servletContext.addListener(listener); + if (applicationContext instanceof ConfigurableApplicationContext cac) { + servletContext.addListener(new ServletContextDestroyedListener(cac)); } } diff --git a/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java b/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java index a037452b6061..1d5c5843cc73 100644 --- a/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java @@ -46,6 +46,7 @@ * @author Juergen Hoeller * @author Rossen Stoyanchev * @author Phillip Webb + * @author Sam Brannen * @since 3.1.3 * @see Hierarchical URIs */ @@ -552,10 +553,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof HierarchicalUriComponents)) { + if (!(other instanceof HierarchicalUriComponents otherComp)) { return false; } - HierarchicalUriComponents otherComp = (HierarchicalUriComponents) other; return (ObjectUtils.nullSafeEquals(getScheme(), otherComp.getScheme()) && ObjectUtils.nullSafeEquals(getUserInfo(), otherComp.getUserInfo()) && ObjectUtils.nullSafeEquals(getHost(), otherComp.getHost()) && @@ -925,8 +925,8 @@ public void copyToUriComponentsBuilder(UriComponentsBuilder builder) { @Override public boolean equals(@Nullable Object other) { - return (this == other || (other instanceof FullPathComponent && - getPath().equals(((FullPathComponent) other).getPath()))); + return (this == other || (other instanceof FullPathComponent fullPathComponent && + getPath().equals(fullPathComponent.getPath()))); } @Override @@ -999,8 +999,8 @@ public void copyToUriComponentsBuilder(UriComponentsBuilder builder) { @Override public boolean equals(@Nullable Object other) { - return (this == other || (other instanceof PathSegmentComponent && - getPathSegments().equals(((PathSegmentComponent) other).getPathSegments()))); + return (this == other || (other instanceof PathSegmentComponent pathSegmentComponent && + getPathSegments().equals(pathSegmentComponent.getPathSegments()))); } @Override diff --git a/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java b/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java index a588cffaf4dc..f6a231c47058 100644 --- a/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -161,10 +161,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof OpaqueUriComponents)) { + if (!(other instanceof OpaqueUriComponents otherComp)) { return false; } - OpaqueUriComponents otherComp = (OpaqueUriComponents) other; return (ObjectUtils.nullSafeEquals(getScheme(), otherComp.getScheme()) && ObjectUtils.nullSafeEquals(this.ssp, otherComp.ssp) && ObjectUtils.nullSafeEquals(getFragment(), otherComp.getFragment())); diff --git a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java index 6b2532a2a312..e2f44487490a 100644 --- a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,11 +48,12 @@ /** * Miscellaneous utilities for web applications. - * Used by various framework classes. + *

    Used by various framework classes. * * @author Rod Johnson * @author Juergen Hoeller * @author Sebastien Deleuze + * @author Sam Brannen */ public abstract class WebUtils { @@ -460,8 +461,8 @@ public static T getNativeRequest(ServletRequest request, @Nullable Class if (requiredType.isInstance(request)) { return (T) request; } - else if (request instanceof ServletRequestWrapper) { - return getNativeRequest(((ServletRequestWrapper) request).getRequest(), requiredType); + else if (request instanceof ServletRequestWrapper wrapper) { + return getNativeRequest(wrapper.getRequest(), requiredType); } } return null; @@ -482,8 +483,8 @@ public static T getNativeResponse(ServletResponse response, @Nullable Class< if (requiredType.isInstance(response)) { return (T) response; } - else if (response instanceof ServletResponseWrapper) { - return getNativeResponse(((ServletResponseWrapper) response).getResponse(), requiredType); + else if (response instanceof ServletResponseWrapper wrapper) { + return getNativeResponse(wrapper.getResponse(), requiredType); } } return null; @@ -649,8 +650,7 @@ public static String findParameterValue(ServletRequest request, String name) { public static String findParameterValue(Map parameters, String name) { // First try to get it as a normal name=value parameter Object value = parameters.get(name); - if (value instanceof String[]) { - String[] values = (String[]) value; + if (value instanceof String[] values) { return (values.length > 0 ? values[0] : null); } else if (value != null) { @@ -801,9 +801,9 @@ public static boolean isSameOrigin(HttpRequest request) { String scheme; String host; int port; - if (request instanceof ServletServerHttpRequest) { + if (request instanceof ServletServerHttpRequest servletServerHttpRequest) { // Build more efficiently if we can: we only need scheme, host, port for origin comparison - HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest(); + HttpServletRequest servletRequest = servletServerHttpRequest.getServletRequest(); scheme = servletRequest.getScheme(); host = servletRequest.getServerName(); port = servletRequest.getServerPort(); diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java b/spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java index ba87fd6b6f75..956aafe34a9b 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java @@ -430,10 +430,9 @@ else if (!StringUtils.hasLength(pattern2string.patternString)) { @Override public boolean equals(@Nullable Object other) { - if (!(other instanceof PathPattern)) { + if (!(other instanceof PathPattern otherPattern)) { return false; } - PathPattern otherPattern = (PathPattern) other; return (this.patternString.equals(otherPattern.getPatternString()) && getSeparator() == otherPattern.getSeparator() && this.caseSensitive == otherPattern.caseSensitive); @@ -726,10 +725,7 @@ boolean isSeparator(int pathIndex) { */ String pathElementValue(int pathIndex) { Element element = (pathIndex < this.pathLength) ? this.pathElements.get(pathIndex) : null; - if (element instanceof PathContainer.PathSegment) { - return ((PathContainer.PathSegment)element).valueToMatch(); - } - return ""; + return (element instanceof PathContainer.PathSegment pathSegment ? pathSegment.valueToMatch() : ""); } } From 8135ae6d38b19f0e15d792709331cc17ce5a6701 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 17 Oct 2021 13:30:05 +0200 Subject: [PATCH 268/735] Apply "instanceof pattern matching" in spring-webflux This commit also applies additional clean-up tasks such as the following. - final fields - diamond operator (<>) for anonymous inner classes - multi-catch This has only been applied to `src/main/java`. --- .../client/DefaultClientResponseBuilder.java | 8 +++---- .../client/ExchangeFilterFunctions.java | 8 +++---- .../ChangePathPatternParserVisitor.java | 5 ++--- .../server/DefaultEntityResponseBuilder.java | 2 +- .../server/DefaultServerRequestBuilder.java | 4 ++-- .../server/DefaultServerResponseBuilder.java | 5 ++--- .../handler/AbstractUrlHandlerMapping.java | 6 ++---- .../resource/CssLinkResourceTransformer.java | 5 ++--- .../resource/PathResourceResolver.java | 21 +++++++++---------- .../resource/ResourceUrlProvider.java | 3 +-- .../reactive/resource/ResourceWebHandler.java | 13 ++++-------- .../resource/VersionResourceResolver.java | 8 +++---- .../method/AbstractHandlerMethodMapping.java | 13 ++++++------ .../result/method/InvocableHandlerMethod.java | 3 +-- .../result/method/RequestMappingInfo.java | 3 +-- .../reactive/result/view/RequestContext.java | 16 +++++++------- .../result/view/ViewResolverSupport.java | 4 ++-- .../web/reactive/socket/CloseStatus.java | 5 ++--- .../web/reactive/socket/WebSocketMessage.java | 5 ++--- .../StandardWebSocketHandlerAdapter.java | 17 ++++++++------- 20 files changed, 68 insertions(+), 86 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponseBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponseBuilder.java index 055a1d9ed5c2..a63ba76bf7e0 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponseBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponseBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,7 +66,7 @@ public HttpHeaders getHeaders() { }; - private ExchangeStrategies strategies; + private final ExchangeStrategies strategies; private int statusCode = 200; @@ -104,8 +104,8 @@ public HttpHeaders getHeaders() { this.headers.addAll(other.headers().asHttpHeaders()); } this.originalResponse = other; - this.request = (other instanceof DefaultClientResponse ? - ((DefaultClientResponse) other).request() : EMPTY_REQUEST); + this.request = (other instanceof DefaultClientResponse defaultClientResponse ? + defaultClientResponse.request() : EMPTY_REQUEST); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunctions.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunctions.java index b7d6c3d72005..42ad43e22c4f 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunctions.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunctions.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -116,8 +116,7 @@ public static ExchangeFilterFunction basicAuthentication(String username, String public static ExchangeFilterFunction basicAuthentication() { return (request, next) -> { Object attr = request.attributes().get(BASIC_AUTHENTICATION_CREDENTIALS_ATTRIBUTE); - if (attr instanceof Credentials) { - Credentials cred = (Credentials) attr; + if (attr instanceof Credentials cred) { return next.exchange(ClientRequest.from(request) .headers(headers -> headers.setBasicAuth(cred.username, cred.password)) .build()); @@ -174,10 +173,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof Credentials)) { + if (!(other instanceof Credentials otherCred)) { return false; } - Credentials otherCred = (Credentials) other; return (this.username.equals(otherCred.username) && this.password.equals(otherCred.password)); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ChangePathPatternParserVisitor.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ChangePathPatternParserVisitor.java index 10f34a3e7656..dc971a467ac1 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ChangePathPatternParserVisitor.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ChangePathPatternParserVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,8 +70,7 @@ public void unknown(RouterFunction routerFunction) { } private void changeParser(RequestPredicate predicate) { - if (predicate instanceof Target) { - Target target = (Target) predicate; + if (predicate instanceof Target target) { target.changeParser(this.parser); } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultEntityResponseBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultEntityResponseBuilder.java index d43a4e71f1a5..461a82efd28d 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultEntityResponseBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultEntityResponseBuilder.java @@ -195,7 +195,7 @@ public EntityResponse.Builder varyBy(String... requestHeaders) { @Override public Mono> build() { - return Mono.just(new DefaultEntityResponse( + return Mono.just(new DefaultEntityResponse<>( this.status, this.headers, this.cookies, this.entity, this.inserter, this.hints)); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java index 940118866f4c..174899b88946 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -69,7 +69,7 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder { private final List> messageReaders; - private ServerWebExchange exchange; + private final ServerWebExchange exchange; private String methodName; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java index da71fbe565a1..cf4452b60eac 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,8 +78,7 @@ public DefaultServerResponseBuilder(ServerResponse other) { Assert.notNull(other, "ServerResponse must not be null"); this.headers.addAll(other.headers()); this.cookies.addAll(other.cookies()); - if (other instanceof AbstractServerResponse) { - AbstractServerResponse abstractOther = (AbstractServerResponse) other; + if (other instanceof AbstractServerResponse abstractOther) { this.statusCode = abstractOther.statusCode; this.hints.putAll(abstractOther.hints); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java index abaf4cf86f96..417d7f47c8fa 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java @@ -153,8 +153,7 @@ protected Object lookupHandler(PathContainer lookupPath, ServerWebExchange excha Object handler = this.handlerMap.get(pattern); // Bean name or resolved handler? - if (handler instanceof String) { - String handlerName = (String) handler; + if (handler instanceof String handlerName) { handler = obtainApplicationContext().getBean(handlerName); } @@ -223,8 +222,7 @@ protected void registerHandler(String urlPath, Object handler) throws BeansExcep } // Eagerly resolve handler if referencing singleton via name. - if (!this.lazyInitHandlers && handler instanceof String) { - String handlerName = (String) handler; + if (!this.lazyInitHandlers && handler instanceof String handlerName) { if (obtainApplicationContext().isSingleton(handlerName)) { resolvedHandler = obtainApplicationContext().getBean(handlerName); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java index 3d96ff0b571b..ab0dfd4c6c7b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -288,10 +288,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ContentChunkInfo)) { + if (!(other instanceof ContentChunkInfo otherCci)) { return false; } - ContentChunkInfo otherCci = (ContentChunkInfo) other; return (this.start == otherCci.start && this.end == otherCci.end); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/PathResourceResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/PathResourceResolver.java index dd86b8e9a264..e99c3978790c 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/PathResourceResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/PathResourceResolver.java @@ -42,6 +42,7 @@ * expected to be configured at the end in a chain of resolvers. * * @author Rossen Stoyanchev + * @author Sam Brannen * @since 5.0 */ public class PathResourceResolver extends AbstractResourceResolver { @@ -119,11 +120,12 @@ protected Mono getResource(String resourcePath, Resource location) { return Mono.just(resource); } else if (logger.isWarnEnabled()) { - Resource[] allowedLocations = getAllowedLocations(); - logger.warn("Resource path \"" + resourcePath + "\" was successfully resolved " + - "but resource \"" + resource.getURL() + "\" is neither under the " + - "current location \"" + location.getURL() + "\" nor under any of the " + - "allowed locations " + (allowedLocations != null ? Arrays.asList(allowedLocations) : "[]")); + Object allowedLocationsText = (getAllowedLocations() != null ? Arrays.asList(getAllowedLocations()) : "[]"); + logger.warn(""" + Resource path "%s" was successfully resolved, but resource \ + "%s" is neither under the current location "%s" nor under any \ + of the allowed locations %s"\ + """.formatted(resourcePath, resource.getURL(),location.getURL(), allowedLocationsText)); } } return Mono.empty(); @@ -177,8 +179,8 @@ private boolean isResourceUnderLocation(Resource resource, Resource location) th resourcePath = resource.getURL().toExternalForm(); locationPath = StringUtils.cleanPath(location.getURL().toString()); } - else if (resource instanceof ClassPathResource) { - resourcePath = ((ClassPathResource) resource).getPath(); + else if (resource instanceof ClassPathResource classPathResource) { + resourcePath = classPathResource.getPath(); locationPath = StringUtils.cleanPath(((ClassPathResource) location).getPath()); } else { @@ -203,10 +205,7 @@ private boolean isInvalidEncodedPath(String resourcePath) { return true; } } - catch (IllegalArgumentException ex) { - // May not be possible to decode... - } - catch (UnsupportedEncodingException ex) { + catch (IllegalArgumentException | UnsupportedEncodingException ex) { // Should never happen... } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceUrlProvider.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceUrlProvider.java index b78d85320085..8f3e3b0bbf06 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceUrlProvider.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceUrlProvider.java @@ -106,8 +106,7 @@ private void detectResourceHandlers(ApplicationContext context) { mappings.forEach(mapping -> mapping.getHandlerMap().forEach((pattern, handler) -> { - if (handler instanceof ResourceWebHandler) { - ResourceWebHandler resourceHandler = (ResourceWebHandler) handler; + if (handler instanceof ResourceWebHandler resourceHandler) { this.handlerMap.put(pattern, resourceHandler); } })); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java index 75ac8ddd320e..50fe84bf2014 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java @@ -354,8 +354,7 @@ protected void initAllowedLocations() { return; } for (int i = getResourceResolvers().size() - 1; i >= 0; i--) { - if (getResourceResolvers().get(i) instanceof PathResourceResolver) { - PathResourceResolver resolver = (PathResourceResolver) getResourceResolvers().get(i); + if (getResourceResolvers().get(i) instanceof PathResourceResolver resolver) { if (ObjectUtils.isEmpty(resolver.getAllowedLocations())) { resolver.setAllowedLocations(getLocations().toArray(new Resource[0])); } @@ -522,10 +521,7 @@ private boolean isInvalidEncodedPath(String path) { return true; } } - catch (IllegalArgumentException ex) { - // May not be possible to decode... - } - catch (UnsupportedEncodingException ex) { + catch (IllegalArgumentException | UnsupportedEncodingException ex) { // Should never happen... } } @@ -609,9 +605,8 @@ protected void setHeaders(ServerWebExchange exchange, Resource resource, @Nullab headers.setContentType(mediaType); } - if (resource instanceof HttpResource) { - HttpHeaders resourceHeaders = ((HttpResource) resource).getResponseHeaders(); - exchange.getResponse().getHeaders().putAll(resourceHeaders); + if (resource instanceof HttpResource httpResource) { + exchange.getResponse().getHeaders().putAll(httpResource.getResponseHeaders()); } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/VersionResourceResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/VersionResourceResolver.java index ff712f7068ba..d923e96024c8 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/VersionResourceResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/VersionResourceResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,7 +65,7 @@ */ public class VersionResourceResolver extends AbstractResourceResolver { - private AntPathMatcher pathMatcher = new AntPathMatcher(); + private final AntPathMatcher pathMatcher = new AntPathMatcher(); /** Map from path pattern -> VersionStrategy. */ private final Map versionStrategyMap = new LinkedHashMap<>(); @@ -315,8 +315,8 @@ public InputStream getInputStream() throws IOException { @Override public HttpHeaders getResponseHeaders() { - HttpHeaders headers = (this.original instanceof HttpResource ? - ((HttpResource) this.original).getResponseHeaders() : new HttpHeaders()); + HttpHeaders headers = (this.original instanceof HttpResource httpResource ? + httpResource.getResponseHeaders() : new HttpHeaders()); headers.setETag("W/\"" + this.version + "\""); return headers; } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java index 7d59209955d6..f1210150d0f1 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java @@ -200,8 +200,8 @@ protected void initHandlerMethods() { * @param handler the bean name of a handler or a handler instance */ protected void detectHandlerMethods(final Object handler) { - Class handlerType = (handler instanceof String ? - obtainApplicationContext().getType((String) handler) : handler.getClass()); + Class handlerType = (handler instanceof String beanName ? + obtainApplicationContext().getType(beanName) : handler.getClass()); if (handlerType != null) { final Class userType = ClassUtils.getUserClass(handlerType); @@ -258,8 +258,8 @@ protected void registerHandlerMethod(Object handler, Method method, T mapping) { * @return the created HandlerMethod */ protected HandlerMethod createHandlerMethod(Object handler, Method method) { - if (handler instanceof String) { - return new HandlerMethod((String) handler, + if (handler instanceof String beanName) { + return new HandlerMethod(beanName, obtainApplicationContext().getAutowireCapableBeanFactory(), obtainApplicationContext(), method); @@ -397,14 +397,13 @@ protected HandlerMethod handleNoMatch(Set mappings, ServerWebExchange exchang @Override protected boolean hasCorsConfigurationSource(Object handler) { return super.hasCorsConfigurationSource(handler) || - (handler instanceof HandlerMethod && this.mappingRegistry.getCorsConfiguration((HandlerMethod) handler) != null); + (handler instanceof HandlerMethod handlerMethod && this.mappingRegistry.getCorsConfiguration(handlerMethod) != null); } @Override protected CorsConfiguration getCorsConfiguration(Object handler, ServerWebExchange exchange) { CorsConfiguration corsConfig = super.getCorsConfiguration(handler, exchange); - if (handler instanceof HandlerMethod) { - HandlerMethod handlerMethod = (HandlerMethod) handler; + if (handler instanceof HandlerMethod handlerMethod) { if (handlerMethod.equals(PREFLIGHT_AMBIGUOUS_MATCH)) { return ALLOW_CORS_CONFIG; } 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 b117a197aa8e..4a2fee3ef118 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 @@ -224,8 +224,7 @@ private static boolean isAsyncVoidReturnType(MethodParameter returnType, @Nullab return true; } Type parameterType = returnType.getGenericParameterType(); - if (parameterType instanceof ParameterizedType) { - ParameterizedType type = (ParameterizedType) parameterType; + if (parameterType instanceof ParameterizedType type) { if (type.getActualTypeArguments().length == 1) { return Void.class.equals(type.getActualTypeArguments()[0]); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfo.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfo.java index 8782b9a5b831..2842d1213f4a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfo.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfo.java @@ -343,10 +343,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof RequestMappingInfo)) { + if (!(other instanceof RequestMappingInfo otherInfo)) { return false; } - RequestMappingInfo otherInfo = (RequestMappingInfo) other; return (this.patternsCondition.equals(otherInfo.patternsCondition) && this.methodsCondition.equals(otherInfo.methodsCondition) && this.paramsCondition.equals(otherInfo.paramsCondition) && diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestContext.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestContext.java index b964acb6ebde..b1dfca61f158 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestContext.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +72,7 @@ public class RequestContext { private Map errorsMap; @Nullable - private RequestDataValueProcessor dataValueProcessor; + private final RequestDataValueProcessor dataValueProcessor; public RequestContext(ServerWebExchange exchange, Map model, MessageSource messageSource) { @@ -92,8 +92,8 @@ public RequestContext(ServerWebExchange exchange, Map model, Mes LocaleContext localeContext = exchange.getLocaleContext(); Locale locale = localeContext.getLocale(); this.locale = (locale != null ? locale : Locale.getDefault()); - TimeZone timeZone = (localeContext instanceof TimeZoneAwareLocaleContext ? - ((TimeZoneAwareLocaleContext) localeContext).getTimeZone() : null); + TimeZone timeZone = (localeContext instanceof TimeZoneAwareLocaleContext tzaLocaleContext ? + tzaLocaleContext.getTimeZone() : null); this.timeZone = (timeZone != null ? timeZone : TimeZone.getDefault()); this.defaultHtmlEscape = null; // TODO @@ -385,15 +385,15 @@ public Errors getErrors(String name, boolean htmlEscape) { } } - if (errors instanceof BindException) { - errors = ((BindException) errors).getBindingResult(); + if (errors instanceof BindException bindException) { + errors = bindException.getBindingResult(); } if (htmlEscape && !(errors instanceof EscapedErrors)) { errors = new EscapedErrors(errors); } - else if (!htmlEscape && errors instanceof EscapedErrors) { - errors = ((EscapedErrors) errors).getSource(); + else if (!htmlEscape && errors instanceof EscapedErrors escapedErrors) { + errors = escapedErrors.getSource(); } this.errorsMap.put(name, errors); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolverSupport.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolverSupport.java index e97a983af5c2..6d0db61d1498 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolverSupport.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolverSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ public abstract class ViewResolverSupport implements Ordered { public static final MediaType DEFAULT_CONTENT_TYPE = MediaType.parseMediaType("text/html;charset=UTF-8"); - private List mediaTypes = new ArrayList<>(4); + private final List mediaTypes = new ArrayList<>(4); private Charset defaultCharset = StandardCharsets.UTF_8; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/CloseStatus.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/CloseStatus.java index 304eb797d790..603f2ba16561 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/CloseStatus.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/CloseStatus.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -239,10 +239,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof CloseStatus)) { + if (!(other instanceof CloseStatus otherStatus)) { return false; } - CloseStatus otherStatus = (CloseStatus) other; return (this.code == otherStatus.code && ObjectUtils.nullSafeEquals(this.reason, otherStatus.reason)); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketMessage.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketMessage.java index 32175f160b54..b7d4de6937d4 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketMessage.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketMessage.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -151,10 +151,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof WebSocketMessage)) { + if (!(other instanceof WebSocketMessage otherMessage)) { return false; } - WebSocketMessage otherMessage = (WebSocketMessage) other; return (this.type.equals(otherMessage.type) && ObjectUtils.nullSafeEquals(this.payload, otherMessage.payload)); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/StandardWebSocketHandlerAdapter.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/StandardWebSocketHandlerAdapter.java index d4699ca32e0a..68fed3f2b5db 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/StandardWebSocketHandlerAdapter.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/StandardWebSocketHandlerAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,13 +41,14 @@ * * @author Violeta Georgieva * @author Rossen Stoyanchev + * @author Sam Brannen * @since 5.0 */ public class StandardWebSocketHandlerAdapter extends Endpoint { private final WebSocketHandler delegateHandler; - private Function sessionFactory; + private final Function sessionFactory; @Nullable private StandardWebSocketSession delegateSession; @@ -89,16 +90,16 @@ public void onOpen(Session session, EndpointConfig config) { private WebSocketMessage toMessage(T message) { WebSocketSession session = this.delegateSession; Assert.state(session != null, "Cannot create message without a session"); - if (message instanceof String) { - byte[] bytes = ((String) message).getBytes(StandardCharsets.UTF_8); + if (message instanceof String text) { + byte[] bytes = text.getBytes(StandardCharsets.UTF_8); return new WebSocketMessage(Type.TEXT, session.bufferFactory().wrap(bytes)); } - else if (message instanceof ByteBuffer) { - DataBuffer buffer = session.bufferFactory().wrap((ByteBuffer) message); + else if (message instanceof ByteBuffer byteBuffer) { + DataBuffer buffer = session.bufferFactory().wrap(byteBuffer); return new WebSocketMessage(Type.BINARY, buffer); } - else if (message instanceof PongMessage) { - DataBuffer buffer = session.bufferFactory().wrap(((PongMessage) message).getApplicationData()); + else if (message instanceof PongMessage pongMessage) { + DataBuffer buffer = session.bufferFactory().wrap(pongMessage.getApplicationData()); return new WebSocketMessage(Type.PONG, buffer); } else { From 1f248b34f6a39e7741eb30965bc8d4cb74051b0e Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 17 Oct 2021 18:49:02 +0200 Subject: [PATCH 269/735] Apply "instanceof pattern matching" in spring-webmvc This commit also applies additional clean-up tasks such as the following. - final fields - diamond operator (<>) for anonymous inner classes - try with resources - multi-catch This has only been applied to `src/main/java`. --- .../springframework/web/servlet/FlashMap.java | 5 +- .../web/servlet/FrameworkServlet.java | 35 +++++------ .../web/servlet/HandlerExecutionChain.java | 8 +-- .../AnnotationDrivenBeanDefinitionParser.java | 5 +- .../annotation/ViewControllerRegistry.java | 4 +- .../annotation/ViewResolverRegistry.java | 6 +- .../ChangePathPatternParserVisitor.java | 5 +- .../DefaultEntityResponseBuilder.java | 11 ++-- .../function/DefaultServerRequest.java | 19 +++--- .../servlet/function/RequestPredicates.java | 23 ++++---- .../handler/AbstractHandlerMapping.java | 59 +++++++++---------- ...bstractHandlerMethodExceptionResolver.java | 5 +- .../handler/AbstractHandlerMethodMapping.java | 15 +++-- .../handler/AbstractUrlHandlerMapping.java | 15 ++--- .../SimpleMappingExceptionResolver.java | 4 +- .../WebRequestHandlerInterceptorAdapter.java | 5 +- .../mvc/ParameterizableViewController.java | 3 +- .../servlet/mvc/WebContentInterceptor.java | 14 ++--- .../mvc/method/RequestMappingInfo.java | 3 +- .../annotation/HttpEntityMethodProcessor.java | 20 +++---- .../RequestResponseBodyAdviceChain.java | 9 ++- .../ResponseEntityExceptionHandler.java | 6 +- .../ViewMethodReturnValueHandler.java | 3 +- .../resource/CssLinkResourceTransformer.java | 5 +- .../resource/PathResourceResolver.java | 15 ++--- .../resource/ResourceHttpRequestHandler.java | 14 ++--- .../servlet/resource/ResourceUrlProvider.java | 3 +- .../resource/VersionResourceResolver.java | 8 +-- .../support/JspAwareRequestContext.java | 8 +-- .../web/servlet/support/RequestContext.java | 10 ++-- .../tags/form/SelectedValueComparator.java | 15 +++-- .../view/AbstractCachingViewResolver.java | 4 +- .../view/ContentNegotiatingViewResolver.java | 5 +- .../view/json/AbstractJackson2View.java | 5 +- .../view/script/ScriptTemplateView.java | 5 +- .../web/servlet/view/xslt/XsltView.java | 34 +++++------ 36 files changed, 185 insertions(+), 228 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/FlashMap.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/FlashMap.java index c1a814589afd..d0904bb8ac1b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/FlashMap.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/FlashMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -165,10 +165,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof FlashMap)) { + if (!(other instanceof FlashMap otherFlashMap)) { return false; } - FlashMap otherFlashMap = (FlashMap) other; return (super.equals(otherFlashMap) && ObjectUtils.nullSafeEquals(this.targetRequestPath, otherFlashMap.targetRequestPath) && this.targetRequestParams.equals(otherFlashMap.targetRequestParams)); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java index ea0f30431854..36510490adee 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java @@ -507,8 +507,8 @@ public boolean isEnableLoggingRequestDetails() { */ @Override public void setApplicationContext(ApplicationContext applicationContext) { - if (this.webApplicationContext == null && applicationContext instanceof WebApplicationContext) { - this.webApplicationContext = (WebApplicationContext) applicationContext; + if (this.webApplicationContext == null && applicationContext instanceof WebApplicationContext wac) { + this.webApplicationContext = wac; this.webApplicationContextInjected = true; } } @@ -565,18 +565,15 @@ protected WebApplicationContext initWebApplicationContext() { if (this.webApplicationContext != null) { // A context instance was injected at construction time -> use it wac = this.webApplicationContext; - if (wac instanceof ConfigurableWebApplicationContext) { - ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac; - if (!cwac.isActive()) { - // The context has not yet been refreshed -> provide services such as - // setting the parent context, setting the application context id, etc - if (cwac.getParent() == null) { - // The context instance was injected without an explicit parent -> set - // the root application context (if any; may be null) as the parent - cwac.setParent(rootContext); - } - configureAndRefreshWebApplicationContext(cwac); + if (wac instanceof ConfigurableWebApplicationContext cwac && !cwac.isActive()) { + // The context has not yet been refreshed -> provide services such as + // setting the parent context, setting the application context id, etc + if (cwac.getParent() == null) { + // The context instance was injected without an explicit parent -> set + // the root application context (if any; may be null) as the parent + cwac.setParent(rootContext); } + configureAndRefreshWebApplicationContext(cwac); } } if (wac == null) { @@ -693,8 +690,8 @@ protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicati // is refreshed; do it eagerly here to ensure servlet property sources are in place for // use in any post-processing or initialization that occurs below prior to #refresh ConfigurableEnvironment env = wac.getEnvironment(); - if (env instanceof ConfigurableWebEnvironment) { - ((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig()); + if (env instanceof ConfigurableWebEnvironment cwe) { + cwe.initPropertySources(getServletContext(), getServletConfig()); } postProcessWebApplicationContext(wac); @@ -824,10 +821,10 @@ protected void initFrameworkServlet() throws ServletException { */ public void refresh() { WebApplicationContext wac = getWebApplicationContext(); - if (!(wac instanceof ConfigurableApplicationContext)) { + if (!(wac instanceof ConfigurableApplicationContext cac)) { throw new IllegalStateException("WebApplicationContext does not support refresh: " + wac); } - ((ConfigurableApplicationContext) wac).refresh(); + cac.refresh(); } /** @@ -862,8 +859,8 @@ protected void onRefresh(ApplicationContext context) { public void destroy() { getServletContext().log("Destroying Spring FrameworkServlet '" + getServletName() + "'"); // Only call close() on WebApplicationContext if locally managed... - if (this.webApplicationContext instanceof ConfigurableApplicationContext && !this.webApplicationContextInjected) { - ((ConfigurableApplicationContext) this.webApplicationContext).close(); + if (!this.webApplicationContextInjected && this.webApplicationContext instanceof ConfigurableApplicationContext cac) { + cac.close(); } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExecutionChain.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExecutionChain.java index 76f5cb357712..f90bf35cc012 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExecutionChain.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExecutionChain.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,8 +74,7 @@ public HandlerExecutionChain(Object handler, @Nullable HandlerInterceptor... int * @since 5.3 */ public HandlerExecutionChain(Object handler, List interceptorList) { - if (handler instanceof HandlerExecutionChain) { - HandlerExecutionChain originalChain = (HandlerExecutionChain) handler; + if (handler instanceof HandlerExecutionChain originalChain) { this.handler = originalChain.getHandler(); this.interceptorList.addAll(originalChain.interceptorList); } @@ -188,9 +187,8 @@ void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse resp void applyAfterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response) { for (int i = this.interceptorList.size() - 1; i >= 0; i--) { HandlerInterceptor interceptor = this.interceptorList.get(i); - if (interceptor instanceof AsyncHandlerInterceptor) { + if (interceptor instanceof AsyncHandlerInterceptor asyncInterceptor) { try { - AsyncHandlerInterceptor asyncInterceptor = (AsyncHandlerInterceptor) interceptor; asyncInterceptor.afterConcurrentHandlingStarted(request, response, this.handler); } catch (Throwable ex) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java index 2684d24e5ea7..a4e4fa85eebf 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -514,8 +514,7 @@ private ManagedList getArgumentResolvers(Element element, ParserContext conte private ManagedList wrapLegacyResolvers(List list, ParserContext context) { ManagedList result = new ManagedList<>(); for (Object object : list) { - if (object instanceof BeanDefinitionHolder) { - BeanDefinitionHolder beanDef = (BeanDefinitionHolder) object; + if (object instanceof BeanDefinitionHolder beanDef) { String className = beanDef.getBeanDefinition().getBeanClassName(); Assert.notNull(className, "No resolver class"); Class clazz = ClassUtils.resolveClassName(className, context.getReaderContext().getBeanClassLoader()); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistry.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistry.java index 3cedaf21449b..1bfdd3d65c7b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistry.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,7 @@ public class ViewControllerRegistry { @Nullable - private ApplicationContext applicationContext; + private final ApplicationContext applicationContext; private final List registrations = new ArrayList<>(4); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolverRegistry.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolverRegistry.java index 87c414d27792..14443da995fe 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolverRegistry.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolverRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,10 +53,10 @@ public class ViewResolverRegistry { @Nullable - private ContentNegotiationManager contentNegotiationManager; + private final ContentNegotiationManager contentNegotiationManager; @Nullable - private ApplicationContext applicationContext; + private final ApplicationContext applicationContext; @Nullable private ContentNegotiatingViewResolver contentNegotiatingResolver; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ChangePathPatternParserVisitor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ChangePathPatternParserVisitor.java index 264a30bf6793..9fbc37e01340 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ChangePathPatternParserVisitor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/ChangePathPatternParserVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -69,8 +69,7 @@ public void unknown(RouterFunction routerFunction) { } private void changeParser(RequestPredicate predicate) { - if (predicate instanceof Target) { - Target target = (Target) predicate; + if (predicate instanceof Target target) { target.changeParser(this.parser); } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultEntityResponseBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultEntityResponseBuilder.java index cf674214be4b..68326e0027c3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultEntityResponseBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultEntityResponseBuilder.java @@ -202,8 +202,7 @@ public EntityResponse.Builder varyBy(String... requestHeaders) { @SuppressWarnings({"rawtypes", "unchecked"}) @Override public EntityResponse build() { - if (this.entity instanceof CompletionStage) { - CompletionStage completionStage = (CompletionStage) this.entity; + if (this.entity instanceof CompletionStage completionStage) { return new CompletionStageEntityResponse(this.status, this.headers, this.cookies, completionStage, this.entityType); } @@ -264,7 +263,7 @@ protected ModelAndView writeToInternal(HttpServletRequest servletRequest, return null; } - @SuppressWarnings({ "unchecked", "resource" }) + @SuppressWarnings({ "unchecked", "resource", "rawtypes" }) protected void writeEntityWithMessageConverters(Object entity, HttpServletRequest request, HttpServletResponse response, ServerResponse.Context context) throws ServletException, IOException { @@ -294,16 +293,14 @@ protected void writeEntityWithMessageConverters(Object entity, HttpServletReques } for (HttpMessageConverter messageConverter : context.messageConverters()) { - if (messageConverter instanceof GenericHttpMessageConverter) { - GenericHttpMessageConverter genericMessageConverter = - (GenericHttpMessageConverter) messageConverter; + if (messageConverter instanceof GenericHttpMessageConverter genericMessageConverter) { if (genericMessageConverter.canWrite(entityType, entityClass, contentType)) { genericMessageConverter.write(entity, entityType, contentType, serverResponse); return; } } if (messageConverter.canWrite(entityClass, contentType)) { - ((HttpMessageConverter)messageConverter).write(entity, contentType, serverResponse); + ((HttpMessageConverter) messageConverter).write(entity, contentType, serverResponse); return; } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java index c874c05d7a63..81f3700daee0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java @@ -70,6 +70,7 @@ * {@code ServerRequest} implementation based on a {@link HttpServletRequest}. * * @author Arjen Poutsma + * @author Sam Brannen * @since 5.2 */ class DefaultServerRequest implements ServerRequest { @@ -171,14 +172,12 @@ public T body(ParameterizedTypeReference bodyType) throws IOException, Se } static Class bodyClass(Type type) { - if (type instanceof Class) { - return (Class) type; + if (type instanceof Class clazz) { + return clazz; } - if (type instanceof ParameterizedType) { - ParameterizedType parameterizedType = (ParameterizedType) type; - if (parameterizedType.getRawType() instanceof Class) { - return (Class) parameterizedType.getRawType(); - } + if (type instanceof ParameterizedType parameterizedType && + parameterizedType.getRawType() instanceof Class rawType) { + return rawType; } return Object.class; } @@ -188,11 +187,9 @@ private T bodyInternal(Type bodyType, Class bodyClass) throws ServletExce MediaType contentType = this.headers.contentType().orElse(MediaType.APPLICATION_OCTET_STREAM); for (HttpMessageConverter messageConverter : this.messageConverters) { - if (messageConverter instanceof GenericHttpMessageConverter) { - GenericHttpMessageConverter genericMessageConverter = - (GenericHttpMessageConverter) messageConverter; + if (messageConverter instanceof GenericHttpMessageConverter genericMessageConverter) { if (genericMessageConverter.canRead(bodyType, bodyClass, contentType)) { - return genericMessageConverter.read(bodyType, bodyClass, this.serverHttpRequest); + return (T) genericMessageConverter.read(bodyType, bodyClass, this.serverHttpRequest); } } if (messageConverter.canRead(bodyClass, contentType)) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java index e25a624599a0..d29a96271e9c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java @@ -65,6 +65,7 @@ * request matching operations, such as matching based on path, HTTP method, etc. * * @author Arjen Poutsma + * @author Sam Brannen * @since 5.2 */ public abstract class RequestPredicates { @@ -792,11 +793,11 @@ public void accept(Visitor visitor) { @Override public void changeParser(PathPatternParser parser) { - if (this.left instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) this.left).changeParser(parser); + if (this.left instanceof ChangePathPatternParserVisitor.Target target) { + target.changeParser(parser); } - if (this.right instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) this.right).changeParser(parser); + if (this.right instanceof ChangePathPatternParserVisitor.Target target) { + target.changeParser(parser); } } @@ -837,8 +838,8 @@ public void accept(Visitor visitor) { @Override public void changeParser(PathPatternParser parser) { - if (this.delegate instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) this.delegate).changeParser(parser); + if (this.delegate instanceof ChangePathPatternParserVisitor.Target target) { + target.changeParser(parser); } } @@ -904,11 +905,11 @@ public void accept(Visitor visitor) { @Override public void changeParser(PathPatternParser parser) { - if (this.left instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) this.left).changeParser(parser); + if (this.left instanceof ChangePathPatternParserVisitor.Target target) { + target.changeParser(parser); } - if (this.right instanceof ChangePathPatternParserVisitor.Target) { - ((ChangePathPatternParserVisitor.Target) this.right).changeParser(parser); + if (this.right instanceof ChangePathPatternParserVisitor.Target target) { + target.changeParser(parser); } } @@ -923,7 +924,7 @@ private static class SubPathServerRequestWrapper implements ServerRequest { private final ServerRequest request; - private RequestPath requestPath; + private final RequestPath requestPath; private final Map attributes; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java index f100a8ad33ae..0f4f30ae3293 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java @@ -68,6 +68,7 @@ * * @author Juergen Hoeller * @author Rossen Stoyanchev + * @author Sam Brannen * @since 07.04.2003 * @see #getHandlerInternal * @see #setDefaultHandler @@ -179,8 +180,8 @@ public PathPatternParser getPatternParser() { @SuppressWarnings("deprecation") public void setAlwaysUseFullPath(boolean alwaysUseFullPath) { this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath); - if (this.corsConfigurationSource instanceof UrlBasedCorsConfigurationSource) { - ((UrlBasedCorsConfigurationSource) this.corsConfigurationSource).setAlwaysUseFullPath(alwaysUseFullPath); + if (this.corsConfigurationSource instanceof UrlBasedCorsConfigurationSource urlConfigSource) { + urlConfigSource.setAlwaysUseFullPath(alwaysUseFullPath); } } @@ -193,8 +194,8 @@ public void setAlwaysUseFullPath(boolean alwaysUseFullPath) { @SuppressWarnings("deprecation") public void setUrlDecode(boolean urlDecode) { this.urlPathHelper.setUrlDecode(urlDecode); - if (this.corsConfigurationSource instanceof UrlBasedCorsConfigurationSource) { - ((UrlBasedCorsConfigurationSource) this.corsConfigurationSource).setUrlDecode(urlDecode); + if (this.corsConfigurationSource instanceof UrlBasedCorsConfigurationSource urlConfigSource) { + urlConfigSource.setUrlDecode(urlDecode); } } @@ -207,8 +208,8 @@ public void setUrlDecode(boolean urlDecode) { @SuppressWarnings("deprecation") public void setRemoveSemicolonContent(boolean removeSemicolonContent) { this.urlPathHelper.setRemoveSemicolonContent(removeSemicolonContent); - if (this.corsConfigurationSource instanceof UrlBasedCorsConfigurationSource) { - ((UrlBasedCorsConfigurationSource) this.corsConfigurationSource).setRemoveSemicolonContent(removeSemicolonContent); + if (this.corsConfigurationSource instanceof UrlBasedCorsConfigurationSource urlConfigSource) { + urlConfigSource.setRemoveSemicolonContent(removeSemicolonContent); } } @@ -220,8 +221,8 @@ public void setRemoveSemicolonContent(boolean removeSemicolonContent) { public void setUrlPathHelper(UrlPathHelper urlPathHelper) { Assert.notNull(urlPathHelper, "UrlPathHelper must not be null"); this.urlPathHelper = urlPathHelper; - if (this.corsConfigurationSource instanceof UrlBasedCorsConfigurationSource) { - ((UrlBasedCorsConfigurationSource) this.corsConfigurationSource).setUrlPathHelper(urlPathHelper); + if (this.corsConfigurationSource instanceof UrlBasedCorsConfigurationSource urlConfigSource) { + urlConfigSource.setUrlPathHelper(urlPathHelper); } } @@ -242,8 +243,8 @@ public UrlPathHelper getUrlPathHelper() { public void setPathMatcher(PathMatcher pathMatcher) { Assert.notNull(pathMatcher, "PathMatcher must not be null"); this.pathMatcher = pathMatcher; - if (this.corsConfigurationSource instanceof UrlBasedCorsConfigurationSource) { - ((UrlBasedCorsConfigurationSource) this.corsConfigurationSource).setPathMatcher(pathMatcher); + if (this.corsConfigurationSource instanceof UrlBasedCorsConfigurationSource urlConfigSource) { + urlConfigSource.setPathMatcher(pathMatcher); } } @@ -311,8 +312,8 @@ public void setCorsConfigurations(Map corsConfigurati public void setCorsConfigurationSource(CorsConfigurationSource source) { Assert.notNull(source, "CorsConfigurationSource must not be null"); this.corsConfigurationSource = source; - if (source instanceof UrlBasedCorsConfigurationSource) { - ((UrlBasedCorsConfigurationSource) source).setAllowInitLookupPath(false); + if (source instanceof UrlBasedCorsConfigurationSource urlConfigSource) { + urlConfigSource.setAllowInitLookupPath(false); } } @@ -437,11 +438,11 @@ protected void initInterceptors() { * @see WebRequestHandlerInterceptorAdapter */ protected HandlerInterceptor adaptInterceptor(Object interceptor) { - if (interceptor instanceof HandlerInterceptor) { - return (HandlerInterceptor) interceptor; + if (interceptor instanceof HandlerInterceptor handlerInterceptor) { + return handlerInterceptor; } - else if (interceptor instanceof WebRequestInterceptor) { - return new WebRequestHandlerInterceptorAdapter((WebRequestInterceptor) interceptor); + else if (interceptor instanceof WebRequestInterceptor webRequestInterceptor) { + return new WebRequestHandlerInterceptorAdapter(webRequestInterceptor); } else { throw new IllegalArgumentException("Interceptor type not supported: " + interceptor.getClass().getName()); @@ -467,8 +468,8 @@ protected final HandlerInterceptor[] getAdaptedInterceptors() { protected final MappedInterceptor[] getMappedInterceptors() { List mappedInterceptors = new ArrayList<>(this.adaptedInterceptors.size()); for (HandlerInterceptor interceptor : this.adaptedInterceptors) { - if (interceptor instanceof MappedInterceptor) { - mappedInterceptors.add((MappedInterceptor) interceptor); + if (interceptor instanceof MappedInterceptor mappedInterceptor) { + mappedInterceptors.add(mappedInterceptor); } } return (!mappedInterceptors.isEmpty() ? mappedInterceptors.toArray(new MappedInterceptor[0]) : null); @@ -502,8 +503,7 @@ public final HandlerExecutionChain getHandler(HttpServletRequest request) throws return null; } // Bean name or resolved handler? - if (handler instanceof String) { - String handlerName = (String) handler; + if (handler instanceof String handlerName) { handler = obtainApplicationContext().getBean(handlerName); } @@ -600,12 +600,11 @@ protected String initLookupPath(HttpServletRequest request) { * @see #getAdaptedInterceptors() */ protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { - HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? - (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); + HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain handlerExecutionChain ? + handlerExecutionChain : new HandlerExecutionChain(handler)); for (HandlerInterceptor interceptor : this.adaptedInterceptors) { - if (interceptor instanceof MappedInterceptor) { - MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor; + if (interceptor instanceof MappedInterceptor mappedInterceptor) { if (mappedInterceptor.matches(request)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); } @@ -622,8 +621,8 @@ protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpSer * @since 5.2 */ protected boolean hasCorsConfigurationSource(Object handler) { - if (handler instanceof HandlerExecutionChain) { - handler = ((HandlerExecutionChain) handler).getHandler(); + if (handler instanceof HandlerExecutionChain handlerExecutionChain) { + handler = handlerExecutionChain.getHandler(); } return (handler instanceof CorsConfigurationSource || this.corsConfigurationSource != null); } @@ -638,11 +637,11 @@ protected boolean hasCorsConfigurationSource(Object handler) { @Nullable protected CorsConfiguration getCorsConfiguration(Object handler, HttpServletRequest request) { Object resolvedHandler = handler; - if (handler instanceof HandlerExecutionChain) { - resolvedHandler = ((HandlerExecutionChain) handler).getHandler(); + if (handler instanceof HandlerExecutionChain handlerExecutionChain) { + resolvedHandler = handlerExecutionChain.getHandler(); } - if (resolvedHandler instanceof CorsConfigurationSource) { - return ((CorsConfigurationSource) resolvedHandler).getCorsConfiguration(request); + if (resolvedHandler instanceof CorsConfigurationSource configSource) { + return configSource.getCorsConfiguration(request); } return null; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodExceptionResolver.java index 47acaf4bc526..00ecd4f6909b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodExceptionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,8 +43,7 @@ protected boolean shouldApplyTo(HttpServletRequest request, @Nullable Object han if (handler == null) { return super.shouldApplyTo(request, null); } - else if (handler instanceof HandlerMethod) { - HandlerMethod handlerMethod = (HandlerMethod) handler; + else if (handler instanceof HandlerMethod handlerMethod) { handler = handlerMethod.getBean(); return super.shouldApplyTo(request, handler); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java index 2073087a1508..39480d914744 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java @@ -273,8 +273,8 @@ protected void processCandidateBean(String beanName) { * @see #getMappingForMethod */ protected void detectHandlerMethods(Object handler) { - Class handlerType = (handler instanceof String ? - obtainApplicationContext().getType((String) handler) : handler.getClass()); + Class handlerType = (handler instanceof String beanName ? + obtainApplicationContext().getType(beanName) : handler.getClass()); if (handlerType != null) { Class userType = ClassUtils.getUserClass(handlerType); @@ -339,8 +339,8 @@ protected void registerHandlerMethod(Object handler, Method method, T mapping) { * @return the created HandlerMethod */ protected HandlerMethod createHandlerMethod(Object handler, Method method) { - if (handler instanceof String) { - return new HandlerMethod((String) handler, + if (handler instanceof String beanName) { + return new HandlerMethod(beanName, obtainApplicationContext().getAutowireCapableBeanFactory(), obtainApplicationContext(), method); @@ -479,15 +479,14 @@ protected HandlerMethod handleNoMatch(Set mappings, String lookupPath, HttpSe @Override protected boolean hasCorsConfigurationSource(Object handler) { return super.hasCorsConfigurationSource(handler) || - (handler instanceof HandlerMethod && - this.mappingRegistry.getCorsConfiguration((HandlerMethod) handler) != null); + (handler instanceof HandlerMethod handerMethod && + this.mappingRegistry.getCorsConfiguration(handerMethod) != null); } @Override protected CorsConfiguration getCorsConfiguration(Object handler, HttpServletRequest request) { CorsConfiguration corsConfig = super.getCorsConfiguration(handler, request); - if (handler instanceof HandlerMethod) { - HandlerMethod handlerMethod = (HandlerMethod) handler; + if (handler instanceof HandlerMethod handlerMethod) { if (handlerMethod.equals(PREFLIGHT_AMBIGUOUS_MATCH)) { return AbstractHandlerMethodMapping.ALLOW_CORS_CONFIG; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java index f244dfdada25..812855a1f19a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java @@ -163,8 +163,7 @@ protected Object getHandlerInternal(HttpServletRequest request) throws Exception } if (rawHandler != null) { // Bean name or resolved handler? - if (rawHandler instanceof String) { - String handlerName = (String) rawHandler; + if (rawHandler instanceof String handlerName) { rawHandler = obtainApplicationContext().getBean(handlerName); } validateHandler(rawHandler, request); @@ -211,8 +210,7 @@ protected Object lookupHandler( } PathPattern pattern = matches.get(0); handler = this.pathPatternHandlerMap.get(pattern); - if (handler instanceof String) { - String handlerName = (String) handler; + if (handler instanceof String handlerName) { handler = obtainApplicationContext().getBean(handlerName); } validateHandler(handler, request); @@ -270,8 +268,7 @@ else if (useTrailingSlashMatch()) { } } // Bean name or resolved handler? - if (handler instanceof String) { - String handlerName = (String) handler; + if (handler instanceof String handlerName) { handler = obtainApplicationContext().getBean(handlerName); } validateHandler(handler, request); @@ -302,8 +299,7 @@ private Object getDirectMatch(String urlPath, HttpServletRequest request) throws Object handler = this.handlerMap.get(urlPath); if (handler != null) { // Bean name or resolved handler? - if (handler instanceof String) { - String handlerName = (String) handler; + if (handler instanceof String handlerName) { handler = obtainApplicationContext().getBean(handlerName); } validateHandler(handler, request); @@ -413,8 +409,7 @@ protected void registerHandler(String urlPath, Object handler) throws BeansExcep Object resolvedHandler = handler; // Eagerly resolve handler if referencing singleton via name. - if (!this.lazyInitHandlers && handler instanceof String) { - String handlerName = (String) handler; + if (!this.lazyInitHandlers && handler instanceof String handlerName) { ApplicationContext applicationContext = obtainApplicationContext(); if (applicationContext.isSingleton(handlerName)) { resolvedHandler = applicationContext.getBean(handlerName); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleMappingExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleMappingExceptionResolver.java index 61645c5c8de5..c6f90e8c64fa 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleMappingExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleMappingExceptionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,7 +61,7 @@ public class SimpleMappingExceptionResolver extends AbstractHandlerExceptionReso @Nullable private Integer defaultStatusCode; - private Map statusCodes = new HashMap<>(); + private final Map statusCodes = new HashMap<>(); @Nullable private String exceptionAttribute = DEFAULT_EXCEPTION_ATTRIBUTE; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/WebRequestHandlerInterceptorAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/WebRequestHandlerInterceptorAdapter.java index a3028dcb27d7..80ff163790ad 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/WebRequestHandlerInterceptorAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/WebRequestHandlerInterceptorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -75,8 +75,7 @@ public void afterCompletion(HttpServletRequest request, HttpServletResponse resp @Override public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) { - if (this.requestInterceptor instanceof AsyncWebRequestInterceptor) { - AsyncWebRequestInterceptor asyncInterceptor = (AsyncWebRequestInterceptor) this.requestInterceptor; + if (this.requestInterceptor instanceof AsyncWebRequestInterceptor asyncInterceptor) { DispatcherServletWebRequest webRequest = new DispatcherServletWebRequest(request, response); asyncInterceptor.afterConcurrentHandlingStarted(webRequest); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ParameterizableViewController.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ParameterizableViewController.java index 6cf029898ce2..dd43a0ae3ab4 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ParameterizableViewController.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ParameterizableViewController.java @@ -67,8 +67,7 @@ public void setViewName(@Nullable String viewName) { */ @Nullable public String getViewName() { - if (this.view instanceof String) { - String viewName = (String) this.view; + if (this.view instanceof String viewName) { if (getStatusCode() != null && getStatusCode().is3xxRedirection()) { return viewName.startsWith("redirect:") ? viewName : "redirect:" + viewName; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/WebContentInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/WebContentInterceptor.java index 450ec25c9a81..b0e94f7f0b2c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/WebContentInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/WebContentInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -80,9 +80,9 @@ public class WebContentInterceptor extends WebContentGenerator implements Handle private PathMatcher pathMatcher = defaultPathMatcher; - private Map cacheMappings = new HashMap<>(); + private final Map cacheMappings = new HashMap<>(); - private Map cacheControlMappings = new HashMap<>(); + private final Map cacheControlMappings = new HashMap<>(); /** @@ -215,8 +215,8 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons } if (!ObjectUtils.isEmpty(this.cacheControlMappings)) { - CacheControl control = (path instanceof PathContainer ? - lookupCacheControl((PathContainer) path) : lookupCacheControl((String) path)); + CacheControl control = (path instanceof PathContainer pathContainer ? + lookupCacheControl(pathContainer) : lookupCacheControl((String) path)); if (control != null) { if (logger.isTraceEnabled()) { logger.trace("Applying " + control); @@ -227,8 +227,8 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons } if (!ObjectUtils.isEmpty(this.cacheMappings)) { - Integer cacheSeconds = (path instanceof PathContainer ? - lookupCacheSeconds((PathContainer) path) : lookupCacheSeconds((String) path)); + Integer cacheSeconds = (path instanceof PathContainer pathContainer ? + lookupCacheSeconds(pathContainer) : lookupCacheSeconds((String) path)); if (cacheSeconds != null) { if (logger.isTraceEnabled()) { logger.trace("Applying cacheSeconds " + cacheSeconds); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java index 615ce1149414..3adf3ca633d7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java @@ -470,10 +470,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof RequestMappingInfo)) { + if (!(other instanceof RequestMappingInfo otherInfo)) { return false; } - RequestMappingInfo otherInfo = (RequestMappingInfo) other; return (getActivePatternsCondition().equals(otherInfo.getActivePatternsCondition()) && this.methodsCondition.equals(otherInfo.methodsCondition) && this.paramsCondition.equals(otherInfo.paramsCondition) && 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 f498494a3a21..6aa15c723521 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,6 +63,7 @@ * @author Arjen Poutsma * @author Rossen Stoyanchev * @author Brian Clozel + * @author Sam Brannen * @since 3.1 */ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodProcessor { @@ -149,8 +150,7 @@ public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewC private Type getHttpEntityType(MethodParameter parameter) { Assert.isAssignable(HttpEntity.class, parameter.getParameterType()); Type parameterType = parameter.getGenericParameterType(); - if (parameterType instanceof ParameterizedType) { - ParameterizedType type = (ParameterizedType) parameterType; + if (parameterType instanceof ParameterizedType type) { if (type.getActualTypeArguments().length != 1) { throw new IllegalArgumentException("Expected single generic parameter on '" + parameter.getParameterName() + "' in method " + parameter.getMethod()); @@ -178,10 +178,10 @@ public void handleReturnValue(@Nullable Object returnValue, MethodParameter retu ServletServerHttpResponse outputMessage = createOutputMessage(webRequest); Assert.isInstanceOf(HttpEntity.class, returnValue); - HttpEntity responseEntity = (HttpEntity) returnValue; + HttpEntity httpEntity = (HttpEntity) returnValue; HttpHeaders outputHeaders = outputMessage.getHeaders(); - HttpHeaders entityHeaders = responseEntity.getHeaders(); + HttpHeaders entityHeaders = httpEntity.getHeaders(); if (!entityHeaders.isEmpty()) { entityHeaders.forEach((key, value) -> { if (HttpHeaders.VARY.equals(key) && outputHeaders.containsKey(HttpHeaders.VARY)) { @@ -196,8 +196,8 @@ public void handleReturnValue(@Nullable Object returnValue, MethodParameter retu }); } - if (responseEntity instanceof ResponseEntity) { - int returnStatus = ((ResponseEntity) responseEntity).getStatusCodeValue(); + if (httpEntity instanceof ResponseEntity responseEntity) { + int returnStatus = responseEntity.getStatusCodeValue(); outputMessage.getServletResponse().setStatus(returnStatus); if (returnStatus == 200) { HttpMethod method = inputMessage.getMethod(); @@ -216,7 +216,7 @@ else if (returnStatus / 100 == 3) { } // Try even with null body. ResponseBodyAdvice could get involved. - writeWithMessageConverters(responseEntity.getBody(), returnType, inputMessage, outputMessage); + writeWithMessageConverters(httpEntity.getBody(), returnType, inputMessage, outputMessage); // Ensure headers are flushed even if no body was written. outputMessage.flush(); @@ -261,8 +261,8 @@ private boolean isResourceNotModified(ServletServerHttpRequest request, ServletS private void saveFlashAttributes(ModelAndViewContainer mav, NativeWebRequest request, String location) { mav.setRedirectModelScenario(true); ModelMap model = mav.getModel(); - if (model instanceof RedirectAttributes) { - Map flashAttributes = ((RedirectAttributes) model).getFlashAttributes(); + if (model instanceof RedirectAttributes redirectAttributes) { + Map flashAttributes = redirectAttributes.getFlashAttributes(); if (!CollectionUtils.isEmpty(flashAttributes)) { HttpServletRequest req = request.getNativeRequest(HttpServletRequest.class); HttpServletResponse res = request.getNativeResponse(HttpServletResponse.class); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyAdviceChain.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyAdviceChain.java index f72115ab8289..f5e483490781 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyAdviceChain.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyAdviceChain.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,8 +61,8 @@ static List getAdviceByType(@Nullable List requestResponseBodyAdv if (requestResponseBodyAdvice != null) { List result = new ArrayList<>(); for (Object advice : requestResponseBodyAdvice) { - Class beanType = (advice instanceof ControllerAdviceBean ? - ((ControllerAdviceBean) advice).getBeanType() : advice.getClass()); + Class beanType = (advice instanceof ControllerAdviceBean adviceBean ? + adviceBean.getBeanType() : advice.getClass()); if (beanType != null && adviceType.isAssignableFrom(beanType)) { result.add((T) advice); } @@ -153,8 +153,7 @@ private List getMatchingAdvice(MethodParameter parameter, Class result = new ArrayList<>(availableAdvice.size()); for (Object advice : availableAdvice) { - if (advice instanceof ControllerAdviceBean) { - ControllerAdviceBean adviceBean = (ControllerAdviceBean) advice; + if (advice instanceof ControllerAdviceBean adviceBean) { if (!adviceBean.isApplicableToBeanType(parameter.getContainingClass())) { continue; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java index 2c96722b14ef..c4f3076efa55 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java @@ -230,8 +230,7 @@ protected ResponseEntity handleHttpMediaTypeNotSupported( List mediaTypes = ex.getSupportedMediaTypes(); if (!CollectionUtils.isEmpty(mediaTypes)) { headers.setAccept(mediaTypes); - if (request instanceof ServletWebRequest) { - ServletWebRequest servletWebRequest = (ServletWebRequest) request; + if (request instanceof ServletWebRequest servletWebRequest) { if (HttpMethod.PATCH.equals(servletWebRequest.getHttpMethod())) { headers.setAcceptPatch(mediaTypes); } @@ -437,8 +436,7 @@ protected ResponseEntity handleNoHandlerFoundException( protected ResponseEntity handleAsyncRequestTimeoutException( AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatus status, WebRequest webRequest) { - if (webRequest instanceof ServletWebRequest) { - ServletWebRequest servletWebRequest = (ServletWebRequest) webRequest; + if (webRequest instanceof ServletWebRequest servletWebRequest) { HttpServletResponse response = servletWebRequest.getResponse(); if (response != null && response.isCommitted()) { if (logger.isWarnEnabled()) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewMethodReturnValueHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewMethodReturnValueHandler.java index 4934ea9a52ed..80d63ad1f113 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewMethodReturnValueHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewMethodReturnValueHandler.java @@ -50,8 +50,7 @@ public boolean supportsReturnType(MethodParameter returnType) { public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { - if (returnValue instanceof View) { - View view = (View) returnValue; + if (returnValue instanceof View view) { mavContainer.setView(view); if (view instanceof SmartView && ((SmartView) view).isRedirectView()) { mavContainer.setRedirectModelScenario(true); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java index e27e2ac1dab6..319381462562 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -235,10 +235,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof ContentChunkInfo)) { + if (!(other instanceof ContentChunkInfo otherCci)) { return false; } - ContentChunkInfo otherCci = (ContentChunkInfo) other; return (this.start == otherCci.start && this.end == otherCci.end); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java index 34c782c52990..002705603f6d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java @@ -237,12 +237,12 @@ private boolean isResourceUnderLocation(Resource resource, Resource location) th resourcePath = resource.getURL().toExternalForm(); locationPath = StringUtils.cleanPath(location.getURL().toString()); } - else if (resource instanceof ClassPathResource) { - resourcePath = ((ClassPathResource) resource).getPath(); + else if (resource instanceof ClassPathResource classPathResource) { + resourcePath = classPathResource.getPath(); locationPath = StringUtils.cleanPath(((ClassPathResource) location).getPath()); } - else if (resource instanceof ServletContextResource) { - resourcePath = ((ServletContextResource) resource).getPath(); + else if (resource instanceof ServletContextResource servletContextResource) { + resourcePath = servletContextResource.getPath(); locationPath = StringUtils.cleanPath(((ServletContextResource) location).getPath()); } else { @@ -301,11 +301,8 @@ private boolean isInvalidEncodedPath(String resourcePath) { return true; } } - catch (IllegalArgumentException ex) { - // May not be possible to decode... - } - catch (UnsupportedEncodingException ex) { - // Should never happen... + catch (IllegalArgumentException | UnsupportedEncodingException ex) { + // May not be possible to decode... | Should never happen... } } return false; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index 87cf98da13b1..f0455d303c40 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -484,8 +484,7 @@ protected void initAllowedLocations() { return; } for (int i = getResourceResolvers().size() - 1; i >= 0; i--) { - if (getResourceResolvers().get(i) instanceof PathResourceResolver) { - PathResourceResolver pathResolver = (PathResourceResolver) getResourceResolvers().get(i); + if (getResourceResolvers().get(i) instanceof PathResourceResolver pathResolver) { if (ObjectUtils.isEmpty(pathResolver.getAllowedLocations())) { pathResolver.setAllowedLocations(getLocations().toArray(new Resource[0])); } @@ -681,11 +680,8 @@ private boolean isInvalidEncodedPath(String path) { return true; } } - catch (IllegalArgumentException ex) { - // May not be possible to decode... - } - catch (UnsupportedEncodingException ex) { - // Should never happen... + catch (IllegalArgumentException | UnsupportedEncodingException ex) { + // May not be possible to decode... | Should never happen... } } return false; @@ -788,8 +784,8 @@ protected void setHeaders(HttpServletResponse response, Resource resource, @Null response.setContentType(mediaType.toString()); } - if (resource instanceof HttpResource) { - HttpHeaders resourceHeaders = ((HttpResource) resource).getResponseHeaders(); + if (resource instanceof HttpResource httpResource) { + HttpHeaders resourceHeaders = httpResource.getResponseHeaders(); resourceHeaders.forEach((headerName, headerValues) -> { boolean first = true; for (String headerValue : headerValues) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java index 7a2a6e2a67c6..afd47b83b3c0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java @@ -154,8 +154,7 @@ protected void detectResourceHandlers(ApplicationContext appContext) { for (SimpleUrlHandlerMapping mapping : mappings) { for (String pattern : mapping.getHandlerMap().keySet()) { Object handler = mapping.getHandlerMap().get(pattern); - if (handler instanceof ResourceHttpRequestHandler) { - ResourceHttpRequestHandler resourceHandler = (ResourceHttpRequestHandler) handler; + if (handler instanceof ResourceHttpRequestHandler resourceHandler) { this.handlerMap.put(pattern, resourceHandler); } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java index f4800afc4d24..f2469483abc3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,7 +65,7 @@ */ public class VersionResourceResolver extends AbstractResourceResolver { - private AntPathMatcher pathMatcher = new AntPathMatcher(); + private final AntPathMatcher pathMatcher = new AntPathMatcher(); /** Map from path pattern -> VersionStrategy. */ private final Map versionStrategyMap = new LinkedHashMap<>(); @@ -311,8 +311,8 @@ public InputStream getInputStream() throws IOException { @Override public HttpHeaders getResponseHeaders() { - HttpHeaders headers = (this.original instanceof HttpResource ? - ((HttpResource) this.original).getResponseHeaders() : new HttpHeaders()); + HttpHeaders headers = (this.original instanceof HttpResource httpResource ? + httpResource.getResponseHeaders() : new HttpHeaders()); headers.setETag("W/\"" + this.version + "\""); return headers; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/JspAwareRequestContext.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/JspAwareRequestContext.java index b02d169ea8d0..b0f3e2bd04a6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/JspAwareRequestContext.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/JspAwareRequestContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ */ public class JspAwareRequestContext extends RequestContext { - private PageContext pageContext; + private final PageContext pageContext; /** @@ -115,13 +115,13 @@ private static class JstlPageLocaleResolver { @Nullable public static Locale getJstlLocale(PageContext pageContext) { Object localeObject = Config.find(pageContext, Config.FMT_LOCALE); - return (localeObject instanceof Locale ? (Locale) localeObject : null); + return (localeObject instanceof Locale locale ? locale : null); } @Nullable public static TimeZone getJstlTimeZone(PageContext pageContext) { Object timeZoneObject = Config.find(pageContext, Config.FMT_TIME_ZONE); - return (timeZoneObject instanceof TimeZone ? (TimeZone) timeZoneObject : null); + return (timeZoneObject instanceof TimeZone timeZone ? timeZone : null); } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java index db97efc2bae6..2de52f3cbca5 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java @@ -95,15 +95,15 @@ public class RequestContext { protected static final boolean jstlPresent = ClassUtils.isPresent( "jakarta.servlet.jsp.jstl.core.Config", RequestContext.class.getClassLoader()); - private HttpServletRequest request; + private final HttpServletRequest request; @Nullable - private HttpServletResponse response; + private final HttpServletResponse response; @Nullable - private Map model; + private final Map model; - private WebApplicationContext webApplicationContext; + private final WebApplicationContext webApplicationContext; @Nullable private Locale locale; @@ -118,7 +118,7 @@ public class RequestContext { private Boolean defaultHtmlEscape; @Nullable - private Boolean responseEncodedHtmlEscape; + private final Boolean responseEncodedHtmlEscape; private UrlPathHelper urlPathHelper; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/SelectedValueComparator.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/SelectedValueComparator.java index 3ad6c33b9c6e..f8b41e029527 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/SelectedValueComparator.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/SelectedValueComparator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ * *

    Equality Contract

    * For single-valued objects equality is first tested using standard {@link Object#equals Java equality}. As - * such, user code should endeavour to implement {@link Object#equals} to speed up the comparison process. If + * such, user code should endeavor to implement {@link Object#equals} to speed up the comparison process. If * {@link Object#equals} returns {@code false} then an attempt is made at an * {@link #exhaustiveCompare exhaustive comparison} with the aim being to prove equality rather * than disprove it. @@ -86,11 +86,11 @@ else if (boundValue == null) { if (boundValue.getClass().isArray()) { selected = collectionCompare(CollectionUtils.arrayToList(boundValue), candidateValue, bindStatus); } - else if (boundValue instanceof Collection) { - selected = collectionCompare((Collection) boundValue, candidateValue, bindStatus); + else if (boundValue instanceof Collection collection) { + selected = collectionCompare(collection, candidateValue, bindStatus); } - else if (boundValue instanceof Map) { - selected = mapCompare((Map) boundValue, candidateValue, bindStatus); + else if (boundValue instanceof Map map) { + selected = mapCompare(map, candidateValue, bindStatus); } } if (!selected) { @@ -163,9 +163,8 @@ else if (ObjectUtils.getDisplayString(boundValue).equals(candidateDisplayString) return true; } - if (editor != null && candidate instanceof String) { + if (editor != null && candidate instanceof String candidateAsString) { // Try PE-based comparison (PE should *not* be allowed to escape creating thread) - String candidateAsString = (String) candidate; Object candidateAsValue; if (convertedValueCache != null && convertedValueCache.containsKey(editor)) { candidateAsValue = convertedValueCache.get(editor); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractCachingViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractCachingViewResolver.java index d7bf2fa33762..53cfc10f27d6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractCachingViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractCachingViewResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,7 +79,7 @@ public void render(@Nullable Map model, HttpServletRequest request, H /** Map from view key to View instance, synchronized for View creation. */ @SuppressWarnings("serial") private final Map viewCreationCache = - new LinkedHashMap(DEFAULT_CACHE_LIMIT, 0.75f, true) { + new LinkedHashMap<>(DEFAULT_CACHE_LIMIT, 0.75f, true) { @Override protected boolean removeEldestEntry(Map.Entry eldest) { if (size() > getCacheLimit()) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java index 3c1699a5abd4..4fdb0a2c8835 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -332,8 +332,7 @@ private List getCandidateViews(String viewName, Locale locale, List candidateViews, List requestedMediaTypes, RequestAttributes attrs) { for (View candidateView : candidateViews) { - if (candidateView instanceof SmartView) { - SmartView smartView = (SmartView) candidateView; + if (candidateView instanceof SmartView smartView) { if (smartView.isRedirectView()) { return candidateView; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/AbstractJackson2View.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/AbstractJackson2View.java index e85cea4415e6..176cf840a526 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/AbstractJackson2View.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/AbstractJackson2View.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -212,8 +212,7 @@ protected void writeContent(OutputStream stream, Object object) throws IOExcepti Class serializationView = null; FilterProvider filters = null; - if (value instanceof MappingJacksonValue) { - MappingJacksonValue container = (MappingJacksonValue) value; + if (value instanceof MappingJacksonValue container) { value = container.getValue(); serializationView = container.getSerializationView(); filters = container.getFilters(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateView.java index 57e627e89cb4..f7626a9debba 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateView.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -470,10 +470,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof EngineKey)) { + if (!(other instanceof EngineKey otherKey)) { return false; } - EngineKey otherKey = (EngineKey) other; return (this.engineName.equals(otherKey.engineName) && Arrays.equals(this.scripts, otherKey.scripts)); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xslt/XsltView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xslt/XsltView.java index 1d3c29b9395e..e80d827832b0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xslt/XsltView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xslt/XsltView.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -302,32 +302,31 @@ protected Class[] getSourceTypes() { /** * Convert the supplied {@link Object} into an XSLT {@link Source} if the * {@link Object} type is {@link #getSourceTypes() supported}. - * @param source the original source object + * @param sourceObject the original source object * @return the adapted XSLT Source * @throws IllegalArgumentException if the given Object is not of a supported type */ - protected Source convertSource(Object source) throws Exception { - if (source instanceof Source) { - return (Source) source; + protected Source convertSource(Object sourceObject) throws Exception { + if (sourceObject instanceof Source source) { + return source; } - else if (source instanceof Document) { - return new DOMSource(((Document) source).getDocumentElement()); + else if (sourceObject instanceof Document document) { + return new DOMSource(document.getDocumentElement()); } - else if (source instanceof Node) { - return new DOMSource((Node) source); + else if (sourceObject instanceof Node node) { + return new DOMSource(node); } - else if (source instanceof Reader) { - return new StreamSource((Reader) source); + else if (sourceObject instanceof Reader reader) { + return new StreamSource(reader); } - else if (source instanceof InputStream) { - return new StreamSource((InputStream) source); + else if (sourceObject instanceof InputStream inputStream) { + return new StreamSource(inputStream); } - else if (source instanceof Resource) { - Resource resource = (Resource) source; + else if (sourceObject instanceof Resource resource) { return new StreamSource(resource.getInputStream(), resource.getURI().toASCIIString()); } else { - throw new IllegalArgumentException("Value '" + source + "' cannot be converted to XSLT Source"); + throw new IllegalArgumentException("Value '" + sourceObject + "' cannot be converted to XSLT Source"); } } @@ -481,8 +480,7 @@ protected Source getStylesheetSource() { * @param source the XSLT Source to close (may be {@code null}) */ private void closeSourceIfNecessary(@Nullable Source source) { - if (source instanceof StreamSource) { - StreamSource streamSource = (StreamSource) source; + if (source instanceof StreamSource streamSource) { if (streamSource.getReader() != null) { try { streamSource.getReader().close(); From b51813e40853af56ffeca37db08408d02d6c60a5 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 17 Oct 2021 19:04:32 +0200 Subject: [PATCH 270/735] Apply "instanceof pattern matching" in spring-websocket This commit also applies additional clean-up tasks such as the following. - final fields - diamond operator (<>) for anonymous inner classes This has only been applied to `src/main/java`. --- .../web/socket/CloseStatus.java | 5 ++--- .../web/socket/WebSocketHttpHeaders.java | 5 ++--- .../client/WebSocketConnectionManager.java | 13 ++++++------ .../messaging/DefaultSimpUserRegistry.java | 14 ++++++------- .../HttpSessionHandshakeInterceptor.java | 9 ++++---- .../client/DefaultTransportRequest.java | 4 ++-- .../socket/sockjs/client/SockJsClient.java | 21 +++++++------------ .../sockjs/client/UndertowXhrTransport.java | 8 +++---- .../sockjs/client/XhrClientSockJsSession.java | 6 +++--- .../web/socket/sockjs/frame/SockJsFrame.java | 5 ++--- 10 files changed, 41 insertions(+), 49 deletions(-) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/CloseStatus.java b/spring-websocket/src/main/java/org/springframework/web/socket/CloseStatus.java index 493f009283a4..fe9972e7c875 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/CloseStatus.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/CloseStatus.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -209,10 +209,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof CloseStatus)) { + if (!(other instanceof CloseStatus otherStatus)) { return false; } - CloseStatus otherStatus = (CloseStatus) other; return (this.code == otherStatus.code && ObjectUtils.nullSafeEquals(this.reason, otherStatus.reason)); } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketHttpHeaders.java b/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketHttpHeaders.java index 84a3503bfc93..cb30c423bbcf 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketHttpHeaders.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketHttpHeaders.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -311,10 +311,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof WebSocketHttpHeaders)) { + if (!(other instanceof WebSocketHttpHeaders otherHeaders)) { return false; } - WebSocketHttpHeaders otherHeaders = (WebSocketHttpHeaders) other; return this.headers.equals(otherHeaders.headers); } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/client/WebSocketConnectionManager.java b/spring-websocket/src/main/java/org/springframework/web/socket/client/WebSocketConnectionManager.java index 989100f93598..c2ad134e8e98 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/client/WebSocketConnectionManager.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/client/WebSocketConnectionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ * this will be done automatically when the Spring ApplicationContext is refreshed. * * @author Rossen Stoyanchev + * @author Sam Brannen * @since 4.0 */ public class WebSocketConnectionManager extends ConnectionManagerSupport { @@ -46,7 +47,7 @@ public class WebSocketConnectionManager extends ConnectionManagerSupport { @Nullable private WebSocketSession webSocketSession; - private WebSocketHttpHeaders headers = new WebSocketHttpHeaders(); + private final WebSocketHttpHeaders headers = new WebSocketHttpHeaders(); public WebSocketConnectionManager(WebSocketClient client, @@ -116,16 +117,16 @@ public HttpHeaders getHeaders() { @Override public void startInternal() { - if (this.client instanceof Lifecycle && !((Lifecycle) this.client).isRunning()) { - ((Lifecycle) this.client).start(); + if (this.client instanceof Lifecycle lifecycle && !lifecycle.isRunning()) { + lifecycle.start(); } super.startInternal(); } @Override public void stopInternal() throws Exception { - if (this.client instanceof Lifecycle && ((Lifecycle) this.client).isRunning()) { - ((Lifecycle) this.client).stop(); + if (this.client instanceof Lifecycle lifecycle && lifecycle.isRunning()) { + lifecycle.stop(); } super.stopInternal(); } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/messaging/DefaultSimpUserRegistry.java b/spring-websocket/src/main/java/org/springframework/web/socket/messaging/DefaultSimpUserRegistry.java index 5bef6ac61fc4..ba9d1f9e5401 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/messaging/DefaultSimpUserRegistry.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/messaging/DefaultSimpUserRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,6 +43,7 @@ * track of connected users and their subscriptions. * * @author Rossen Stoyanchev + * @author Sam Brannen * @since 4.2 */ public class DefaultSimpUserRegistry implements SimpUserRegistry, SmartApplicationListener { @@ -105,8 +106,8 @@ else if (event instanceof SessionConnectedEvent) { return; } String name = user.getName(); - if (user instanceof DestinationUserNameProvider) { - name = ((DestinationUserNameProvider) user).getDestinationUserName(); + if (user instanceof DestinationUserNameProvider destinationUserNameProvider) { + name = destinationUserNameProvider.getDestinationUserName(); } synchronized (this.sessionLock) { LocalSimpUser simpUser = this.users.get(name); @@ -238,7 +239,7 @@ void removeSession(String sessionId) { @Override public boolean equals(@Nullable Object other) { return (this == other || - (other instanceof SimpUser && getName().equals(((SimpUser) other).getName()))); + (other instanceof SimpUser otherSimpUser && getName().equals(otherSimpUser.getName()))); } @Override @@ -294,7 +295,7 @@ void removeSubscription(String id) { @Override public boolean equals(@Nullable Object other) { return (this == other || - (other instanceof SimpSubscription && getId().equals(((SimpSubscription) other).getId()))); + (other instanceof SimpSubscription otherSubscription && getId().equals(otherSubscription.getId()))); } @Override @@ -346,10 +347,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof SimpSubscription)) { + if (!(other instanceof SimpSubscription otherSubscription)) { return false; } - SimpSubscription otherSubscription = (SimpSubscription) other; return (getId().equals(otherSubscription.getId()) && getSession().getId().equals(otherSubscription.getSession().getId())); } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java index ba020c32fe82..8ce26a371123 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,9 +33,9 @@ /** * An interceptor to copy information from the HTTP session to the "handshake - * attributes" map to made available via{@link WebSocketSession#getAttributes()}. + * attributes" map to be made available via {@link WebSocketSession#getAttributes()}. * - *

    Copies a subset or all HTTP session attributes and/or the HTTP session id + *

    Copies a subset or all HTTP session attributes and/or the HTTP session ID * under the key {@link #HTTP_SESSION_ID_ATTR_NAME}. * * @author Rossen Stoyanchev @@ -164,8 +164,7 @@ public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse res @Nullable private HttpSession getSession(ServerHttpRequest request) { - if (request instanceof ServletServerHttpRequest) { - ServletServerHttpRequest serverRequest = (ServletServerHttpRequest) request; + if (request instanceof ServletServerHttpRequest serverRequest) { return serverRequest.getServletRequest().getSession(isCreateSession()); } return null; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/DefaultTransportRequest.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/DefaultTransportRequest.java index 32eb9c0f4c3a..e69f0e2ce60b 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/DefaultTransportRequest.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/DefaultTransportRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,7 +59,7 @@ class DefaultTransportRequest implements TransportRequest { private final TransportType serverTransportType; - private SockJsMessageCodec codec; + private final SockJsMessageCodec codec; @Nullable private Principal user; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/SockJsClient.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/SockJsClient.java index 1ac4bc8fba40..6f59483348ea 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/SockJsClient.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/SockJsClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,6 +56,7 @@ * the transports it is configured with. * * @author Rossen Stoyanchev + * @author Sam Brannen * @since 4.1 * @see https://github.com/sockjs/sockjs-client * @see org.springframework.web.socket.sockjs.client.Transport @@ -114,8 +115,8 @@ public SockJsClient(List transports) { private static InfoReceiver initInfoReceiver(List transports) { for (Transport transport : transports) { - if (transport instanceof InfoReceiver) { - return ((InfoReceiver) transport); + if (transport instanceof InfoReceiver infoReceiver) { + return infoReceiver; } } return new RestTemplateXhrTransport(); @@ -202,11 +203,8 @@ public void start() { if (!isRunning()) { this.running = true; for (Transport transport : this.transports) { - if (transport instanceof Lifecycle) { - Lifecycle lifecycle = (Lifecycle) transport; - if (!lifecycle.isRunning()) { - lifecycle.start(); - } + if (transport instanceof Lifecycle lifecycle && !lifecycle.isRunning()) { + lifecycle.start(); } } } @@ -217,11 +215,8 @@ public void stop() { if (isRunning()) { this.running = false; for (Transport transport : this.transports) { - if (transport instanceof Lifecycle) { - Lifecycle lifecycle = (Lifecycle) transport; - if (lifecycle.isRunning()) { - lifecycle.stop(); - } + if (transport instanceof Lifecycle lifecycle && lifecycle.isRunning()) { + lifecycle.stop(); } } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/UndertowXhrTransport.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/UndertowXhrTransport.java index 6d2ace34418e..1e12b914a654 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/UndertowXhrTransport.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/UndertowXhrTransport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -148,7 +148,7 @@ private void executeReceiveRequest(final TransportRequest transportRequest, logger.trace("Starting XHR receive request for " + url); } - ClientCallback clientCallback = new ClientCallback() { + ClientCallback clientCallback = new ClientCallback<>() { @Override public void completed(ClientConnection connection) { ClientRequest request = new ClientRequest().setMethod(Methods.POST).setPath(url.getPath()); @@ -182,7 +182,7 @@ private ClientCallback createReceiveCallback(final TransportRequ final URI url, final HttpHeaders headers, final XhrClientSockJsSession sockJsSession, final SettableListenableFuture connectFuture) { - return new ClientCallback() { + return new ClientCallback<>() { @Override public void completed(final ClientExchange exchange) { exchange.setResponseListener(new ClientCallback() { @@ -309,7 +309,7 @@ protected ResponseEntity executeRequest( private ClientCallback createRequestCallback(final @Nullable String body, final List responses, final CountDownLatch latch) { - return new ClientCallback() { + return new ClientCallback<>() { @Override public void completed(ClientExchange result) { result.setResponseListener(new ClientCallback() { diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/XhrClientSockJsSession.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/XhrClientSockJsSession.java index 9137473fbf8e..4c3954aa2765 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/XhrClientSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/XhrClientSockJsSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,9 +43,9 @@ public class XhrClientSockJsSession extends AbstractClientSockJsSession { private final XhrTransport transport; - private HttpHeaders headers; + private final HttpHeaders headers; - private HttpHeaders sendHeaders; + private final HttpHeaders sendHeaders; private final URI sendUrl; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/frame/SockJsFrame.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/frame/SockJsFrame.java index 55580318bec2..35cf0fbff675 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/frame/SockJsFrame.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/frame/SockJsFrame.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -125,10 +125,9 @@ public boolean equals(@Nullable Object other) { if (this == other) { return true; } - if (!(other instanceof SockJsFrame)) { + if (!(other instanceof SockJsFrame otherFrame)) { return false; } - SockJsFrame otherFrame = (SockJsFrame) other; return (this.type.equals(otherFrame.type) && this.content.equals(otherFrame.content)); } From 052ed50f480d290d1d4e4d3721a1425fa33e0e62 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 17 Oct 2021 19:32:53 +0200 Subject: [PATCH 271/735] Fix copy-and-paste error in Javadoc --- .../web/reactive/function/client/ClientRequest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientRequest.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientRequest.java index 2b61dba1836a..5c24b2ab30d6 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientRequest.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientRequest.java @@ -209,8 +209,8 @@ interface Builder { /** * Manipulate this request's cookies with the given consumer. The * map provided to the consumer is "live", so that the consumer can be used to - * {@linkplain MultiValueMap#set(Object, Object) overwrite} existing header values, - * {@linkplain MultiValueMap#remove(Object) remove} values, or use any of the other + * {@linkplain MultiValueMap#set(Object, Object) overwrite} existing cookie values, + * {@linkplain MultiValueMap#remove(Object) remove} cookies, or use any of the other * {@link MultiValueMap} methods. * @param cookiesConsumer a function that consumes the cookies map * @return this builder From 4978eeff7fe399dff75a800679e50fee4afba130 Mon Sep 17 00:00:00 2001 From: Smile Date: Mon, 18 Oct 2021 10:26:55 +0530 Subject: [PATCH 272/735] Update Javadoc in DefaultResponseErrorHandler Closes gh-27569 --- .../web/client/DefaultResponseErrorHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java index 70e1038871a5..a12095d88fac 100644 --- a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java @@ -123,9 +123,9 @@ public void handleError(ClientHttpResponse response) throws IOException { } /** - * Return error message with details from the response body, possibly truncated: + * Return error message with details from the response body: *

    -	 * 404 Not Found: [{'id': 123, 'message': 'my very long... (500 bytes)]
    +	 * 404 Not Found: [{'id': 123, 'message': 'my message'}]
     	 * 
    */ private String getErrorMessage( From 346b75580267dc5d8d257be198d5841ce4e1add5 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 18 Oct 2021 16:53:39 +0100 Subject: [PATCH 273/735] Fix assertion message in DefaultDataBuffer Closes gh-27567 --- .../springframework/core/io/buffer/DefaultDataBuffer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java index be2155f34332..19346e00c56d 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -462,9 +462,9 @@ public String toString() { private void checkIndex(int index, int length) { assertIndex(index >= 0, "index %d must be >= 0", index); - assertIndex(length >= 0, "length %d must be >= 0", index); + assertIndex(length >= 0, "length %d must be >= 0", length); assertIndex(index <= this.capacity, "index %d must be <= %d", index, this.capacity); - assertIndex(length <= this.capacity, "length %d must be <= %d", index, this.capacity); + assertIndex(length <= this.capacity, "length %d must be <= %d", length, this.capacity); } private void assertIndex(boolean expression, String format, Object... args) { From bad87be30630b9a3283e092ea70b5579a8c6a9ad Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 18 Oct 2021 17:04:11 +0100 Subject: [PATCH 274/735] Fix checkstyle warning See gh-27569 --- .../springframework/web/client/DefaultResponseErrorHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java index a12095d88fac..505c51fff699 100644 --- a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java @@ -123,7 +123,7 @@ public void handleError(ClientHttpResponse response) throws IOException { } /** - * Return error message with details from the response body: + * Return error message with details from the response body. For example: *
     	 * 404 Not Found: [{'id': 123, 'message': 'my message'}]
     	 * 
    From 2a3c9e403f7cf016c90949eb7fc1f8bcf0db1f98 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 19 Oct 2021 10:16:27 +0200 Subject: [PATCH 275/735] Revert "Polishing" This reverts commit bfa01b35df42c526253866a4b601e8be83746a4b. --- .../src/main/java/org/springframework/util/MimeType.java | 4 ++-- .../src/main/java/org/springframework/http/MediaType.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/MimeType.java b/spring-core/src/main/java/org/springframework/util/MimeType.java index aa4ef6f53a31..b6e1ff2ff3de 100644 --- a/spring-core/src/main/java/org/springframework/util/MimeType.java +++ b/spring-core/src/main/java/org/springframework/util/MimeType.java @@ -637,14 +637,14 @@ public int compare(T mimeType1, T mimeType2) { else if (mimeType2.isWildcardType() && !mimeType1.isWildcardType()) { // audio/* > */* return -1; } - else { + else { // mediaType1.getType().equals(mediaType2.getType()) if (mimeType1.isWildcardSubtype() && !mimeType2.isWildcardSubtype()) { // audio/* < audio/basic return 1; } else if (mimeType2.isWildcardSubtype() && !mimeType1.isWildcardSubtype()) { // audio/basic > audio/* return -1; } - else { + else { // mediaType2.getSubtype().equals(mediaType2.getSubtype()) return compareParameters(mimeType1, mimeType2); } } diff --git a/spring-web/src/main/java/org/springframework/http/MediaType.java b/spring-web/src/main/java/org/springframework/http/MediaType.java index ec57d77a5ac2..34d05d41d329 100644 --- a/spring-web/src/main/java/org/springframework/http/MediaType.java +++ b/spring-web/src/main/java/org/springframework/http/MediaType.java @@ -798,7 +798,7 @@ else if (mediaType1.isWildcardType() && !mediaType2.isWildcardType()) { // */* else if (mediaType2.isWildcardType() && !mediaType1.isWildcardType()) { // audio/* > */* return -1; } - else { + else { // mediaType1.getType().equals(mediaType2.getType()) if (mediaType1.isWildcardSubtype() && !mediaType2.isWildcardSubtype()) { // audio/* < audio/basic return 1; } From a248a525756923e20e159b56fee7eddb8a709a29 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 19 Oct 2021 11:53:22 +0200 Subject: [PATCH 276/735] Revert transitive MediaType comparators The fix made for gh-27488 resulted in a change of the default order of codecs. This commit reverts these changes, so that the previous order is restored. Closes gh-27573 --- .../src/main/java/org/springframework/util/MimeType.java | 6 ++++++ .../src/main/java/org/springframework/http/MediaType.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/spring-core/src/main/java/org/springframework/util/MimeType.java b/spring-core/src/main/java/org/springframework/util/MimeType.java index b6e1ff2ff3de..de29040b07f6 100644 --- a/spring-core/src/main/java/org/springframework/util/MimeType.java +++ b/spring-core/src/main/java/org/springframework/util/MimeType.java @@ -637,6 +637,9 @@ public int compare(T mimeType1, T mimeType2) { else if (mimeType2.isWildcardType() && !mimeType1.isWildcardType()) { // audio/* > */* return -1; } + else if (!mimeType1.getType().equals(mimeType2.getType())) { // audio/basic == text/html + return 0; + } else { // mediaType1.getType().equals(mediaType2.getType()) if (mimeType1.isWildcardSubtype() && !mimeType2.isWildcardSubtype()) { // audio/* < audio/basic return 1; @@ -644,6 +647,9 @@ else if (mimeType2.isWildcardType() && !mimeType1.isWildcardType()) { // audio/ else if (mimeType2.isWildcardSubtype() && !mimeType1.isWildcardSubtype()) { // audio/basic > audio/* return -1; } + else if (!mimeType1.getSubtype().equals(mimeType2.getSubtype())) { // audio/basic == audio/wave + return 0; + } else { // mediaType2.getSubtype().equals(mediaType2.getSubtype()) return compareParameters(mimeType1, mimeType2); } diff --git a/spring-web/src/main/java/org/springframework/http/MediaType.java b/spring-web/src/main/java/org/springframework/http/MediaType.java index 34d05d41d329..729555add951 100644 --- a/spring-web/src/main/java/org/springframework/http/MediaType.java +++ b/spring-web/src/main/java/org/springframework/http/MediaType.java @@ -798,6 +798,9 @@ else if (mediaType1.isWildcardType() && !mediaType2.isWildcardType()) { // */* else if (mediaType2.isWildcardType() && !mediaType1.isWildcardType()) { // audio/* > */* return -1; } + else if (!mediaType1.getType().equals(mediaType2.getType())) { // audio/basic == text/html + return 0; + } else { // mediaType1.getType().equals(mediaType2.getType()) if (mediaType1.isWildcardSubtype() && !mediaType2.isWildcardSubtype()) { // audio/* < audio/basic return 1; @@ -805,6 +808,9 @@ else if (mediaType2.isWildcardType() && !mediaType1.isWildcardType()) { // audi else if (mediaType2.isWildcardSubtype() && !mediaType1.isWildcardSubtype()) { // audio/basic > audio/* return -1; } + else if (!mediaType1.getSubtype().equals(mediaType2.getSubtype())) { // audio/basic == audio/wave + return 0; + } else { int paramsSize1 = mediaType1.getParameters().size(); int paramsSize2 = mediaType2.getParameters().size(); From 05ea991d6220069f089a190a86f0f3105c26c049 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 19 Oct 2021 12:25:11 +0100 Subject: [PATCH 277/735] Removing locations logging in ResourceHttpRequestHandler See gh-27575 --- .../web/reactive/resource/ResourceWebHandler.java | 6 ------ .../web/servlet/resource/ResourceHttpRequestHandler.java | 6 ------ 2 files changed, 12 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java index 75ac8ddd320e..c2ba1b234bf1 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java @@ -336,12 +336,6 @@ private void resolveResourceLocations() { this.locationsToUse.clear(); this.locationsToUse.addAll(result); - - if (logger.isInfoEnabled()) { - logger.info(!this.locationsToUse.isEmpty() ? - "Locations in use: " + locationToString(this.locationsToUse) : - "0 locations in use."); - } } /** diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index 7456f37f0318..22f06ccf58d7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -467,12 +467,6 @@ private void resolveResourceLocations() { this.locationsToUse.clear(); this.locationsToUse.addAll(result); - - if (logger.isInfoEnabled()) { - logger.info(!this.locationsToUse.isEmpty() ? - "Locations in use: " + locationToString(this.locationsToUse) : - "0 locations in use."); - } } /** From aa5a2a860045b84457f8b6e596ebb54cf8863d36 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 19 Oct 2021 16:42:22 +0200 Subject: [PATCH 278/735] Disable custom stylesheet for Javadoc The custom stylesheet used with JDK 8 no longer works with JDK 17. Thus in order to make the generated Javadoc usable, we are disabling the custom stylesheet for the time being. See gh-27496 --- gradle/docs.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gradle/docs.gradle b/gradle/docs.gradle index c9bc9053031f..fb7ad3d0069a 100644 --- a/gradle/docs.gradle +++ b/gradle/docs.gradle @@ -43,7 +43,8 @@ task api(type: Javadoc) { header = rootProject.description use = true overview = "src/docs/api/overview.html" - stylesheetFile = file("src/docs/api/stylesheet.css") + // Disable custom stylesheet until we resolve https://github.com/spring-projects/spring-framework/issues/27496 + // stylesheetFile = file("src/docs/api/stylesheet.css") splitIndex = true links(project.ext.javadocLinks) addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint From 6fa6bfe421e0ca41e8dfe5fc0701ba2291dd376e Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 19 Oct 2021 16:46:01 +0200 Subject: [PATCH 279/735] Fix link to Spring Framework project page in Javadoc overview --- src/docs/api/overview.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/api/overview.html b/src/docs/api/overview.html index f37932935e5c..e6086dc458d1 100644 --- a/src/docs/api/overview.html +++ b/src/docs/api/overview.html @@ -1,7 +1,7 @@

    -This is the public API documentation for the Spring Framework. +This is the public API documentation for the Spring Framework.

    From f78d9cdf22252134c2fdc43add52eebd6bca6737 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 19 Oct 2021 16:58:36 +0200 Subject: [PATCH 280/735] Remove configuration of obsolete html5 javadoc option --- gradle/docs.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/gradle/docs.gradle b/gradle/docs.gradle index fb7ad3d0069a..043282176abf 100644 --- a/gradle/docs.gradle +++ b/gradle/docs.gradle @@ -49,9 +49,6 @@ task api(type: Javadoc) { links(project.ext.javadocLinks) addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint addBooleanOption('Werror', true) // fail build on Javadoc warnings - if (JavaVersion.current().isJava9Compatible()) { - addBooleanOption('html5', true) - } } source moduleProjects.collect { project -> project.sourceSets.main.allJava From 8e245e4410f0d017794828660c05b448efb3cd4e Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 20 Oct 2021 13:07:45 +0200 Subject: [PATCH 281/735] Remove commented-out custom stylesheet for Javadoc The team has decided to use the default Javadoc stylesheet with JDK 17. Closes gh-27496 --- gradle/docs.gradle | 2 -- 1 file changed, 2 deletions(-) diff --git a/gradle/docs.gradle b/gradle/docs.gradle index 043282176abf..470c854cc9b7 100644 --- a/gradle/docs.gradle +++ b/gradle/docs.gradle @@ -43,8 +43,6 @@ task api(type: Javadoc) { header = rootProject.description use = true overview = "src/docs/api/overview.html" - // Disable custom stylesheet until we resolve https://github.com/spring-projects/spring-framework/issues/27496 - // stylesheetFile = file("src/docs/api/stylesheet.css") splitIndex = true links(project.ext.javadocLinks) addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint From 3d6d8a947a8e1f252ae64306244ed4f4204cc627 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 20 Oct 2021 14:48:51 +0200 Subject: [PATCH 282/735] Update "Reporting a Vulnerability" link --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 8ed0ff412377..038a36b56539 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -8,4 +8,4 @@ wiki page. ## Reporting a Vulnerability -Please see https://pivotal.io/security. +Please see https://spring.io/security-policy. From e4b493456b6f2bae10748e02a5663b1bb46bd21d Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 20 Oct 2021 18:29:33 +0200 Subject: [PATCH 283/735] Remove custom EnumerationIterator This commit removes our custom EnumerationIterator, in favor of Enumeration::asIterator (since JDK 9). --- .../springframework/util/CollectionUtils.java | 35 ++----------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/CollectionUtils.java b/spring-core/src/main/java/org/springframework/util/CollectionUtils.java index d1e9354abda9..530e5222ba08 100644 --- a/spring-core/src/main/java/org/springframework/util/CollectionUtils.java +++ b/spring-core/src/main/java/org/springframework/util/CollectionUtils.java @@ -233,15 +233,14 @@ public static boolean containsAny(Collection source, Collection candidates * @param candidates the candidates to search for * @return the first present object, or {@code null} if not found */ - @SuppressWarnings("unchecked") @Nullable public static E findFirstMatch(Collection source, Collection candidates) { if (isEmpty(source) || isEmpty(candidates)) { return null; } - for (Object candidate : candidates) { + for (E candidate : candidates) { if (source.contains(candidate)) { - return (E) candidate; + return candidate; } } return null; @@ -447,7 +446,7 @@ public static A[] toArray(Enumeration enumeration, A[] array * @return the adapted {@code Iterator} */ public static Iterator toIterator(@Nullable Enumeration enumeration) { - return (enumeration != null ? new EnumerationIterator<>(enumeration) : Collections.emptyIterator()); + return (enumeration != null ? enumeration.asIterator() : Collections.emptyIterator()); } /** @@ -481,32 +480,4 @@ public static MultiValueMap unmodifiableMultiValueMap( } - /** - * Iterator wrapping an Enumeration. - */ - private static class EnumerationIterator implements Iterator { - - private final Enumeration enumeration; - - public EnumerationIterator(Enumeration enumeration) { - this.enumeration = enumeration; - } - - @Override - public boolean hasNext() { - return this.enumeration.hasMoreElements(); - } - - @Override - public E next() { - return this.enumeration.nextElement(); - } - - @Override - public void remove() throws UnsupportedOperationException { - throw new UnsupportedOperationException("Not supported"); - } - } - - } From bce850aa12ee678a98a44b1074c7fc5a2f2f8e96 Mon Sep 17 00:00:00 2001 From: Spring Builds Date: Thu, 21 Oct 2021 05:57:00 +0000 Subject: [PATCH 284/735] Next development version (v5.3.13-SNAPSHOT) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index aea3f16f967a..b46dbd487055 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=5.3.12-SNAPSHOT +version=5.3.13-SNAPSHOT org.gradle.jvmargs=-Xmx1536M org.gradle.caching=true org.gradle.parallel=true From b3eb1a2ad725ab4e8c9af7e1fe51840fa01289d0 Mon Sep 17 00:00:00 2001 From: no-brand Date: Thu, 21 Oct 2021 07:19:26 +0000 Subject: [PATCH 285/735] Improve example in Javadoc for HttpEntity Closes gh-27586 --- .../src/main/java/org/springframework/http/HttpEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/http/HttpEntity.java b/spring-web/src/main/java/org/springframework/http/HttpEntity.java index 7b7fe9af6002..d6493c4bed06 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpEntity.java +++ b/spring-web/src/main/java/org/springframework/http/HttpEntity.java @@ -28,7 +28,7 @@ *
      * HttpHeaders headers = new HttpHeaders();
      * headers.setContentType(MediaType.TEXT_PLAIN);
    - * HttpEntity<String> entity = new HttpEntity<String>(helloWorld, headers);
    + * HttpEntity<String> entity = new HttpEntity<String>("helloWorld", headers);
      * URI location = template.postForLocation("https://example.com", entity);
      * 
    * or From ec3f857bda2ffbba5d96787215cc99565d95c3cf Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 21 Oct 2021 12:40:10 +0200 Subject: [PATCH 286/735] Polish contribution See gh-27586 --- .../main/java/org/springframework/http/HttpEntity.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/HttpEntity.java b/spring-web/src/main/java/org/springframework/http/HttpEntity.java index d6493c4bed06..9b5be7c625ae 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpEntity.java +++ b/spring-web/src/main/java/org/springframework/http/HttpEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,12 +23,12 @@ /** * Represents an HTTP request or response entity, consisting of headers and body. * - *

    Typically used in combination with the {@link org.springframework.web.client.RestTemplate}, + *

    Often used in combination with the {@link org.springframework.web.client.RestTemplate}, * like so: *

      * HttpHeaders headers = new HttpHeaders();
      * headers.setContentType(MediaType.TEXT_PLAIN);
    - * HttpEntity<String> entity = new HttpEntity<String>("helloWorld", headers);
    + * HttpEntity<String> entity = new HttpEntity<>("Hello World", headers);
      * URI location = template.postForLocation("https://example.com", entity);
      * 
    * or @@ -39,11 +39,11 @@ * * Can also be used in Spring MVC, as a return value from a @Controller method: *
    - * @RequestMapping("/handle")
    + * @GetMapping("/handle")
      * public HttpEntity<String> handle() {
      *   HttpHeaders responseHeaders = new HttpHeaders();
      *   responseHeaders.set("MyResponseHeader", "MyValue");
    - *   return new HttpEntity<String>("Hello World", responseHeaders);
    + *   return new HttpEntity<>("Hello World", responseHeaders);
      * }
      * 
    * From 7a54ff2d21ad7e1900ce603ea1a814d8021bacb9 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 21 Oct 2021 14:07:17 +0200 Subject: [PATCH 287/735] Extract public TypeFilterUtils from ComponentScanAnnotationParser Prior to this commit, third parties using @ComponentScan's @Filter annotation had to implement their own parsing for @Filter AnnotationAttributes as well as instantiation of the corresponding TypeFilters. In such cases the various *Aware callbacks (BeanFactoryAware, EnvironmentAware, etc.) should also be supported. This commit therefore extracts a new public TypeFilterUtils class from ComponentScanAnnotationParser so that third parties can benefit from consistent TypeFilter creation from @ComponentScan @Filter annotations. Closes gh-27553 --- .../ComponentScanAnnotationParser.java | 65 ++-------- .../context/annotation/TypeFilterUtils.java | 119 ++++++++++++++++++ 2 files changed, 127 insertions(+), 57 deletions(-) create mode 100644 spring-context/src/main/java/org/springframework/context/annotation/TypeFilterUtils.java diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java index 90575862c6bd..27e879bfb338 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java @@ -16,13 +16,10 @@ package org.springframework.context.annotation; -import java.lang.annotation.Annotation; -import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import java.util.regex.Pattern; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.config.BeanDefinitionHolder; @@ -33,12 +30,7 @@ import org.springframework.core.env.Environment; import org.springframework.core.io.ResourceLoader; import org.springframework.core.type.filter.AbstractTypeHierarchyTraversingFilter; -import org.springframework.core.type.filter.AnnotationTypeFilter; -import org.springframework.core.type.filter.AspectJTypeFilter; -import org.springframework.core.type.filter.AssignableTypeFilter; -import org.springframework.core.type.filter.RegexPatternTypeFilter; import org.springframework.core.type.filter.TypeFilter; -import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; @@ -93,13 +85,17 @@ public Set parse(AnnotationAttributes componentScan, final scanner.setResourcePattern(componentScan.getString("resourcePattern")); - for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) { - for (TypeFilter typeFilter : typeFiltersFor(filter)) { + for (AnnotationAttributes includeFilterAttributes : componentScan.getAnnotationArray("includeFilters")) { + List typeFilters = TypeFilterUtils.createTypeFiltersFor(includeFilterAttributes, this.environment, + this.resourceLoader, this.registry); + for (TypeFilter typeFilter : typeFilters) { scanner.addIncludeFilter(typeFilter); } } - for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) { - for (TypeFilter typeFilter : typeFiltersFor(filter)) { + for (AnnotationAttributes excludeFilterAttributes : componentScan.getAnnotationArray("excludeFilters")) { + List typeFilters = TypeFilterUtils.createTypeFiltersFor(excludeFilterAttributes, this.environment, + this.resourceLoader, this.registry); + for (TypeFilter typeFilter : typeFilters) { scanner.addExcludeFilter(typeFilter); } } @@ -132,49 +128,4 @@ protected boolean matchClassName(String className) { return scanner.doScan(StringUtils.toStringArray(basePackages)); } - private List typeFiltersFor(AnnotationAttributes filterAttributes) { - List typeFilters = new ArrayList<>(); - FilterType filterType = filterAttributes.getEnum("type"); - - for (Class filterClass : filterAttributes.getClassArray("classes")) { - switch (filterType) { - case ANNOTATION: - Assert.isAssignable(Annotation.class, filterClass, - "@ComponentScan ANNOTATION type filter requires an annotation type"); - @SuppressWarnings("unchecked") - Class annotationType = (Class) filterClass; - typeFilters.add(new AnnotationTypeFilter(annotationType)); - break; - case ASSIGNABLE_TYPE: - typeFilters.add(new AssignableTypeFilter(filterClass)); - break; - case CUSTOM: - Assert.isAssignable(TypeFilter.class, filterClass, - "@ComponentScan CUSTOM type filter requires a TypeFilter implementation"); - - TypeFilter filter = ParserStrategyUtils.instantiateClass(filterClass, TypeFilter.class, - this.environment, this.resourceLoader, this.registry); - typeFilters.add(filter); - break; - default: - throw new IllegalArgumentException("Filter type not supported with Class value: " + filterType); - } - } - - for (String expression : filterAttributes.getStringArray("pattern")) { - switch (filterType) { - case ASPECTJ: - typeFilters.add(new AspectJTypeFilter(expression, this.resourceLoader.getClassLoader())); - break; - case REGEX: - typeFilters.add(new RegexPatternTypeFilter(Pattern.compile(expression))); - break; - default: - throw new IllegalArgumentException("Filter type not supported with String pattern: " + filterType); - } - } - - return typeFilters; - } - } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/TypeFilterUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/TypeFilterUtils.java new file mode 100644 index 000000000000..340c232f60f1 --- /dev/null +++ b/spring-context/src/main/java/org/springframework/context/annotation/TypeFilterUtils.java @@ -0,0 +1,119 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation; + +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.env.Environment; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.type.filter.AnnotationTypeFilter; +import org.springframework.core.type.filter.AspectJTypeFilter; +import org.springframework.core.type.filter.AssignableTypeFilter; +import org.springframework.core.type.filter.RegexPatternTypeFilter; +import org.springframework.core.type.filter.TypeFilter; +import org.springframework.util.Assert; + +/** + * Collection of utilities for working with {@link ComponentScan @ComponentScan} + * {@linkplain ComponentScan.Filter type filters}. + * + * @author Chris Beams + * @author Juergen Hoeller + * @author Sam Brannen + * @since 5.3.13 + * @see ComponentScan.Filter + * @see org.springframework.core.type.filter.TypeFilter + */ +public abstract class TypeFilterUtils { + + /** + * Create {@linkplain TypeFilter type filters} from the supplied + * {@link AnnotationAttributes}, such as those sourced from + * {@link ComponentScan#includeFilters()} or {@link ComponentScan#excludeFilters()}. + *

    Each {@link TypeFilter} will be instantiated using an appropriate + * constructor, with {@code BeanClassLoaderAware}, {@code BeanFactoryAware}, + * {@code EnvironmentAware}, and {@code ResourceLoaderAware} contracts + * invoked if they are implemented by the type filter. + * @param filterAttributes {@code AnnotationAttributes} for a + * {@link ComponentScan.Filter @Filter} declaration + * @param environment the {@code Environment} to make available to filters + * @param resourceLoader the {@code ResourceLoader} to make available to filters + * @param registry the {@code BeanDefinitionRegistry} to make available to filters + * as a {@link org.springframework.beans.factory.BeanFactory} if applicable + * @return a list of instantiated and configured type filters + * @see TypeFilter + * @see AnnotationTypeFilter + * @see AssignableTypeFilter + * @see AspectJTypeFilter + * @see RegexPatternTypeFilter + * @see org.springframework.beans.factory.BeanClassLoaderAware + * @see org.springframework.beans.factory.BeanFactoryAware + * @see org.springframework.context.EnvironmentAware + * @see org.springframework.context.ResourceLoaderAware + */ + public static List createTypeFiltersFor(AnnotationAttributes filterAttributes, Environment environment, + ResourceLoader resourceLoader, BeanDefinitionRegistry registry) { + + List typeFilters = new ArrayList<>(); + FilterType filterType = filterAttributes.getEnum("type"); + + for (Class filterClass : filterAttributes.getClassArray("classes")) { + switch (filterType) { + case ANNOTATION: + Assert.isAssignable(Annotation.class, filterClass, + "@ComponentScan ANNOTATION type filter requires an annotation type"); + @SuppressWarnings("unchecked") + Class annotationType = (Class) filterClass; + typeFilters.add(new AnnotationTypeFilter(annotationType)); + break; + case ASSIGNABLE_TYPE: + typeFilters.add(new AssignableTypeFilter(filterClass)); + break; + case CUSTOM: + Assert.isAssignable(TypeFilter.class, filterClass, + "@ComponentScan CUSTOM type filter requires a TypeFilter implementation"); + TypeFilter filter = ParserStrategyUtils.instantiateClass(filterClass, TypeFilter.class, + environment, resourceLoader, registry); + typeFilters.add(filter); + break; + default: + throw new IllegalArgumentException("Filter type not supported with Class value: " + filterType); + } + } + + for (String expression : filterAttributes.getStringArray("pattern")) { + switch (filterType) { + case ASPECTJ: + typeFilters.add(new AspectJTypeFilter(expression, resourceLoader.getClassLoader())); + break; + case REGEX: + typeFilters.add(new RegexPatternTypeFilter(Pattern.compile(expression))); + break; + default: + throw new IllegalArgumentException("Filter type not supported with String pattern: " + filterType); + } + } + + return typeFilters; + } + +} From 9af11ad5ce137e8fe71f0ce9e980745e4c840818 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 22 Oct 2021 11:08:33 +0200 Subject: [PATCH 288/735] Fix Javadoc formatting issues --- .../core/convert/TypeDescriptor.java | 14 +++++++------- .../springframework/expression/TypeConverter.java | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java index 1bc8cb281b1f..f6e25824e004 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java +++ b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java @@ -37,7 +37,7 @@ /** * Contextual descriptor about a type to convert from or to. - * Capable of representing arrays and generic collection types. + *

    Capable of representing arrays and generic collection types. * * @author Keith Donald * @author Andy Clement @@ -345,9 +345,9 @@ public TypeDescriptor getElementTypeDescriptor() { * from the provided collection or array element. *

    Narrows the {@link #getElementTypeDescriptor() elementType} property to the class * of the provided collection or array element. For example, if this describes a - * {@code java.util.List<java.lang.Number<} and the element argument is an + * {@code java.util.List} and the element argument is a * {@code java.lang.Integer}, the returned TypeDescriptor will be {@code java.lang.Integer}. - * If this describes a {@code java.util.List<?>} and the element argument is an + * If this describes a {@code java.util.List} and the element argument is a * {@code java.lang.Integer}, the returned TypeDescriptor will be {@code java.lang.Integer} * as well. *

    Annotation and nested type context will be preserved in the narrowed @@ -388,9 +388,9 @@ public TypeDescriptor getMapKeyTypeDescriptor() { * from the provided map key. *

    Narrows the {@link #getMapKeyTypeDescriptor() mapKeyType} property * to the class of the provided map key. For example, if this describes a - * {@code java.util.Map<java.lang.Number, java.lang.String<} and the key + * {@code java.util.Map} and the key * argument is a {@code java.lang.Integer}, the returned TypeDescriptor will be - * {@code java.lang.Integer}. If this describes a {@code java.util.Map<?, ?>} + * {@code java.lang.Integer}. If this describes a {@code java.util.Map} * and the key argument is a {@code java.lang.Integer}, the returned * TypeDescriptor will be {@code java.lang.Integer} as well. *

    Annotation and nested type context will be preserved in the narrowed @@ -425,9 +425,9 @@ public TypeDescriptor getMapValueTypeDescriptor() { * from the provided map value. *

    Narrows the {@link #getMapValueTypeDescriptor() mapValueType} property * to the class of the provided map value. For example, if this describes a - * {@code java.util.Map<java.lang.String, java.lang.Number<} and the value + * {@code java.util.Map} and the value * argument is a {@code java.lang.Integer}, the returned TypeDescriptor will be - * {@code java.lang.Integer}. If this describes a {@code java.util.Map<?, ?>} + * {@code java.lang.Integer}. If this describes a {@code java.util.Map} * and the value argument is a {@code java.lang.Integer}, the returned * TypeDescriptor will be {@code java.lang.Integer} as well. *

    Annotation and nested type context will be preserved in the narrowed diff --git a/spring-expression/src/main/java/org/springframework/expression/TypeConverter.java b/spring-expression/src/main/java/org/springframework/expression/TypeConverter.java index f2f67c0965c8..6974d6b8747c 100644 --- a/spring-expression/src/main/java/org/springframework/expression/TypeConverter.java +++ b/spring-expression/src/main/java/org/springframework/expression/TypeConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ public interface TypeConverter { * Convert (or coerce) a value from one type to another, for example from a * {@code boolean} to a {@code String}. *

    The {@link TypeDescriptor} parameters enable support for typed collections: - * A caller may prefer a {@code List<Integer>}, for example, rather than + * A caller may prefer a {@code List}, for example, rather than * simply any {@code List}. * @param value the value to be converted * @param sourceType a type descriptor that supplies extra information about the From 9b967775ede2d885746d734347a356abb8b3d1db Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 22 Oct 2021 10:45:34 +0200 Subject: [PATCH 289/735] Polish Spel's ReflectionHelper.setupArgumentsForVarargsInvocation() --- .../spel/support/ReflectionHelper.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java index d8af41170d67..65e3cff83a86 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java @@ -332,8 +332,8 @@ private static boolean isFirstEntryInArray(Object value, @Nullable Object possib } /** - * Package up the arguments so that they correctly match what is expected in parameterTypes. - * For example, if parameterTypes is {@code (int, String[])} because the second parameter + * Package up the arguments so that they correctly match what is expected in requiredParameterTypes. + *

    For example, if requiredParameterTypes is {@code (int, String[])} because the second parameter * was declared {@code String...}, then if arguments is {@code [1,"a","b"]} then it must be * repackaged as {@code [1,new String[]{"a","b"}]} in order to match the expected types. * @param requiredParameterTypes the types of the parameters for the invocation @@ -350,23 +350,24 @@ public static Object[] setupArgumentsForVarargsInvocation(Class[] requiredPar requiredParameterTypes[parameterCount - 1] != (args[argumentCount - 1] != null ? args[argumentCount - 1].getClass() : null)) { - int arraySize = 0; // zero size array if nothing to pass as the varargs parameter - if (argumentCount >= parameterCount) { - arraySize = argumentCount - (parameterCount - 1); - } - - // Create an array for the varargs arguments + // Create an array for the leading arguments plus the varargs array argument. Object[] newArgs = new Object[parameterCount]; + // Copy all leading arguments to the new array, omitting the varargs array argument. System.arraycopy(args, 0, newArgs, 0, newArgs.length - 1); // Now sort out the final argument, which is the varargs one. Before entering this method, // the arguments should have been converted to the box form of the required type. + int varargsArraySize = 0; // zero size array if nothing to pass as the varargs parameter + if (argumentCount >= parameterCount) { + varargsArraySize = argumentCount - (parameterCount - 1); + } Class componentType = requiredParameterTypes[parameterCount - 1].getComponentType(); - Object repackagedArgs = Array.newInstance(componentType, arraySize); - for (int i = 0; i < arraySize; i++) { - Array.set(repackagedArgs, i, args[parameterCount - 1 + i]); + Object varargsArray = Array.newInstance(componentType, varargsArraySize); + for (int i = 0; i < varargsArraySize; i++) { + Array.set(varargsArray, i, args[parameterCount - 1 + i]); } - newArgs[newArgs.length - 1] = repackagedArgs; + // Finally, add the varargs array to the new arguments array. + newArgs[newArgs.length - 1] = varargsArray; return newArgs; } return args; From bc657eb4d5babccf5065ef26fca8c9723675a083 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 21 Oct 2021 14:50:34 +0200 Subject: [PATCH 290/735] Fix SpEL vararg method invocation for strings containing commas Prior to this commit, if a SpEL expression invoked a method or registered function that declares a String varargs argument, there were sometimes issues with converting the input arguments into the varargs array argument. Specifically, if the expression supplied a single String argument containing a comma for the varargs (such as "a,b"), SpEL's ReflectionHelper.convertArguments() method incorrectly converted that single String to an array via the ConversionService, which indirectly converted that String using the StringToArrayConverter, which converts a comma-delimited String to an array. Thus, "a,b" effectively got converted to a two-dimensional array ["a", "b"] instead of simply ["a,b"]. This commit fixes this bug by avoiding use of the TypeConverter and ConversionService for single arguments supplied as varargs when the single argument's type matches the varargs array component type. Closes gh-27582 --- .../spel/support/ReflectionHelper.java | 28 +++++++----- .../spel/MethodInvocationTests.java | 43 ++++++++++++++++--- .../spel/testresources/Inventor.java | 11 ++++- 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java index 65e3cff83a86..821c0b246ae6 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,6 +38,7 @@ * * @author Andy Clement * @author Juergen Hoeller + * @author Sam Brannen * @since 3.0 */ public abstract class ReflectionHelper { @@ -281,25 +282,32 @@ static boolean convertArguments(TypeConverter converter, Object[] arguments, Exe arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType); conversionOccurred |= (argument != arguments[i]); } + MethodParameter methodParam = MethodParameter.forExecutable(executable, varargsPosition); + + // If the target is varargs and there is just one more argument, then convert it here. if (varargsPosition == arguments.length - 1) { - // If the target is varargs and there is just one more argument - // then convert it here - TypeDescriptor targetType = new TypeDescriptor(methodParam); Object argument = arguments[varargsPosition]; + TypeDescriptor targetType = new TypeDescriptor(methodParam); TypeDescriptor sourceType = TypeDescriptor.forObject(argument); - arguments[varargsPosition] = converter.convertValue(argument, sourceType, targetType); - // Three outcomes of that previous line: - // 1) the input argument was already compatible (ie. array of valid type) and nothing was done - // 2) the input argument was correct type but not in an array so it was made into an array - // 3) the input argument was the wrong type and got converted and put into an array + // If the argument type is equal to the varargs element type, there is no need + // to convert it or wrap it in an array. For example, using StringToArrayConverter + // to convert a String containing a comma would result in the String being split + // and repackaged in an array when it should be used as-is. + if (!sourceType.equals(targetType.getElementTypeDescriptor())) { + arguments[varargsPosition] = converter.convertValue(argument, sourceType, targetType); + } + // Three outcomes of the above if-block: + // 1) the input argument was correct type but not wrapped in an array, and nothing was done. + // 2) the input argument was already compatible (i.e., array of valid type), and nothing was done. + // 3) the input argument was the wrong type and got converted and wrapped in an array. if (argument != arguments[varargsPosition] && !isFirstEntryInArray(argument, arguments[varargsPosition])) { conversionOccurred = true; // case 3 } } + // Otherwise, convert remaining arguments to the varargs element type. else { - // Convert remaining arguments to the varargs element type TypeDescriptor targetType = new TypeDescriptor(methodParam).getElementTypeDescriptor(); Assert.state(targetType != null, "No element type"); for (int i = varargsPosition; i < arguments.length; i++) { diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java index 0a025acf723f..b2cde1f10ff3 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +46,7 @@ * * @author Andy Clement * @author Phillip Webb + * @author Sam Brannen */ public class MethodInvocationTests extends AbstractExpressionTests { @@ -233,26 +234,54 @@ public void testAddingMethodResolvers() { @Test public void testVarargsInvocation01() { - // Calling 'public int aVarargsMethod(String... strings)' - //evaluate("aVarargsMethod('a','b','c')", 3, Integer.class); - //evaluate("aVarargsMethod('a')", 1, Integer.class); + // Calling 'public int aVarargsMethod(String... strings)' - returns number of arguments + evaluate("aVarargsMethod('a','b','c')", 3, Integer.class); + evaluate("aVarargsMethod('a')", 1, Integer.class); evaluate("aVarargsMethod()", 0, Integer.class); evaluate("aVarargsMethod(1,2,3)", 3, Integer.class); // all need converting to strings evaluate("aVarargsMethod(1)", 1, Integer.class); // needs string conversion evaluate("aVarargsMethod(1,'a',3.0d)", 3, Integer.class); // first and last need conversion - // evaluate("aVarargsMethod(new String[]{'a','b','c'})", 3, Integer.class); + evaluate("aVarargsMethod(new String[]{'a','b','c'})", 3, Integer.class); } @Test public void testVarargsInvocation02() { - // Calling 'public int aVarargsMethod2(int i, String... strings)' - returns int+length_of_strings + // Calling 'public int aVarargsMethod2(int i, String... strings)' - returns int + length_of_strings evaluate("aVarargsMethod2(5,'a','b','c')", 8, Integer.class); evaluate("aVarargsMethod2(2,'a')", 3, Integer.class); evaluate("aVarargsMethod2(4)", 4, Integer.class); evaluate("aVarargsMethod2(8,2,3)", 10, Integer.class); evaluate("aVarargsMethod2(9)", 9, Integer.class); evaluate("aVarargsMethod2(2,'a',3.0d)", 4, Integer.class); - // evaluate("aVarargsMethod2(8,new String[]{'a','b','c'})", 11, Integer.class); + evaluate("aVarargsMethod2(8,new String[]{'a','b','c'})", 11, Integer.class); + } + + @Test + public void testVarargsInvocation03() { + // Calling 'public int aVarargsMethod3(String str1, String... strings)' - returns all strings concatenated with "-" + + // No conversion necessary + evaluate("aVarargsMethod3('x')", "x", String.class); + evaluate("aVarargsMethod3('x', 'a')", "x-a", String.class); + evaluate("aVarargsMethod3('x', 'a', 'b', 'c')", "x-a-b-c", String.class); + + // Conversion necessary + evaluate("aVarargsMethod3(9)", "9", String.class); + evaluate("aVarargsMethod3(8,2,3)", "8-2-3", String.class); + evaluate("aVarargsMethod3('2','a',3.0d)", "2-a-3.0", String.class); + evaluate("aVarargsMethod3('8',new String[]{'a','b','c'})", "8-a-b-c", String.class); + + // Individual string contains a comma with multiple varargs arguments + evaluate("aVarargsMethod3('foo', ',', 'baz')", "foo-,-baz", String.class); + evaluate("aVarargsMethod3('foo', 'bar', ',baz')", "foo-bar-,baz", String.class); + evaluate("aVarargsMethod3('foo', 'bar,', 'baz')", "foo-bar,-baz", String.class); + + // Individual string contains a comma with single varargs argument. + // Reproduces https://github.com/spring-projects/spring-framework/issues/27582 + evaluate("aVarargsMethod3('foo', ',')", "foo-,", String.class); + evaluate("aVarargsMethod3('foo', ',bar')", "foo-,bar", String.class); + evaluate("aVarargsMethod3('foo', 'bar,')", "foo-bar,", String.class); + evaluate("aVarargsMethod3('foo', 'bar,baz')", "foo-bar,baz", String.class); } @Test diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java b/spring-expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java index bdf6d79c1ddc..34960d982fe3 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ ///CLOVER:OFF @SuppressWarnings("unused") public class Inventor { + private String name; public String _name; public String _name_; @@ -202,8 +203,14 @@ public int aVarargsMethod2(int i, String... strings) { return strings.length + i; } - public Inventor(String... strings) { + public String aVarargsMethod3(String str1, String... strings) { + if (ObjectUtils.isEmpty(strings)) { + return str1; + } + return str1 + "-" + String.join("-", strings); + } + public Inventor(String... strings) { } public boolean getSomeProperty() { From b728b4640b70c293c18ca1290ee303dee1f0d413 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 22 Oct 2021 13:46:11 +0200 Subject: [PATCH 291/735] Add explicit tests for SpEL functions for fix for gh-27582 --- .../expression/spel/VariableAndFunctionTests.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/VariableAndFunctionTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/VariableAndFunctionTests.java index 0333e20ff961..3271e45ea6d1 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/VariableAndFunctionTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/VariableAndFunctionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ * Tests the evaluation of expressions that access variables and functions (lambda/java). * * @author Andy Clement + * @author Sam Brannen */ public class VariableAndFunctionTests extends AbstractExpressionTests { @@ -58,12 +59,17 @@ public void testFunctionAccess02() { @Test public void testCallVarargsFunction() { + evaluate("#varargsFunctionReverseStringsAndMerge('a,b')", "a,b", String.class); + evaluate("#varargsFunctionReverseStringsAndMerge('a', 'b,c', 'd')", "db,ca", String.class); evaluate("#varargsFunctionReverseStringsAndMerge('a','b','c')", "cba", String.class); evaluate("#varargsFunctionReverseStringsAndMerge('a')", "a", String.class); evaluate("#varargsFunctionReverseStringsAndMerge()", "", String.class); evaluate("#varargsFunctionReverseStringsAndMerge('b',25)", "25b", String.class); evaluate("#varargsFunctionReverseStringsAndMerge(25)", "25", String.class); + + evaluate("#varargsFunctionReverseStringsAndMerge2(1, 'a,b')", "1a,b", String.class); evaluate("#varargsFunctionReverseStringsAndMerge2(1,'a','b','c')", "1cba", String.class); + evaluate("#varargsFunctionReverseStringsAndMerge2(1, 'a', 'b,c', 'd')", "1db,ca", String.class); evaluate("#varargsFunctionReverseStringsAndMerge2(2,'a')", "2a", String.class); evaluate("#varargsFunctionReverseStringsAndMerge2(3)", "3", String.class); evaluate("#varargsFunctionReverseStringsAndMerge2(4,'b',25)", "425b", String.class); From e5475d698a8a861a03a18c24de16e3e4f0d22f72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=A6=D1=8B=D0=BF?= =?UTF-8?q?=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Fri, 22 Oct 2021 14:38:13 +0300 Subject: [PATCH 292/735] Iterate over Map's entrySet() instead of keySet() in PropertyEditorRegistrySupport Closes gh-27591 --- .../beans/PropertyEditorRegistrySupport.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/PropertyEditorRegistrySupport.java b/spring-beans/src/main/java/org/springframework/beans/PropertyEditorRegistrySupport.java index d1354e1d89b0..e17a4e52e697 100644 --- a/spring-beans/src/main/java/org/springframework/beans/PropertyEditorRegistrySupport.java +++ b/spring-beans/src/main/java/org/springframework/beans/PropertyEditorRegistrySupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -422,10 +422,13 @@ private PropertyEditor getCustomEditor(@Nullable Class requiredType) { } if (editor == null) { // Find editor for superclass or interface. - for (Iterator> it = this.customEditors.keySet().iterator(); it.hasNext() && editor == null;) { - Class key = it.next(); + for (Map.Entry, PropertyEditor> entry : this.customEditors.entrySet()) { + if (editor != null) { + break; + } + Class key = entry.getKey(); if (key.isAssignableFrom(requiredType)) { - editor = this.customEditors.get(key); + editor = entry.getValue(); // Cache editor for search type, to avoid the overhead // of repeated assignable-from checks. if (this.customEditorCache == null) { From a603779f33d47cd9ac87919ccc26f8c2d279fa40 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 22 Oct 2021 14:57:12 +0200 Subject: [PATCH 293/735] Return previous value in UndertowHeadersAdapter's remove() method Prior to this commit, UndertowHeadersAdapter's remove() method violated the java.util.Map contract by always returning null. This commit fixes this by returning the previous list stored under the specified key, and otherwise returning null if no previous value was present. Closes gh-27592 --- .../http/server/reactive/UndertowHeadersAdapter.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHeadersAdapter.java index fa197aa0c208..8b7c6aed14dd 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHeadersAdapter.java @@ -17,6 +17,7 @@ package org.springframework.http.server.reactive; import java.util.AbstractSet; +import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -36,6 +37,7 @@ * {@code MultiValueMap} implementation for wrapping Undertow HTTP headers. * * @author Brian Clozel + * @author Sam Brannen * @since 5.1.1 */ class UndertowHeadersAdapter implements MultiValueMap { @@ -131,7 +133,10 @@ public List put(String key, List value) { @Nullable public List remove(Object key) { if (key instanceof String) { - this.headers.remove((String) key); + Collection removed = this.headers.remove((String) key); + if (removed != null) { + return new ArrayList<>(removed); + } } return null; } From 66826ac960be20aa0df25f22f1a47612c5b91845 Mon Sep 17 00:00:00 2001 From: xxpain Date: Fri, 22 Oct 2021 15:47:13 +0800 Subject: [PATCH 294/735] Fix typo in Javadoc in HeaderAssertions Closes gh-27589 --- .../test/web/reactive/server/HeaderAssertions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/HeaderAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/HeaderAssertions.java index dfd8ce89c7e4..aa20066960d0 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/HeaderAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/HeaderAssertions.java @@ -115,7 +115,7 @@ public WebTestClient.ResponseSpec valueMatches(String name, String pattern) { /** * Match all values of the response header with the given regex * patterns which are applied to the values of the header in the - * same order. Note that the number of pattenrs must match the + * same order. Note that the number of patterns must match the * number of actual values. * @param name the header name * @param patterns one or more regex patterns, one per expected value From c58853f5e5891147c43487fac3a249ba5c98de0c Mon Sep 17 00:00:00 2001 From: Daniil Pozdeev Date: Thu, 14 Oct 2021 17:20:41 +0300 Subject: [PATCH 295/735] Use LocalDataSourceJobStore only if one is not set via Quartz properties Prior to this commit, Spring's SchedulerFactoryBean always set the "org.quartz.jobStore.class" property to LocalDataSourceJobStore even if the user had already specified a custom JobStore implementation via the Quartz properties file or Properties object, thereby effectively ignoring the user configuration. This commit addresses this by configuring Quartz to use Spring's LocalDataSourceJobStore only if a JobStore has not already been specified via user configuration. Closes gh-27560 --- .../quartz/SchedulerFactoryBean.java | 2 +- .../scheduling/quartz/QuartzSupportTests.java | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java index 50ef456cfc9a..cb4c0d2a3adb 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java @@ -570,7 +570,7 @@ private void initSchedulerFactory(StdSchedulerFactory schedulerFactory) throws S CollectionUtils.mergePropertiesIntoMap(this.quartzProperties, mergedProps); if (this.dataSource != null) { - mergedProps.setProperty(StdSchedulerFactory.PROP_JOB_STORE_CLASS, LocalDataSourceJobStore.class.getName()); + mergedProps.putIfAbsent(StdSchedulerFactory.PROP_JOB_STORE_CLASS, LocalDataSourceJobStore.class.getName()); } // Determine scheduler name across local settings and Quartz properties... diff --git a/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java b/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java index 6c7d5b8691c7..a300ce010aeb 100644 --- a/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java +++ b/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java @@ -18,6 +18,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Properties; import javax.sql.DataSource; @@ -30,6 +31,7 @@ import org.quartz.SchedulerFactory; import org.quartz.impl.JobDetailImpl; import org.quartz.impl.SchedulerRepository; +import org.quartz.impl.jdbcjobstore.JobStoreTX; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; @@ -40,6 +42,8 @@ import org.springframework.core.task.TaskExecutor; import org.springframework.core.testfixture.EnabledForTestGroups; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -396,6 +400,29 @@ public void schedulerWithHsqlDataSource() throws Exception { } } + @Test + public void schedulerFactoryBeanWithCustomJobStore() throws Exception { + StaticApplicationContext context = new StaticApplicationContext(); + + final String dbName = "mydb"; + final EmbeddedDatabase database = new EmbeddedDatabaseBuilder().setName(dbName).build(); + + final Properties properties = new Properties(); + properties.setProperty("org.quartz.jobStore.class", JobStoreTX.class.getName()); + properties.setProperty("org.quartz.jobStore.dataSource", dbName); + + BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SchedulerFactoryBean.class) + .addPropertyValue("autoStartup", false) + .addPropertyValue("dataSource", database) + .addPropertyValue("quartzProperties", properties) + .getBeanDefinition(); + context.registerBeanDefinition("scheduler", beanDefinition); + + Scheduler bean = context.getBean("scheduler", Scheduler.class); + + assertThat(bean.getMetaData().getJobStoreClass()).isEqualTo(JobStoreTX.class); + } + private ClassPathXmlApplicationContext context(String path) { return new ClassPathXmlApplicationContext(path, getClass()); } From 2c89ff934ddd5b7efa14f715c4ec6a67bab7fd69 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 23 Oct 2021 15:59:46 +0200 Subject: [PATCH 296/735] Update copyright date See gh-27560 --- .../springframework/scheduling/quartz/SchedulerFactoryBean.java | 2 +- .../springframework/scheduling/quartz/QuartzSupportTests.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java index cb4c0d2a3adb..e0982a2e5ff9 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java b/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java index a300ce010aeb..71cd93810e52 100644 --- a/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java +++ b/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 995aaa6159957222b189f352672e20e3626ac442 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 23 Oct 2021 16:00:26 +0200 Subject: [PATCH 297/735] Polishing --- .../scheduling/quartz/QuartzSupportTests.java | 64 ++++++++++--------- ...ipleAnonymousMethodInvokingJobDetailFB.xml | 4 +- .../quartz/schedulerAccessorBean.xml | 4 +- .../client/DefaultWebClientTests.java | 3 +- 4 files changed, 41 insertions(+), 34 deletions(-) diff --git a/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java b/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java index 71cd93810e52..9d461d2e400f 100644 --- a/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java +++ b/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java @@ -61,10 +61,10 @@ * @author Sam Brannen * @since 20.02.2004 */ -public class QuartzSupportTests { +class QuartzSupportTests { @Test - public void schedulerFactoryBeanWithApplicationContext() throws Exception { + void schedulerFactoryBeanWithApplicationContext() throws Exception { TestBean tb = new TestBean("tb", 99); StaticApplicationContext ac = new StaticApplicationContext(); @@ -101,7 +101,7 @@ protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String sc @Test @EnabledForTestGroups(LONG_RUNNING) - public void schedulerWithTaskExecutor() throws Exception { + void schedulerWithTaskExecutor() throws Exception { CountingTaskExecutor taskExecutor = new CountingTaskExecutor(); DummyJob.count = 0; @@ -134,7 +134,7 @@ public void schedulerWithTaskExecutor() throws Exception { @Test @SuppressWarnings({ "unchecked", "rawtypes" }) - public void jobDetailWithRunnableInsteadOfJob() { + void jobDetailWithRunnableInsteadOfJob() { JobDetailImpl jobDetail = new JobDetailImpl(); assertThatIllegalArgumentException().isThrownBy(() -> jobDetail.setJobClass((Class) DummyRunnable.class)); @@ -142,7 +142,7 @@ public void jobDetailWithRunnableInsteadOfJob() { @Test @EnabledForTestGroups(LONG_RUNNING) - public void schedulerWithQuartzJobBean() throws Exception { + void schedulerWithQuartzJobBean() throws Exception { DummyJob.param = 0; DummyJob.count = 0; @@ -175,7 +175,7 @@ public void schedulerWithQuartzJobBean() throws Exception { @Test @EnabledForTestGroups(LONG_RUNNING) - public void schedulerWithSpringBeanJobFactory() throws Exception { + void schedulerWithSpringBeanJobFactory() throws Exception { DummyJob.param = 0; DummyJob.count = 0; @@ -210,7 +210,7 @@ public void schedulerWithSpringBeanJobFactory() throws Exception { @Test @EnabledForTestGroups(LONG_RUNNING) - public void schedulerWithSpringBeanJobFactoryAndParamMismatchNotIgnored() throws Exception { + void schedulerWithSpringBeanJobFactoryAndParamMismatchNotIgnored() throws Exception { DummyJob.param = 0; DummyJob.count = 0; @@ -246,7 +246,7 @@ public void schedulerWithSpringBeanJobFactoryAndParamMismatchNotIgnored() throws @Test @EnabledForTestGroups(LONG_RUNNING) - public void schedulerWithSpringBeanJobFactoryAndQuartzJobBean() throws Exception { + void schedulerWithSpringBeanJobFactoryAndQuartzJobBean() throws Exception { DummyJobBean.param = 0; DummyJobBean.count = 0; @@ -280,7 +280,7 @@ public void schedulerWithSpringBeanJobFactoryAndQuartzJobBean() throws Exception @Test @EnabledForTestGroups(LONG_RUNNING) - public void schedulerWithSpringBeanJobFactoryAndJobSchedulingData() throws Exception { + void schedulerWithSpringBeanJobFactoryAndJobSchedulingData() throws Exception { DummyJob.param = 0; DummyJob.count = 0; @@ -298,7 +298,7 @@ public void schedulerWithSpringBeanJobFactoryAndJobSchedulingData() throws Excep } @Test // SPR-772 - public void multipleSchedulers() throws Exception { + void multipleSchedulers() throws Exception { try (ClassPathXmlApplicationContext ctx = context("multipleSchedulers.xml")) { Scheduler scheduler1 = (Scheduler) ctx.getBean("scheduler1"); Scheduler scheduler2 = (Scheduler) ctx.getBean("scheduler2"); @@ -309,7 +309,7 @@ public void multipleSchedulers() throws Exception { } @Test // SPR-16884 - public void multipleSchedulersWithQuartzProperties() throws Exception { + void multipleSchedulersWithQuartzProperties() throws Exception { try (ClassPathXmlApplicationContext ctx = context("multipleSchedulersWithQuartzProperties.xml")) { Scheduler scheduler1 = (Scheduler) ctx.getBean("scheduler1"); Scheduler scheduler2 = (Scheduler) ctx.getBean("scheduler2"); @@ -321,12 +321,13 @@ public void multipleSchedulersWithQuartzProperties() throws Exception { @Test @EnabledForTestGroups(LONG_RUNNING) - public void twoAnonymousMethodInvokingJobDetailFactoryBeans() throws Exception { - Thread.sleep(3000); + void twoAnonymousMethodInvokingJobDetailFactoryBeans() throws Exception { try (ClassPathXmlApplicationContext ctx = context("multipleAnonymousMethodInvokingJobDetailFB.xml")) { QuartzTestBean exportService = (QuartzTestBean) ctx.getBean("exportService"); QuartzTestBean importService = (QuartzTestBean) ctx.getBean("importService"); + Thread.sleep(400); + assertThat(exportService.getImportCount()).as("doImport called exportService").isEqualTo(0); assertThat(exportService.getExportCount()).as("doExport not called on exportService").isEqualTo(2); assertThat(importService.getImportCount()).as("doImport not called on importService").isEqualTo(2); @@ -336,12 +337,13 @@ public void twoAnonymousMethodInvokingJobDetailFactoryBeans() throws Exception { @Test @EnabledForTestGroups(LONG_RUNNING) - public void schedulerAccessorBean() throws Exception { - Thread.sleep(3000); + void schedulerAccessorBean() throws Exception { try (ClassPathXmlApplicationContext ctx = context("schedulerAccessorBean.xml")) { QuartzTestBean exportService = (QuartzTestBean) ctx.getBean("exportService"); QuartzTestBean importService = (QuartzTestBean) ctx.getBean("importService"); + Thread.sleep(400); + assertThat(exportService.getImportCount()).as("doImport called exportService").isEqualTo(0); assertThat(exportService.getExportCount()).as("doExport not called on exportService").isEqualTo(2); assertThat(importService.getImportCount()).as("doImport not called on importService").isEqualTo(2); @@ -351,7 +353,7 @@ public void schedulerAccessorBean() throws Exception { @Test @SuppressWarnings("resource") - public void schedulerAutoStartsOnContextRefreshedEventByDefault() throws Exception { + void schedulerAutoStartsOnContextRefreshedEventByDefault() throws Exception { StaticApplicationContext context = new StaticApplicationContext(); context.registerBeanDefinition("scheduler", new RootBeanDefinition(SchedulerFactoryBean.class)); Scheduler bean = context.getBean("scheduler", Scheduler.class); @@ -362,7 +364,7 @@ public void schedulerAutoStartsOnContextRefreshedEventByDefault() throws Excepti @Test @SuppressWarnings("resource") - public void schedulerAutoStartupFalse() throws Exception { + void schedulerAutoStartupFalse() throws Exception { StaticApplicationContext context = new StaticApplicationContext(); BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SchedulerFactoryBean.class) .addPropertyValue("autoStartup", false).getBeanDefinition(); @@ -374,7 +376,7 @@ public void schedulerAutoStartupFalse() throws Exception { } @Test - public void schedulerRepositoryExposure() throws Exception { + void schedulerRepositoryExposure() throws Exception { try (ClassPathXmlApplicationContext ctx = context("schedulerRepositoryExposure.xml")) { assertThat(ctx.getBean("scheduler")).isSameAs(SchedulerRepository.getInstance().lookup("myScheduler")); } @@ -385,7 +387,7 @@ public void schedulerRepositoryExposure() throws Exception { * TODO: Against Quartz 2.2, this test's job doesn't actually execute anymore... */ @Test - public void schedulerWithHsqlDataSource() throws Exception { + void schedulerWithHsqlDataSource() throws Exception { DummyJob.param = 0; DummyJob.count = 0; @@ -401,13 +403,14 @@ public void schedulerWithHsqlDataSource() throws Exception { } @Test - public void schedulerFactoryBeanWithCustomJobStore() throws Exception { + @SuppressWarnings("resource") + void schedulerFactoryBeanWithCustomJobStore() throws Exception { StaticApplicationContext context = new StaticApplicationContext(); - final String dbName = "mydb"; - final EmbeddedDatabase database = new EmbeddedDatabaseBuilder().setName(dbName).build(); + String dbName = "mydb"; + EmbeddedDatabase database = new EmbeddedDatabaseBuilder().setName(dbName).build(); - final Properties properties = new Properties(); + Properties properties = new Properties(); properties.setProperty("org.quartz.jobStore.class", JobStoreTX.class.getName()); properties.setProperty("org.quartz.jobStore.dataSource", dbName); @@ -418,9 +421,9 @@ public void schedulerFactoryBeanWithCustomJobStore() throws Exception { .getBeanDefinition(); context.registerBeanDefinition("scheduler", beanDefinition); - Scheduler bean = context.getBean("scheduler", Scheduler.class); + Scheduler scheduler = context.getBean(Scheduler.class); - assertThat(bean.getMetaData().getJobStoreClass()).isEqualTo(JobStoreTX.class); + assertThat(scheduler.getMetaData().getJobStoreClass()).isEqualTo(JobStoreTX.class); } private ClassPathXmlApplicationContext context(String path) { @@ -428,7 +431,7 @@ private ClassPathXmlApplicationContext context(String path) { } - public static class CountingTaskExecutor implements TaskExecutor { + private static class CountingTaskExecutor implements TaskExecutor { private int count; @@ -440,12 +443,14 @@ public void execute(Runnable task) { } - public static class DummyJob implements Job { + private static class DummyJob implements Job { private static int param; private static int count; + @SuppressWarnings("unused") + // Must be public public void setParam(int value) { if (param > 0) { throw new IllegalStateException("Param already set"); @@ -460,12 +465,13 @@ public synchronized void execute(JobExecutionContext jobExecutionContext) throws } - public static class DummyJobBean extends QuartzJobBean { + private static class DummyJobBean extends QuartzJobBean { private static int param; private static int count; + @SuppressWarnings("unused") public void setParam(int value) { if (param > 0) { throw new IllegalStateException("Param already set"); @@ -480,7 +486,7 @@ protected synchronized void executeInternal(JobExecutionContext jobExecutionCont } - public static class DummyRunnable implements Runnable { + private static class DummyRunnable implements Runnable { @Override public void run() { diff --git a/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/multipleAnonymousMethodInvokingJobDetailFB.xml b/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/multipleAnonymousMethodInvokingJobDetailFB.xml index e45ccd195feb..58e771f3ad4a 100644 --- a/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/multipleAnonymousMethodInvokingJobDetailFB.xml +++ b/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/multipleAnonymousMethodInvokingJobDetailFB.xml @@ -19,7 +19,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/schedulerAccessorBean.xml b/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/schedulerAccessorBean.xml index 0ba9c4a57a84..3634002664cc 100644 --- a/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/schedulerAccessorBean.xml +++ b/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/schedulerAccessorBean.xml @@ -21,7 +21,7 @@ - + @@ -32,7 +32,7 @@ - + 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 37928d2fb1b7..a33a24c01647 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-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -133,6 +133,7 @@ public void requestHeaderAndCookie() { } @Test + @SuppressWarnings("deprecation") public void contextFromThreadLocal() { WebClient client = this.builder .filter((request, next) -> From 4ec8ae42f48da6415a3be29507c9e327dec94538 Mon Sep 17 00:00:00 2001 From: Kenzo Spaulding Date: Wed, 26 May 2021 22:33:51 -0700 Subject: [PATCH 298/735] Add test cases to SpEL's MapAccessorTests Closes gh-26981 --- .../context/expression/MapAccessorTests.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/spring-context/src/test/java/org/springframework/context/expression/MapAccessorTests.java b/spring-context/src/test/java/org/springframework/context/expression/MapAccessorTests.java index df73adaa36d1..8fd4d2fb9a99 100644 --- a/spring-context/src/test/java/org/springframework/context/expression/MapAccessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/expression/MapAccessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,6 +67,17 @@ public void mapAccessorCompilable() { assertThat(ex.getValue(sec,mapGetter)).isEqualTo("bar"); assertThat(SpelCompiler.compile(ex)).isTrue(); assertThat(ex.getValue(sec,mapGetter)).isEqualTo("bar"); + + // basic isWritable + ex = sep.parseExpression("foo"); + assertThat(ex.isWritable(sec,testMap)).isTrue(); + + // basic write + ex = sep.parseExpression("foo2"); + ex.setValue(sec, testMap, "bar2"); + assertThat(ex.getValue(sec,testMap)).isEqualTo("bar2"); + assertThat(SpelCompiler.compile(ex)).isTrue(); + assertThat(ex.getValue(sec,testMap)).isEqualTo("bar2"); } public static class MapGetter { From e4e667acdb774b45164f3ec345bfdf9e406e537f Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 23 Oct 2021 18:02:55 +0200 Subject: [PATCH 299/735] Polishing --- .../org/springframework/context/expression/MapAccessor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/expression/MapAccessor.java b/spring-context/src/main/java/org/springframework/context/expression/MapAccessor.java index 5acc804d2a01..e7374fe305fc 100644 --- a/spring-context/src/main/java/org/springframework/context/expression/MapAccessor.java +++ b/spring-context/src/main/java/org/springframework/context/expression/MapAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ public Class[] getSpecificTargetClasses() { @Override public boolean canRead(EvaluationContext context, @Nullable Object target, String name) throws AccessException { - return (target instanceof Map && ((Map) target).containsKey(name)); + return (target instanceof Map map && map.containsKey(name)); } @Override From 65bf5f7c81fb35f3291a548e9d326a65e331e5eb Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 25 Oct 2021 09:58:04 +0200 Subject: [PATCH 300/735] Add JDK18 variant to CI pipeline This commit adds a new JDK 18 variant to the CI build image and configures a JDK18 build (sources compiled with JDK17, tests compiled and run with JDK18) to the CI pipeline. Closes gh-27607 --- ci/images/ci-image/Dockerfile | 3 ++- ci/images/get-jdk-url.sh | 13 ++++++---- ci/pipeline.yml | 45 ++++++++++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/ci/images/ci-image/Dockerfile b/ci/images/ci-image/Dockerfile index 548a7cd7c233..6ddd3a38eb31 100644 --- a/ci/images/ci-image/Dockerfile +++ b/ci/images/ci-image/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:focal-20210827 +FROM ubuntu:focal-20211006 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh @@ -6,5 +6,6 @@ RUN ./setup.sh ENV JAVA_HOME /opt/openjdk/java17 ENV JDK17 /opt/openjdk/java17 +ENV JDK18 /opt/openjdk/java18 ENV PATH $JAVA_HOME/bin:$PATH diff --git a/ci/images/get-jdk-url.sh b/ci/images/get-jdk-url.sh index a3babd3ae7d4..783b8bb3c758 100755 --- a/ci/images/get-jdk-url.sh +++ b/ci/images/get-jdk-url.sh @@ -2,10 +2,13 @@ set -e case "$1" in - java17) - echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17%2B35/OpenJDK17-jdk_x64_linux_hotspot_17_35.tar.gz" - ;; + java17) + echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17%2B35/OpenJDK17-jdk_x64_linux_hotspot_17_35.tar.gz" + ;; + java18) + echo "https://github.com/adoptium/temurin18-binaries/releases/download/jdk-2021-10-22-05-05-beta/OpenJDK-jdk_x64_linux_hotspot_2021-10-21-23-30.tar.gz" + ;; *) - echo $"Unknown java version" - exit 1 + echo $"Unknown java version" + exit 1 esac diff --git a/ci/pipeline.yml b/ci/pipeline.yml index 53f168b105e9..8596734ed611 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -85,6 +85,13 @@ resources: source: <<: *docker-resource-source repository: ((docker-hub-organization))/spring-framework-ci-jdk17 +- name: every-morning + type: time + icon: alarm + source: + start: 8:00 AM + stop: 9:00 AM + location: Europe/Vienna - name: artifactory-repo type: artifactory-resource icon: package-variant @@ -109,6 +116,14 @@ resources: access_token: ((github-ci-status-token)) branch: ((branch)) context: build +- name: repo-status-jdk18-build + type: github-status-resource + icon: eye-check-outline + source: + repository: ((github-repo-name)) + access_token: ((github-ci-status-token)) + branch: ((branch)) + context: jdk18-build - name: slack-alert type: slack-notification icon: slack @@ -198,6 +213,34 @@ jobs: "zip.type": "schema" get_params: threads: 8 +- name: jdk18-build + serial: true + public: true + plan: + - get: ci-image + - get: git-repo + - get: every-morning + trigger: true + - put: repo-status-jdk18-build + params: { state: "pending", commit: "git-repo" } + - do: + - task: check-project + image: ci-image + file: git-repo/ci/tasks/check-project.yml + privileged: true + timeout: ((task-timeout)) + params: + TEST_TOOLCHAIN: 18 + <<: *build-project-task-params + on_failure: + do: + - put: repo-status-jdk18-build + params: { state: "failure", commit: "git-repo" } + - put: slack-alert + params: + <<: *slack-fail-params + - put: repo-status-jdk18-build + params: { state: "success", commit: "git-repo" } - name: build-pull-requests serial: true public: true @@ -379,7 +422,7 @@ jobs: groups: - name: "builds" - jobs: ["build"] + jobs: ["build", "jdk18-build"] - name: "releases" jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"] - name: "ci-images" From 683bdf2675c2a2a9664e913579cfdb883bfc186f Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 25 Oct 2021 10:06:06 +0200 Subject: [PATCH 301/735] Polish JDK 18 CI pipeline This commit ensures that JDK 18 is properly installed in the CI image. See gh-27607 --- ci/images/setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/images/setup.sh b/ci/images/setup.sh index 43af1979a261..4ede919fe303 100755 --- a/ci/images/setup.sh +++ b/ci/images/setup.sh @@ -22,7 +22,7 @@ curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/ mkdir -p /opt/openjdk pushd /opt/openjdk > /dev/null -for jdk in java17 +for jdk in java17 java18 do JDK_URL=$( /get-jdk-url.sh $jdk ) mkdir $jdk From 0268e762980f302e251a92743dd6724403660399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=A6=D1=8B=D0=BF?= =?UTF-8?q?=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Thu, 23 Sep 2021 14:48:04 +0300 Subject: [PATCH 302/735] Improve mapping function in ExtendedEntityManagerCreator.createProxy() Closes gh-27456 --- .../orm/jpa/ExtendedEntityManagerCreator.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java b/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java index 8e9173a94bfd..55431d805f3e 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java @@ -230,10 +230,10 @@ private static EntityManager createProxy( if (emIfc != null) { interfaces = cachedEntityManagerInterfaces.computeIfAbsent(emIfc, key -> { - Set> ifcs = new LinkedHashSet<>(4); - ifcs.add(key); - ifcs.add(EntityManagerProxy.class); - return ClassUtils.toClassArray(ifcs); + if (EntityManagerProxy.class.equals(key)) { + return new Class[] {key}; + } + return new Class[] {key, EntityManagerProxy.class}; }); } else { From c4c3d59d07bfe7775f0df88f40babebd27975ca2 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 25 Oct 2021 17:02:58 +0200 Subject: [PATCH 303/735] Remove unused code in FormattingConversionServiceTests --- .../FormattingConversionServiceTests.java | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/spring-context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java b/spring-context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java index eeb6895eddea..8aff305f22fa 100644 --- a/spring-context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java +++ b/spring-context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -321,28 +321,6 @@ public Date convert(MyDate source) { TypeDescriptor.valueOf(String.class)); } - @Test - public void registerDefaultValueViaFormatter() { - registerDefaultValue(Date.class, new Date()); - } - - private void registerDefaultValue(Class clazz, final T defaultValue) { - formattingService.addFormatterForFieldType(clazz, new Formatter() { - @Override - public T parse(String text, Locale locale) { - return defaultValue; - } - @Override - public String print(T t, Locale locale) { - return defaultValue.toString(); - } - @Override - public String toString() { - return defaultValue.toString(); - } - }); - } - @Test public void introspectedFormatter() { formattingService.addFormatter(new NumberStyleFormatter("#,#00.0#")); From c989470f94926ee5c7474bead278b00e9aaac787 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 25 Oct 2021 17:12:55 +0200 Subject: [PATCH 304/735] Remove unused code in FormattingConversionServiceTests This commit removes test code that became obsolete with the removal of Joda Time support. --- .../FormattingConversionServiceTests.java | 92 ------------------- 1 file changed, 92 deletions(-) diff --git a/spring-context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java b/spring-context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java index 07cc3ecffcd4..00a56960ef01 100644 --- a/spring-context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java +++ b/spring-context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java @@ -16,10 +16,6 @@ package org.springframework.format.support; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Date; -import java.util.List; import java.util.Locale; import org.junit.jupiter.api.AfterEach; @@ -27,7 +23,6 @@ import org.junit.jupiter.api.Test; import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.TypeDescriptor; @@ -35,7 +30,6 @@ import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.format.Formatter; -import org.springframework.format.annotation.NumberFormat; import org.springframework.format.number.NumberStyleFormatter; import static org.assertj.core.api.Assertions.assertThat; @@ -187,80 +181,6 @@ public void proxiedConverterFactory() { } - public static class ValueBean { - - @Value("10-31-09") - @org.springframework.format.annotation.DateTimeFormat(pattern="MM-d-yy") - public Date date; - } - - - public static class MetaValueBean { - - @MyDateAnn - public Date date; - - @MyNumberAnn - public Double number; - } - - - @Value("${myDate}") - @org.springframework.format.annotation.DateTimeFormat(pattern="MM-d-yy") - @Retention(RetentionPolicy.RUNTIME) - public @interface MyDateAnn { - } - - - @Value("${myNumber}") - @NumberFormat(style = NumberFormat.Style.PERCENT) - @Retention(RetentionPolicy.RUNTIME) - public @interface MyNumberAnn { - } - - - public static class Model { - - @org.springframework.format.annotation.DateTimeFormat(style="S-") - public Date date; - - @org.springframework.format.annotation.DateTimeFormat(pattern="M-d-yy") - public List dates; - - public List getDates() { - return dates; - } - - public void setDates(List dates) { - this.dates = dates; - } - } - - - public static class ModelWithPlaceholders { - - @org.springframework.format.annotation.DateTimeFormat(style="${dateStyle}") - public Date date; - - @MyDatePattern - public List dates; - - public List getDates() { - return dates; - } - - public void setDates(List dates) { - this.dates = dates; - } - } - - - @org.springframework.format.annotation.DateTimeFormat(pattern="${datePattern}") - @Retention(RetentionPolicy.RUNTIME) - public @interface MyDatePattern { - } - - public static class NullReturningFormatter implements Formatter { @Override @@ -275,18 +195,6 @@ public Integer parse(String text, Locale locale) { } - @SuppressWarnings("serial") - public static class MyDate extends Date { - } - - - private static class ModelWithSubclassField { - - @org.springframework.format.annotation.DateTimeFormat(style = "S-") - public MyDate date; - } - - private static class IntegerConverter implements Converter { @Override From 6fd0615be9003a86c4ac5a0cb89e78aac4cc83f6 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 26 Oct 2021 09:12:30 +0200 Subject: [PATCH 305/735] Fix JDK18 declaration in CI pipeline See gh-27607 --- ci/scripts/check-project.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/scripts/check-project.sh b/ci/scripts/check-project.sh index 0620dc17164d..c0b66efc7d3d 100755 --- a/ci/scripts/check-project.sh +++ b/ci/scripts/check-project.sh @@ -4,6 +4,6 @@ set -e source $(dirname $0)/common.sh pushd git-repo > /dev/null -./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK17 \ +./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK17,JDK18 \ -PmainToolchain=${MAIN_TOOLCHAIN} -PtestToolchain=${TEST_TOOLCHAIN} --no-daemon --max-workers=4 check popd > /dev/null From 0a58419df4fee5e50b6831c065c1a14bedc5f5f8 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Mon, 25 Oct 2021 15:25:39 +0200 Subject: [PATCH 306/735] Add immutable MultiValueMap wrapper This commit introduces UnmodifiableMultiValueMap, an immutable wrapper around a MultiValueMap, similar to what is returned by Collections.unmodifiable*. CollectionUtils::unmodifiableMultiValueMap now returns UnmodifiableMultiValueMap. Closes gh-27608 --- .../springframework/util/CollectionUtils.java | 11 +- .../util/UnmodifiableMultiValueMap.java | 732 ++++++++++++++++++ .../util/UnmodifiableMultiValueMapTests.java | 179 +++++ .../web/util/UriComponentsBuilder.java | 3 +- 4 files changed, 917 insertions(+), 8 deletions(-) create mode 100644 spring-core/src/main/java/org/springframework/util/UnmodifiableMultiValueMap.java create mode 100644 spring-core/src/test/java/org/springframework/util/UnmodifiableMultiValueMapTests.java diff --git a/spring-core/src/main/java/org/springframework/util/CollectionUtils.java b/spring-core/src/main/java/org/springframework/util/CollectionUtils.java index 530e5222ba08..a574fff2674b 100644 --- a/spring-core/src/main/java/org/springframework/util/CollectionUtils.java +++ b/spring-core/src/main/java/org/springframework/util/CollectionUtils.java @@ -470,13 +470,10 @@ public static MultiValueMap unmodifiableMultiValueMap( MultiValueMap targetMap) { Assert.notNull(targetMap, "'targetMap' must not be null"); - Map> result = newLinkedHashMap(targetMap.size()); - targetMap.forEach((key, value) -> { - List values = Collections.unmodifiableList(value); - result.put(key, (List) values); - }); - Map> unmodifiableMap = Collections.unmodifiableMap(result); - return toMultiValueMap(unmodifiableMap); + if (targetMap instanceof UnmodifiableMultiValueMap) { + return (MultiValueMap) targetMap; + } + return new UnmodifiableMultiValueMap<>(targetMap); } diff --git a/spring-core/src/main/java/org/springframework/util/UnmodifiableMultiValueMap.java b/spring-core/src/main/java/org/springframework/util/UnmodifiableMultiValueMap.java new file mode 100644 index 000000000000..7623ff8770f8 --- /dev/null +++ b/spring-core/src/main/java/org/springframework/util/UnmodifiableMultiValueMap.java @@ -0,0 +1,732 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.util; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Spliterator; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import org.springframework.lang.Nullable; + +/** + * Unmodifiable wrapper for {@link MultiValueMap}. + * + * @author Arjen Poutsma + * @since 6.0 + * @param the key type + * @param the value element type + */ +final class UnmodifiableMultiValueMap implements MultiValueMap, Serializable { + + private static final long serialVersionUID = -8697084563854098920L; + + + private final MultiValueMap delegate; + + @Nullable + private transient Set keySet; + + @Nullable + private transient Set>> entrySet; + + @Nullable + private transient Collection> values; + + + @SuppressWarnings("unchecked") + public UnmodifiableMultiValueMap(MultiValueMap delegate) { + Assert.notNull(delegate, "Delegate must not be null"); + this.delegate = (MultiValueMap) delegate; + } + + // delegation + + @Override + public int size() { + return this.delegate.size(); + } + + @Override + public boolean isEmpty() { + return this.delegate.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return this.delegate.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return this.delegate.containsValue(value); + } + + @Override + @Nullable + public List get(Object key) { + List result = this.delegate.get(key); + return result != null ? Collections.unmodifiableList(result) : null; + } + + @Override + public V getFirst(K key) { + return this.delegate.getFirst(key); + } + + @Override + public List getOrDefault(Object key, List defaultValue) { + List result = this.delegate.getOrDefault(key, defaultValue); + if (result != defaultValue) { + result = Collections.unmodifiableList(result); + } + return result; + } + + @Override + public void forEach(BiConsumer> action) { + this.delegate.forEach((k, vs) -> action.accept(k, Collections.unmodifiableList(vs))); + } + + @Override + public Map toSingleValueMap() { + return this.delegate.toSingleValueMap(); + } + + @Override + public int hashCode() { + return this.delegate.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return this == obj || this.delegate.equals(obj); + } + + @Override + public String toString() { + return this.delegate.toString(); + } + + // lazy init + + @Override + public Set keySet() { + if (this.keySet == null) { + this.keySet = Collections.unmodifiableSet(this.delegate.keySet()); + } + return this.keySet; + } + + @Override + public Set>> entrySet() { + if (this.entrySet == null) { + this.entrySet = new UnmodifiableEntrySet<>(this.delegate.entrySet()); + } + return this.entrySet; + } + + @Override + public Collection> values() { + if (this.values == null) { + this.values = new UnmodifiableValueCollection<>(this.delegate.values()); + } + return this.values; + } + + // unsupported + + @Nullable + @Override + public List put(K key, List value) { + throw new UnsupportedOperationException(); + } + + @Override + public List putIfAbsent(K key, List value) { + throw new UnsupportedOperationException(); + } + + @Override + public void putAll(Map> m) { + throw new UnsupportedOperationException(); + } + + @Override + public List remove(Object key) { + throw new UnsupportedOperationException(); + } + + @Override + public void add(K key, @Nullable V value) { + throw new UnsupportedOperationException(); + } + + @Override + public void addAll(K key, List values) { + throw new UnsupportedOperationException(); + } + + @Override + public void addAll(MultiValueMap values) { + throw new UnsupportedOperationException(); + } + + @Override + public void addIfAbsent(K key, @Nullable V value) { + throw new UnsupportedOperationException(); + } + + @Override + public void set(K key, @Nullable V value) { + throw new UnsupportedOperationException(); + } + + @Override + public void setAll(Map values) { + throw new UnsupportedOperationException(); + } + + @Override + public void replaceAll(BiFunction, ? extends List> function) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object key, Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean replace(K key, List oldValue, List newValue) { + throw new UnsupportedOperationException(); + } + + @Override + public List replace(K key, List value) { + throw new UnsupportedOperationException(); + } + + @Override + public List computeIfAbsent(K key, Function> mappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public List computeIfPresent(K key, + BiFunction, ? extends List> remappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public List compute(K key, + BiFunction, ? extends List> remappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public List merge(K key, List value, + BiFunction, ? super List, ? extends List> remappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + + private static class UnmodifiableEntrySet implements Set>>, Serializable { + + private static final long serialVersionUID = 2407578793783925203L; + + + private final Set>> delegate; + + + @SuppressWarnings("unchecked") + public UnmodifiableEntrySet(Set>> delegate) { + this.delegate = (Set>>) delegate; + } + + // delegation + + @Override + public int size() { + return this.delegate.size(); + } + + @Override + public boolean isEmpty() { + return this.delegate.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return this.delegate.contains(o); + } + + @Override + public boolean containsAll(Collection c) { + return this.delegate.containsAll(c); + } + + @Override + public Iterator>> iterator() { + Iterator>> iterator = this.delegate.iterator(); + return new Iterator<>() { + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public Entry> next() { + return new UnmodifiableEntry<>(iterator.next()); + } + }; + } + + @Override + public Object[] toArray() { + Object[] result = this.delegate.toArray(); + filterArray(result); + return result; + } + + @Override + public T[] toArray(T[] a) { + T[] result = this.delegate.toArray(a); + filterArray(result); + return result; + } + + @SuppressWarnings("unchecked") + private void filterArray(Object[] result) { + for (int i = 0; i < result.length; i++) { + if (result[i] instanceof Map.Entry entry) { + result[i] = new UnmodifiableEntry<>((Entry>) entry); + } + } + } + + @Override + public void forEach(Consumer>> action) { + this.delegate.forEach(e -> action.accept(new UnmodifiableEntry<>(e))); + } + + @Override + public Stream>> stream() { + return StreamSupport.stream(spliterator(), false); + } + + @Override + public Stream>> parallelStream() { + return StreamSupport.stream(spliterator(), true); + } + + @Override + public Spliterator>> spliterator() { + return new UnmodifiableEntrySpliterator<>(this.delegate.spliterator()); + } + + @Override + public int hashCode() { + return this.delegate.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + else if (obj instanceof Set other) { + return other.size() == this.delegate.size() && + containsAll(other); + } + return false; + } + + @Override + public String toString() { + return this.delegate.toString(); + } + + // unsupported + + @Override + public boolean add(Entry> kListEntry) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeIf(Predicate>> filter) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection>> c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + + private static class UnmodifiableEntrySpliterator implements Spliterator>> { + + private final Spliterator>> delegate; + + + @SuppressWarnings("unchecked") + public UnmodifiableEntrySpliterator( + Spliterator>> delegate) { + this.delegate = (Spliterator>>) delegate; + } + + @Override + public boolean tryAdvance(Consumer>> action) { + return this.delegate.tryAdvance(entry -> action.accept(new UnmodifiableEntry<>(entry))); + } + + @Override + public void forEachRemaining(Consumer>> action) { + this.delegate.forEachRemaining(entry -> action.accept(new UnmodifiableEntry<>(entry))); + } + + @Override + @Nullable + public Spliterator>> trySplit() { + Spliterator>> split = this.delegate.trySplit(); + if (split != null) { + return new UnmodifiableEntrySpliterator<>(split); + } + else { + return null; + } + } + + @Override + public long estimateSize() { + return this.delegate.estimateSize(); + } + + @Override + public long getExactSizeIfKnown() { + return this.delegate.getExactSizeIfKnown(); + } + + @Override + public int characteristics() { + return this.delegate.characteristics(); + } + + @Override + public boolean hasCharacteristics(int characteristics) { + return this.delegate.hasCharacteristics(characteristics); + } + + @Override + public Comparator>> getComparator() { + return this.delegate.getComparator(); + } + } + + + private static class UnmodifiableEntry implements Map.Entry> { + + private final Entry> delegate; + + + @SuppressWarnings("unchecked") + public UnmodifiableEntry(Entry> delegate) { + Assert.notNull(delegate, "Delegate must not be null"); + this.delegate = (Entry>) delegate; + } + + @Override + public K getKey() { + return this.delegate.getKey(); + } + + @Override + public List getValue() { + return Collections.unmodifiableList(this.delegate.getValue()); + } + + @Override + public List setValue(List value) { + throw new UnsupportedOperationException(); + } + + @Override + public int hashCode() { + return this.delegate.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + else if (obj instanceof Map.Entry other) { + return getKey().equals(other.getKey()) && + getValue().equals(other.getValue()); + } + return false; + } + + @Override + public String toString() { + return this.delegate.toString(); + } + } + } + + + private static class UnmodifiableValueCollection implements Collection>, Serializable { + + private static final long serialVersionUID = 5518377583904339588L; + + private final Collection> delegate; + + + public UnmodifiableValueCollection(Collection> delegate) { + this.delegate = delegate; + } + + // delegation + + @Override + public int size() { + return this.delegate.size(); + } + + @Override + public boolean isEmpty() { + return this.delegate.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return this.delegate.contains(o); + } + + @Override + public boolean containsAll(Collection c) { + return this.delegate.containsAll(c); + } + + @Override + public Object[] toArray() { + Object[] result = this.delegate.toArray(); + filterArray(result); + return result; + } + + @Override + public T[] toArray(T[] a) { + T[] result = this.delegate.toArray(a); + filterArray(result); + return result; + } + + private void filterArray(Object[] array) { + for (int i = 0; i < array.length; i++) { + if (array[i] instanceof List list) { + array[i] = Collections.unmodifiableList(list); + } + } + } + + @Override + public Iterator> iterator() { + Iterator> iterator = this.delegate.iterator(); + return new Iterator<>() { + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public List next() { + return Collections.unmodifiableList(iterator.next()); + } + }; + } + + @Override + public void forEach(Consumer> action) { + this.delegate.forEach(list -> action.accept(Collections.unmodifiableList(list))); + } + + @Override + public Spliterator> spliterator() { + return new UnmodifiableValueSpliterator<>(this.delegate.spliterator()); + } + + @Override + public Stream> stream() { + return StreamSupport.stream(spliterator(), false); + } + + @Override + public Stream> parallelStream() { + return StreamSupport.stream(spliterator(), true); + } + + @Override + public int hashCode() { + return this.delegate.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return this == obj || this.delegate.equals(obj); + } + + @Override + public String toString() { + return this.delegate.toString(); + } + + // unsupported + + @Override + public boolean add(List ts) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection> c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeIf(Predicate> filter) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + + private static class UnmodifiableValueSpliterator implements Spliterator> { + + private final Spliterator> delegate; + + + public UnmodifiableValueSpliterator(Spliterator> delegate) { + this.delegate = delegate; + } + + @Override + public boolean tryAdvance(Consumer> action) { + return this.delegate.tryAdvance(l -> action.accept(Collections.unmodifiableList(l))); + } + + @Override + public void forEachRemaining(Consumer> action) { + this.delegate.forEachRemaining(l -> action.accept(Collections.unmodifiableList(l))); + } + + @Override + @Nullable + public Spliterator> trySplit() { + Spliterator> split = this.delegate.trySplit(); + if (split != null) { + return new UnmodifiableValueSpliterator<>(split); + } + else { + return null; + } + } + + @Override + public long estimateSize() { + return this.delegate.estimateSize(); + } + + @Override + public long getExactSizeIfKnown() { + return this.delegate.getExactSizeIfKnown(); + } + + @Override + public int characteristics() { + return this.delegate.characteristics(); + } + + @Override + public boolean hasCharacteristics(int characteristics) { + return this.delegate.hasCharacteristics(characteristics); + } + + @Override + public Comparator> getComparator() { + return this.delegate.getComparator(); + } + } + + } +} diff --git a/spring-core/src/test/java/org/springframework/util/UnmodifiableMultiValueMapTests.java b/spring-core/src/test/java/org/springframework/util/UnmodifiableMultiValueMapTests.java new file mode 100644 index 000000000000..27c856eb5640 --- /dev/null +++ b/spring-core/src/test/java/org/springframework/util/UnmodifiableMultiValueMapTests.java @@ -0,0 +1,179 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.assertj.core.api.ThrowableTypeAssert; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.entry; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * @author Arjen Poutsma + */ +class UnmodifiableMultiValueMapTests { + + @Test + void delegation() { + MultiValueMap mock = mock(MultiValueMap.class); + UnmodifiableMultiValueMap map = new UnmodifiableMultiValueMap<>(mock); + + given(mock.size()).willReturn(1); + assertThat(map.size()).isEqualTo(1); + + given(mock.isEmpty()).willReturn(false); + assertThat(map.isEmpty()).isFalse(); + + given(mock.containsKey("foo")).willReturn(true); + assertThat(map.containsKey("foo")).isTrue(); + + given(mock.containsValue(List.of("bar"))).willReturn(true); + assertThat(map.containsValue(List.of("bar"))).isTrue(); + + List list = new ArrayList<>(); + list.add("bar"); + given(mock.get("foo")).willReturn(list); + List result = map.get("foo"); + assertThat(result).isNotNull().containsExactly("bar"); + assertThatUnsupportedOperationException().isThrownBy(() -> result.add("baz")); + + given(mock.getOrDefault("foo", List.of("bar"))).willReturn(List.of("baz")); + assertThat(map.getOrDefault("foo", List.of("bar"))).containsExactly("baz"); + + given(mock.toSingleValueMap()).willReturn(Map.of("foo", "bar")); + assertThat(map.toSingleValueMap()).containsExactly(entry("foo", "bar")); + } + + @Test + void unsupported() { + UnmodifiableMultiValueMap map = new UnmodifiableMultiValueMap<>(new LinkedMultiValueMap<>()); + + assertThatUnsupportedOperationException().isThrownBy(() -> map.put("foo", List.of("bar"))); + assertThatUnsupportedOperationException().isThrownBy(() -> map.putIfAbsent("foo", List.of("bar"))); + assertThatUnsupportedOperationException().isThrownBy(() -> map.putAll(Map.of("foo", List.of("bar")))); + assertThatUnsupportedOperationException().isThrownBy(() -> map.remove("foo")); + assertThatUnsupportedOperationException().isThrownBy(() -> map.add("foo", "bar")); + assertThatUnsupportedOperationException().isThrownBy(() -> map.addAll("foo", List.of("bar"))); + assertThatUnsupportedOperationException().isThrownBy(() -> map.addAll(new LinkedMultiValueMap<>())); + assertThatUnsupportedOperationException().isThrownBy(() -> map.addIfAbsent("foo", "baz")); + assertThatUnsupportedOperationException().isThrownBy(() -> map.set("foo", "baz")); + assertThatUnsupportedOperationException().isThrownBy(() -> map.setAll(Map.of("foo", "baz"))); + assertThatUnsupportedOperationException().isThrownBy(() -> map.replaceAll((s, strings) -> strings)); + assertThatUnsupportedOperationException().isThrownBy(() -> map.remove("foo", List.of("bar"))); + assertThatUnsupportedOperationException().isThrownBy(() -> map.replace("foo", List.of("bar"))); + assertThatUnsupportedOperationException().isThrownBy(() -> map.replace("foo", List.of("bar"), List.of("baz"))); + assertThatUnsupportedOperationException().isThrownBy(() -> map.computeIfAbsent("foo", s -> List.of("bar"))); + assertThatUnsupportedOperationException().isThrownBy( + () -> map.computeIfPresent("foo", (s1, s2) -> List.of("bar"))); + assertThatUnsupportedOperationException().isThrownBy(() -> map.compute("foo", (s1, s2) -> List.of("bar"))); + assertThatUnsupportedOperationException().isThrownBy(() -> map.merge("foo", List.of("bar"), (s1, s2) -> s1)); + assertThatUnsupportedOperationException().isThrownBy(() -> map.clear()); + } + + @Test + void entrySetDelegation() { + MultiValueMap mockMap = mock(MultiValueMap.class); + Set>> mockSet = mock(Set.class); + given(mockMap.entrySet()).willReturn(mockSet); + Set>> set = new UnmodifiableMultiValueMap<>(mockMap).entrySet(); + + given(mockSet.size()).willReturn(1); + assertThat(set.size()).isEqualTo(1); + + given(mockSet.isEmpty()).willReturn(false); + assertThat(set.isEmpty()).isFalse(); + + given(mockSet.contains("foo")).willReturn(true); + assertThat(set.contains("foo")).isTrue(); + + List>> mockEntries = List.of(mock(Map.Entry.class)); + given(mockSet.containsAll(mockEntries)).willReturn(true); + assertThat(set.containsAll(mockEntries)).isTrue(); + + Iterator>> mockIterator = mock(Iterator.class); + given(mockSet.iterator()).willReturn(mockIterator); + given(mockIterator.hasNext()).willReturn(false); + assertThat(set.iterator()).isExhausted(); + } + + @Test + void entrySetUnsupported() { + Set>> set = new UnmodifiableMultiValueMap(new LinkedMultiValueMap<>()).entrySet(); + + assertThatUnsupportedOperationException().isThrownBy(() -> set.add(mock(Map.Entry.class))); + assertThatUnsupportedOperationException().isThrownBy(() -> set.remove("foo")); + assertThatUnsupportedOperationException().isThrownBy(() -> set.removeIf(e -> true)); + assertThatUnsupportedOperationException().isThrownBy(() -> set.addAll(mock(List.class))); + assertThatUnsupportedOperationException().isThrownBy(() -> set.retainAll(mock(List.class))); + assertThatUnsupportedOperationException().isThrownBy(() -> set.removeAll(mock(List.class))); + assertThatUnsupportedOperationException().isThrownBy(() -> set.clear()); + } + + @Test + void valuesDelegation() { + MultiValueMap mockMap = mock(MultiValueMap.class); + Collection> mockValues = mock(Collection.class); + given(mockMap.values()).willReturn(mockValues); + Collection> values = new UnmodifiableMultiValueMap<>(mockMap).values(); + + given(mockValues.size()).willReturn(1); + assertThat(values.size()).isEqualTo(1); + + given(mockValues.isEmpty()).willReturn(false); + assertThat(values.isEmpty()).isFalse(); + + given(mockValues.contains(List.of("foo"))).willReturn(true); + assertThat(mockValues.contains(List.of("foo"))).isTrue(); + + given(mockValues.containsAll(List.of(List.of("foo")))).willReturn(true); + assertThat(mockValues.containsAll(List.of(List.of("foo")))).isTrue(); + + Iterator> mockIterator = mock(Iterator.class); + given(mockValues.iterator()).willReturn(mockIterator); + given(mockIterator.hasNext()).willReturn(false); + assertThat(values.iterator()).isExhausted(); + } + + @Test + void valuesUnsupported() { + Collection> values = + new UnmodifiableMultiValueMap(new LinkedMultiValueMap<>()).values(); + + assertThatUnsupportedOperationException().isThrownBy(() -> values.add(List.of("foo"))); + assertThatUnsupportedOperationException().isThrownBy(() -> values.remove(List.of("foo"))); + assertThatUnsupportedOperationException().isThrownBy(() -> values.addAll(List.of(List.of("foo")))); + assertThatUnsupportedOperationException().isThrownBy(() -> values.removeAll(List.of(List.of("foo")))); + assertThatUnsupportedOperationException().isThrownBy(() -> values.retainAll(List.of(List.of("foo")))); + assertThatUnsupportedOperationException().isThrownBy(() -> values.removeIf(s -> true)); + assertThatUnsupportedOperationException().isThrownBy(() -> values.clear()); + } + + private static ThrowableTypeAssert assertThatUnsupportedOperationException() { + return assertThatExceptionOfType(UnsupportedOperationException.class); + } + +} diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index 68c98562a280..37fbf44b7b9e 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -479,8 +479,9 @@ private UriComponents buildInternal(EncodingHint hint) { result = new OpaqueUriComponents(this.scheme, this.ssp, this.fragment); } else { + MultiValueMap queryParams = new LinkedMultiValueMap<>(this.queryParams); HierarchicalUriComponents uric = new HierarchicalUriComponents(this.scheme, this.fragment, - this.userInfo, this.host, this.port, this.pathBuilder.build(), this.queryParams, + this.userInfo, this.host, this.port, this.pathBuilder.build(), queryParams, hint == EncodingHint.FULLY_ENCODED); result = (hint == EncodingHint.ENCODE_TEMPLATE ? uric.encodeTemplate(this.charset) : uric); } From 0416168d0edfaa8f321e318bd4129df7b425ee79 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 27 Oct 2021 15:07:15 +0200 Subject: [PATCH 307/735] Fix bug in max header calculation in DefaultPartHttpMessageReader This commit fixes a bug in the DefaultPartHttpMessageReader, in the check for exceeding the maximum header size. Before this commit, the entire buffer size was considered, thus triggering an exception even though the max header limit was not exceeded. After this commit, we only consider the size up until the end-of-header mark (CRLFCRLF). Furthermore, this commit increases the default maximum header size to 10k, the same default as Commons File upload. Closes gh-27612 --- .../DefaultPartHttpMessageReader.java | 2 +- .../http/codec/multipart/MultipartParser.java | 71 +++++++++++-------- .../DefaultPartHttpMessageReaderTests.java | 25 +++++++ .../http/codec/multipart/files.multipart | 2 - 4 files changed, 67 insertions(+), 33 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/DefaultPartHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/DefaultPartHttpMessageReader.java index d4248c8442d3..6e94678cef11 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/DefaultPartHttpMessageReader.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/DefaultPartHttpMessageReader.java @@ -63,7 +63,7 @@ public class DefaultPartHttpMessageReader extends LoggingCodecSupport implements private int maxInMemorySize = 256 * 1024; - private int maxHeadersSize = 8 * 1024; + private int maxHeadersSize = 10 * 1024; private long maxDiskUsagePerPart = -1; 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 d2057f53d627..d797b99f4b1b 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 @@ -342,33 +342,23 @@ private final class HeadersState implements State { /** * First checks whether the multipart boundary leading to this state - * was the final boundary, or whether {@link #maxHeadersSize} is - * exceeded. Then looks for the header-body boundary - * ({@code CR LF CR LF}) in the given buffer. If found, convert - * all buffers collected so far into a {@link HttpHeaders} object + * was the final boundary. Then looks for the header-body boundary + * ({@code CR LF CR LF}) in the given buffer. If found, checks whether + * the size of all header buffers does not exceed {@link #maxHeadersSize}, + * converts all buffers collected so far into a {@link HttpHeaders} object * and changes to {@link BodyState}, passing the remainder of the - * buffer. If the boundary is not found, the buffer is collected. + * buffer. If the boundary is not found, the buffer is collected if + * its size does not exceed {@link #maxHeadersSize}. */ @Override public void onNext(DataBuffer buf) { - long prevCount = this.byteCount.get(); - long count = this.byteCount.addAndGet(buf.readableByteCount()); - if (prevCount < 2 && count >= 2) { - if (isLastBoundary(buf)) { - if (logger.isTraceEnabled()) { - logger.trace("Last boundary found in " + buf); - } - - if (changeState(this, DisposedState.INSTANCE, buf)) { - emitComplete(); - } - return; + if (isLastBoundary(buf)) { + if (logger.isTraceEnabled()) { + logger.trace("Last boundary found in " + buf); } - } - else if (count > MultipartParser.this.maxHeadersSize) { + if (changeState(this, DisposedState.INSTANCE, buf)) { - emitError(new DataBufferLimitException("Part headers exceeded the memory usage limit of " + - MultipartParser.this.maxHeadersSize + " bytes")); + emitComplete(); } return; } @@ -377,17 +367,23 @@ else if (count > MultipartParser.this.maxHeadersSize) { if (logger.isTraceEnabled()) { logger.trace("End of headers found @" + endIdx + " in " + buf); } - DataBuffer headerBuf = MultipartUtils.sliceTo(buf, endIdx); - this.buffers.add(headerBuf); - DataBuffer bodyBuf = MultipartUtils.sliceFrom(buf, endIdx); - DataBufferUtils.release(buf); - - emitHeaders(parseHeaders()); - changeState(this, new BodyState(), bodyBuf); + long count = this.byteCount.addAndGet(endIdx); + if (belowMaxHeaderSize(count)) { + DataBuffer headerBuf = MultipartUtils.sliceTo(buf, endIdx); + this.buffers.add(headerBuf); + DataBuffer bodyBuf = MultipartUtils.sliceFrom(buf, endIdx); + DataBufferUtils.release(buf); + + emitHeaders(parseHeaders()); + changeState(this, new BodyState(), bodyBuf); + } } else { - this.buffers.add(buf); - requestBuffer(); + long count = this.byteCount.addAndGet(buf.readableByteCount()); + if (belowMaxHeaderSize(count)) { + this.buffers.add(buf); + requestBuffer(); + } } } @@ -407,6 +403,21 @@ private boolean isLastBoundary(DataBuffer buf) { buf.getByte(0) == HYPHEN); } + /** + * Checks whether the given {@code count} is below or equal to {@link #maxHeadersSize} + * and emits a {@link DataBufferLimitException} if not. + */ + private boolean belowMaxHeaderSize(long count) { + if (count <= MultipartParser.this.maxHeadersSize) { + return true; + } + else { + emitError(new DataBufferLimitException("Part headers exceeded the memory usage limit of " + + MultipartParser.this.maxHeadersSize + " bytes")); + return false; + } + } + /** * Parses the list of buffers into a {@link HttpHeaders} instance. * Converts the joined buffers into a string using ISO=8859-1, and parses diff --git a/spring-web/src/test/java/org/springframework/http/codec/multipart/DefaultPartHttpMessageReaderTests.java b/spring-web/src/test/java/org/springframework/http/codec/multipart/DefaultPartHttpMessageReaderTests.java index 8e812e720fb0..9179a546820f 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/multipart/DefaultPartHttpMessageReaderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/multipart/DefaultPartHttpMessageReaderTests.java @@ -270,6 +270,31 @@ public void utf8Headers(String displayName, DefaultPartHttpMessageReader reader) latch.await(); } + // gh-27612 + @Test + public void exceedHeaderLimit() throws InterruptedException { + Flux body = DataBufferUtils + .readByteChannel((new ClassPathResource("files.multipart", getClass()))::readableChannel, bufferFactory, 282); + + MediaType contentType = new MediaType("multipart", "form-data", singletonMap("boundary", "----WebKitFormBoundaryG8fJ50opQOML0oGD")); + MockServerHttpRequest request = MockServerHttpRequest.post("/") + .contentType(contentType) + .body(body); + + DefaultPartHttpMessageReader reader = new DefaultPartHttpMessageReader(); + + reader.setMaxHeadersSize(230); + + Flux result = reader.read(forClass(Part.class), request, emptyMap()); + + CountDownLatch latch = new CountDownLatch(2); + StepVerifier.create(result) + .consumeNextWith(part -> testPart(part, null, LOREM_IPSUM, latch)) + .consumeNextWith(part -> testPart(part, null, MUSPI_MEROL, latch)) + .verifyComplete(); + + latch.await(); + } private void testBrowser(DefaultPartHttpMessageReader reader, Resource resource, String boundary) throws InterruptedException { diff --git a/spring-web/src/test/resources/org/springframework/http/codec/multipart/files.multipart b/spring-web/src/test/resources/org/springframework/http/codec/multipart/files.multipart index 03b41190647e..bd10aea6b0a3 100644 --- a/spring-web/src/test/resources/org/springframework/http/codec/multipart/files.multipart +++ b/spring-web/src/test/resources/org/springframework/http/codec/multipart/files.multipart @@ -3,11 +3,9 @@ Content-Disposition: form-data; name="file2"; filename="a.txt" Content-Type: text/plain Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer iaculis metus id vestibulum nullam. - ------WebKitFormBoundaryG8fJ50opQOML0oGD Content-Disposition: form-data; name="file2"; filename="b.txt" Content-Type: text/plain .mallun mulubitsev di sutem silucai regetnI .tile gnicsipida rutetcesnoc ,tema tis rolod muspi meroL - ------WebKitFormBoundaryG8fJ50opQOML0oGD-- From 40d84c297bd88a2c4b7979b14eb7925e5fce0170 Mon Sep 17 00:00:00 2001 From: Xjzon <1070809335@qq.com> Date: Thu, 28 Oct 2021 00:11:59 +0800 Subject: [PATCH 308/735] Add support for custom expression parsing See gh-27604 --- .../context/expression/CachedExpressionEvaluator.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/spring-context/src/main/java/org/springframework/context/expression/CachedExpressionEvaluator.java b/spring-context/src/main/java/org/springframework/context/expression/CachedExpressionEvaluator.java index 7b868fc9871e..13a04440d542 100644 --- a/spring-context/src/main/java/org/springframework/context/expression/CachedExpressionEvaluator.java +++ b/spring-context/src/main/java/org/springframework/context/expression/CachedExpressionEvaluator.java @@ -86,7 +86,7 @@ protected Expression getExpression(Map cache, ExpressionKey expressionKey = createKey(elementKey, expression); Expression expr = cache.get(expressionKey); if (expr == null) { - expr = getParser().parseExpression(expression); + expr = parseExpression(expression); cache.put(expressionKey, expr); } return expr; @@ -96,6 +96,13 @@ private ExpressionKey createKey(AnnotatedElementKey elementKey, String expressio return new ExpressionKey(elementKey, expression); } + /** + * Parse the expression + * @param expression the expression to parse + */ + protected Expression parseExpression(String expression) { + return getParser().parseExpression(expression); + } /** * An expression key. From f295c8b2fbb8ac61f570c9b35abb45f0837fdd66 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 28 Oct 2021 14:10:21 +0200 Subject: [PATCH 309/735] Polish "Add support for custom expression parsing" See gh-27604 --- .../expression/CachedExpressionEvaluator.java | 14 ++++++++------ .../expression/CachedExpressionEvaluatorTests.java | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/expression/CachedExpressionEvaluator.java b/spring-context/src/main/java/org/springframework/context/expression/CachedExpressionEvaluator.java index 13a04440d542..c2d197a122e0 100644 --- a/spring-context/src/main/java/org/springframework/context/expression/CachedExpressionEvaluator.java +++ b/spring-context/src/main/java/org/springframework/context/expression/CachedExpressionEvaluator.java @@ -75,7 +75,7 @@ protected ParameterNameDiscoverer getParameterNameDiscoverer() { /** * Return the {@link Expression} for the specified SpEL value - *

    Parse the expression if it hasn't been already. + *

    {@link #parseExpression(String) Parse the expression} if it hasn't been already. * @param cache the cache to use * @param elementKey the element on which the expression is defined * @param expression the expression to parse @@ -92,18 +92,20 @@ protected Expression getExpression(Map cache, return expr; } - private ExpressionKey createKey(AnnotatedElementKey elementKey, String expression) { - return new ExpressionKey(elementKey, expression); - } - /** - * Parse the expression + * Parse the specified {@code expression}. * @param expression the expression to parse + * @since 5.3.13 */ protected Expression parseExpression(String expression) { return getParser().parseExpression(expression); } + private ExpressionKey createKey(AnnotatedElementKey elementKey, String expression) { + return new ExpressionKey(elementKey, expression); + } + + /** * An expression key. */ diff --git a/spring-context/src/test/java/org/springframework/context/expression/CachedExpressionEvaluatorTests.java b/spring-context/src/test/java/org/springframework/context/expression/CachedExpressionEvaluatorTests.java index f81a7945d738..1594137c0411 100644 --- a/spring-context/src/test/java/org/springframework/context/expression/CachedExpressionEvaluatorTests.java +++ b/spring-context/src/test/java/org/springframework/context/expression/CachedExpressionEvaluatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 8dd385b440cb2e432ce7151be08d313982d3b00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EC=9C=A0=EC=A7=84=28Yujin=20Choi=29/Platform=20E?= =?UTF-8?q?ngineering=ED=8C=80/11ST?= Date: Thu, 28 Oct 2021 10:58:11 +0900 Subject: [PATCH 310/735] Use toUnmodifiableSet and toList instead of collectingAndThen Since Spring Framework 6 uses JDK 17 for its baseline, we can make use of toList() and toUnmodifiableSet() which were introduced in JDK 16 and JDK 10, respectively. Closes gh-27618 --- .../springframework/beans/factory/config/YamlProcessor.java | 2 +- .../core/io/support/SpringFactoriesLoader.java | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java index 7949003c68bd..140370b56504 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java @@ -146,7 +146,7 @@ public void setSupportedTypes(Class... supportedTypes) { else { Assert.noNullElements(supportedTypes, "'supportedTypes' must not contain null elements"); this.supportedTypes = Arrays.stream(supportedTypes).map(Class::getName) - .collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet)); + .collect(Collectors.toUnmodifiableSet()); } } 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 c73e775b39c2..abba0cbd86e3 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.stream.Collectors; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -157,8 +156,7 @@ private static Map> loadSpringFactories(ClassLoader classLo } // Replace all lists with unmodifiable lists containing unique elements - result.replaceAll((factoryType, implementations) -> implementations.stream().distinct() - .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList))); + result.replaceAll((factoryType, implementations) -> implementations.stream().distinct().toList()); cache.put(classLoader, result); } catch (IOException ex) { From 32c14a2b4218005048ff26fdf8ad43ddef071db8 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 29 Oct 2021 11:04:01 +0200 Subject: [PATCH 311/735] Update Javadoc regarding repeatable annotation support --- .../jmx/export/annotation/ManagedNotification.java | 5 +++-- .../jmx/export/annotation/ManagedOperationParameter.java | 6 +++--- .../springframework/scheduling/annotation/Scheduled.java | 3 +++ .../org/springframework/jms/annotation/JmsListener.java | 5 ++++- .../springframework/test/context/TestPropertySource.java | 6 +++--- .../java/org/springframework/test/context/jdbc/Sql.java | 9 ++++----- 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/jmx/export/annotation/ManagedNotification.java b/spring-context/src/main/java/org/springframework/jmx/export/annotation/ManagedNotification.java index 1a4f933e942b..2543a359505a 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/annotation/ManagedNotification.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/annotation/ManagedNotification.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,8 @@ /** * Type-level annotation that indicates a JMX notification emitted by a bean. * - *

    As of Spring Framework 4.2.4, this annotation is declared as repeatable. + *

    This annotation can be used as a {@linkplain Repeatable repeatable} + * annotation. * * @author Rob Harrop * @since 2.0 diff --git a/spring-context/src/main/java/org/springframework/jmx/export/annotation/ManagedOperationParameter.java b/spring-context/src/main/java/org/springframework/jmx/export/annotation/ManagedOperationParameter.java index 1b9843608065..5f2366fdd5d0 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/annotation/ManagedOperationParameter.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/annotation/ManagedOperationParameter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,9 +26,9 @@ /** * Method-level annotation used to provide metadata about operation parameters, * corresponding to a {@code ManagedOperationParameter} attribute. - * Used as part of a {@link ManagedOperationParameters} annotation. * - *

    As of Spring Framework 4.2.4, this annotation is declared as repeatable. + *

    This annotation can be used as a {@linkplain Repeatable repeatable} + * annotation. * * @author Rob Harrop * @since 1.2 diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java index f3aa81296a23..e3f4de5408cf 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java @@ -40,6 +40,9 @@ * done manually or, more conveniently, through the {@code } * XML element or {@link EnableScheduling @EnableScheduling} annotation. * + *

    This annotation can be used as a {@linkplain Repeatable repeatable} + * annotation. + * *

    This annotation may be used as a meta-annotation to create custom * composed annotations with attribute overrides. * diff --git a/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java b/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java index 7fee7e70935c..72faf09e8166 100644 --- a/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java +++ b/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,6 +72,9 @@ * {@link org.springframework.messaging.handler.annotation.SendTo @SendTo} to the * method declaration. * + *

    This annotation can be used as a {@linkplain Repeatable repeatable} + * annotation. + * *

    This annotation may be used as a meta-annotation to create custom * composed annotations with attribute overrides. * diff --git a/spring-test/src/main/java/org/springframework/test/context/TestPropertySource.java b/spring-test/src/main/java/org/springframework/test/context/TestPropertySource.java index f74b9c5c6262..27bbc81c5f8b 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestPropertySource.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestPropertySource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,8 +70,8 @@ *

      *
    • Typically, {@code @TestPropertySource} will be used in conjunction with * {@link ContextConfiguration @ContextConfiguration}.
    • - *
    • As of Spring Framework 5.2, {@code @TestPropertySource} can be used as a - * {@linkplain Repeatable repeatable} annotation.
    • + *
    • {@code @TestPropertySource} can be used as a {@linkplain Repeatable + * repeatable} annotation.
    • *
    • This annotation may be used as a meta-annotation to create * custom composed annotations; however, caution should be taken if * this annotation and {@code @ContextConfiguration} are combined on a composed diff --git a/spring-test/src/main/java/org/springframework/test/context/jdbc/Sql.java b/spring-test/src/main/java/org/springframework/test/context/jdbc/Sql.java index fb69e925c0bb..50322c463397 100644 --- a/spring-test/src/main/java/org/springframework/test/context/jdbc/Sql.java +++ b/spring-test/src/main/java/org/springframework/test/context/jdbc/Sql.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,10 +45,9 @@ * XML namespace element. Consult the javadocs of individual attributes in this * annotation and {@link SqlConfig @SqlConfig} for details. * - *

      Beginning with Java 8, {@code @Sql} can be used as a - * {@linkplain Repeatable repeatable} annotation. Otherwise, - * {@link SqlGroup @SqlGroup} can be used as an explicit container for declaring - * multiple instances of {@code @Sql}. + *

      {@code @Sql} can be used as a {@linkplain Repeatable repeatable} + * annotation. Otherwise, {@link SqlGroup @SqlGroup} can be used as an explicit + * container for declaring multiple instances of {@code @Sql}. * *

      This annotation may be used as a meta-annotation to create custom * composed annotations with attribute overrides. From 44644684652d1eaeabaa79b05235a58e6fa1643b Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 29 Oct 2021 11:27:38 +0200 Subject: [PATCH 312/735] Clean up warnings in UnmodifiableMultiValueMapTests --- .../util/UnmodifiableMultiValueMapTests.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/spring-core/src/test/java/org/springframework/util/UnmodifiableMultiValueMapTests.java b/spring-core/src/test/java/org/springframework/util/UnmodifiableMultiValueMapTests.java index 27c856eb5640..a489ccf41106 100644 --- a/spring-core/src/test/java/org/springframework/util/UnmodifiableMultiValueMapTests.java +++ b/spring-core/src/test/java/org/springframework/util/UnmodifiableMultiValueMapTests.java @@ -33,11 +33,15 @@ import static org.mockito.Mockito.mock; /** + * Unit tests for {@link UnmodifiableMultiValueMap}. + * * @author Arjen Poutsma + * @since 6.0 */ class UnmodifiableMultiValueMapTests { @Test + @SuppressWarnings("unchecked") void delegation() { MultiValueMap mock = mock(MultiValueMap.class); UnmodifiableMultiValueMap map = new UnmodifiableMultiValueMap<>(mock); @@ -95,6 +99,7 @@ void unsupported() { } @Test + @SuppressWarnings("unchecked") void entrySetDelegation() { MultiValueMap mockMap = mock(MultiValueMap.class); Set>> mockSet = mock(Set.class); @@ -107,8 +112,9 @@ void entrySetDelegation() { given(mockSet.isEmpty()).willReturn(false); assertThat(set.isEmpty()).isFalse(); - given(mockSet.contains("foo")).willReturn(true); - assertThat(set.contains("foo")).isTrue(); + Map.Entry> mockedEntry = mock(Map.Entry.class); + given(mockSet.contains(mockedEntry)).willReturn(true); + assertThat(set.contains(mockedEntry)).isTrue(); List>> mockEntries = List.of(mock(Map.Entry.class)); given(mockSet.containsAll(mockEntries)).willReturn(true); @@ -121,11 +127,12 @@ void entrySetDelegation() { } @Test + @SuppressWarnings("unchecked") void entrySetUnsupported() { Set>> set = new UnmodifiableMultiValueMap(new LinkedMultiValueMap<>()).entrySet(); assertThatUnsupportedOperationException().isThrownBy(() -> set.add(mock(Map.Entry.class))); - assertThatUnsupportedOperationException().isThrownBy(() -> set.remove("foo")); + assertThatUnsupportedOperationException().isThrownBy(() -> set.remove(mock(Map.Entry.class))); assertThatUnsupportedOperationException().isThrownBy(() -> set.removeIf(e -> true)); assertThatUnsupportedOperationException().isThrownBy(() -> set.addAll(mock(List.class))); assertThatUnsupportedOperationException().isThrownBy(() -> set.retainAll(mock(List.class))); @@ -134,6 +141,7 @@ void entrySetUnsupported() { } @Test + @SuppressWarnings("unchecked") void valuesDelegation() { MultiValueMap mockMap = mock(MultiValueMap.class); Collection> mockValues = mock(Collection.class); From 56fd97184c8ca26c90c6ba1b76565f4e1c49dbc7 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 29 Oct 2021 11:32:44 +0200 Subject: [PATCH 313/735] Avoid generic type parameter hiding in UnmodifiableValueCollection --- .../util/UnmodifiableMultiValueMap.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/UnmodifiableMultiValueMap.java b/spring-core/src/main/java/org/springframework/util/UnmodifiableMultiValueMap.java index 7623ff8770f8..067a64250a20 100644 --- a/spring-core/src/main/java/org/springframework/util/UnmodifiableMultiValueMap.java +++ b/spring-core/src/main/java/org/springframework/util/UnmodifiableMultiValueMap.java @@ -527,14 +527,14 @@ public String toString() { } - private static class UnmodifiableValueCollection implements Collection>, Serializable { + private static class UnmodifiableValueCollection implements Collection>, Serializable { private static final long serialVersionUID = 5518377583904339588L; - private final Collection> delegate; + private final Collection> delegate; - public UnmodifiableValueCollection(Collection> delegate) { + public UnmodifiableValueCollection(Collection> delegate) { this.delegate = delegate; } @@ -583,8 +583,8 @@ private void filterArray(Object[] array) { } @Override - public Iterator> iterator() { - Iterator> iterator = this.delegate.iterator(); + public Iterator> iterator() { + Iterator> iterator = this.delegate.iterator(); return new Iterator<>() { @Override public boolean hasNext() { @@ -592,29 +592,29 @@ public boolean hasNext() { } @Override - public List next() { + public List next() { return Collections.unmodifiableList(iterator.next()); } }; } @Override - public void forEach(Consumer> action) { + public void forEach(Consumer> action) { this.delegate.forEach(list -> action.accept(Collections.unmodifiableList(list))); } @Override - public Spliterator> spliterator() { + public Spliterator> spliterator() { return new UnmodifiableValueSpliterator<>(this.delegate.spliterator()); } @Override - public Stream> stream() { + public Stream> stream() { return StreamSupport.stream(spliterator(), false); } @Override - public Stream> parallelStream() { + public Stream> parallelStream() { return StreamSupport.stream(spliterator(), true); } @@ -636,7 +636,7 @@ public String toString() { // unsupported @Override - public boolean add(List ts) { + public boolean add(List ts) { throw new UnsupportedOperationException(); } @@ -646,7 +646,7 @@ public boolean remove(Object o) { } @Override - public boolean addAll(Collection> c) { + public boolean addAll(Collection> c) { throw new UnsupportedOperationException(); } @@ -661,7 +661,7 @@ public boolean retainAll(Collection c) { } @Override - public boolean removeIf(Predicate> filter) { + public boolean removeIf(Predicate> filter) { throw new UnsupportedOperationException(); } From 694db2273f24be1152914c9f5bb849a8c0ccbb12 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 2 Nov 2021 16:13:35 +0100 Subject: [PATCH 314/735] Add Part::delete method This commit introduces the Part::delete method, that deletes its underlying storage. Closes gh-27612 --- .../http/codec/multipart/Content.java | 129 ++++++++++++++++++ .../http/codec/multipart/DefaultParts.java | 17 ++- .../http/codec/multipart/Part.java | 10 ++ .../http/codec/multipart/PartGenerator.java | 16 +-- .../SynchronossPartHttpMessageReader.java | 35 +++++ 5 files changed, 189 insertions(+), 18 deletions(-) create mode 100644 spring-web/src/main/java/org/springframework/http/codec/multipart/Content.java diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/Content.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/Content.java new file mode 100644 index 000000000000..28178c8c8ee4 --- /dev/null +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/Content.java @@ -0,0 +1,129 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.http.codec.multipart; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Scheduler; + +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.core.io.buffer.DefaultDataBufferFactory; + +/** + * Part content abstraction used by {@link DefaultParts}. + * + * @author Arjen Poutsma + * @since 5.3.13 + */ +abstract class Content { + + + protected Content() { + } + + /** + * Return the content. + */ + public abstract Flux content(); + + /** + * Delete this content. Default implementation does nothing. + */ + public Mono delete() { + return Mono.empty(); + } + + /** + * Returns a new {@code Content} based on the given flux of data buffers. + */ + public static Content fromFlux(Flux content) { + return new FluxContent(content); + } + + /** + * Return a new {@code Content} based on the given file path. + */ + public static Content fromFile(Path file, Scheduler scheduler) { + return new FileContent(file, scheduler); + } + + + /** + * {@code Content} implementation based on a flux of data buffers. + */ + private static final class FluxContent extends Content { + + private final Flux content; + + + public FluxContent(Flux content) { + this.content = content; + } + + + @Override + public Flux content() { + return this.content; + } + } + + + /** + * {@code Content} implementation based on a file. + */ + private static final class FileContent extends Content { + + private final Path file; + + private final Scheduler scheduler; + + + public FileContent(Path file, Scheduler scheduler) { + this.file = file; + this.scheduler = scheduler; + } + + + @Override + public Flux content() { + return DataBufferUtils.readByteChannel( + () -> Files.newByteChannel(this.file, StandardOpenOption.READ), + DefaultDataBufferFactory.sharedInstance, 1024) + .subscribeOn(this.scheduler); + } + + @Override + public Mono delete() { + return Mono.fromRunnable(() -> { + try { + Files.delete(this.file); + } + catch (IOException ex) { + throw new UncheckedIOException(ex); + } + }) + .subscribeOn(this.scheduler); + } + } +} diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/DefaultParts.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/DefaultParts.java index 77044db0a8dc..f18ec157b9ad 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/DefaultParts.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/DefaultParts.java @@ -57,7 +57,7 @@ public static FormFieldPart formFieldPart(HttpHeaders headers, String value) { * @param content the content of the part * @return {@link Part} or {@link FilePart}, depending on {@link HttpHeaders#getContentDisposition()} */ - public static Part part(HttpHeaders headers, Flux content) { + public static Part part(HttpHeaders headers, Content content) { Assert.notNull(headers, "Headers must not be null"); Assert.notNull(content, "Content must not be null"); @@ -142,16 +142,21 @@ public String toString() { */ private static class DefaultPart extends AbstractPart { - private final Flux content; + private final Content content; - public DefaultPart(HttpHeaders headers, Flux content) { + public DefaultPart(HttpHeaders headers, Content content) { super(headers); this.content = content; } @Override public Flux content() { - return this.content; + return this.content.content(); + } + + @Override + public Mono delete() { + return this.content.delete(); } @Override @@ -171,9 +176,9 @@ public String toString() { /** * Default implementation of {@link FilePart}. */ - private static class DefaultFilePart extends DefaultPart implements FilePart { + private static final class DefaultFilePart extends DefaultPart implements FilePart { - public DefaultFilePart(HttpHeaders headers, Flux content) { + public DefaultFilePart(HttpHeaders headers, Content content) { super(headers, content); } diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/Part.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/Part.java index c611adf22ae6..c39b36ff5faf 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/Part.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/Part.java @@ -17,6 +17,7 @@ package org.springframework.http.codec.multipart; import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.HttpHeaders; @@ -57,4 +58,13 @@ public interface Part { */ Flux content(); + /** + * Return a mono that, when subscribed to, deletes the underlying storage + * for this part. + * @since 5.3.13 + */ + default Mono delete() { + return Mono.empty(); + } + } 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 32a923d8a7d5..42b43e2eb5ef 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 @@ -160,7 +160,7 @@ else if (!this.streaming) { requestToken(); } }); - emitPart(DefaultParts.part(headers, streamingContent)); + emitPart(DefaultParts.part(headers, Content.fromFlux(streamingContent))); } } @@ -518,7 +518,7 @@ private void emitMemoryPart() { } this.content.clear(); Flux content = Flux.just(DefaultDataBufferFactory.sharedInstance.wrap(bytes)); - emitPart(DefaultParts.part(this.headers, content)); + emitPart(DefaultParts.part(this.headers, Content.fromFlux(content))); } @Override @@ -674,21 +674,13 @@ public void body(DataBuffer dataBuffer) { @Override public void partComplete(boolean finalPart) { MultipartUtils.closeChannel(this.channel); - Flux content = partContent(); - emitPart(DefaultParts.part(this.headers, content)); + emitPart(DefaultParts.part(this.headers, + Content.fromFile(this.file, PartGenerator.this.blockingOperationScheduler))); if (finalPart) { emitComplete(); } } - private Flux partContent() { - return DataBufferUtils - .readByteChannel( - () -> Files.newByteChannel(this.file, StandardOpenOption.READ), - DefaultDataBufferFactory.sharedInstance, 1024) - .subscribeOn(PartGenerator.this.blockingOperationScheduler); - } - @Override public void dispose() { if (this.closeOnDispose) { diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java index 032b787d887b..a35c9d5712de 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java @@ -16,7 +16,9 @@ package org.springframework.http.codec.multipart; +import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; @@ -40,6 +42,7 @@ import org.synchronoss.cloud.nio.multipart.NioMultipartParser; import org.synchronoss.cloud.nio.multipart.NioMultipartParserListener; import org.synchronoss.cloud.nio.multipart.PartBodyStreamStorageFactory; +import org.synchronoss.cloud.nio.stream.storage.NameAwarePurgableFileInputStream; import org.synchronoss.cloud.nio.stream.storage.StreamStorage; import reactor.core.publisher.BaseSubscriber; import reactor.core.publisher.Flux; @@ -497,6 +500,38 @@ public Flux content() { protected StreamStorage getStorage() { return this.storage; } + + @Override + public Mono delete() { + return Mono.fromRunnable(() -> { + File file = getFile(); + if (file != null) { + file.delete(); + } + }); + } + + @Nullable + private File getFile() { + InputStream inputStream = null; + try { + inputStream = getStorage().getInputStream(); + if (inputStream instanceof NameAwarePurgableFileInputStream) { + NameAwarePurgableFileInputStream stream = (NameAwarePurgableFileInputStream) inputStream; + return stream.getFile(); + } + } + finally { + if (inputStream != null) { + try { + inputStream.close(); + } + catch (IOException ignore) { + } + } + } + return null; + } } From 0c7e0002504f728d3ca3e182406d19ed3c4c9973 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 3 Nov 2021 15:02:12 +0100 Subject: [PATCH 315/735] Refactor Contents to DefaultParts This commit moves the Contents abstraction into DefaultParts See gh-27613 --- .../http/codec/multipart/Content.java | 129 ---------------- .../http/codec/multipart/DefaultParts.java | 139 +++++++++++++++++- .../http/codec/multipart/PartGenerator.java | 7 +- 3 files changed, 135 insertions(+), 140 deletions(-) delete mode 100644 spring-web/src/main/java/org/springframework/http/codec/multipart/Content.java diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/Content.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/Content.java deleted file mode 100644 index 28178c8c8ee4..000000000000 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/Content.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.codec.multipart; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.scheduler.Scheduler; - -import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.core.io.buffer.DataBufferUtils; -import org.springframework.core.io.buffer.DefaultDataBufferFactory; - -/** - * Part content abstraction used by {@link DefaultParts}. - * - * @author Arjen Poutsma - * @since 5.3.13 - */ -abstract class Content { - - - protected Content() { - } - - /** - * Return the content. - */ - public abstract Flux content(); - - /** - * Delete this content. Default implementation does nothing. - */ - public Mono delete() { - return Mono.empty(); - } - - /** - * Returns a new {@code Content} based on the given flux of data buffers. - */ - public static Content fromFlux(Flux content) { - return new FluxContent(content); - } - - /** - * Return a new {@code Content} based on the given file path. - */ - public static Content fromFile(Path file, Scheduler scheduler) { - return new FileContent(file, scheduler); - } - - - /** - * {@code Content} implementation based on a flux of data buffers. - */ - private static final class FluxContent extends Content { - - private final Flux content; - - - public FluxContent(Flux content) { - this.content = content; - } - - - @Override - public Flux content() { - return this.content; - } - } - - - /** - * {@code Content} implementation based on a file. - */ - private static final class FileContent extends Content { - - private final Path file; - - private final Scheduler scheduler; - - - public FileContent(Path file, Scheduler scheduler) { - this.file = file; - this.scheduler = scheduler; - } - - - @Override - public Flux content() { - return DataBufferUtils.readByteChannel( - () -> Files.newByteChannel(this.file, StandardOpenOption.READ), - DefaultDataBufferFactory.sharedInstance, 1024) - .subscribeOn(this.scheduler); - } - - @Override - public Mono delete() { - return Mono.fromRunnable(() -> { - try { - Files.delete(this.file); - } - catch (IOException ex) { - throw new UncheckedIOException(ex); - } - }) - .subscribeOn(this.scheduler); - } - } -} diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/DefaultParts.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/DefaultParts.java index f18ec157b9ad..284c82497b96 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/DefaultParts.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/DefaultParts.java @@ -16,10 +16,15 @@ package org.springframework.http.codec.multipart; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.nio.file.StandardOpenOption; +import java.util.concurrent.Callable; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import reactor.core.scheduler.Scheduler; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferUtils; @@ -50,17 +55,40 @@ public static FormFieldPart formFieldPart(HttpHeaders headers, String value) { } /** - * Create a new {@link Part} or {@link FilePart} with the given parameters. + * Create a new {@link Part} or {@link FilePart} based on a flux of data + * buffers. Returns {@link FilePart} if the {@code Content-Disposition} of + * the given headers contains a filename, or a "normal" {@link Part} + * otherwise. + * @param headers the part headers + * @param dataBuffers the content of the part + * @return {@link Part} or {@link FilePart}, depending on {@link HttpHeaders#getContentDisposition()} + */ + public static Part part(HttpHeaders headers, Flux dataBuffers) { + Assert.notNull(headers, "Headers must not be null"); + Assert.notNull(dataBuffers, "DataBuffers must not be null"); + + return partInternal(headers, new FluxContent(dataBuffers)); + } + + /** + * Create a new {@link Part} or {@link FilePart} based on the given file. * Returns {@link FilePart} if the {@code Content-Disposition} of the given * headers contains a filename, or a "normal" {@link Part} otherwise * @param headers the part headers - * @param content the content of the part + * @param file the file + * @param scheduler the scheduler used for reading the file * @return {@link Part} or {@link FilePart}, depending on {@link HttpHeaders#getContentDisposition()} */ - public static Part part(HttpHeaders headers, Content content) { + public static Part part(HttpHeaders headers, Path file, Scheduler scheduler) { Assert.notNull(headers, "Headers must not be null"); - Assert.notNull(content, "Content must not be null"); + Assert.notNull(file, "File must not be null"); + Assert.notNull(scheduler, "Scheduler must not be null"); + + return partInternal(headers, new FileContent(file, scheduler)); + } + + private static Part partInternal(HttpHeaders headers, Content content) { String filename = headers.getContentDisposition().getFilename(); if (filename != null) { return new DefaultFilePart(headers, content); @@ -142,7 +170,8 @@ public String toString() { */ private static class DefaultPart extends AbstractPart { - private final Content content; + protected final Content content; + public DefaultPart(HttpHeaders headers, Content content) { super(headers); @@ -191,7 +220,7 @@ public String filename() { @Override public Mono transferTo(Path dest) { - return DataBufferUtils.write(content(), dest); + return this.content.transferTo(dest); } @Override @@ -200,7 +229,7 @@ public String toString() { String name = contentDisposition.getName(); String filename = contentDisposition.getFilename(); if (name != null) { - return "DefaultFilePart{" + name() + " (" + filename + ")}"; + return "DefaultFilePart{" + name + " (" + filename + ")}"; } else { return "DefaultFilePart{(" + filename + ")}"; @@ -209,4 +238,100 @@ public String toString() { } + + /** + * Part content abstraction. + */ + private interface Content { + + Flux content(); + + Mono transferTo(Path dest); + + Mono delete(); + + } + + /** + * {@code Content} implementation based on a flux of data buffers. + */ + private static final class FluxContent implements Content { + + private final Flux content; + + + public FluxContent(Flux content) { + this.content = content; + } + + + @Override + public Flux content() { + return this.content; + } + + @Override + public Mono transferTo(Path dest) { + return DataBufferUtils.write(this.content, dest); + } + + @Override + public Mono delete() { + return Mono.empty(); + } + + } + + + /** + * {@code Content} implementation based on a file. + */ + private static final class FileContent implements Content { + + private final Path file; + + private final Scheduler scheduler; + + + public FileContent(Path file, Scheduler scheduler) { + this.file = file; + this.scheduler = scheduler; + } + + + @Override + public Flux content() { + return DataBufferUtils.readByteChannel( + () -> Files.newByteChannel(this.file, StandardOpenOption.READ), + DefaultDataBufferFactory.sharedInstance, 1024) + .subscribeOn(this.scheduler); + } + + @Override + public Mono transferTo(Path dest) { + return blockingOperation(() -> Files.copy(this.file, dest, StandardCopyOption.REPLACE_EXISTING)); + } + + @Override + public Mono delete() { + return blockingOperation(() -> { + Files.delete(this.file); + return null; + }); + } + + private Mono blockingOperation(Callable callable) { + return Mono.create(sink -> { + try { + callable.call(); + sink.success(); + } + catch (Exception ex) { + sink.error(ex); + } + }) + .subscribeOn(this.scheduler); + } + } + } 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 42b43e2eb5ef..88d689d90e9b 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 @@ -160,7 +160,7 @@ else if (!this.streaming) { requestToken(); } }); - emitPart(DefaultParts.part(headers, Content.fromFlux(streamingContent))); + emitPart(DefaultParts.part(headers, streamingContent)); } } @@ -518,7 +518,7 @@ private void emitMemoryPart() { } this.content.clear(); Flux content = Flux.just(DefaultDataBufferFactory.sharedInstance.wrap(bytes)); - emitPart(DefaultParts.part(this.headers, Content.fromFlux(content))); + emitPart(DefaultParts.part(this.headers, content)); } @Override @@ -674,8 +674,7 @@ public void body(DataBuffer dataBuffer) { @Override public void partComplete(boolean finalPart) { MultipartUtils.closeChannel(this.channel); - emitPart(DefaultParts.part(this.headers, - Content.fromFile(this.file, PartGenerator.this.blockingOperationScheduler))); + emitPart(DefaultParts.part(this.headers, this.file, PartGenerator.this.blockingOperationScheduler)); if (finalPart) { emitComplete(); } From 1b4438caacee097238de7e7713a2a50bf73ed216 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 4 Nov 2021 14:47:37 +0100 Subject: [PATCH 316/735] Start building against Reactor 2020.0.13 snapshots See gh-27636 --- build.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e5aa6b6b7d1d..d954fa16003d 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ configure(allprojects) { project -> imports { mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5" mavenBom "io.netty:netty-bom:4.1.69.Final" - mavenBom "io.projectreactor:reactor-bom:2020.0.12" + mavenBom "io.projectreactor:reactor-bom:2020.0.13-SNAPSHOT" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" mavenBom "io.rsocket:rsocket-bom:1.1.1" mavenBom "org.eclipse.jetty:jetty-bom:9.4.44.v20210927" @@ -292,6 +292,8 @@ configure(allprojects) { project -> repositories { mavenCentral() maven { url "https://repo.spring.io/libs-spring-framework-build" } + maven { url "https://repo.spring.io/snapshot" } // reactor + } } configurations.all { From ff1485fd8d6581edce2ad9bfbe2eb36d2efae8cc Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 5 Nov 2021 10:31:10 +0100 Subject: [PATCH 317/735] Fix log message formatting in CandidateComponentsIndexLoader --- .../context/index/CandidateComponentsIndexLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-context/src/main/java/org/springframework/context/index/CandidateComponentsIndexLoader.java b/spring-context/src/main/java/org/springframework/context/index/CandidateComponentsIndexLoader.java index af068373d8c9..ee95954b10ee 100644 --- a/spring-context/src/main/java/org/springframework/context/index/CandidateComponentsIndexLoader.java +++ b/spring-context/src/main/java/org/springframework/context/index/CandidateComponentsIndexLoader.java @@ -107,7 +107,7 @@ private static CandidateComponentsIndex doLoadIndex(ClassLoader classLoader) { result.add(properties); } if (logger.isDebugEnabled()) { - logger.debug("Loaded " + result.size() + "] index(es)"); + logger.debug("Loaded " + result.size() + " index(es)"); } int totalCount = result.stream().mapToInt(Properties::size).sum(); return (totalCount > 0 ? new CandidateComponentsIndex(result) : null); From 5acc3228f772630b44113286b9c0f2ab3768ab4a Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 8 Nov 2021 17:42:02 +0100 Subject: [PATCH 318/735] Upgrade to Hibernate ORM 5.6.1, Tomcat 10.0.12, Netty 4.1.70, HtmlUnit 2.54, XMLUnit 2.8.3 --- build.gradle | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index b01dde861908..203844d724b6 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ configure(allprojects) { project -> dependencyManagement { imports { mavenBom "com.fasterxml.jackson:jackson-bom:2.13.0" - mavenBom "io.netty:netty-bom:4.1.69.Final" + mavenBom "io.netty:netty-bom:4.1.70.Final" mavenBom "io.projectreactor:reactor-bom:2020.0.13-SNAPSHOT" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" mavenBom "io.rsocket:rsocket-bom:1.1.1" @@ -112,19 +112,19 @@ configure(allprojects) { project -> dependency "org.quartz-scheduler:quartz:2.3.2" dependency "org.ehcache:jcache:1.0.1" dependency "org.ehcache:ehcache:3.4.0" - dependency "org.hibernate:hibernate-core-jakarta:5.6.0.Final" + dependency "org.hibernate:hibernate-core-jakarta:5.6.1.Final" dependency "org.hibernate:hibernate-validator:7.0.1.Final" dependency "org.webjars:webjars-locator-core:0.48" dependency "org.webjars:underscorejs:1.8.3" - dependencySet(group: 'org.apache.tomcat', version: '10.0.11') { + dependencySet(group: 'org.apache.tomcat', version: '10.0.12') { entry 'tomcat-util' entry('tomcat-websocket') { exclude group: "org.apache.tomcat", name: "tomcat-websocket-api" exclude group: "org.apache.tomcat", name: "tomcat-servlet-api" } } - dependencySet(group: 'org.apache.tomcat.embed', version: '10.0.11') { + dependencySet(group: 'org.apache.tomcat.embed', version: '10.0.12') { entry 'tomcat-embed-core' entry 'tomcat-embed-websocket' } @@ -175,7 +175,7 @@ configure(allprojects) { project -> dependency "org.hamcrest:hamcrest:2.1" dependency "org.awaitility:awaitility:3.1.6" dependency "org.assertj:assertj-core:3.21.0" - dependencySet(group: 'org.xmlunit', version: '2.8.2') { + dependencySet(group: 'org.xmlunit', version: '2.8.3') { entry 'xmlunit-assertj' entry('xmlunit-matchers') { exclude group: "org.hamcrest", name: "hamcrest-core" @@ -189,10 +189,10 @@ configure(allprojects) { project -> } dependency "io.mockk:mockk:1.12.0" - dependency("net.sourceforge.htmlunit:htmlunit:2.53.0") { + dependency("net.sourceforge.htmlunit:htmlunit:2.54.0") { exclude group: "commons-logging", name: "commons-logging" } - dependency("org.seleniumhq.selenium:htmlunit-driver:2.53.0") { + dependency("org.seleniumhq.selenium:htmlunit-driver:2.54.0") { exclude group: "commons-logging", name: "commons-logging" } dependency("org.seleniumhq.selenium:selenium-java:3.141.59") { From c5de5c99390a69f23e7682b7748c273b01a63907 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 8 Nov 2021 21:21:54 +0000 Subject: [PATCH 319/735] Update Javadoc of LogFormatUtils Closes gh-27632 --- .../java/org/springframework/core/log/LogFormatUtils.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java b/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java index e3ae033e9f22..51ffd98cf0ab 100644 --- a/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java +++ b/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java @@ -36,8 +36,9 @@ public abstract class LogFormatUtils { /** - * Variant of {@link #formatValue(Object, int, boolean)} and a convenience - * method that truncates at 100 characters when {@code limitLength} is set. + * Convenience variant of {@link #formatValue(Object, int, boolean)} that + * limits the length of a log message to 100 characters and also replaces + * newline characters if {@code limitLength} is set to "true". * @param value the value to format * @param limitLength whether to truncate the value at a length of 100 * @return the formatted value From b5743966d6d926ed9b146ca4c34713b406628038 Mon Sep 17 00:00:00 2001 From: happyWilliam0 Date: Fri, 29 Oct 2021 14:14:05 +0800 Subject: [PATCH 320/735] Improve efficiency of UrlPathHelper#getSanitizedPath See gh-27623 --- .../web/util/UrlPathHelper.java | 19 ++++++++++--------- .../web/util/UrlPathHelperTests.java | 6 ++++++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java index e38fdff9b53c..a4a85e707b8b 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java +++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java @@ -405,16 +405,17 @@ else if (index1 == requestUri.length()) { *

    */ private static String getSanitizedPath(final String path) { - int index = path.indexOf("//"); - if (index >= 0) { - StringBuilder sanitized = new StringBuilder(path); - while (index != -1) { - sanitized.deleteCharAt(index); - index = sanitized.indexOf("//", index); + if (path.length() == 0) { + return path; + } + char[] arr = path.toCharArray(); + int slowIndex = 0; + for (int fastIndex = 1; fastIndex < arr.length; fastIndex++) { + if (arr[fastIndex] != '/' || arr[slowIndex] != '/') { + arr[++slowIndex] = arr[fastIndex]; } - return sanitized.toString(); } - return path; + return new String(arr, 0, slowIndex + 1); } /** @@ -532,7 +533,7 @@ public String getOriginatingServletPath(HttpServletRequest request) { */ public String getOriginatingQueryString(HttpServletRequest request) { if ((request.getAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE) != null) || - (request.getAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE) != null)) { + (request.getAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE) != null)) { return (String) request.getAttribute(WebUtils.FORWARD_QUERY_STRING_ATTRIBUTE); } else { diff --git a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java index e3281e55273f..49d8ed6a079a 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java @@ -246,6 +246,12 @@ void removeDuplicateSlashesInPath() { request.setRequestURI("/SPR-12372/foo/bar//"); assertThat(helper.getLookupPathForRequest(request)).isEqualTo("/foo/bar//"); + + // "enhance" case + request.setServletPath("/foo/bar//"); + request.setRequestURI("/SPR-12372////////////////////////foo//////////////////bar////////////////////"); + + assertThat(helper.getLookupPathForRequest(request)).isEqualTo("/foo/bar//"); } @Test From c6ce65ef564dfb89944ae07dd3a2c25f28fc287f Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 9 Nov 2021 09:45:35 +0000 Subject: [PATCH 321/735] Polishing contribution Closes gh-27623 --- .../springframework/web/util/UrlPathHelper.java | 15 ++++++++------- .../web/util/UrlPathHelperTests.java | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java index a4a85e707b8b..685f376b426a 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java +++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java @@ -405,17 +405,18 @@ else if (index1 == requestUri.length()) { * */ private static String getSanitizedPath(final String path) { - if (path.length() == 0) { + int start = path.indexOf("//"); + if (start == -1) { return path; } - char[] arr = path.toCharArray(); - int slowIndex = 0; - for (int fastIndex = 1; fastIndex < arr.length; fastIndex++) { - if (arr[fastIndex] != '/' || arr[slowIndex] != '/') { - arr[++slowIndex] = arr[fastIndex]; + char[] content = path.toCharArray(); + int slowIndex = start; + for (int fastIndex = start + 1; fastIndex < content.length; fastIndex++) { + if (content[fastIndex] != '/' || content[slowIndex] != '/') { + content[++slowIndex] = content[fastIndex]; } } - return new String(arr, 0, slowIndex + 1); + return new String(content, 0, slowIndex + 1); } /** diff --git a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java index 49d8ed6a079a..e7ef05083780 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java @@ -232,12 +232,12 @@ void removeDuplicateSlashesInPath() { request.setContextPath("/SPR-12372"); request.setPathInfo(null); request.setServletPath("/foo/bar/"); - request.setRequestURI("/SPR-12372/foo//bar/"); + request.setRequestURI("/SPR-12372/foo///bar/"); assertThat(helper.getLookupPathForRequest(request)).isEqualTo("/foo/bar/"); request.setServletPath("/foo/bar/"); - request.setRequestURI("/SPR-12372/foo/bar//"); + request.setRequestURI("////SPR-12372/foo/bar//"); assertThat(helper.getLookupPathForRequest(request)).isEqualTo("/foo/bar/"); From 6ac780d595b9a661d6ec357183f0d5bd0028981b Mon Sep 17 00:00:00 2001 From: Abdullah Khan Date: Tue, 9 Nov 2021 17:47:15 +0530 Subject: [PATCH 322/735] Fix grammar in webflux-webclient.adoc Closes gh-27657 --- src/docs/asciidoc/web/webflux-webclient.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/asciidoc/web/webflux-webclient.adoc b/src/docs/asciidoc/web/webflux-webclient.adoc index 22e0d265136e..3099ecb02d26 100644 --- a/src/docs/asciidoc/web/webflux-webclient.adoc +++ b/src/docs/asciidoc/web/webflux-webclient.adoc @@ -89,7 +89,7 @@ modified copy as follows: === MaxInMemorySize Codecs have <> for buffering data in -memory to avoid application memory issues. By the default those are set to 256KB. +memory to avoid application memory issues. By default those are set to 256KB. If that's not enough you'll get the following error: ---- From 39be572a7a70b7db24d0a0c4fd9a74a200ca6e3f Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 9 Nov 2021 19:38:10 +0100 Subject: [PATCH 323/735] Upgrade to Reactor 2020.0.13 Closes gh-27636 --- build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d954fa16003d..98c85c3d008b 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ configure(allprojects) { project -> imports { mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5" mavenBom "io.netty:netty-bom:4.1.69.Final" - mavenBom "io.projectreactor:reactor-bom:2020.0.13-SNAPSHOT" + mavenBom "io.projectreactor:reactor-bom:2020.0.13" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" mavenBom "io.rsocket:rsocket-bom:1.1.1" mavenBom "org.eclipse.jetty:jetty-bom:9.4.44.v20210927" @@ -292,7 +292,6 @@ configure(allprojects) { project -> repositories { mavenCentral() maven { url "https://repo.spring.io/libs-spring-framework-build" } - maven { url "https://repo.spring.io/snapshot" } // reactor } } From 9bc09631d61e2d011972232a5b32c1edc51c6dcf Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 9 Nov 2021 22:29:56 +0100 Subject: [PATCH 324/735] Recommend ObjectProvider as alternative to @Lazy for optional dependencies Closes gh-27649 --- .../org/springframework/context/annotation/Lazy.java | 7 ++++++- src/docs/asciidoc/core/core-beans.adoc | 10 ++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Lazy.java b/spring-context/src/main/java/org/springframework/context/annotation/Lazy.java index 9d04a9df26ee..8369957f5917 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/Lazy.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/Lazy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +47,11 @@ * or {@link javax.inject.Inject}: In that context, it leads to the creation of a * lazy-resolution proxy for all affected dependencies, as an alternative to using * {@link org.springframework.beans.factory.ObjectFactory} or {@link javax.inject.Provider}. + * Please note that such a lazy-resolution proxy will always be injected; if the target + * dependency does not exist, you will only be able to find out through an exception on + * invocation. As a consequence, such an injection point results in unintuitive behavior + * for optional dependencies. For a programmatic equivalent, allowing for lazy references + * with more sophistication, consider {@link org.springframework.beans.factory.ObjectProvider}. * * @author Chris Beams * @author Juergen Hoeller diff --git a/src/docs/asciidoc/core/core-beans.adoc b/src/docs/asciidoc/core/core-beans.adoc index 5ba741761f28..8d701befcbcc 100644 --- a/src/docs/asciidoc/core/core-beans.adoc +++ b/src/docs/asciidoc/core/core-beans.adoc @@ -3039,7 +3039,7 @@ constructor or setter argument or autowired field) as `ObjectFactory`, which delivers +As an extended variant, you may declare `ObjectProvider` which delivers several additional access variants, including `getIfAvailable` and `getIfUnique`. The JSR-330 variant of this is called `Provider` and is used with a `Provider` @@ -6675,9 +6675,11 @@ factory method and other bean definition properties, such as a qualifier value t the `@Qualifier` annotation. Other method-level annotations that can be specified are `@Scope`, `@Lazy`, and custom qualifier annotations. -TIP: In addition to its role for component initialization, you can also place the `@Lazy` annotation -on injection points marked with `@Autowired` or `@Inject`. In this context, it -leads to the injection of a lazy-resolution proxy. +TIP: In addition to its role for component initialization, you can also place the `@Lazy` +annotation on injection points marked with `@Autowired` or `@Inject`. In this context, +it leads to the injection of a lazy-resolution proxy. However, such a proxy approach +is rather limited. For sophisticated lazy interactions, in particular in combination +with optional dependencies, we recommend `ObjectProvider` instead. Autowired fields and methods are supported, as previously discussed, with additional support for autowiring of `@Bean` methods. The following example shows how to do so: From 8d735e6e605737f561252bb4e629c8fb160b9ddf Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 9 Nov 2021 22:30:44 +0100 Subject: [PATCH 325/735] Note on PersistenceExceptionTranslator sorting and non-singleton retrieval Closes gh-26412 --- .../PersistenceExceptionTranslationPostProcessor.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/spring-tx/src/main/java/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessor.java b/spring-tx/src/main/java/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessor.java index c975e9ec6b05..a612fe808d09 100644 --- a/spring-tx/src/main/java/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessor.java +++ b/spring-tx/src/main/java/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,6 @@ * PersistenceExceptionTranslator} interface, which are subsequently asked to translate * candidate exceptions. * - *

    All of Spring's applicable resource factories (e.g. * {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean}) * implement the {@code PersistenceExceptionTranslator} interface out of the box. @@ -47,6 +46,11 @@ * with the {@code @Repository} annotation, along with defining this post-processor * as a bean in the application context. * + *

    As of 5.3, {@code PersistenceExceptionTranslator} beans will be sorted according + * to Spring's dependency ordering rules: see {@link org.springframework.core.Ordered} + * and {@link org.springframework.core.annotation.Order}. Note that such beans will + * get retrieved from any scope, not just singleton scope, as of this 5.3 revision. + * * @author Rod Johnson * @author Juergen Hoeller * @since 2.0 From b167e1a93fe299b19f339896d86e65337b05b78f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 9 Nov 2021 22:35:24 +0100 Subject: [PATCH 326/735] Remove unnecessary final declarations (for consistency) --- .../AutowiredAnnotationBeanPostProcessor.java | 2 +- .../CommonAnnotationBeanPostProcessor.java | 4 ++-- .../annotation/ComponentScanAnnotationParser.java | 4 ++-- .../annotation/ConfigurationClassEnhancer.java | 14 +++++++------- .../PersistenceAnnotationBeanPostProcessor.java | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index e7131a562ef7..37f5884e671e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -459,7 +459,7 @@ private InjectionMetadata findAutowiringMetadata(String beanName, Class clazz return metadata; } - private InjectionMetadata buildAutowiringMetadata(final Class clazz) { + private InjectionMetadata buildAutowiringMetadata(Class clazz) { if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) { return InjectionMetadata.EMPTY; } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java index 8a3ca5a9f889..ecfdf8f83a9a 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java @@ -343,7 +343,7 @@ public PropertyValues postProcessPropertyValues( } - private InjectionMetadata findResourceMetadata(String beanName, final Class clazz, @Nullable PropertyValues pvs) { + private InjectionMetadata findResourceMetadata(String beanName, Class clazz, @Nullable PropertyValues pvs) { // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // Quick check on the concurrent map first, with minimal locking. @@ -363,7 +363,7 @@ private InjectionMetadata findResourceMetadata(String beanName, final Class c return metadata; } - private InjectionMetadata buildResourceMetadata(final Class clazz) { + private InjectionMetadata buildResourceMetadata(Class clazz) { if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) { return InjectionMetadata.EMPTY; } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java index 27e879bfb338..0a3c751ff395 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,7 +65,7 @@ public ComponentScanAnnotationParser(Environment environment, ResourceLoader res } - public Set parse(AnnotationAttributes componentScan, final String declaringClass) { + public Set parse(AnnotationAttributes componentScan, String declaringClass) { ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader); diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java index 17079522c7f6..1b215e524cc9 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -453,8 +453,8 @@ private boolean isCurrentlyInvokedFactoryMethod(Method method) { * instance directly. If a FactoryBean instance is fetched through the container via &-dereferencing, * it will not be proxied. This too is aligned with the way XML configuration works. */ - private Object enhanceFactoryBean(final Object factoryBean, Class exposedType, - final ConfigurableBeanFactory beanFactory, final String beanName) { + private Object enhanceFactoryBean(Object factoryBean, Class exposedType, + ConfigurableBeanFactory beanFactory, String beanName) { try { Class clazz = factoryBean.getClass(); @@ -489,8 +489,8 @@ private Object enhanceFactoryBean(final Object factoryBean, Class exposedType return createCglibProxyForFactoryBean(factoryBean, beanFactory, beanName); } - private Object createInterfaceProxyForFactoryBean(final Object factoryBean, Class interfaceType, - final ConfigurableBeanFactory beanFactory, final String beanName) { + private Object createInterfaceProxyForFactoryBean(Object factoryBean, Class interfaceType, + ConfigurableBeanFactory beanFactory, String beanName) { return Proxy.newProxyInstance( factoryBean.getClass().getClassLoader(), new Class[] {interfaceType}, @@ -502,8 +502,8 @@ private Object createInterfaceProxyForFactoryBean(final Object factoryBean, Clas }); } - private Object createCglibProxyForFactoryBean(final Object factoryBean, - final ConfigurableBeanFactory beanFactory, final String beanName) { + private Object createCglibProxyForFactoryBean(Object factoryBean, + ConfigurableBeanFactory beanFactory, String beanName) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(factoryBean.getClass()); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java index d9ff7afc1414..61582bee1180 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -373,7 +373,7 @@ public boolean requiresDestruction(Object bean) { } - private InjectionMetadata findPersistenceMetadata(String beanName, final Class clazz, @Nullable PropertyValues pvs) { + private InjectionMetadata findPersistenceMetadata(String beanName, Class clazz, @Nullable PropertyValues pvs) { // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // Quick check on the concurrent map first, with minimal locking. @@ -393,7 +393,7 @@ private InjectionMetadata findPersistenceMetadata(String beanName, final Class clazz) { + private InjectionMetadata buildPersistenceMetadata(Class clazz) { if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(PersistenceContext.class, PersistenceUnit.class))) { return InjectionMetadata.EMPTY; } From 11a0df3fd144a8c792cd2f9d5a721d21abe52f2b Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 9 Nov 2021 22:36:11 +0100 Subject: [PATCH 327/735] Upgrade to Tomcat 9.0.54, Netty 4.1.70, HtmlUnit 2.54, XMLUnit 2.8.3 --- build.gradle | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 98c85c3d008b..6021fa574ddf 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ configure(allprojects) { project -> dependencyManagement { imports { mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5" - mavenBom "io.netty:netty-bom:4.1.69.Final" + mavenBom "io.netty:netty-bom:4.1.70.Final" mavenBom "io.projectreactor:reactor-bom:2020.0.13" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10" mavenBom "io.rsocket:rsocket-bom:1.1.1" @@ -128,14 +128,14 @@ configure(allprojects) { project -> dependency "org.webjars:webjars-locator-core:0.48" dependency "org.webjars:underscorejs:1.8.3" - dependencySet(group: 'org.apache.tomcat', version: '9.0.53') { + dependencySet(group: 'org.apache.tomcat', version: '9.0.54') { entry 'tomcat-util' entry('tomcat-websocket') { exclude group: "org.apache.tomcat", name: "tomcat-websocket-api" exclude group: "org.apache.tomcat", name: "tomcat-servlet-api" } } - dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.53') { + dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.54') { entry 'tomcat-embed-core' entry 'tomcat-embed-websocket' } @@ -192,7 +192,7 @@ configure(allprojects) { project -> dependency "org.hamcrest:hamcrest:2.1" dependency "org.awaitility:awaitility:3.1.6" dependency "org.assertj:assertj-core:3.21.0" - dependencySet(group: 'org.xmlunit', version: '2.8.2') { + dependencySet(group: 'org.xmlunit', version: '2.8.3') { entry 'xmlunit-assertj' entry('xmlunit-matchers') { exclude group: "org.hamcrest", name: "hamcrest-core" @@ -206,10 +206,10 @@ configure(allprojects) { project -> } dependency "io.mockk:mockk:1.12.0" - dependency("net.sourceforge.htmlunit:htmlunit:2.53.0") { + dependency("net.sourceforge.htmlunit:htmlunit:2.54.0") { exclude group: "commons-logging", name: "commons-logging" } - dependency("org.seleniumhq.selenium:htmlunit-driver:2.53.0") { + dependency("org.seleniumhq.selenium:htmlunit-driver:2.54.0") { exclude group: "commons-logging", name: "commons-logging" } dependency("org.seleniumhq.selenium:selenium-java:3.141.59") { @@ -292,7 +292,6 @@ configure(allprojects) { project -> repositories { mavenCentral() maven { url "https://repo.spring.io/libs-spring-framework-build" } - } } configurations.all { From 2a268701c41aaa1324a6c2fcf0e7e71c40f91ec2 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 10 Nov 2021 14:21:48 +0100 Subject: [PATCH 328/735] Introduce optimizeLocations flag for resource location filtering on startup This flag is off by default since it requires jar files with directory entries. Closes gh-27624 --- .../config/ResourceHandlerRegistration.java | 25 +++- .../reactive/resource/ResourceWebHandler.java | 122 +++++++++++------- .../resource/ResourceWebHandlerTests.java | 4 +- .../ResourceHandlerRegistration.java | 23 +++- .../resource/ResourceHttpRequestHandler.java | 77 +++++++---- .../ResourceHttpRequestHandlerTests.java | 3 +- src/docs/asciidoc/web/webflux.adoc | 7 +- src/docs/asciidoc/web/webmvc.adoc | 7 +- 8 files changed, 188 insertions(+), 80 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistration.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistration.java index 8ee0e87eafb1..9734347cc665 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistration.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistration.java @@ -54,6 +54,8 @@ public class ResourceHandlerRegistration { private boolean useLastModified = true; + private boolean optimizeLocations = false; + @Nullable private Map mediaTypes; @@ -105,15 +107,33 @@ public ResourceHandlerRegistration setCacheControl(CacheControl cacheControl) { /** * Set whether the {@link Resource#lastModified()} information should be used to drive HTTP responses. *

    This configuration is set to {@code true} by default. - * @param useLastModified whether the "last modified" resource information should be used. + * @param useLastModified whether the "last modified" resource information should be used * @return the same {@link ResourceHandlerRegistration} instance, for chained method invocation * @since 5.3 + * @see ResourceWebHandler#setUseLastModified */ public ResourceHandlerRegistration setUseLastModified(boolean useLastModified) { this.useLastModified = useLastModified; return this; } + /** + * Set whether to optimize the specified locations through an existence check on startup, + * filtering non-existing directories upfront so that they do not have to be checked + * on every resource access. + *

    The default is {@code false}, for defensiveness against zip files without directory + * entries which are unable to expose the existence of a directory upfront. Switch this flag to + * {@code true} for optimized access in case of a consistent jar layout with directory entries. + * @param optimizeLocations whether to optimize the locations through an existence check on startup + * @return the same {@link ResourceHandlerRegistration} instance, for chained method invocation + * @since 5.3.13 + * @see ResourceWebHandler#setOptimizeLocations + */ + public ResourceHandlerRegistration setOptimizeLocations(boolean optimizeLocations) { + this.optimizeLocations = optimizeLocations; + return this; + } + /** * Configure a chain of resource resolvers and transformers to use. This * can be useful, for example, to apply a version strategy to resource URLs. @@ -181,8 +201,8 @@ protected String[] getPathPatterns() { */ protected ResourceWebHandler getRequestHandler() { ResourceWebHandler handler = new ResourceWebHandler(); - handler.setLocationValues(this.locationValues); handler.setResourceLoader(this.resourceLoader); + handler.setLocationValues(this.locationValues); if (this.resourceChainRegistration != null) { handler.setResourceResolvers(this.resourceChainRegistration.getResourceResolvers()); handler.setResourceTransformers(this.resourceChainRegistration.getResourceTransformers()); @@ -191,6 +211,7 @@ protected ResourceWebHandler getRequestHandler() { handler.setCacheControl(this.cacheControl); } handler.setUseLastModified(this.useLastModified); + handler.setOptimizeLocations(this.optimizeLocations); if (this.mediaTypes != null) { handler.setMediaTypes(this.mediaTypes); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java index c2ba1b234bf1..e6f0640a7022 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java @@ -72,8 +72,8 @@ *

    This request handler may also be configured with a * {@link #setResourceResolvers(List) resourcesResolver} and * {@link #setResourceTransformers(List) resourceTransformer} chains to support - * arbitrary resolution and transformation of resources being served. By default a - * {@link PathResourceResolver} simply finds resources based on the configured + * arbitrary resolution and transformation of resources being served. By default + * a {@link PathResourceResolver} simply finds resources based on the configured * "locations". An application can configure additional resolvers and * transformers such as the {@link VersionResourceResolver} which can resolve * and prepare URLs for resources with a version in the URL. @@ -85,6 +85,7 @@ * * @author Rossen Stoyanchev * @author Brian Clozel + * @author Juergen Hoeller * @since 5.0 */ public class ResourceWebHandler implements WebHandler, InitializingBean { @@ -94,6 +95,9 @@ public class ResourceWebHandler implements WebHandler, InitializingBean { private static final Log logger = LogFactory.getLog(ResourceWebHandler.class); + @Nullable + private ResourceLoader resourceLoader; + private final List locationValues = new ArrayList<>(4); private final List locationResources = new ArrayList<>(4); @@ -119,11 +123,18 @@ public class ResourceWebHandler implements WebHandler, InitializingBean { @Nullable private Map mediaTypes; - @Nullable - private ResourceLoader resourceLoader; - private boolean useLastModified = true; + private boolean optimizeLocations = false; + + + /** + * Provide the ResourceLoader to load {@link #setLocationValues location values} with. + * @since 5.1 + */ + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } /** * Accepts a list of String-based location values to be resolved into @@ -161,9 +172,9 @@ public void setLocations(@Nullable List locations) { *

    Note that if {@link #setLocationValues(List) locationValues} are provided, * instead of loaded Resource-based locations, this method will return * empty until after initialization via {@link #afterPropertiesSet()}. - *

    Note: As of 5.3.11 the list of locations is filtered - * to exclude those that don't actually exist and therefore the list returned - * from this method may be a subset of all given locations. + *

    Note: As of 5.3.11 the list of locations may be filtered to + * exclude those that don't actually exist and therefore the list returned from this + * method may be a subset of all given locations. See {@link #setOptimizeLocations}. * @see #setLocationValues * @see #setLocations */ @@ -212,6 +223,22 @@ public List getResourceTransformers() { return this.resourceTransformers; } + /** + * Configure the {@link ResourceHttpMessageWriter} to use. + *

    By default a {@link ResourceHttpMessageWriter} will be configured. + */ + public void setResourceHttpMessageWriter(@Nullable ResourceHttpMessageWriter httpMessageWriter) { + this.resourceHttpMessageWriter = httpMessageWriter; + } + + /** + * Return the configured resource message writer. + */ + @Nullable + public ResourceHttpMessageWriter getResourceHttpMessageWriter() { + return this.resourceHttpMessageWriter; + } + /** * Set the {@link org.springframework.http.CacheControl} instance to build * the Cache-Control HTTP response header. @@ -230,19 +257,48 @@ public CacheControl getCacheControl() { } /** - * Configure the {@link ResourceHttpMessageWriter} to use. - *

    By default a {@link ResourceHttpMessageWriter} will be configured. + * Set whether we should look at the {@link Resource#lastModified()} + * when serving resources and use this information to drive {@code "Last-Modified"} + * HTTP response headers. + *

    This option is enabled by default and should be turned off if the metadata of + * the static files should be ignored. + * @since 5.3 */ - public void setResourceHttpMessageWriter(@Nullable ResourceHttpMessageWriter httpMessageWriter) { - this.resourceHttpMessageWriter = httpMessageWriter; + public void setUseLastModified(boolean useLastModified) { + this.useLastModified = useLastModified; } /** - * Return the configured resource message writer. + * Return whether the {@link Resource#lastModified()} information is used + * to drive HTTP responses when serving static resources. + * @since 5.3 */ - @Nullable - public ResourceHttpMessageWriter getResourceHttpMessageWriter() { - return this.resourceHttpMessageWriter; + public boolean isUseLastModified() { + return this.useLastModified; + } + + /** + * Set whether to optimize the specified locations through an existence + * check on startup, filtering non-existing directories upfront so that + * they do not have to be checked on every resource access. + *

    The default is {@code false}, for defensiveness against zip files + * without directory entries which are unable to expose the existence of + * a directory upfront. Switch this flag to {@code true} for optimized + * access in case of a consistent jar layout with directory entries. + * @since 5.3.13 + */ + public void setOptimizeLocations(boolean optimizeLocations) { + this.optimizeLocations = optimizeLocations; + } + + /** + * Return whether to optimize the specified locations through an existence + * check on startup, filtering non-existing directories upfront so that + * they do not have to be checked on every resource access. + * @since 5.3.13 + */ + public boolean isOptimizeLocations() { + return this.optimizeLocations; } /** @@ -269,36 +325,6 @@ public Map getMediaTypes() { return (this.mediaTypes != null ? this.mediaTypes : Collections.emptyMap()); } - /** - * Provide the ResourceLoader to load {@link #setLocationValues(List) - * location values} with. - * @since 5.1 - */ - public void setResourceLoader(ResourceLoader resourceLoader) { - this.resourceLoader = resourceLoader; - } - - /** - * Return whether the {@link Resource#lastModified()} information is used - * to drive HTTP responses when serving static resources. - * @since 5.3 - */ - public boolean isUseLastModified() { - return this.useLastModified; - } - - /** - * Set whether we should look at the {@link Resource#lastModified()} - * when serving resources and use this information to drive {@code "Last-Modified"} - * HTTP response headers. - *

    This option is enabled by default and should be turned off if the metadata of - * the static files should be ignored. - * @param useLastModified whether to use the resource last-modified information. - * @since 5.3 - */ - public void setUseLastModified(boolean useLastModified) { - this.useLastModified = useLastModified; - } @Override public void afterPropertiesSet() throws Exception { @@ -332,7 +358,9 @@ private void resolveResourceLocations() { } } - result = result.stream().filter(Resource::exists).collect(Collectors.toList()); + if (isOptimizeLocations()) { + result = result.stream().filter(Resource::exists).collect(Collectors.toList()); + } this.locationsToUse.clear(); this.locationsToUse.addAll(result); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceWebHandlerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceWebHandlerTests.java index b668172197d6..c213b1672ac4 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceWebHandlerTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceWebHandlerTests.java @@ -74,6 +74,7 @@ public class ResourceWebHandlerTests { private ResourceWebHandler handler; + @BeforeEach public void setup() throws Exception { List locations = new ArrayList<>(2); @@ -253,7 +254,7 @@ public void getResourceFromFileSystem() throws Exception { assertResponseBody(exchange, "h1 { color:red; }"); } - @Test // gh-27538 + @Test // gh-27538, gh-27624 public void filterNonExistingLocations() throws Exception { List inputLocations = Arrays.asList( new ClassPathResource("test/", getClass()), @@ -262,6 +263,7 @@ public void filterNonExistingLocations() throws Exception { ResourceWebHandler handler = new ResourceWebHandler(); handler.setLocations(inputLocations); + handler.setOptimizeLocations(true); handler.afterPropertiesSet(); List actual = handler.getLocations(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistration.java index fd822bedd55b..c173f602455e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistration.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistration.java @@ -55,6 +55,8 @@ public class ResourceHandlerRegistration { private boolean useLastModified = true; + private boolean optimizeLocations = false; + /** * Create a {@link ResourceHandlerRegistration} instance. @@ -130,15 +132,33 @@ public ResourceHandlerRegistration setCacheControl(CacheControl cacheControl) { /** * Set whether the {@link Resource#lastModified()} information should be used to drive HTTP responses. *

    This configuration is set to {@code true} by default. - * @param useLastModified whether the "last modified" resource information should be used. + * @param useLastModified whether the "last modified" resource information should be used * @return the same {@link ResourceHandlerRegistration} instance, for chained method invocation * @since 5.3 + * @see ResourceHttpRequestHandler#setUseLastModified */ public ResourceHandlerRegistration setUseLastModified(boolean useLastModified) { this.useLastModified = useLastModified; return this; } + /** + * Set whether to optimize the specified locations through an existence check on startup, + * filtering non-existing directories upfront so that they do not have to be checked + * on every resource access. + *

    The default is {@code false}, for defensiveness against zip files without directory + * entries which are unable to expose the existence of a directory upfront. Switch this flag to + * {@code true} for optimized access in case of a consistent jar layout with directory entries. + * @param optimizeLocations whether to optimize the locations through an existence check on startup + * @return the same {@link ResourceHandlerRegistration} instance, for chained method invocation + * @since 5.3.13 + * @see ResourceHttpRequestHandler#setOptimizeLocations + */ + public ResourceHandlerRegistration setOptimizeLocations(boolean optimizeLocations) { + this.optimizeLocations = optimizeLocations; + return this; + } + /** * Configure a chain of resource resolvers and transformers to use. This * can be useful, for example, to apply a version strategy to resource URLs. @@ -204,6 +224,7 @@ else if (this.cachePeriod != null) { handler.setCacheSeconds(this.cachePeriod); } handler.setUseLastModified(this.useLastModified); + handler.setOptimizeLocations(this.optimizeLocations); return handler; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index 22f06ccf58d7..7855a1171cb3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -140,11 +140,13 @@ public class ResourceHttpRequestHandler extends WebContentGenerator @Nullable private UrlPathHelper urlPathHelper; + private boolean useLastModified = true; + + private boolean optimizeLocations = false; + @Nullable private StringValueResolver embeddedValueResolver; - private boolean useLastModified = true; - public ResourceHttpRequestHandler() { super(HttpMethod.GET.name(), HttpMethod.HEAD.name()); @@ -185,13 +187,13 @@ public void setLocations(List locations) { /** * Return the configured {@code List} of {@code Resource} locations including * both String-based locations provided via - * {@link #setLocationValues(List) setLocationValues} and pre-resolved {@code Resource} - * locations provided via {@link #setLocations(List) setLocations}. + * {@link #setLocationValues(List) setLocationValues} and pre-resolved + * {@code Resource} locations provided via {@link #setLocations(List) setLocations}. *

    Note that the returned list is fully initialized only after * initialization via {@link #afterPropertiesSet()}. - *

    Note: As of 5.3.11 the list of locations is filtered - * to exclude those that don't actually exist and therefore the list returned - * from this method may be a subset of all given locations. + *

    Note: As of 5.3.11 the list of locations may be filtered to + * exclude those that don't actually exist and therefore the list returned from this + * method may be a subset of all given locations. See {@link #setOptimizeLocations}. * @see #setLocationValues * @see #setLocations */ @@ -293,7 +295,7 @@ public void setContentNegotiationManager(@Nullable ContentNegotiationManager con /** * Return the configured content negotiation manager. * @since 4.3 - * @deprecated as of 5.2.4. + * @deprecated as of 5.2.4 */ @Nullable @Deprecated @@ -303,7 +305,7 @@ public ContentNegotiationManager getContentNegotiationManager() { /** * Add mappings between file extensions, extracted from the filename of a - * static {@link Resource}, and corresponding media type to set on the + * static {@link Resource}, and corresponding media type to set on the * response. *

    Use of this method is typically not necessary since mappings are * otherwise determined via @@ -361,9 +363,16 @@ public UrlPathHelper getUrlPathHelper() { return this.urlPathHelper; } - @Override - public void setEmbeddedValueResolver(StringValueResolver resolver) { - this.embeddedValueResolver = resolver; + /** + * Set whether we should look at the {@link Resource#lastModified()} when + * serving resources and use this information to drive {@code "Last-Modified"} + * HTTP response headers. + *

    This option is enabled by default and should be turned off if the metadata + * of the static files should be ignored. + * @since 5.3 + */ + public void setUseLastModified(boolean useLastModified) { + this.useLastModified = useLastModified; } /** @@ -376,18 +385,35 @@ public boolean isUseLastModified() { } /** - * Set whether we should look at the {@link Resource#lastModified()} - * when serving resources and use this information to drive {@code "Last-Modified"} - * HTTP response headers. - *

    This option is enabled by default and should be turned off if the metadata of - * the static files should be ignored. - * @param useLastModified whether to use the resource last-modified information. - * @since 5.3 + * Set whether to optimize the specified locations through an existence + * check on startup, filtering non-existing directories upfront so that + * they do not have to be checked on every resource access. + *

    The default is {@code false}, for defensiveness against zip files + * without directory entries which are unable to expose the existence of + * a directory upfront. Switch this flag to {@code true} for optimized + * access in case of a consistent jar layout with directory entries. + * @since 5.3.13 */ - public void setUseLastModified(boolean useLastModified) { - this.useLastModified = useLastModified; + public void setOptimizeLocations(boolean optimizeLocations) { + this.optimizeLocations = optimizeLocations; + } + + /** + * Return whether to optimize the specified locations through an existence + * check on startup, filtering non-existing directories upfront so that + * they do not have to be checked on every resource access. + * @since 5.3.13 + */ + public boolean isOptimizeLocations() { + return this.optimizeLocations; } + @Override + public void setEmbeddedValueResolver(StringValueResolver resolver) { + this.embeddedValueResolver = resolver; + } + + @Override public void afterPropertiesSet() throws Exception { resolveResourceLocations(); @@ -449,8 +475,8 @@ private void resolveResourceLocations() { if (location.equals("/") && !(resource instanceof ServletContextResource)) { throw new IllegalStateException( "The String-based location \"/\" should be relative to the web application root " + - "but resolved to a Resource of type: " + resource.getClass() + ". " + - "If this is intentional, please pass it as a pre-configured Resource via setLocations."); + "but resolved to a Resource of type: " + resource.getClass() + ". " + + "If this is intentional, please pass it as a pre-configured Resource via setLocations."); } result.add(resource); if (charset != null) { @@ -463,7 +489,9 @@ private void resolveResourceLocations() { } result.addAll(this.locationResources); - result = result.stream().filter(Resource::exists).collect(Collectors.toList()); + if (isOptimizeLocations()) { + result = result.stream().filter(Resource::exists).collect(Collectors.toList()); + } this.locationsToUse.clear(); this.locationsToUse.addAll(result); @@ -508,6 +536,7 @@ protected org.springframework.web.accept.PathExtensionContentNegotiationStrategy return null; } + /** * Processes a resource request. *

    Checks for the existence of the requested resource in the configured list of locations. diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index 9aefd7f9d07b..834aab2694a6 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -311,7 +311,7 @@ public String getMimeType(String filePath) { assertThat(this.response.getContentAsString()).isEqualTo("h1 { color:red; }"); } - @Test // gh-27538 + @Test // gh-27538, gh-27624 public void filterNonExistingLocations() throws Exception { List inputLocations = Arrays.asList( new ClassPathResource("test/", getClass()), @@ -321,6 +321,7 @@ public void filterNonExistingLocations() throws Exception { ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler(); handler.setServletContext(new MockServletContext()); handler.setLocations(inputLocations); + handler.setOptimizeLocations(true); handler.afterPropertiesSet(); List actual = handler.getLocations(); diff --git a/src/docs/asciidoc/web/webflux.adoc b/src/docs/asciidoc/web/webflux.adoc index 3b601ea4c885..1cc302102126 100644 --- a/src/docs/asciidoc/web/webflux.adoc +++ b/src/docs/asciidoc/web/webflux.adoc @@ -4170,8 +4170,8 @@ the example: @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**") - .addResourceLocations("/public", "classpath:/static/") - .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS)); + .addResourceLocations("/public", "classpath:/static/") + .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS)); } } @@ -4259,6 +4259,9 @@ re-write URLs to include the version of the jar and can also match against incom without versions -- for example, from `/jquery/jquery.min.js` to `/jquery/1.2.0/jquery.min.js`. +TIP: The Java configuration based on `ResourceHandlerRegistry` provides further options +for fine-grained control, e.g. last-modified behavior and optimized resource resolution. + [[webflux-config-path-matching]] diff --git a/src/docs/asciidoc/web/webmvc.adoc b/src/docs/asciidoc/web/webmvc.adoc index b49666303e98..33b49bef56a5 100644 --- a/src/docs/asciidoc/web/webmvc.adoc +++ b/src/docs/asciidoc/web/webmvc.adoc @@ -5738,8 +5738,8 @@ The following listing shows how to do so with Java configuration: @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**") - .addResourceLocations("/public", "classpath:/static/") - .setCacheControl(CacheControl.maxAge(Duration.ofDays(365))); + .addResourceLocations("/public", "classpath:/static/") + .setCacheControl(CacheControl.maxAge(Duration.ofDays(365))); } } ---- @@ -5846,6 +5846,9 @@ re-write URLs to include the version of the jar and can also match against incom without versions -- for example, from `/jquery/jquery.min.js` to `/jquery/1.2.0/jquery.min.js`. +TIP: The Java configuration based on `ResourceHandlerRegistry` provides further options +for fine-grained control, e.g. last-modified behavior and optimized resource resolution. + [[mvc-default-servlet-handler]] From 15a6373fed1b8acf6dcda7cc2a144de34e32f4cd Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 10 Nov 2021 14:22:06 +0100 Subject: [PATCH 329/735] Avoid nullability warnings --- .../test/web/reactive/server/CookieAssertions.java | 7 ++++--- .../test/web/reactive/server/HeaderAssertions.java | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/CookieAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/CookieAssertions.java index 26b28b486a41..f9804915f72b 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/CookieAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/CookieAssertions.java @@ -17,6 +17,7 @@ package org.springframework.test.web.reactive.server; import java.time.Duration; +import java.util.Objects; import java.util.function.Consumer; import org.hamcrest.Matcher; @@ -210,10 +211,10 @@ public WebTestClient.ResponseSpec sameSite(String name, String expected) { private ResponseCookie getCookie(String name) { ResponseCookie cookie = this.exchangeResult.getResponseCookies().getFirst(name); if (cookie == null) { - String message = "No cookie with name '" + name + "'"; - this.exchangeResult.assertWithDiagnostics(() -> AssertionErrors.fail(message)); + this.exchangeResult.assertWithDiagnostics(() -> + AssertionErrors.fail("No cookie with name '" + name + "'")); } - return cookie; + return Objects.requireNonNull(cookie); } private String getMessage(String cookie) { diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/HeaderAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/HeaderAssertions.java index aa20066960d0..c3750d27c3c4 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/HeaderAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/HeaderAssertions.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import java.net.URI; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.function.Consumer; import org.hamcrest.Matcher; @@ -73,7 +74,7 @@ public WebTestClient.ResponseSpec valueEquals(String headerName, long value) { String actual = getHeaders().getFirst(headerName); this.exchangeResult.assertWithDiagnostics(() -> assertTrue("Response does not contain header '" + headerName + "'", actual != null)); - return assertHeader(headerName, value, Long.parseLong(actual)); + return assertHeader(headerName, value, Long.parseLong(Objects.requireNonNull(actual))); } /** @@ -203,7 +204,7 @@ private List getRequiredValues(String name) { this.exchangeResult.assertWithDiagnostics(() -> AssertionErrors.fail(getMessage(name) + " not found")); } - return values; + return Objects.requireNonNull(values); } /** From 32af39d6e6daaac2d5860b4b806f1fc2128f57db Mon Sep 17 00:00:00 2001 From: SungMin Date: Wed, 10 Nov 2021 23:11:33 +0900 Subject: [PATCH 330/735] Use 'toString(Charset)' instead of 'toString(String)' for encodings (#27646) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 홍성민(SungMin Hong)/Platform Engineering팀/11ST --- .../index/processor/SortedProperties.java | 2 +- .../core/SortedProperties.java | 2 +- .../support/PropertiesToStringConverter.java | 3 ++- .../org/springframework/util/StreamUtils.java | 11 ++------- .../converter/ProtobufMessageConverter.java | 2 +- .../mock/web/MockHttpServletResponse.java | 7 ++++-- .../http/codec/FormHttpMessageReader.java | 24 +++++++------------ .../http/codec/FormHttpMessageWriter.java | 18 +++++--------- .../converter/FormHttpMessageConverter.java | 23 +++++++----------- .../http/server/ServletServerHttpRequest.java | 4 ++-- .../servlet/MockHttpServletResponse.java | 7 ++++-- .../client/RestTemplateXhrTransport.java | 4 ++-- 12 files changed, 45 insertions(+), 62 deletions(-) diff --git a/spring-context-indexer/src/main/java/org/springframework/context/index/processor/SortedProperties.java b/spring-context-indexer/src/main/java/org/springframework/context/index/processor/SortedProperties.java index 127a1a2b9614..816ec3ea3ee7 100644 --- a/spring-context-indexer/src/main/java/org/springframework/context/index/processor/SortedProperties.java +++ b/spring-context-indexer/src/main/java/org/springframework/context/index/processor/SortedProperties.java @@ -88,7 +88,7 @@ class SortedProperties extends Properties { public void store(OutputStream out, String comments) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); super.store(baos, (this.omitComments ? null : comments)); - String contents = baos.toString(StandardCharsets.ISO_8859_1.name()); + String contents = baos.toString(StandardCharsets.ISO_8859_1); for (String line : contents.split(EOL)) { if (!(this.omitComments && line.startsWith("#"))) { out.write((line + EOL).getBytes(StandardCharsets.ISO_8859_1)); diff --git a/spring-core/src/main/java/org/springframework/core/SortedProperties.java b/spring-core/src/main/java/org/springframework/core/SortedProperties.java index 63f87ac28c5d..cb3e7a93e28b 100644 --- a/spring-core/src/main/java/org/springframework/core/SortedProperties.java +++ b/spring-core/src/main/java/org/springframework/core/SortedProperties.java @@ -90,7 +90,7 @@ class SortedProperties extends Properties { public void store(OutputStream out, @Nullable String comments) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); super.store(baos, (this.omitComments ? null : comments)); - String contents = baos.toString(StandardCharsets.ISO_8859_1.name()); + String contents = baos.toString(StandardCharsets.ISO_8859_1); for (String line : contents.split(EOL)) { if (!(this.omitComments && line.startsWith("#"))) { out.write((line + EOL).getBytes(StandardCharsets.ISO_8859_1)); diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/PropertiesToStringConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/PropertiesToStringConverter.java index c953280ba316..02a61515ceae 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/PropertiesToStringConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/PropertiesToStringConverter.java @@ -18,6 +18,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Properties; import org.springframework.core.convert.converter.Converter; @@ -36,7 +37,7 @@ public String convert(Properties source) { try { ByteArrayOutputStream os = new ByteArrayOutputStream(256); source.store(os, null); - return os.toString("ISO-8859-1"); + return os.toString(StandardCharsets.ISO_8859_1); } catch (IOException ex) { // Should never happen. diff --git a/spring-core/src/main/java/org/springframework/util/StreamUtils.java b/spring-core/src/main/java/org/springframework/util/StreamUtils.java index 272abd9f8e25..f57943a29e8d 100644 --- a/spring-core/src/main/java/org/springframework/util/StreamUtils.java +++ b/spring-core/src/main/java/org/springframework/util/StreamUtils.java @@ -25,7 +25,6 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; import java.io.Writer; import java.nio.charset.Charset; @@ -105,14 +104,8 @@ public static String copyToString(@Nullable InputStream in, Charset charset) thr public static String copyToString(ByteArrayOutputStream baos, Charset charset) { Assert.notNull(baos, "No ByteArrayOutputStream specified"); Assert.notNull(charset, "No Charset specified"); - try { - // Can be replaced with toString(Charset) call in Java 10+ - return baos.toString(charset.name()); - } - catch (UnsupportedEncodingException ex) { - // Should never happen - throw new IllegalArgumentException("Invalid charset name: " + charset, ex); - } + + return baos.toString(charset); } /** diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/ProtobufMessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/ProtobufMessageConverter.java index 085957e4d4b9..179ae215528c 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/ProtobufMessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/ProtobufMessageConverter.java @@ -183,7 +183,7 @@ protected Object convertToInternal( else if (this.protobufFormatSupport != null) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); this.protobufFormatSupport.print(message, outputStream, contentType, charset); - payload = outputStream.toString(charset.name()); + payload = outputStream.toString(charset); } } catch (IOException ex) { diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java index 981f3a515ad3..397cec961678 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java @@ -279,8 +279,11 @@ public String getContentAsString() throws UnsupportedEncodingException { * @see #setContentType(String) */ public String getContentAsString(Charset fallbackCharset) throws UnsupportedEncodingException { - String charsetName = (this.characterEncodingSet ? getCharacterEncoding() : fallbackCharset.name()); - return this.content.toString(charsetName); + if (this.characterEncodingSet) { + return this.content.toString(getCharacterEncoding()); + } + + return this.content.toString(fallbackCharset); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java index 63e4a10259fa..cc08b15628b9 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java +++ b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java @@ -16,7 +16,6 @@ package org.springframework.http.codec; -import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.CharBuffer; import java.nio.charset.Charset; @@ -158,21 +157,16 @@ private Charset getMediaTypeCharset(@Nullable MediaType mediaType) { private MultiValueMap parseFormData(Charset charset, String body) { String[] pairs = StringUtils.tokenizeToStringArray(body, "&"); MultiValueMap result = new LinkedMultiValueMap<>(pairs.length); - try { - for (String pair : pairs) { - int idx = pair.indexOf('='); - if (idx == -1) { - result.add(URLDecoder.decode(pair, charset.name()), null); - } - else { - String name = URLDecoder.decode(pair.substring(0, idx), charset.name()); - String value = URLDecoder.decode(pair.substring(idx + 1), charset.name()); - result.add(name, value); - } + 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 (UnsupportedEncodingException ex) { - throw new IllegalStateException(ex); } return result; } diff --git a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageWriter.java index 81c68d847bfd..a36705f37692 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageWriter.java +++ b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageWriter.java @@ -16,7 +16,6 @@ package org.springframework.http.codec; -import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.ByteBuffer; import java.nio.charset.Charset; @@ -162,18 +161,13 @@ protected String serializeForm(MultiValueMap formData, Charset c StringBuilder builder = new StringBuilder(); formData.forEach((name, values) -> values.forEach(value -> { - try { - if (builder.length() != 0) { - builder.append('&'); - } - builder.append(URLEncoder.encode(name, charset.name())); - if (value != null) { - builder.append('='); - builder.append(URLEncoder.encode(value, charset.name())); - } + if (builder.length() != 0) { + builder.append('&'); } - catch (UnsupportedEncodingException ex) { - throw new IllegalStateException(ex); + builder.append(URLEncoder.encode(name, charset)); + if (value != null) { + builder.append('='); + builder.append(URLEncoder.encode(value, charset)); } })); return builder.toString(); 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 680da1ae2a10..732546474153 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 @@ -348,11 +348,11 @@ public MultiValueMap read(@Nullable Class formData, Charset c return; } values.forEach(value -> { - try { - if (builder.length() != 0) { - builder.append('&'); - } - builder.append(URLEncoder.encode(name, charset.name())); - if (value != null) { - builder.append('='); - builder.append(URLEncoder.encode(String.valueOf(value), charset.name())); - } + if (builder.length() != 0) { + builder.append('&'); } - catch (UnsupportedEncodingException ex) { - throw new IllegalStateException(ex); + builder.append(URLEncoder.encode(name, charset)); + if (value != null) { + builder.append('='); + builder.append(URLEncoder.encode(String.valueOf(value), charset)); } }); }); diff --git a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java index 7bac4b70a94e..478ae10542ca 100644 --- a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java @@ -249,10 +249,10 @@ private static InputStream getBodyFromServletRequestParameters(HttpServletReques List values = Arrays.asList(entry.getValue()); for (Iterator valueIterator = values.iterator(); valueIterator.hasNext();) { String value = valueIterator.next(); - writer.write(URLEncoder.encode(name, FORM_CHARSET.name())); + writer.write(URLEncoder.encode(name, FORM_CHARSET)); if (value != null) { writer.write('='); - writer.write(URLEncoder.encode(value, FORM_CHARSET.name())); + writer.write(URLEncoder.encode(value, FORM_CHARSET)); if (valueIterator.hasNext()) { writer.write('&'); } diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java index 00763fa97465..af9773ce330c 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java @@ -279,8 +279,11 @@ public String getContentAsString() throws UnsupportedEncodingException { * @see #setContentType(String) */ public String getContentAsString(Charset fallbackCharset) throws UnsupportedEncodingException { - String charsetName = (this.characterEncodingSet ? getCharacterEncoding() : fallbackCharset.name()); - return this.content.toString(charsetName); + if (this.characterEncodingSet) { + return this.content.toString(getCharacterEncoding()); + } + + return this.content.toString(fallbackCharset); } @Override diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/RestTemplateXhrTransport.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/RestTemplateXhrTransport.java index 7d47173b03da..41afb4f671a8 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/RestTemplateXhrTransport.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/RestTemplateXhrTransport.java @@ -252,8 +252,8 @@ public Object extractData(ClientHttpResponse response) throws IOException { return null; } - private void handleFrame(ByteArrayOutputStream os) throws IOException { - String content = os.toString(SockJsFrame.CHARSET.name()); + private void handleFrame(ByteArrayOutputStream os) { + String content = os.toString(SockJsFrame.CHARSET); os.reset(); if (logger.isTraceEnabled()) { logger.trace("XHR receive content: " + content); From 54bd66755c12b7dc7f353796ebe128da98e2831e Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 10 Nov 2021 15:19:51 +0100 Subject: [PATCH 331/735] Consistently replace String encoding names with StandardCharset arguments Closes gh-27664 --- .../scripting/support/ResourceScriptSource.java | 5 +++-- .../org/springframework/oxm/jaxb/Jaxb2Marshaller.java | 8 ++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scripting/support/ResourceScriptSource.java b/spring-context/src/main/java/org/springframework/scripting/support/ResourceScriptSource.java index 8f345085a2b2..0cdceadfe7f2 100644 --- a/spring-context/src/main/java/org/springframework/scripting/support/ResourceScriptSource.java +++ b/spring-context/src/main/java/org/springframework/scripting/support/ResourceScriptSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.io.IOException; import java.io.Reader; +import java.nio.charset.StandardCharsets; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -72,7 +73,7 @@ public ResourceScriptSource(EncodedResource resource) { */ public ResourceScriptSource(Resource resource) { Assert.notNull(resource, "Resource must not be null"); - this.resource = new EncodedResource(resource, "UTF-8"); + this.resource = new EncodedResource(resource, StandardCharsets.UTF_8); } diff --git a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java index 4b30aad1e06d..41d967aaf3a3 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java @@ -32,6 +32,7 @@ import java.net.URISyntaxException; import java.net.URLDecoder; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Calendar; import java.util.Date; @@ -972,12 +973,7 @@ public String addMtomAttachment(DataHandler dataHandler, String elementNamespace String host = getHost(elementNamespace, dataHandler); String contentId = UUID.randomUUID() + "@" + host; this.mimeContainer.addAttachment("<" + contentId + ">", dataHandler); - try { - contentId = URLEncoder.encode(contentId, "UTF-8"); - } - catch (UnsupportedEncodingException ex) { - // ignore - } + contentId = URLEncoder.encode(contentId, StandardCharsets.UTF_8); return CID + contentId; } From 2fba0bc27268d863f04734b96bdce331dad57438 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 10 Nov 2021 15:20:56 +0100 Subject: [PATCH 332/735] Allow BeanUtils#instantiateClass inlining with native Closes gh-27072 --- .../java/org/springframework/beans/BeanUtils.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index 77aff7ffe08e..d908dbde63ae 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -142,19 +142,20 @@ public static T instantiateClass(Class clazz) throws BeanInstantiationExc if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } + Constructor ctor; try { - return instantiateClass(clazz.getDeclaredConstructor()); + ctor = clazz.getDeclaredConstructor(); } catch (NoSuchMethodException ex) { - Constructor ctor = findPrimaryConstructor(clazz); - if (ctor != null) { - return instantiateClass(ctor); + ctor = findPrimaryConstructor(clazz); + if (ctor == null) { + throw new BeanInstantiationException(clazz, "No default constructor found", ex); } - throw new BeanInstantiationException(clazz, "No default constructor found", ex); } catch (LinkageError err) { throw new BeanInstantiationException(clazz, "Unresolvable class definition", err); } + return instantiateClass(ctor); } /** From 5c972fcc548ce537ac706a5b2b8d4d8703140684 Mon Sep 17 00:00:00 2001 From: Christoph Dreis Date: Wed, 13 Oct 2021 14:38:58 +0200 Subject: [PATCH 333/735] Use Charset variants of URLEncoder and URLDecoder methods --- .../beans/factory/xml/ResourceEntityResolver.java | 5 +++-- .../springframework/oxm/jaxb/Jaxb2Marshaller.java | 8 +------- .../servlet/htmlunit/HtmlUnitRequestBuilder.java | 8 +------- .../http/codec/FormHttpMessageReader.java | 2 +- .../http/codec/FormHttpMessageWriter.java | 2 +- .../server/reactive/AbstractServerHttpRequest.java | 13 +++---------- .../web/reactive/resource/PathResourceResolver.java | 7 +++---- .../web/reactive/resource/ResourceWebHandler.java | 8 ++++---- .../web/servlet/resource/PathResourceResolver.java | 7 +++---- .../resource/ResourceHttpRequestHandler.java | 8 ++++---- .../web/servlet/support/FlashMapManagerTests.java | 5 +++-- 11 files changed, 27 insertions(+), 46 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/ResourceEntityResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/ResourceEntityResolver.java index b74e0133263a..eea87d5524b4 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/ResourceEntityResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/ResourceEntityResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import java.io.IOException; import java.net.URL; import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -80,7 +81,7 @@ public InputSource resolveEntity(@Nullable String publicId, @Nullable String sys if (source == null && systemId != null) { String resourcePath = null; try { - String decodedSystemId = URLDecoder.decode(systemId, "UTF-8"); + String decodedSystemId = URLDecoder.decode(systemId, StandardCharsets.UTF_8); String givenUrl = new URL(decodedSystemId).toString(); String systemRootUrl = new File("").toURI().toURL().toString(); // Try relative to resource base if currently in system root. diff --git a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java index 41d967aaf3a3..78b4ca23e4a5 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java @@ -22,7 +22,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.StringReader; -import java.io.UnsupportedEncodingException; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -1025,12 +1024,7 @@ public byte[] getAttachmentAsByteArray(String cid) { public DataHandler getAttachmentAsDataHandler(String contentId) { if (contentId.startsWith(CID)) { contentId = contentId.substring(CID.length()); - try { - contentId = URLDecoder.decode(contentId, "UTF-8"); - } - catch (UnsupportedEncodingException ex) { - // ignore - } + contentId = URLDecoder.decode(contentId, StandardCharsets.UTF_8); contentId = '<' + contentId + '>'; } DataHandler dataHandler = this.mimeContainer.getAttachment(contentId); diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java index 81bde230655b..e897ae5aa80c 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java @@ -18,7 +18,6 @@ import java.io.File; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; import java.nio.charset.Charset; @@ -396,12 +395,7 @@ private void params(MockHttpServletRequest request, UriComponents uriComponents) } private String urlDecode(String value) { - try { - return URLDecoder.decode(value, "UTF-8"); - } - catch (UnsupportedEncodingException ex) { - throw new IllegalStateException(ex); - } + return URLDecoder.decode(value, StandardCharsets.UTF_8); } private byte[] readAllBytes(File file) { diff --git a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java index cc08b15628b9..c797232b9c03 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java +++ b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageWriter.java index a36705f37692..f4867dcb82ec 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageWriter.java +++ b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java index 3b8bb8ad7046..c33ae2c3c0d5 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,9 @@ package org.springframework.http.server.reactive; -import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -158,15 +158,8 @@ protected MultiValueMap initQueryParams() { return queryParams; } - @SuppressWarnings("deprecation") private String decodeQueryParam(String value) { - try { - return URLDecoder.decode(value, "UTF-8"); - } - catch (UnsupportedEncodingException ex) { - // Should never happen but we got a platform default fallback anyway. - return URLDecoder.decode(value); - } + return URLDecoder.decode(value, StandardCharsets.UTF_8); } @Override diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/PathResourceResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/PathResourceResolver.java index e99c3978790c..8d27a77ac74f 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/PathResourceResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/PathResourceResolver.java @@ -17,7 +17,6 @@ package org.springframework.web.reactive.resource; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -199,14 +198,14 @@ private boolean isInvalidEncodedPath(String resourcePath) { if (resourcePath.contains("%")) { // Use URLDecoder (vs UriUtils) to preserve potentially decoded UTF-8 chars... try { - String decodedPath = URLDecoder.decode(resourcePath, "UTF-8"); + String decodedPath = URLDecoder.decode(resourcePath, StandardCharsets.UTF_8); if (decodedPath.contains("../") || decodedPath.contains("..\\")) { logger.warn("Resolved resource path contains encoded \"../\" or \"..\\\": " + resourcePath); return true; } } - catch (IllegalArgumentException | UnsupportedEncodingException ex) { - // Should never happen... + catch (IllegalArgumentException ex) { + // May not be possible to decode... } } return false; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java index 6553f86394d9..8a8ba5894d1b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java @@ -17,8 +17,8 @@ package org.springframework.web.reactive.resource; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.time.Instant; import java.util.ArrayList; import java.util.Collections; @@ -534,7 +534,7 @@ private boolean isInvalidEncodedPath(String path) { if (path.contains("%")) { try { // Use URLDecoder (vs UriUtils) to preserve potentially decoded UTF-8 chars - String decodedPath = URLDecoder.decode(path, "UTF-8"); + String decodedPath = URLDecoder.decode(path, StandardCharsets.UTF_8); if (isInvalidPath(decodedPath)) { return true; } @@ -543,8 +543,8 @@ private boolean isInvalidEncodedPath(String path) { return true; } } - catch (IllegalArgumentException | UnsupportedEncodingException ex) { - // Should never happen... + catch (IllegalArgumentException ex) { + // May not be possible to decode... } } return false; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java index 002705603f6d..13daebdd9bd2 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java @@ -17,7 +17,6 @@ package org.springframework.web.servlet.resource; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -295,14 +294,14 @@ private boolean isInvalidEncodedPath(String resourcePath) { if (resourcePath.contains("%")) { // Use URLDecoder (vs UriUtils) to preserve potentially decoded UTF-8 chars... try { - String decodedPath = URLDecoder.decode(resourcePath, "UTF-8"); + String decodedPath = URLDecoder.decode(resourcePath, StandardCharsets.UTF_8); if (decodedPath.contains("../") || decodedPath.contains("..\\")) { logger.warn("Resolved resource path contains encoded \"../\" or \"..\\\": " + resourcePath); return true; } } - catch (IllegalArgumentException | UnsupportedEncodingException ex) { - // May not be possible to decode... | Should never happen... + catch (IllegalArgumentException ex) { + // May not be possible to decode... } } return false; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index 85eb4e8d51b8..824a9aa6b677 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -17,9 +17,9 @@ package org.springframework.web.servlet.resource; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -694,7 +694,7 @@ private boolean isInvalidEncodedPath(String path) { if (path.contains("%")) { try { // Use URLDecoder (vs UriUtils) to preserve potentially decoded UTF-8 chars - String decodedPath = URLDecoder.decode(path, "UTF-8"); + String decodedPath = URLDecoder.decode(path, StandardCharsets.UTF_8); if (isInvalidPath(decodedPath)) { return true; } @@ -703,8 +703,8 @@ private boolean isInvalidEncodedPath(String path) { return true; } } - catch (IllegalArgumentException | UnsupportedEncodingException ex) { - // May not be possible to decode... | Should never happen... + catch (IllegalArgumentException ex) { + // May not be possible to decode... } } return false; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/FlashMapManagerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/FlashMapManagerTests.java index 46be451297ef..de19d49f6f03 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/FlashMapManagerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/FlashMapManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.web.servlet.support; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -291,7 +292,7 @@ public void saveOutputFlashMapDecodeParameters() throws Exception { @Test // SPR-12569 public void flashAttributesWithQueryParamsWithSpace() throws Exception { - String encodedValue = URLEncoder.encode("1 2", "UTF-8"); + String encodedValue = URLEncoder.encode("1 2", StandardCharsets.UTF_8); FlashMap flashMap = new FlashMap(); flashMap.put("key", "value"); From 9197f15a306a497b3aa10c6ed48c581b3e938f58 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 10 Nov 2021 16:23:41 +0100 Subject: [PATCH 334/735] Use ByteArrayDecoder in DefaultClientResponse::createException This commit changes DefaultClientResponse::createException to use the ByteArrayDecoder, instead of converting to DataBuffers and turning these into a byte array. Closes gh-27666 --- .../client/DefaultClientResponse.java | 8 +----- .../client/DefaultClientResponseTests.java | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java index 0931bf214072..37f14f34ae0b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java @@ -195,13 +195,7 @@ public Mono>> toEntityList(ParameterizedTypeReference @Override public Mono createException() { - return DataBufferUtils.join(body(BodyExtractors.toDataBuffers())) - .map(dataBuffer -> { - byte[] bytes = new byte[dataBuffer.readableByteCount()]; - dataBuffer.read(bytes); - DataBufferUtils.release(dataBuffer); - return bytes; - }) + return bodyToMono(byte[].class) .defaultIfEmpty(EMPTY) .onErrorReturn(ex -> !(ex instanceof Error), EMPTY) .map(bodyBytes -> { diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultClientResponseTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultClientResponseTests.java index 0b21511feab1..f9b626a60c79 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultClientResponseTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultClientResponseTests.java @@ -30,6 +30,7 @@ import reactor.core.publisher.Mono; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.codec.ByteArrayDecoder; import org.springframework.core.codec.StringDecoder; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DefaultDataBuffer; @@ -48,6 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.entry; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.springframework.web.reactive.function.BodyExtractors.toMono; @@ -328,6 +330,29 @@ public void toEntityListTypeReference() { assertThat(result.getHeaders().getContentType()).isEqualTo(MediaType.TEXT_PLAIN); } + @Test + public void createException() { + byte[] bytes = "foo".getBytes(StandardCharsets.UTF_8); + DefaultDataBuffer dataBuffer = DefaultDataBufferFactory.sharedInstance.wrap(ByteBuffer.wrap(bytes)); + Flux body = Flux.just(dataBuffer); + httpHeaders.setContentType(MediaType.TEXT_PLAIN); + given(mockResponse.getStatusCode()).willReturn(HttpStatus.NOT_FOUND); + given(mockResponse.getRawStatusCode()).willReturn(HttpStatus.NOT_FOUND.value()); + given(mockResponse.getBody()).willReturn(body); + + List> messageReaders = Collections.singletonList( + new DecoderHttpMessageReader<>(new ByteArrayDecoder())); + given(mockExchangeStrategies.messageReaders()).willReturn(messageReaders); + + Mono resultMono = defaultClientResponse.createException(); + WebClientResponseException exception = resultMono.block(); + assertThat(exception.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); + assertThat(exception.getMessage()).isEqualTo("404 Not Found"); + assertThat(exception.getHeaders()).containsExactly(entry("Content-Type", + Collections.singletonList("text/plain"))); + assertThat(exception.getResponseBodyAsByteArray()).isEqualTo(bytes); + } + private void mockTextPlainResponse(Flux body) { httpHeaders.setContentType(MediaType.TEXT_PLAIN); From ac694eeac82da01b6da3e017a099c3af65b55bb7 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 10 Nov 2021 19:40:39 +0100 Subject: [PATCH 335/735] Upgrade to Gradle 7.3 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ffed3a254e91..e750102e0926 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From aaf626a53725f5cc6f63424f1095ef5e02b86108 Mon Sep 17 00:00:00 2001 From: Spring Builds Date: Thu, 11 Nov 2021 07:42:44 +0000 Subject: [PATCH 336/735] Next development version (v5.3.14-SNAPSHOT) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index b46dbd487055..bc834bbefe0d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=5.3.13-SNAPSHOT +version=5.3.14-SNAPSHOT org.gradle.jvmargs=-Xmx1536M org.gradle.caching=true org.gradle.parallel=true From 29572600dcb442ffdc7f95dced84e1c8d137bbc1 Mon Sep 17 00:00:00 2001 From: d4ksn Date: Tue, 16 Nov 2021 15:01:28 +0100 Subject: [PATCH 337/735] Ensure that references > MAX_REFERENCE_SIZE are not processed This commit ensures that only HTML references of length < MAX_REFERENCE_SIZE are considered as potential references. This check is possible because reference longer than 10 digits are out of bounds for Integers. Closes gh-1249 --- .../web/util/HtmlCharacterEntityDecoder.java | 4 ++-- .../org/springframework/web/util/HtmlUtilsTests.java | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityDecoder.java b/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityDecoder.java index 2277edfff3ad..2d6db518b20a 100644 --- a/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityDecoder.java +++ b/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +72,7 @@ private void findNextPotentialReference(int startPosition) { boolean isPotentialReference = (this.nextPotentialReferencePosition != -1 && this.nextSemicolonPosition != -1 && - this.nextPotentialReferencePosition - this.nextSemicolonPosition < MAX_REFERENCE_SIZE); + this.nextSemicolonPosition - this.nextPotentialReferencePosition < MAX_REFERENCE_SIZE); if (isPotentialReference) { break; diff --git a/spring-web/src/test/java/org/springframework/web/util/HtmlUtilsTests.java b/spring-web/src/test/java/org/springframework/web/util/HtmlUtilsTests.java index 68d31898f54f..232a436e503c 100644 --- a/spring-web/src/test/java/org/springframework/web/util/HtmlUtilsTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/HtmlUtilsTests.java @@ -28,7 +28,7 @@ public class HtmlUtilsTests { @Test - public void testHtmlEscape() { + void testHtmlEscape() { String unescaped = "\"This is a quote'"; String escaped = HtmlUtils.htmlEscape(unescaped); assertThat(escaped).isEqualTo(""This is a quote'"); @@ -39,14 +39,14 @@ public void testHtmlEscape() { } @Test - public void testHtmlUnescape() { + void testHtmlUnescape() { String escaped = ""This is a quote'"; String unescaped = HtmlUtils.htmlUnescape(escaped); assertThat(unescaped).isEqualTo("\"This is a quote'"); } @Test - public void testEncodeIntoHtmlCharacterSet() { + void testEncodeIntoHtmlCharacterSet() { assertThat(HtmlUtils.htmlEscape("")).as("An empty string should be converted to an empty string").isEqualTo(""); assertThat(HtmlUtils.htmlEscape("A sentence containing no special characters.")).as("A string containing no special characters should not be affected").isEqualTo("A sentence containing no special characters."); @@ -62,7 +62,7 @@ public void testEncodeIntoHtmlCharacterSet() { // SPR-9293 @Test - public void testEncodeIntoHtmlCharacterSetFromUtf8() { + void testEncodeIntoHtmlCharacterSetFromUtf8() { String utf8 = ("UTF-8"); assertThat(HtmlUtils.htmlEscape("", utf8)).as("An empty string should be converted to an empty string").isEqualTo(""); assertThat(HtmlUtils.htmlEscape("A sentence containing no special characters.")).as("A string containing no special characters should not be affected").isEqualTo("A sentence containing no special characters."); @@ -74,7 +74,7 @@ public void testEncodeIntoHtmlCharacterSetFromUtf8() { } @Test - public void testDecodeFromHtmlCharacterSet() { + void testDecodeFromHtmlCharacterSet() { assertThat(HtmlUtils.htmlUnescape("")).as("An empty string should be converted to an empty string").isEqualTo(""); assertThat(HtmlUtils.htmlUnescape("This is a sentence containing no special characters.")).as("A string containing no special characters should not be affected").isEqualTo("This is a sentence containing no special characters."); From 5593e1e40679592c16cc1ae0f707ae6d47fc1aac Mon Sep 17 00:00:00 2001 From: xixingya <2679431923@qq.com> Date: Wed, 17 Nov 2021 18:29:54 +0800 Subject: [PATCH 338/735] Fix javax.servlet doc to jakarta.servlet (#27692) --- gradle/docs-dokka.gradle | 2 +- .../asciidoc/languages/dynamic-languages.adoc | 4 +-- src/docs/asciidoc/web/webmvc.adoc | 28 +++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/gradle/docs-dokka.gradle b/gradle/docs-dokka.gradle index dfe137d9cfe6..147c39497f2a 100644 --- a/gradle/docs-dokka.gradle +++ b/gradle/docs-dokka.gradle @@ -20,7 +20,7 @@ tasks.findByName("dokkaHtmlPartial")?.configure { url.set(new URL("https://javadoc.io/doc/org.hamcrest/hamcrest/2.1/")) } externalDocumentationLink { - url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/")) + url.set(new URL("https://javadoc.io/doc/jakarta.servlet/jakarta.servlet-api/latest/")) } externalDocumentationLink { url.set(new URL("https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/")) diff --git a/src/docs/asciidoc/languages/dynamic-languages.adoc b/src/docs/asciidoc/languages/dynamic-languages.adoc index ce35eb55e0fc..7362adaa7e92 100644 --- a/src/docs/asciidoc/languages/dynamic-languages.adoc +++ b/src/docs/asciidoc/languages/dynamic-languages.adoc @@ -686,8 +686,8 @@ by using the Groovy dynamic language: import org.springframework.web.servlet.ModelAndView import org.springframework.web.servlet.mvc.Controller - import javax.servlet.http.HttpServletRequest - import javax.servlet.http.HttpServletResponse + import jakarta.servlet.http.HttpServletRequest + import jakarta.servlet.http.HttpServletResponse class FortuneController implements Controller { diff --git a/src/docs/asciidoc/web/webmvc.adoc b/src/docs/asciidoc/web/webmvc.adoc index 33b49bef56a5..805a2f853c07 100644 --- a/src/docs/asciidoc/web/webmvc.adoc +++ b/src/docs/asciidoc/web/webmvc.adoc @@ -736,8 +736,8 @@ or to render a JSON response, as the following example shows: @RequestMapping(path = "/error") public Map handle(HttpServletRequest request) { Map map = new HashMap(); - map.put("status", request.getAttribute("javax.servlet.error.status_code")); - map.put("reason", request.getAttribute("javax.servlet.error.message")); + map.put("status", request.getAttribute("jakarta.servlet.error.status_code")); + map.put("reason", request.getAttribute("jakarta.servlet.error.message")); return map; } } @@ -751,8 +751,8 @@ or to render a JSON response, as the following example shows: @RequestMapping(path = ["/error"]) fun handle(request: HttpServletRequest): Map { val map = HashMap() - map["status"] = request.getAttribute("javax.servlet.error.status_code") - map["reason"] = request.getAttribute("javax.servlet.error.message") + map["status"] = request.getAttribute("jakarta.servlet.error.status_code") + map["reason"] = request.getAttribute("jakarta.servlet.error.message") return map } } @@ -1932,7 +1932,7 @@ instead. `@GetMapping` (and `@RequestMapping(method=HttpMethod.GET)`) support HTTP HEAD transparently for request mapping. Controller methods do not need to change. -A response wrapper, applied in `javax.servlet.http.HttpServlet`, ensures a `Content-Length` +A response wrapper, applied in `jakarta.servlet.http.HttpServlet`, ensures a `Content-Length` header is set to the number of bytes written (without actually writing to the response). `@GetMapping` (and `@RequestMapping(method=HttpMethod.GET)`) are implicitly mapped to @@ -2053,17 +2053,17 @@ and others) and is equivalent to `required=false`. | Generic access to request parameters and request and session attributes, without direct use of the Servlet API. -| `javax.servlet.ServletRequest`, `javax.servlet.ServletResponse` +| `jakarta.servlet.ServletRequest`, `jakarta.servlet.ServletResponse` | Choose any specific request or response type -- for example, `ServletRequest`, `HttpServletRequest`, or Spring's `MultipartRequest`, `MultipartHttpServletRequest`. -| `javax.servlet.http.HttpSession` +| `jakarta.servlet.http.HttpSession` | Enforces the presence of a session. As a consequence, such an argument is never `null`. Note that session access is not thread-safe. Consider setting the `RequestMappingHandlerAdapter` instance's `synchronizeOnSession` flag to `true` if multiple requests are allowed to concurrently access a session. -| `javax.servlet.http.PushBuilder` +| `jakarta.servlet.http.PushBuilder` | Servlet 4.0 push builder API for programmatic HTTP/2 resource pushes. Note that, per the Servlet specification, the injected `PushBuilder` instance can be null if the client does not support that HTTP/2 feature. @@ -2927,7 +2927,7 @@ as the following example shows: For use cases that require adding or removing session attributes, consider injecting `org.springframework.web.context.request.WebRequest` or -`javax.servlet.http.HttpSession` into the controller method. +`jakarta.servlet.http.HttpSession` into the controller method. For temporary storage of model attributes in the session as part of a controller workflow, consider using `@SessionAttributes` as described in @@ -3116,7 +3116,7 @@ When the `@RequestParam` annotation is declared as a `Map `MultiValueMap`, without a parameter name specified in the annotation, then the map is populated with the multipart files for each given parameter name. -NOTE: With Servlet 3.0 multipart parsing, you may also declare `javax.servlet.http.Part` +NOTE: With Servlet 3.0 multipart parsing, you may also declare `jakarta.servlet.http.Part` instead of Spring's `MultipartFile`, as a method argument or collection value type. You can also use multipart content as part of data binding to a @@ -3891,11 +3891,11 @@ level, <> mechanism. | Generic access to request parameters and request and session attributes without direct use of the Servlet API. -| `javax.servlet.ServletRequest`, `javax.servlet.ServletResponse` +| `jakarta.servlet.ServletRequest`, `jakarta.servlet.ServletResponse` | Choose any specific request or response type (for example, `ServletRequest` or `HttpServletRequest` or Spring's `MultipartRequest` or `MultipartHttpServletRequest`). -| `javax.servlet.http.HttpSession` +| `jakarta.servlet.http.HttpSession` | Enforces the presence of a session. As a consequence, such an argument is never `null`. + Note that session access is not thread-safe. Consider setting the `RequestMappingHandlerAdapter` instance's `synchronizeOnSession` flag to `true` if multiple @@ -4768,7 +4768,7 @@ The MVC configuration also exposes several options for asynchronous requests. Filter and Servlet declarations have an `asyncSupported` flag that needs to be set to `true` to enable asynchronous request processing. In addition, Filter mappings should be -declared to handle the `ASYNC` `javax.servlet.DispatchType`. +declared to handle the `ASYNC` `jakarta.servlet.DispatchType`. In Java configuration, when you use `AbstractAnnotationConfigDispatcherServletInitializer` to initialize the Servlet container, this is done automatically. @@ -6097,5 +6097,5 @@ For more details, see the https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page]. The Servlet API does expose one construct related to HTTP/2. You can use the -`javax.servlet.http.PushBuilder` to proactively push resources to clients, and it +`jakarta.servlet.http.PushBuilder` to proactively push resources to clients, and it is supported as a <> to `@RequestMapping` methods. From 555807ea9c632522240b871b025dd9448e837c58 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 17 Nov 2021 12:38:58 +0100 Subject: [PATCH 339/735] Update ServletContainerInitializer filename for Jakarta EE 9 Closes gh-27690 See gh-25354 --- ...nerInitializer => jakarta.servlet.ServletContainerInitializer} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename spring-web/src/main/resources/META-INF/services/{javax.servlet.ServletContainerInitializer => jakarta.servlet.ServletContainerInitializer} (100%) diff --git a/spring-web/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/spring-web/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer similarity index 100% rename from spring-web/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer rename to spring-web/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer From b88ed7f4bb719a71a4a6fb9442e8dc731159c331 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 17 Nov 2021 12:39:23 +0100 Subject: [PATCH 340/735] Update API version and package references for Jakarta EE 9 Closes gh-27689 See gh-25354 --- build.gradle | 6 +- spring-aspects/spring-aspects.gradle | 2 +- .../ServletServerHttpAsyncRequestControl.java | 4 +- .../AbstractListenerReadPublisher.java | 2 +- .../AbstractListenerServerHttpResponse.java | 3 +- .../AbstractListenerWriteProcessor.java | 2 +- .../reactive/ServletHttpHandlerAdapter.java | 2 +- .../http/server/reactive/package-info.java | 2 +- .../SpringServletContainerInitializer.java | 27 +++-- .../web/WebApplicationInitializer.java | 36 ++----- .../web/bind/annotation/RequestPart.java | 4 +- .../web/context/ContextLoader.java | 7 +- .../web/context/ContextLoaderListener.java | 9 +- .../async/StandardServletAsyncWebRequest.java | 2 +- .../web/filter/DelegatingFilterProxy.java | 20 ++-- .../web/filter/OncePerRequestFilter.java | 24 ++--- .../web/filter/ShallowEtagHeaderFilter.java | 5 +- .../RequestParamMethodArgumentResolver.java | 2 +- .../web/multipart/MultipartFile.java | 2 +- .../web/multipart/MultipartResolver.java | 2 +- .../multipart/support/MultipartFilter.java | 6 +- .../RequestPartServletServerHttpRequest.java | 4 +- .../StandardMultipartHttpServletRequest.java | 12 +-- .../StandardServletMultipartResolver.java | 10 +- .../util/ContentCachingRequestWrapper.java | 2 - .../util/ContentCachingResponseWrapper.java | 4 +- .../function/server/RouterFunctions.java | 12 +-- .../web/servlet/DispatcherServlet.java | 2 +- .../web/servlet/FrameworkServlet.java | 2 +- .../RequestPartMethodArgumentResolver.java | 2 +- .../servlet/support/RequestContextUtils.java | 4 +- src/docs/asciidoc/core/core-aop.adoc | 2 +- src/docs/asciidoc/core/core-appendix.adoc | 4 +- src/docs/asciidoc/core/core-beans.adoc | 100 +++++++++--------- src/docs/asciidoc/core/core-validation.adoc | 20 ++-- src/docs/asciidoc/data-access.adoc | 67 +++++------- src/docs/asciidoc/integration.adoc | 86 +++++++-------- .../integration/integration-appendix.adoc | 2 +- src/docs/asciidoc/overview.adoc | 35 +++--- src/docs/asciidoc/testing.adoc | 28 ++--- src/docs/asciidoc/web-reactive.adoc | 2 +- src/docs/asciidoc/web/integration.adoc | 4 +- src/docs/asciidoc/web/webflux.adoc | 50 ++++----- src/docs/asciidoc/web/webmvc.adoc | 34 +++--- src/docs/asciidoc/web/websocket.adoc | 2 +- 45 files changed, 305 insertions(+), 354 deletions(-) diff --git a/build.gradle b/build.gradle index 73223bac3723..a6d25090556f 100644 --- a/build.gradle +++ b/build.gradle @@ -120,8 +120,8 @@ configure(allprojects) { project -> dependencySet(group: 'org.apache.tomcat', version: '10.0.12') { entry 'tomcat-util' entry('tomcat-websocket') { - exclude group: "org.apache.tomcat", name: "tomcat-websocket-api" exclude group: "org.apache.tomcat", name: "tomcat-servlet-api" + exclude group: "org.apache.tomcat", name: "tomcat-websocket-api" } } dependencySet(group: 'org.apache.tomcat.embed', version: '10.0.12') { @@ -130,9 +130,7 @@ configure(allprojects) { project -> } dependencySet(group: 'io.undertow', version: '2.2.12.Final') { entry 'undertow-core' - entry('undertow-servlet-jakartaee9') { - exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.3_spec" - } + entry 'undertow-servlet-jakartaee9' entry 'undertow-websockets-jsr-jakartaee9' } diff --git a/spring-aspects/spring-aspects.gradle b/spring-aspects/spring-aspects.gradle index 0461a8be3fb2..6b319135dba0 100644 --- a/spring-aspects/spring-aspects.gradle +++ b/spring-aspects/spring-aspects.gradle @@ -29,7 +29,7 @@ dependencies { optional(project(":spring-orm")) // for JPA exception translation support optional(project(":spring-tx")) // for JPA, @Transactional support optional("javax.cache:cache-api") // for JCache aspect - optional("jakarta.transaction:jakarta.transaction-api") // for @javax.transaction.Transactional support + optional("jakarta.transaction:jakarta.transaction-api") // for @jakarta.transaction.Transactional support testImplementation(project(":spring-core")) // for CodeStyleAspect testImplementation(project(":spring-test")) testImplementation(testFixtures(project(":spring-context"))) diff --git a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java index 7833b92bbb1d..db87ffb8e4ff 100644 --- a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java +++ b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java @@ -29,7 +29,7 @@ import org.springframework.util.Assert; /** - * A {@link ServerHttpAsyncRequestControl} to use on Servlet containers (Servlet 3.0+). + * A {@link ServerHttpAsyncRequestControl} to use on Servlet containers. * * @author Rossen Stoyanchev * @since 4.0 @@ -62,7 +62,7 @@ public ServletServerHttpAsyncRequestControl(ServletServerHttpRequest request, Se "Async support must be enabled on a servlet and for all filters involved " + "in async request processing. This is done in Java code using the Servlet API " + "or by adding \"true\" to servlet and " + - "filter declarations in web.xml. Also you must use a Servlet 3.0+ container"); + "filter declarations in web.xml."); this.request = request; this.response = response; diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerReadPublisher.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerReadPublisher.java index 0845a9f25f04..210035f57f35 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerReadPublisher.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerReadPublisher.java @@ -35,7 +35,7 @@ * event-listener read APIs and Reactive Streams. * *

    Specifically a base class for reading from the HTTP request body with - * Servlet 3.1 non-blocking I/O and Undertow XNIO as well as handling incoming + * Servlet non-blocking I/O and Undertow XNIO as well as handling incoming * WebSocket messages with standard Java WebSocket (JSR-356), Jetty, and * Undertow. * diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerServerHttpResponse.java index 75c9bc7113ba..45cc2f7787f4 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerServerHttpResponse.java @@ -27,8 +27,7 @@ import org.springframework.http.HttpHeaders; /** - * Abstract base class for listener-based server responses, e.g. Servlet 3.1 - * and Undertow. + * Abstract base class for listener-based server responses. * * @author Arjen Poutsma * @since 5.0 diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteProcessor.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteProcessor.java index 92d7b41846b5..defd6d6302a6 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteProcessor.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteProcessor.java @@ -34,7 +34,7 @@ * event-listener write APIs and Reactive Streams. * *

    Specifically a base class for writing to the HTTP response body with - * Servlet 3.1 non-blocking I/O and Undertow XNIO as well for writing WebSocket + * Servlet non-blocking I/O and Undertow XNIO as well for writing WebSocket * messages through the Java WebSocket API (JSR-356), Jetty, and Undertow. * * @author Arjen Poutsma diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java index 0fe306911e78..8918aa568f69 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java @@ -47,7 +47,7 @@ /** * Adapt {@link HttpHandler} to an {@link HttpServlet} using Servlet Async support - * and Servlet 3.1 non-blocking I/O. + * and Servlet non-blocking I/O. * * @author Arjen Poutsma * @author Rossen Stoyanchev diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/package-info.java b/spring-web/src/main/java/org/springframework/http/server/reactive/package-info.java index f2025bc49324..25e89a1f036b 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/package-info.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/package-info.java @@ -5,7 +5,7 @@ * {@link org.springframework.http.server.reactive.HttpHandler} for processing. * *

    Also provides implementations adapting to different runtimes - * including Servlet 3.1 containers, Netty + Reactor IO, and Undertow. + * including Servlet containers, Netty + Reactor IO, and Undertow. */ @NonNullApi @NonNullFields diff --git a/spring-web/src/main/java/org/springframework/web/SpringServletContainerInitializer.java b/spring-web/src/main/java/org/springframework/web/SpringServletContainerInitializer.java index 6ce5e8fa83f9..3c0d69c46d81 100644 --- a/spring-web/src/main/java/org/springframework/web/SpringServletContainerInitializer.java +++ b/spring-web/src/main/java/org/springframework/web/SpringServletContainerInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,21 +33,18 @@ import org.springframework.util.ReflectionUtils; /** - * Servlet 3.0 {@link ServletContainerInitializer} designed to support code-based + * A Spring-provided {@link ServletContainerInitializer} designed to support code-based * configuration of the servlet container using Spring's {@link WebApplicationInitializer} * SPI as opposed to (or possibly in combination with) the traditional * {@code web.xml}-based approach. * *

    Mechanism of Operation

    * This class will be loaded and instantiated and have its {@link #onStartup} - * method invoked by any Servlet 3.0-compliant container during container startup assuming + * method invoked by any Servlet-compliant container during container startup assuming * that the {@code spring-web} module JAR is present on the classpath. This occurs through * the JAR Services API {@link ServiceLoader#load(Class)} method detecting the * {@code spring-web} module's {@code META-INF/services/jakarta.servlet.ServletContainerInitializer} - * service provider configuration file. See the - * - * JAR Services API documentation as well as section 8.2.4 of the Servlet 3.0 - * Final Draft specification for complete details. + * service provider configuration file. * *

    In combination with {@code web.xml}

    * A web application can choose to limit the amount of classpath scanning the Servlet @@ -80,12 +77,12 @@ *

    General Notes

    * In general, this class should be viewed as supporting infrastructure for * the more important and user-facing {@code WebApplicationInitializer} SPI. Taking - * advantage of this container initializer is also completely optional: while - * it is true that this initializer will be loaded and invoked under all Servlet 3.0+ - * runtimes, it remains the user's choice whether to make any - * {@code WebApplicationInitializer} implementations available on the classpath. If no - * {@code WebApplicationInitializer} types are detected, this container initializer will - * have no effect. + * advantage of this container initializer is also completely optional: + * while it is true that this initializer will be loaded and invoked under all + * Servlet runtimes, it remains the user's choice whether to make any + * {@code WebApplicationInitializer} implementations available on the classpath. + * If no {@code WebApplicationInitializer} types are detected, this container + * initializer will have no effect. * *

    Note that use of this container initializer and of {@code WebApplicationInitializer} * is not in any way "tied" to Spring MVC other than the fact that the types are shipped @@ -117,8 +114,8 @@ public class SpringServletContainerInitializer implements ServletContainerInitia * Delegate the {@code ServletContext} to any {@link WebApplicationInitializer} * implementations present on the application classpath. *

    Because this class declares @{@code HandlesTypes(WebApplicationInitializer.class)}, - * Servlet 3.0+ containers will automatically scan the classpath for implementations - * of Spring's {@code WebApplicationInitializer} interface and provide the set of all + * Servlet containers will automatically scan the classpath for implementations of + * Spring's {@code WebApplicationInitializer} interface and provide the set of all * such types to the {@code webAppInitializerClasses} parameter of this method. *

    If no {@code WebApplicationInitializer} implementations are found on the classpath, * this method is effectively a no-op. An INFO-level log message will be issued notifying diff --git a/spring-web/src/main/java/org/springframework/web/WebApplicationInitializer.java b/spring-web/src/main/java/org/springframework/web/WebApplicationInitializer.java index 736e5031a646..6ee0811cb8ed 100644 --- a/spring-web/src/main/java/org/springframework/web/WebApplicationInitializer.java +++ b/spring-web/src/main/java/org/springframework/web/WebApplicationInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,13 +20,13 @@ import jakarta.servlet.ServletException; /** - * Interface to be implemented in Servlet 3.0+ environments in order to configure the + * Interface to be implemented in Servlet environments in order to configure the * {@link ServletContext} programmatically -- as opposed to (or possibly in conjunction * with) the traditional {@code web.xml}-based approach. * *

    Implementations of this SPI will be detected automatically by {@link * SpringServletContainerInitializer}, which itself is bootstrapped automatically - * by any Servlet 3.0 container. See {@linkplain SpringServletContainerInitializer its + * by any Servlet container. See {@linkplain SpringServletContainerInitializer its * Javadoc} for details on this bootstrapping mechanism. * *

    Example

    @@ -74,10 +74,10 @@ * As an alternative to the above, you can also extend from {@link * org.springframework.web.servlet.support.AbstractDispatcherServletInitializer}. * - * As you can see, thanks to Servlet 3.0's new {@link ServletContext#addServlet} method - * we're actually registering an instance of the {@code DispatcherServlet}, and - * this means that the {@code DispatcherServlet} can now be treated like any other object - * -- receiving constructor injection of its application context in this case. + * As you can see, thanks to the Servlet container's {@link ServletContext#addServlet} + * method we're actually registering an instance of the {@code DispatcherServlet}, + * and this means that the {@code DispatcherServlet} can now be treated like any other + * object -- receiving constructor injection of its application context in this case. * *

    This style is both simpler and more concise. There is no concern for dealing with * init-params, etc, just normal JavaBean-style properties and constructor arguments. You @@ -89,8 +89,8 @@ * {@code ContextLoaderListener} and {@code DelegatingFilterProxy} all now support * constructor arguments. Even if a component (e.g. non-Spring, other third party) has not * been specifically updated for use within {@code WebApplicationInitializers}, they still - * may be used in any case. The Servlet 3.0 {@code ServletContext} API allows for setting - * init-params, context-params, etc programmatically. + * may be used in any case. The {@code ServletContext} API allows for setting init-params, + * context-params, etc programmatically. * *

    A 100% code-based approach to configuration

    * In the example above, {@code WEB-INF/web.xml} was successfully replaced with code in @@ -149,24 +149,6 @@ * occurs. Use of this feature is expected to be rare, as typical applications will likely * centralize all container initialization within a single {@code WebApplicationInitializer}. * - *

    Caveats

    - * - *

    web.xml versioning

    - *

    {@code WEB-INF/web.xml} and {@code WebApplicationInitializer} use are not mutually - * exclusive; for example, web.xml can register one servlet, and a {@code - * WebApplicationInitializer} can register another. An initializer can even - * modify registrations performed in {@code web.xml} through methods such as - * {@link ServletContext#getServletRegistration(String)}. However, if - * {@code WEB-INF/web.xml} is present in the application, its {@code version} attribute - * must be set to "3.0" or greater, otherwise {@code ServletContainerInitializer} - * bootstrapping will be ignored by the servlet container. - * - *

    Mapping to '/' under Tomcat

    - *

    Apache Tomcat maps its internal {@code DefaultServlet} to "/", and on Tomcat versions - * <= 7.0.14, this servlet mapping cannot be overridden programmatically. - * 7.0.15 fixes this issue. Overriding the "/" servlet mapping has also been tested - * successfully under GlassFish 3.1.

    - * * @author Chris Beams * @since 3.1 * @see SpringServletContainerInitializer diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestPart.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestPart.java index b84f09ffd72f..e7c576b73c20 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestPart.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestPart.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ * *

    Supported method argument types include {@link MultipartFile} in conjunction with * Spring's {@link MultipartResolver} abstraction, {@code jakarta.servlet.http.Part} in - * conjunction with Servlet 3.0 multipart requests, or otherwise for any other method + * conjunction with Servlet multipart requests, or otherwise for any other method * argument, the content of the part is passed through an {@link HttpMessageConverter} * taking into consideration the 'Content-Type' header of the request part. This is * analogous to what @{@link RequestBody} does to resolve an argument based on the diff --git a/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java b/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java index 45a4bb69a928..e7c3d8a0f41d 100644 --- a/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java +++ b/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java @@ -72,7 +72,7 @@ * *

    As of Spring 3.1, {@code ContextLoader} supports injecting the root web * application context via the {@link #ContextLoader(WebApplicationContext)} - * constructor, allowing for programmatic configuration in Servlet 3.0+ environments. + * constructor, allowing for programmatic configuration in Servlet initializers. * See {@link org.springframework.web.WebApplicationInitializer} for usage examples. * * @author Juergen Hoeller @@ -193,9 +193,8 @@ public ContextLoader() { /** * Create a new {@code ContextLoader} with the given application context. This - * constructor is useful in Servlet 3.0+ environments where instance-based - * registration of listeners is possible through the {@link ServletContext#addListener} - * API. + * constructor is useful in Servlet initializers where instance-based registration + * of listeners is possible through the {@link ServletContext#addListener} API. *

    The context may or may not yet be {@linkplain * ConfigurableApplicationContext#refresh() refreshed}. If it (a) is an implementation * of {@link ConfigurableWebApplicationContext} and (b) has not diff --git a/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java b/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java index 3f57d6764536..62518ce8659f 100644 --- a/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java +++ b/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ * *

    As of Spring 3.1, {@code ContextLoaderListener} supports injecting the root web * application context via the {@link #ContextLoaderListener(WebApplicationContext)} - * constructor, allowing for programmatic configuration in Servlet 3.0+ environments. + * constructor, allowing for programmatic configuration in Servlet initializers. * See {@link org.springframework.web.WebApplicationInitializer} for usage examples. * * @author Juergen Hoeller @@ -58,9 +58,8 @@ public ContextLoaderListener() { /** * Create a new {@code ContextLoaderListener} with the given application context. This - * constructor is useful in Servlet 3.0+ environments where instance-based - * registration of listeners is possible through the {@link jakarta.servlet.ServletContext#addListener} - * API. + * constructor is useful in Servlet initializers where instance-based registration of + * listeners is possible through the {@link jakarta.servlet.ServletContext#addListener} API. *

    The context may or may not yet be {@linkplain * org.springframework.context.ConfigurableApplicationContext#refresh() refreshed}. If it * (a) is an implementation of {@link ConfigurableWebApplicationContext} and diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequest.java b/spring-web/src/main/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequest.java index 395166f84e92..bc7c6ed76275 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequest.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequest.java @@ -32,7 +32,7 @@ import org.springframework.web.context.request.ServletWebRequest; /** - * A Servlet 3.0 implementation of {@link AsyncWebRequest}. + * A Servlet implementation of {@link AsyncWebRequest}. * *

    The servlet and all filters involved in an async request must have async * support enabled using the Servlet API or by adding an diff --git a/spring-web/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java b/spring-web/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java index 8a85966ed353..96f773e78065 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java +++ b/spring-web/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java @@ -54,9 +54,9 @@ * of the {@code Filter.init} and {@code Filter.destroy} lifecycle methods * on the target bean, letting the servlet container manage the filter lifecycle. * - *

    As of Spring 3.1, {@code DelegatingFilterProxy} has been updated to optionally accept - * constructor parameters when using Servlet 3.0's instance-based filter registration - * methods, usually in conjunction with Spring 3.1's + *

    As of Spring 3.1, {@code DelegatingFilterProxy} has been updated to optionally + * accept constructor parameters when using a Servlet container's instance-based filter + * registration methods, usually in conjunction with Spring's * {@link org.springframework.web.WebApplicationInitializer} SPI. These constructors allow * for providing the delegate Filter bean directly, or providing the application context * and bean name to fetch, avoiding the need to look up the application context from the @@ -100,8 +100,7 @@ public class DelegatingFilterProxy extends GenericFilterBean { /** - * Create a new {@code DelegatingFilterProxy}. For traditional (pre-Servlet 3.0) use - * in {@code web.xml}. + * Create a new {@code DelegatingFilterProxy}. For traditional use in {@code web.xml}. * @see #setTargetBeanName(String) */ public DelegatingFilterProxy() { @@ -111,8 +110,7 @@ public DelegatingFilterProxy() { * Create a new {@code DelegatingFilterProxy} with the given {@link Filter} delegate. * Bypasses entirely the need for interacting with a Spring application context, * specifying the {@linkplain #setTargetBeanName target bean name}, etc. - *

    For use in Servlet 3.0+ environments where instance-based registration of - * filters is supported. + *

    For use with instance-based registration of filters. * @param delegate the {@code Filter} instance that this proxy will delegate to and * manage the lifecycle for (must not be {@code null}). * @see #doFilter(ServletRequest, ServletResponse, FilterChain) @@ -130,9 +128,8 @@ public DelegatingFilterProxy(Filter delegate) { * bean from the Spring {@code WebApplicationContext} found in the {@code ServletContext} * (either the 'root' application context or the context named by * {@link #setContextAttribute}). - *

    For use in Servlet 3.0+ environments where instance-based registration of - * filters is supported. - *

    The target bean must implement the standard Servlet Filter. + *

    For use with instance-based registration of filters. + *

    The target bean must implement the standard Servlet Filter interface. * @param targetBeanName name of the target filter bean to look up in the Spring * application context (must not be {@code null}). * @see #findWebApplicationContext() @@ -145,8 +142,7 @@ public DelegatingFilterProxy(String targetBeanName) { /** * Create a new {@code DelegatingFilterProxy} that will retrieve the named target * bean from the given Spring {@code WebApplicationContext}. - *

    For use in Servlet 3.0+ environments where instance-based registration of - * filters is supported. + *

    For use with instance-based registration of filters. *

    The target bean must implement the standard Servlet Filter interface. *

    The given {@code WebApplicationContext} may or may not be refreshed when passed * in. If it has not, and if the context implements {@link ConfigurableApplicationContext}, diff --git a/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java b/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java index 6f505363829f..46d5163cc7c3 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java @@ -35,7 +35,7 @@ * dispatch, on any servlet container. It provides a {@link #doFilterInternal} * method with HttpServletRequest and HttpServletResponse arguments. * - *

    As of Servlet 3.0, a filter may be invoked as part of a + *

    A filter may be invoked as part of a * {@link jakarta.servlet.DispatcherType#REQUEST REQUEST} or * {@link jakarta.servlet.DispatcherType#ASYNC ASYNC} dispatches that occur in * separate threads. A filter can be configured in {@code web.xml} whether it @@ -133,10 +133,10 @@ private boolean skipDispatch(HttpServletRequest request) { } /** - * The dispatcher type {@code jakarta.servlet.DispatcherType.ASYNC} introduced - * in Servlet 3.0 means a filter can be invoked in more than one thread over - * the course of a single request. This method returns {@code true} if the - * filter is currently executing within an asynchronous dispatch. + * The dispatcher type {@code jakarta.servlet.DispatcherType.ASYNC} means a + * filter can be invoked in more than one thread over the course of a single + * request. This method returns {@code true} if the filter is currently + * executing within an asynchronous dispatch. * @param request the current request * @since 3.2 * @see WebAsyncManager#hasConcurrentResult() @@ -186,15 +186,15 @@ protected boolean shouldNotFilter(HttpServletRequest request) throws ServletExce } /** - * The dispatcher type {@code jakarta.servlet.DispatcherType.ASYNC} introduced - * in Servlet 3.0 means a filter can be invoked in more than one thread - * over the course of a single request. Some filters only need to filter - * the initial thread (e.g. request wrapping) while others may need - * to be invoked at least once in each additional thread for example for - * setting up thread locals or to perform final processing at the very end. + * The dispatcher type {@code jakarta.servlet.DispatcherType.ASYNC} means a + * filter can be invoked in more than one thread over the course of a single + * request. Some filters only need to filter the initial thread (e.g. request + * wrapping) while others may need to be invoked at least once in each + * additional thread for example for setting up thread locals or to perform + * final processing at the very end. *

    Note that although a filter can be mapped to handle specific dispatcher * types via {@code web.xml} or in Java through the {@code ServletContext}, - * servlet containers may enforce different defaults with regards to + * servlet containers may enforce different defaults with respect to * dispatcher types. This flag enforces the design intent of the filter. *

    The default return value is "true", which means the filter will not be * invoked during subsequent async dispatches. If "false", the filter will diff --git a/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java b/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java index 06e164297f8f..229beacf3ee9 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,9 +46,6 @@ * (e.g. a {@link org.springframework.web.servlet.View}) is still rendered. * As such, this filter only saves bandwidth, not server performance. * - *

    NOTE: As of Spring Framework 5.0, this filter uses request/response - * decorators built on the Servlet 3.1 API. - * * @author Arjen Poutsma * @author Rossen Stoyanchev * @author Brian Clozel diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java index ec1aeb1149d6..265d8cae47aa 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java @@ -53,7 +53,7 @@ * Resolves method arguments annotated with @{@link RequestParam}, arguments of * type {@link MultipartFile} in conjunction with Spring's {@link MultipartResolver} * abstraction, and arguments of type {@code jakarta.servlet.http.Part} in conjunction - * with Servlet 3.0 multipart requests. This resolver can also be created in default + * with Servlet multipart requests. This resolver can also be created in default * resolution mode in which simple types (int, long, etc.) not annotated with * {@link RequestParam @RequestParam} are also treated as request parameters with * the parameter name derived from the argument name. diff --git a/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java b/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java index 25790e5f3d1e..90f41da86ece 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java @@ -124,7 +124,7 @@ default Resource getResource() { * in order to work with any storage mechanism. *

    NOTE: Depending on the underlying provider, temporary storage * may be container-dependent, including the base directory for relative - * destinations specified here (e.g. with Servlet 3.0 multipart handling). + * destinations specified here (e.g. with Servlet multipart handling). * For absolute destinations, the target file may get renamed/moved from its * temporary location or newly copied, even if a temporary copy already exists. * @param dest the destination file (typically absolute) diff --git a/spring-web/src/main/java/org/springframework/web/multipart/MultipartResolver.java b/spring-web/src/main/java/org/springframework/web/multipart/MultipartResolver.java index a9c79dfbb82b..1c6ab8398052 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/MultipartResolver.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/MultipartResolver.java @@ -27,7 +27,7 @@ *

    Spring provides the following concrete implementation: *

      *
    • {@link org.springframework.web.multipart.support.StandardServletMultipartResolver} - * for the Servlet 3.0+ Part API + * for the Servlet Part API *
    * *

    There is no default resolver implementation used for Spring diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java b/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java index 276c5a05e201..e1e799dcb7c7 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,8 +38,8 @@ * the default bean name is "filterMultipartResolver". * *

    If no MultipartResolver bean is found, this filter falls back to a default - * MultipartResolver: {@link StandardServletMultipartResolver} for Servlet 3.0, - * based on a multipart-config section in {@code web.xml}. + * MultipartResolver: {@link StandardServletMultipartResolver} for Servlet + * oontainers, based on a multipart-config section in {@code web.xml}. * Note however that at present the Servlet specification only defines how to * enable multipart configuration on a Servlet and as a result multipart request * processing is likely not possible in a Filter unless the Servlet container diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java index aa1bfca3c3fc..424ea4e1d6dd 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ /** * {@link ServerHttpRequest} implementation that accesses one part of a multipart * request. If using {@link MultipartResolver} configuration the part is accessed - * through a {@link MultipartFile}. Or if using Servlet 3.0 multipart processing + * through a {@link MultipartFile}. Or if using Servlet multipart processing * the part is accessed through {@code ServletRequest.getPart}. * * @author Rossen Stoyanchev diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java index 7f21e5e2775b..dffdf4890a96 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,7 +47,7 @@ import org.springframework.web.multipart.MultipartFile; /** - * Spring MultipartHttpServletRequest adapter, wrapping a Servlet 3.0 HttpServletRequest + * Spring MultipartHttpServletRequest adapter, wrapping a Servlet HttpServletRequest * and its Part objects. Parameters get exposed through the native request's getParameter * methods - without any custom processing on our side. * @@ -138,7 +138,7 @@ public Enumeration getParameterNames() { return super.getParameterNames(); } - // Servlet 3.0 getParameterNames() not guaranteed to include multipart form items + // Servlet getParameterNames() not guaranteed to include multipart form items // (e.g. on WebLogic 12) -> need to merge them here to be on the safe side Set paramNames = new LinkedHashSet<>(); Enumeration paramEnum = super.getParameterNames(); @@ -158,7 +158,7 @@ public Map getParameterMap() { return super.getParameterMap(); } - // Servlet 3.0 getParameterMap() not guaranteed to include multipart form items + // Servlet getParameterMap() not guaranteed to include multipart form items // (e.g. on WebLogic 12) -> need to merge them here to be on the safe side Map paramMap = new LinkedHashMap<>(super.getParameterMap()); for (String paramName : this.multipartParameterNames) { @@ -202,7 +202,7 @@ public HttpHeaders getMultipartHeaders(String paramOrFileName) { /** - * Spring MultipartFile adapter, wrapping a Servlet 3.0 Part object. + * Spring MultipartFile adapter, wrapping a Servlet Part object. */ @SuppressWarnings("serial") private static class StandardMultipartFile implements MultipartFile, Serializable { @@ -255,7 +255,7 @@ public InputStream getInputStream() throws IOException { public void transferTo(File dest) throws IOException, IllegalStateException { this.part.write(dest.getPath()); if (dest.isAbsolute() && !dest.exists()) { - // Servlet 3.0 Part.write is not guaranteed to support absolute file paths: + // Servlet Part.write is not guaranteed to support absolute file paths: // may translate the given path to a relative location within a temp dir // (e.g. on Jetty whereas Tomcat and Undertow detect absolute paths). // At least we offloaded the file from memory storage; it'll get deleted diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java index b09dac0ba20a..7888b8bde0fd 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java @@ -28,7 +28,7 @@ /** * Standard implementation of the {@link MultipartResolver} interface, - * based on the Servlet 3.0 {@link jakarta.servlet.http.Part} API. + * based on the Servlet {@link jakarta.servlet.http.Part} API. * To be added as "multipartResolver" bean to a Spring DispatcherServlet context, * without any extra configuration at the bean level (see below). * @@ -38,14 +38,14 @@ * {@linkplain #setStrictServletCompliance strict Servlet compliance}, narrowing the * applicability of Spring's {@link MultipartHttpServletRequest} to form data only. * - *

    Note: In order to use Servlet 3.0 based multipart parsing, + *

    Note: In order to use Servlet container based multipart parsing, * you need to mark the affected servlet with a "multipart-config" section in * {@code web.xml}, or with a {@link jakarta.servlet.MultipartConfigElement} * in programmatic servlet registration, or (in case of a custom servlet class) * possibly with a {@link jakarta.servlet.annotation.MultipartConfig} annotation - * on your servlet class. Configuration settings such as maximum sizes or - * storage locations need to be applied at that servlet registration level; - * Servlet 3.0 does not allow for them to be set at the MultipartResolver level. + * on your servlet class. Configuration settings such as maximum sizes or storage + * locations need to be applied at that servlet registration level; a Servlet + * container does not allow for them to be set at the MultipartResolver level. * *

      * public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    diff --git a/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java b/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java
    index 64df59fb2738..562ab5b1cca5 100644
    --- a/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java
    +++ b/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java
    @@ -46,8 +46,6 @@
      * retrieved via {@link #getContentAsByteArray()}.
      *
      * 

    Used e.g. by {@link org.springframework.web.filter.AbstractRequestLoggingFilter}. - * Note: As of Spring Framework 5.0, this wrapper is built on the Servlet 3.1 API. - * * * @author Juergen Hoeller * @author Brian Clozel diff --git a/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java b/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java index d1de91db742d..d7fdb0e0e213 100644 --- a/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java +++ b/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,6 @@ * and allows this content to be retrieved via a {@link #getContentAsByteArray() byte array}. * *

    Used e.g. by {@link org.springframework.web.filter.ShallowEtagHeaderFilter}. - * Note: As of Spring Framework 5.0, this wrapper is built on the Servlet 3.1 API. * * @author Juergen Hoeller * @since 4.1.3 @@ -128,7 +127,6 @@ public void setContentLength(int len) { this.contentLength = len; } - // Overrides Servlet 3.1 setContentLengthLong(long) at runtime @Override public void setContentLengthLong(long len) { if (len > Integer.MAX_VALUE) { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java index 30157153d4ae..8e52bb25002c 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,9 +50,9 @@ * {@linkplain #nest(RequestPredicate, RouterFunction) subrouting} on an existing routing * function. * - *

    Additionally, this class can {@linkplain #toHttpHandler(RouterFunction) transform} a - * {@code RouterFunction} into an {@code HttpHandler}, which can be run in Servlet 3.1+, - * Reactor, or Undertow. + *

    Additionally, this class can {@linkplain #toHttpHandler(RouterFunction) transform} + * a {@code RouterFunction} into an {@code HttpHandler}, which can be run in Servlet + * environments, Reactor, or Undertow. * * @author Arjen Poutsma * @since 5.0 @@ -192,7 +192,7 @@ public static RouterFunction resources(FunctionThe returned handler can be adapted to run in *

    * * + * + * + * + * * * * @@ -113,10 +117,6 @@ * * * - * - * - * - * * * * @@ -135,6 +135,7 @@ * @author Arjen Poutsma * @author Rossen Stoyanchev * @author Juergen Hoeller + * @author Wonchul Heo * @since 3.0 * @see org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler */ @@ -188,6 +189,10 @@ else if (ex instanceof MissingServletRequestParameterException) { return handleMissingServletRequestParameter( (MissingServletRequestParameterException) ex, request, response, handler); } + else if (ex instanceof MissingServletRequestPartException) { + return handleMissingServletRequestPartException( + (MissingServletRequestPartException) ex, request, response, handler); + } else if (ex instanceof ServletRequestBindingException) { return handleServletRequestBindingException( (ServletRequestBindingException) ex, request, response, handler); @@ -212,10 +217,6 @@ else if (ex instanceof MethodArgumentNotValidException) { return handleMethodArgumentNotValidException( (MethodArgumentNotValidException) ex, request, response, handler); } - else if (ex instanceof MissingServletRequestPartException) { - return handleMissingServletRequestPartException( - (MissingServletRequestPartException) ex, request, response, handler); - } else if (ex instanceof BindException) { return handleBindException((BindException) ex, request, response, handler); } From 7ecfce2386016803742e580fe246a3084d17a813 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Fri, 11 Feb 2022 11:04:35 +0000 Subject: [PATCH 684/735] Polishing contribution See gh-27948 --- .../support/MissingServletRequestPartException.java | 13 +++++-------- .../annotation/ResponseEntityExceptionHandler.java | 1 - .../support/DefaultHandlerExceptionResolver.java | 1 - 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/MissingServletRequestPartException.java b/spring-web/src/main/java/org/springframework/web/multipart/support/MissingServletRequestPartException.java index 539ec6a5ea83..93f332fabf86 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/MissingServletRequestPartException.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/MissingServletRequestPartException.java @@ -20,16 +20,13 @@ import org.springframework.web.multipart.MultipartResolver; /** - * Raised when the part of a "multipart/form-data" request identified by its - * name cannot be found. - * - *

    This may be because the request is not a multipart/form-data request, - * because the part is not present in the request, or because the web - * application is not configured correctly for processing multipart requests, - * e.g. no {@link MultipartResolver}. + * Signals the part of a "multipart/form-data" request, identified by name + * could not be found. This may be because the request is not a multipart + * request, or a part with that name is not present, or because the application + * is not configured correctly for processing multipart requests, e.g. there + * is no {@link MultipartResolver}. * * @author Rossen Stoyanchev - * @author Wonchul Heo * @since 3.1 */ @SuppressWarnings("serial") diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java index 6c9e70c8e46a..6252e7cf25f9 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java @@ -73,7 +73,6 @@ * detected, {@link ExceptionHandlerExceptionResolver} must be configured. * * @author Rossen Stoyanchev - * @author Wonchul Heo * @since 3.2 * @see #handleException(Exception, WebRequest) * @see org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java index 4aa1b2b6646d..6ee73d49ab68 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java @@ -135,7 +135,6 @@ * @author Arjen Poutsma * @author Rossen Stoyanchev * @author Juergen Hoeller - * @author Wonchul Heo * @since 3.0 * @see org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler */ From 4c410cbe54e1383cb5e6b6ee7e2f5330023c218a Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 14 Feb 2022 13:04:09 +0100 Subject: [PATCH 685/735] Remove toolchain configuration for Kotlin Kotlin currently only supports JDK17 language level, which is our minimum requirement so far. This commit simplifies the toolchain setup until this is needed again. See 303e363adfd --- gradle/toolchains.gradle | 56 +++++----------------------------------- 1 file changed, 7 insertions(+), 49 deletions(-) diff --git a/gradle/toolchains.gradle b/gradle/toolchains.gradle index 4f7c96e80ead..f7eaeb8c2f4d 100644 --- a/gradle/toolchains.gradle +++ b/gradle/toolchains.gradle @@ -95,57 +95,15 @@ plugins.withType(GroovyPlugin) { } pluginManager.withPlugin("kotlin") { - // Configure the Kotlin compiler if the 'mainToolchain' property is defined - if (mainToolchainConfigured()) { - def mainLanguageVersion = mainToolchainLanguageVersion() - // See https://kotlinlang.org/docs/gradle.html#attributes-specific-for-jvm - def javaVersion = mainLanguageVersion.toString() - kotlin { - jvmToolchain { - languageVersion.set(mainLanguageVersion) - } - } - compileKotlin { - kotlinOptions { - jvmTarget = javaVersion - } - } - // Compile the test classes with the same version, 'testToolchain' will override if defined - compileTestKotlin { - kotlinOptions { - jvmTarget = javaVersion - } - } - } - else { - // Fallback to JDK17 - compileKotlin { - kotlinOptions { - jvmTarget = '17' - } - } - compileTestKotlin { - kotlinOptions { - jvmTarget = '17' - } + // Fallback to JDK17 + compileKotlin { + kotlinOptions { + jvmTarget = '17' } } - - if (testToolchainConfigured()) { - def testLanguageVersion = testToolchainLanguageVersion() - def compiler = javaToolchains.compilerFor { - languageVersion = testLanguageVersion - } - kotlin { - jvmToolchain { - languageVersion.set(testLanguageVersion) - } - } - // See https://kotlinlang.org/docs/gradle.html#attributes-specific-for-jvm - compileTestKotlin { - kotlinOptions { - jvmTarget = testLanguageVersion.toString() - } + compileTestKotlin { + kotlinOptions { + jvmTarget = '17' } } } From 88f73bffa0e98c1e14db065c86d17c5d6295cee0 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 14 Feb 2022 16:21:41 +0100 Subject: [PATCH 686/735] Make assertion message lazy in ServletRequestPathUtils Closes gh-27946 --- .../org/springframework/web/util/ServletRequestPathUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/ServletRequestPathUtils.java b/spring-web/src/main/java/org/springframework/web/util/ServletRequestPathUtils.java index 1c4455dbbe99..43eda1c21d11 100644 --- a/spring-web/src/main/java/org/springframework/web/util/ServletRequestPathUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/ServletRequestPathUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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 @@ public static RequestPath parseAndCache(HttpServletRequest request) { */ public static RequestPath getParsedRequestPath(ServletRequest request) { RequestPath path = (RequestPath) request.getAttribute(PATH_ATTRIBUTE); - Assert.notNull(path, "Expected parsed RequestPath in request attribute \"" + PATH_ATTRIBUTE + "\"."); + Assert.notNull(path, () -> "Expected parsed RequestPath in request attribute \"" + PATH_ATTRIBUTE + "\"."); return path; } From c5e1a774a5a1e27eb1ca693b663ec37e6583ac41 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 14 Feb 2022 14:31:19 +0100 Subject: [PATCH 687/735] Add bean instance generator infrastructure This commit provides the necessary infrastructure to let components contribute statements that are used to fully instantiate a bean instance. To ease code generation, a dedicated infrastructure to register bean definition is provided in the o.s.beans.factory.generator package. BeanDefinitionRegistrar offers a builder style API that provides a way to hide how injected elements are resolved at runtime and let contributors provide code that may throw a checked exception. BeanInstanceContributor is the interface that components can implement to contribute to a bean instance setup. DefaultBeanInstanceGenerator generates, for a particular bean definition, the necessary statements to instantiate a bean. Closes gh-28047 --- .../generator/BeanInstanceContributor.java | 51 ++ .../generator/BeanParameterGenerator.java | 218 ++++++++ .../DefaultBeanInstanceGenerator.java | 165 ++++++ .../factory/generator/InjectionGenerator.java | 239 +++++++++ .../config/BeanDefinitionRegistrar.java | 408 +++++++++++++++ .../config/InjectedConstructionResolver.java | 175 +++++++ .../config/InjectedElementAttributes.java | 93 ++++ .../config/InjectedElementResolver.java | 75 +++ .../config/InjectedFieldResolver.java | 71 +++ .../config/InjectedMethodResolver.java | 86 ++++ .../generator/config/package-info.java | 9 + .../BeanParameterGeneratorTests.java | 264 ++++++++++ .../DefaultBeanInstanceGeneratorTests.java | 255 ++++++++++ .../generator/InjectionGeneratorTests.java | 269 ++++++++++ .../config/BeanDefinitionRegistrarTests.java | 458 +++++++++++++++++ .../InjectedConstructionResolverTests.java | 476 ++++++++++++++++++ .../InjectedElementAttributesTests.java | 91 ++++ .../config/InjectedFieldResolverTests.java | 78 +++ .../config/InjectedMethodResolverTests.java | 124 +++++ .../InnerComponentConfiguration.java | 36 ++ .../generator/SimpleConfiguration.java | 32 ++ .../generator/factory/NumberHolder.java | 36 ++ .../factory/NumberHolderFactoryBean.java | 45 ++ .../generator/factory/SampleFactory.java | 41 ++ .../injection/InjectionComponent.java | 37 ++ .../generator/property/ConfigurableBean.java | 33 ++ .../ProtectedConstructorComponent.java | 24 + .../visibility/ProtectedFactoryMethod.java | 25 + .../generator/ResolvableTypeGenerator.java | 68 +++ .../aot/hint/ReflectionHints.java | 23 + .../javapoet/support/MultiStatement.java | 26 +- .../ResolvableTypeGeneratorTests.java | 62 +++ .../aot/hint/ReflectionHintsTests.java | 37 +- 33 files changed, 4119 insertions(+), 11 deletions(-) create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceContributor.java create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanParameterGenerator.java create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGenerator.java create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/generator/InjectionGenerator.java create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/generator/config/BeanDefinitionRegistrar.java create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedConstructionResolver.java create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedElementAttributes.java create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedElementResolver.java create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedFieldResolver.java create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedMethodResolver.java create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/generator/config/package-info.java create mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/generator/BeanParameterGeneratorTests.java create mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGeneratorTests.java create mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/generator/InjectionGeneratorTests.java create mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/generator/config/BeanDefinitionRegistrarTests.java create mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedConstructionResolverTests.java create mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedElementAttributesTests.java create mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedFieldResolverTests.java create mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedMethodResolverTests.java create mode 100644 spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/InnerComponentConfiguration.java create mode 100644 spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/SimpleConfiguration.java create mode 100644 spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/factory/NumberHolder.java create mode 100644 spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/factory/NumberHolderFactoryBean.java create mode 100644 spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/factory/SampleFactory.java create mode 100644 spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/injection/InjectionComponent.java create mode 100644 spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/property/ConfigurableBean.java create mode 100644 spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/visibility/ProtectedConstructorComponent.java create mode 100644 spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/visibility/ProtectedFactoryMethod.java create mode 100644 spring-core/src/main/java/org/springframework/aot/generator/ResolvableTypeGenerator.java create mode 100644 spring-core/src/test/java/org/springframework/aot/generator/ResolvableTypeGeneratorTests.java diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceContributor.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceContributor.java new file mode 100644 index 000000000000..338334bbd257 --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceContributor.java @@ -0,0 +1,51 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator; + +import org.springframework.aot.generator.CodeContribution; + +/** + * Strategy interface to be implemented by components that participates in a + * bean instance setup so that the generated code provides an equivalent + * setup. + * + * @author Stephane Nicoll + * @since 6.0 + */ +@FunctionalInterface +public interface BeanInstanceContributor { + + /** + * A {@link BeanInstanceContributor} that does not contribute anything + * to the {@link CodeContribution}. + */ + BeanInstanceContributor NO_OP = contribution -> { }; + + /** + * Contribute to the specified {@link CodeContribution}. + *

    Implementation of this interface can assume the following variables + * to be accessible: + *

      + *
    • {@code beanFactory}: the general {@code DefaultListableBeanFactory}
    • + *
    • {@code instanceContext}: the {@code BeanInstanceContext} callback
    • + *
    • {@code bean}: the variable that refers to the bean instance
    • + *
    + * @param contribution the {@link CodeContribution} to use + */ + void contribute(CodeContribution contribution); + +} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanParameterGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanParameterGenerator.java new file mode 100644 index 000000000000..dccc5b660f55 --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanParameterGenerator.java @@ -0,0 +1,218 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator; + +import java.lang.reflect.Executable; +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import org.springframework.aot.generator.ResolvableTypeGenerator; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanReference; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.ManagedList; +import org.springframework.beans.factory.support.ManagedSet; +import org.springframework.core.ResolvableType; +import org.springframework.javapoet.CodeBlock; +import org.springframework.javapoet.CodeBlock.Builder; +import org.springframework.javapoet.support.MultiCodeBlock; +import org.springframework.lang.Nullable; +import org.springframework.util.ObjectUtils; + +/** + * Support for writing parameters. + * + * @author Stephane Nicoll + * @since 6.0 + */ +public final class BeanParameterGenerator { + + private final ResolvableTypeGenerator typeGenerator = new ResolvableTypeGenerator(); + + private final BiConsumer innerBeanDefinitionWriter; + + + /** + * Create an instance with the callback to use to write an inner bean + * definition. + * @param innerBeanDefinitionWriter the inner bean definition writer + */ + public BeanParameterGenerator(BiConsumer innerBeanDefinitionWriter) { + this.innerBeanDefinitionWriter = innerBeanDefinitionWriter; + } + + /** + * Create an instance with no support for inner bean definitions. + */ + public BeanParameterGenerator() { + this((beanDefinition, builder) -> { + throw new IllegalStateException("Inner bean definition is not supported by this instance"); + }); + } + + + /** + * Write the specified parameter {@code value}. + * @param value the value of the parameter + * @return the value of the parameter + */ + public CodeBlock writeParameterValue(@Nullable Object value) { + return writeParameterValue(value, () -> ResolvableType.forInstance(value)); + } + + /** + * Write the specified parameter {@code value}. + * @param value the value of the parameter + * @param parameterType the type of the parameter + * @return the value of the parameter + */ + public CodeBlock writeParameterValue(@Nullable Object value, Supplier parameterType) { + Builder code = CodeBlock.builder(); + writeParameterValue(code, value, parameterType); + return code.build(); + } + + /** + * Write the parameter types of the specified {@link Executable}. + * @param executable the executable + * @return the parameter types of the executable as a comma separated list + */ + public CodeBlock writeExecutableParameterTypes(Executable executable) { + Class[] parameterTypes = Arrays.stream(executable.getParameters()) + .map(Parameter::getType).toArray(Class[]::new); + return CodeBlock.of(Arrays.stream(parameterTypes).map(d -> "$T.class") + .collect(Collectors.joining(", ")), (Object[]) parameterTypes); + } + + private void writeParameterValue(Builder code, @Nullable Object value, Supplier parameterTypeSupplier) { + if (value == null) { + code.add("null"); + return; + } + ResolvableType parameterType = parameterTypeSupplier.get(); + if (parameterType.isArray()) { + code.add("new $T { ", parameterType.toClass()); + code.add(writeAll(Arrays.asList(ObjectUtils.toObjectArray(value)), + item -> parameterType.getComponentType())); + code.add(" }"); + } + else if (value instanceof List list) { + if (list.isEmpty()) { + code.add("$T.emptyList()", Collections.class); + } + else { + Class listType = (value instanceof ManagedList ? ManagedList.class : List.class); + code.add("$T.of(", listType); + ResolvableType collectionType = parameterType.as(List.class).getGenerics()[0]; + code.add(writeAll(list, item -> collectionType)); + code.add(")"); + } + } + else if (value instanceof Set set) { + if (set.isEmpty()) { + code.add("$T.emptySet()", Collections.class); + } + else { + Class setType = (value instanceof ManagedSet ? ManagedSet.class : Set.class); + code.add("$T.of(", setType); + ResolvableType collectionType = parameterType.as(Set.class).getGenerics()[0]; + code.add(writeAll(set, item -> collectionType)); + code.add(")"); + } + } + else if (value instanceof Map map) { + if (map.size() <= 10) { + code.add("$T.of(", Map.class); + List parameters = new ArrayList<>(); + map.forEach((mapKey, mapValue) -> { + parameters.add(mapKey); + parameters.add(mapValue); + }); + code.add(writeAll(parameters, ResolvableType::forInstance)); + code.add(")"); + } + } + else if (value instanceof Character character) { + String result = '\'' + characterLiteralWithoutSingleQuotes(character) + '\''; + code.add(result); + } + else if (isPrimitiveOrWrapper(value)) { + code.add("$L", value); + } + else if (value instanceof String) { + code.add("$S", value); + } + else if (value instanceof Enum enumValue) { + code.add("$T.$N", enumValue.getClass(), enumValue.name()); + } + else if (value instanceof Class) { + code.add("$T.class", value); + } + else if (value instanceof ResolvableType) { + code.add(this.typeGenerator.generateTypeFor((ResolvableType) value)); + } + else if (value instanceof BeanDefinition) { + this.innerBeanDefinitionWriter.accept((BeanDefinition) value, code); + } + else if (value instanceof BeanReference) { + code.add("new $T($S)", RuntimeBeanReference.class, ((BeanReference) value).getBeanName()); + } + else { + throw new IllegalArgumentException("Parameter of type " + parameterType + " is not supported"); + } + } + + private CodeBlock writeAll(Iterable items, Function elementType) { + MultiCodeBlock multi = new MultiCodeBlock(); + items.forEach(item -> multi.add(code -> + writeParameterValue(code, item, () -> elementType.apply(item)))); + return multi.join(", "); + } + + private boolean isPrimitiveOrWrapper(Object value) { + Class valueType = value.getClass(); + return (valueType.isPrimitive() || valueType == Double.class || valueType == Float.class + || valueType == Long.class || valueType == Integer.class || valueType == Short.class + || valueType == Character.class || valueType == Byte.class || valueType == Boolean.class); + } + + // Copied from com.squareup.javapoet.Util + private static String characterLiteralWithoutSingleQuotes(char c) { + // see https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.6 + return switch (c) { + case '\b' -> "\\b"; /* \u0008: backspace (BS) */ + case '\t' -> "\\t"; /* \u0009: horizontal tab (HT) */ + case '\n' -> "\\n"; /* \u000a: linefeed (LF) */ + case '\f' -> "\\f"; /* \u000c: form feed (FF) */ + case '\r' -> "\\r"; /* \u000d: carriage return (CR) */ + case '\"' -> "\""; /* \u0022: double quote (") */ + case '\'' -> "\\'"; /* \u0027: single quote (') */ + case '\\' -> "\\\\"; /* \u005c: backslash (\) */ + default -> Character.isISOControl(c) ? String.format("\\u%04x", (int) c) : Character.toString(c); + }; + } + +} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGenerator.java new file mode 100644 index 000000000000..8c5006150f5c --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGenerator.java @@ -0,0 +1,165 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.springframework.aot.generator.CodeContribution; +import org.springframework.aot.generator.DefaultCodeContribution; +import org.springframework.aot.generator.ProtectedAccess.Options; +import org.springframework.aot.hint.ExecutableMode; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.javapoet.CodeBlock; +import org.springframework.util.ClassUtils; + +/** + * Write the necessary statements to instantiate a bean. + * + * @author Stephane Nicoll + */ +class DefaultBeanInstanceGenerator { + + private static final Options BEAN_INSTANCE_OPTIONS = new Options(false, true); + + private final Executable instanceCreator; + + private final List contributors; + + private final InjectionGenerator injectionGenerator; + + + DefaultBeanInstanceGenerator(Executable instanceCreator, List contributors) { + this.instanceCreator = instanceCreator; + this.contributors = List.copyOf(contributors); + this.injectionGenerator = new InjectionGenerator(); + } + + /** + * Return the necessary code to instantiate and post-process the bean + * handled by this instance. + * @param runtimeHints the runtime hints instance to use + * @return a code contribution that provides an initialized bean instance + */ + public CodeContribution generateBeanInstance(RuntimeHints runtimeHints) { + DefaultCodeContribution contribution = new DefaultCodeContribution(runtimeHints); + contribution.protectedAccess().analyze(this.instanceCreator, BEAN_INSTANCE_OPTIONS); + if (this.instanceCreator instanceof Constructor constructor) { + writeBeanInstantiation(contribution, constructor); + } + else if (this.instanceCreator instanceof Method method) { + writeBeanInstantiation(contribution, method); + } + return contribution; + } + + private void writeBeanInstantiation(CodeContribution contribution, Constructor constructor) { + Class declaringType = ClassUtils.getUserClass(constructor.getDeclaringClass()); + boolean innerClass = isInnerClass(declaringType); + boolean multiStatements = !this.contributors.isEmpty(); + int minArgs = isInnerClass(declaringType) ? 2 : 1; + CodeBlock.Builder code = CodeBlock.builder(); + // Shortcut for common case + if (!multiStatements && constructor.getParameterTypes().length < minArgs) { + if (innerClass) { + code.add("() -> beanFactory.getBean($T.class).new $L()", + declaringType.getEnclosingClass(), declaringType.getSimpleName()); + } + else { + // Only apply the shortcut if there's one candidate + if (declaringType.getDeclaredConstructors().length > 1) { + code.add("() -> new $T()", declaringType); + } + else { + code.add("$T::new", declaringType); + } + } + contribution.statements().addStatement(code.build()); + return; + } + contribution.runtimeHints().reflection().registerConstructor(constructor, + hint -> hint.withMode(ExecutableMode.INTROSPECT)); + code.add("(instanceContext) ->"); + branch(multiStatements, () -> code.beginControlFlow(""), () -> code.add(" ")); + if (multiStatements) { + code.add("$T bean = ", declaringType); + } + code.add(this.injectionGenerator.writeInstantiation(constructor)); + contribution.statements().addStatement(code.build()); + + if (multiStatements) { + for (BeanInstanceContributor contributor : this.contributors) { + contributor.contribute(contribution); + } + contribution.statements().addStatement("return bean") + .add(codeBlock -> codeBlock.unindent().add("}")); + } + } + + private static boolean isInnerClass(Class type) { + return type.isMemberClass() && !Modifier.isStatic(type.getModifiers()); + } + + private void writeBeanInstantiation(CodeContribution contribution, Method method) { + // Factory method can be introspected + contribution.runtimeHints().reflection().registerMethod(method, + hint -> hint.withMode(ExecutableMode.INTROSPECT)); + List> parameterTypes = new ArrayList<>(Arrays.asList(method.getParameterTypes())); + boolean multiStatements = !this.contributors.isEmpty(); + Class declaringType = method.getDeclaringClass(); + CodeBlock.Builder code = CodeBlock.builder(); + // Shortcut for common case + if (!multiStatements && parameterTypes.isEmpty()) { + code.add("() -> "); + branch(Modifier.isStatic(method.getModifiers()), + () -> code.add("$T", declaringType), + () -> code.add("beanFactory.getBean($T.class)", declaringType)); + code.add(".$L()", method.getName()); + contribution.statements().addStatement(code.build()); + return; + } + code.add("(instanceContext) ->"); + branch(multiStatements, () -> code.beginControlFlow(""), () -> code.add(" ")); + if (multiStatements) { + code.add("$T bean = ", method.getReturnType()); + } + code.add(this.injectionGenerator.writeInstantiation(method)); + contribution.statements().addStatement(code.build()); + if (multiStatements) { + for (BeanInstanceContributor contributor : this.contributors) { + contributor.contribute(contribution); + } + contribution.statements().addStatement("return bean") + .add(codeBlock -> codeBlock.unindent().add("}")); + } + } + + private static void branch(boolean condition, Runnable ifTrue, Runnable ifFalse) { + if (condition) { + ifTrue.run(); + } + else { + ifFalse.run(); + } + } + +} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/InjectionGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/InjectionGenerator.java new file mode 100644 index 000000000000..c4845b339b73 --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/InjectionGenerator.java @@ -0,0 +1,239 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; + +import org.springframework.beans.factory.generator.config.BeanDefinitionRegistrar.BeanInstanceContext; +import org.springframework.javapoet.CodeBlock; +import org.springframework.javapoet.CodeBlock.Builder; +import org.springframework.util.ClassUtils; +import org.springframework.util.ReflectionUtils; + +/** + * Generate the necessary code to {@link #writeInstantiation(Executable) + * create a bean instance} or {@link #writeInjection(Member, boolean) + * inject dependencies}. + *

    + * The generator assumes a number of variables to be accessible: + *

      + *
    • {@code beanFactory}: the general {@code DefaultListableBeanFactory}
    • + *
    • {@code instanceContext}: the {@link BeanInstanceContext} callback
    • + *
    • {@code bean}: the variable that refers to the bean instance
    • + *
    + * + * @author Stephane Nicoll + * @author Brian Clozel + */ +public class InjectionGenerator { + + private final BeanParameterGenerator parameterGenerator = new BeanParameterGenerator(); + + + /** + * Write the necessary code to instantiate an object using the specified + * {@link Executable}. The code is suitable to be assigned to a variable + * or used as a {@literal return} statement. + * @param creator the executable to invoke to create an instance of the + * requested object + * @return the code to instantiate an object using the specified executable + */ + public CodeBlock writeInstantiation(Executable creator) { + if (creator instanceof Constructor constructor) { + return write(constructor); + } + if (creator instanceof Method method) { + return writeMethodInstantiation(method); + } + throw new IllegalArgumentException("Could not handle creator " + creator); + } + + /** + * Write the code to inject a value resolved by {@link BeanInstanceContext} + * in the specified {@link Member}. + * @param member the field or method to inject + * @param required whether the value is required + * @return a statement that injects a value to the specified membmer + */ + public CodeBlock writeInjection(Member member, boolean required) { + if (member instanceof Method method) { + return writeMethodInjection(method, required); + } + if (member instanceof Field field) { + return writeFieldInjection(field, required); + } + throw new IllegalArgumentException("Could not handle member " + member); + } + + private CodeBlock write(Constructor creator) { + Builder code = CodeBlock.builder(); + Class declaringType = ClassUtils.getUserClass(creator.getDeclaringClass()); + boolean innerClass = isInnerClass(declaringType); + Class[] parameterTypes = Arrays.stream(creator.getParameters()).map(Parameter::getType) + .toArray(Class[]::new); + // Shortcut for common case + if (innerClass && parameterTypes.length == 1) { + code.add("beanFactory.getBean($T.class).new $L()", declaringType.getEnclosingClass(), + declaringType.getSimpleName()); + return code.build(); + } + if (parameterTypes.length == 0) { + code.add("new $T()", declaringType); + return code.build(); + } + boolean isAmbiguous = Arrays.stream(creator.getDeclaringClass().getDeclaredConstructors()) + .filter(constructor -> constructor.getParameterCount() == parameterTypes.length).count() > 1; + code.add("instanceContext.create(beanFactory, (attributes) ->"); + List parameters = resolveParameters(creator.getParameters(), isAmbiguous); + if (innerClass) { // Remove the implicit argument + parameters.remove(0); + } + + code.add(" "); + if (innerClass) { + code.add("beanFactory.getBean($T.class).new $L(", declaringType.getEnclosingClass(), + declaringType.getSimpleName()); + } + else { + code.add("new $T(", declaringType); + } + for (int i = 0; i < parameters.size(); i++) { + code.add(parameters.get(i)); + if (i < parameters.size() - 1) { + code.add(", "); + } + } + code.add(")"); + code.add(")"); + return code.build(); + } + + private static boolean isInnerClass(Class type) { + return type.isMemberClass() && !Modifier.isStatic(type.getModifiers()); + } + + private CodeBlock writeMethodInstantiation(Method injectionPoint) { + if (injectionPoint.getParameterCount() == 0) { + Builder code = CodeBlock.builder(); + Class declaringType = injectionPoint.getDeclaringClass(); + if (Modifier.isStatic(injectionPoint.getModifiers())) { + code.add("$T", declaringType); + } + else { + code.add("beanFactory.getBean($T.class)", declaringType); + } + code.add(".$L()", injectionPoint.getName()); + return code.build(); + } + return write(injectionPoint, code -> code.add(".create(beanFactory, (attributes) ->"), true); + } + + private CodeBlock writeMethodInjection(Method injectionPoint, boolean required) { + Consumer attributesResolver = code -> { + if (required) { + code.add(".invoke(beanFactory, (attributes) ->"); + } + else { + code.add(".resolve(beanFactory, false).ifResolved((attributes) ->"); + } + }; + return write(injectionPoint, attributesResolver, false); + } + + private CodeBlock write(Method injectionPoint, Consumer attributesResolver, boolean instantiation) { + Builder code = CodeBlock.builder(); + code.add("instanceContext"); + if (!instantiation) { + code.add(".method($S, ", injectionPoint.getName()); + code.add(this.parameterGenerator.writeExecutableParameterTypes(injectionPoint)); + code.add(")\n").indent().indent(); + } + attributesResolver.accept(code); + List parameters = resolveParameters(injectionPoint.getParameters(), false); + code.add(" "); + if (instantiation) { + if (Modifier.isStatic(injectionPoint.getModifiers())) { + code.add("$T", injectionPoint.getDeclaringClass()); + } + else { + code.add("beanFactory.getBean($T.class)", injectionPoint.getDeclaringClass()); + } + } + else { + code.add("bean"); + } + code.add(".$L(", injectionPoint.getName()); + code.add(CodeBlock.join(parameters, ", ")); + code.add(")"); + code.add(")"); + if (!instantiation) { + code.unindent().unindent(); + } + return code.build(); + } + + CodeBlock writeFieldInjection(Field injectionPoint, boolean required) { + Builder code = CodeBlock.builder(); + code.add("instanceContext.field($S, $T.class", injectionPoint.getName(), injectionPoint.getType()); + code.add(")\n").indent().indent(); + if (required) { + code.add(".invoke(beanFactory, (attributes) ->"); + } + else { + code.add(".resolve(beanFactory, false).ifResolved((attributes) ->"); + } + boolean hasAssignment = Modifier.isPrivate(injectionPoint.getModifiers()); + if (hasAssignment) { + code.beginControlFlow(""); + String fieldName = String.format("%sField", injectionPoint.getName()); + code.addStatement("$T $L = $T.findField($T.class, $S, $T.class)", Field.class, fieldName, ReflectionUtils.class, + injectionPoint.getDeclaringClass(), injectionPoint.getName(), injectionPoint.getType()); + code.addStatement("$T.makeAccessible($L)", ReflectionUtils.class, fieldName); + code.addStatement("$T.setField($L, bean, attributes.get(0))", ReflectionUtils.class, fieldName); + code.unindent().add("}"); + } + else { + code.add(" bean.$L = attributes.get(0)", injectionPoint.getName()); + } + code.add(")").unindent().unindent(); + return code.build(); + } + + private List resolveParameters(Parameter[] parameters, boolean shouldCast) { + List parameterValues = new ArrayList<>(); + for (int i = 0; i < parameters.length; i++) { + if (shouldCast) { + parameterValues.add(CodeBlock.of("attributes.get($L, $T.class)", i, parameters[i].getType())); + } + else { + parameterValues.add(CodeBlock.of("attributes.get($L)", i)); + } + } + return parameterValues; + } + +} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/BeanDefinitionRegistrar.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/BeanDefinitionRegistrar.java new file mode 100644 index 000000000000..149ddcc906af --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/BeanDefinitionRegistrar.java @@ -0,0 +1,408 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator.config; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.core.MethodIntrospector; +import org.springframework.core.ResolvableType; +import org.springframework.lang.Nullable; +import org.springframework.util.ObjectUtils; +import org.springframework.util.ReflectionUtils; + +/** + * {@link BeanDefinition} registration mechanism offering transparent + * dependency resolution, as well as exception management. + * + *

    Used by code generators and for internal use within the framework + * only. + * + * @author Stephane Nicoll + * @since 6.0 + */ +public final class BeanDefinitionRegistrar { + + private static final Log logger = LogFactory.getLog(BeanDefinitionRegistrar.class); + + @Nullable + private final String beanName; + + private final Class beanClass; + + @Nullable + private final ResolvableType beanType; + + private final BeanDefinitionBuilder builder; + + private final List> customizers; + + @Nullable + private Executable instanceCreator; + + @Nullable + private RootBeanDefinition beanDefinition; + + + private BeanDefinitionRegistrar(@Nullable String beanName, Class beanClass, @Nullable ResolvableType beanType) { + this.beanName = beanName; + this.beanClass = beanClass; + this.beanType = beanType; + this.builder = BeanDefinitionBuilder.rootBeanDefinition(beanClass); + this.customizers = new ArrayList<>(); + } + + + /** + * Initialize the registration of a bean with the specified name and type. + * @param beanName the name of the bean + * @param beanType the type of the bean + * @return a registrar for the specified bean + */ + public static BeanDefinitionRegistrar of(String beanName, ResolvableType beanType) { + return new BeanDefinitionRegistrar(beanName, beanType.toClass(), beanType); + } + + /** + * Initialize the registration of a bean with the specified name and type. + * @param beanName the name of the bean + * @param beanType the type of the bean + * @return a registrar for the specified bean + */ + public static BeanDefinitionRegistrar of(String beanName, Class beanType) { + return new BeanDefinitionRegistrar(beanName, beanType, null); + } + + /** + * Initialize the registration of an inner bean with the specified type. + * @param beanType the type of the inner bean + * @return a registrar for the specified inner bean + */ + public static BeanDefinitionRegistrar inner(ResolvableType beanType) { + return new BeanDefinitionRegistrar(null, beanType.toClass(), beanType); + } + + /** + * Initialize the registration of an inner bean with the specified type. + * @param beanType the type of the inner bean + * @return a registrar for the specified inner bean + */ + public static BeanDefinitionRegistrar inner(Class beanType) { + return new BeanDefinitionRegistrar(null, beanType, null); + } + + /** + * Customize the {@link RootBeanDefinition} using the specified consumer. + * @param bd a consumer for the bean definition + * @return {@code this}, to facilitate method chaining + */ + public BeanDefinitionRegistrar customize(ThrowableConsumer bd) { + this.customizers.add(bd); + return this; + } + + /** + * Specify the factory method to use to instantiate the bean. + * @param declaredType the {@link Method#getDeclaringClass() declared type} + * of the factory method. + * @param name the name of the method + * @param parameterTypes the parameter types of the method + * @return {@code this}, to facilitate method chaining + * @see RootBeanDefinition#getResolvedFactoryMethod() + */ + public BeanDefinitionRegistrar withFactoryMethod(Class declaredType, String name, Class... parameterTypes) { + this.instanceCreator = getMethod(declaredType, name, parameterTypes); + return this; + } + + /** + * Specify the constructor to use to instantiate the bean. + * @param parameterTypes the parameter types of the constructor + * @return {@code this}, to facilitate method chaining + */ + public BeanDefinitionRegistrar withConstructor(Class... parameterTypes) { + this.instanceCreator = getConstructor(this.beanClass, parameterTypes); + return this; + } + + /** + * Specify how the bean instance should be created and initialized, using + * the {@link BeanInstanceContext} to resolve dependencies if necessary. + * @param instanceContext the {@link BeanInstanceContext} to use + * @return {@code this}, to facilitate method chaining + */ + public BeanDefinitionRegistrar instanceSupplier(ThrowableFunction instanceContext) { + return customize(beanDefinition -> beanDefinition.setInstanceSupplier(() -> + instanceContext.apply(createBeanInstanceContext()))); + } + + /** + * Specify how the bean instance should be created and initialized. + * @return {@code this}, to facilitate method chaining + */ + public BeanDefinitionRegistrar instanceSupplier(ThrowableSupplier instanceSupplier) { + return customize(beanDefinition -> beanDefinition.setInstanceSupplier(instanceSupplier)); + } + + /** + * Register the {@link RootBeanDefinition} defined by this instance to + * the specified bean factory. + * @param beanFactory the bean factory to use + */ + public void register(DefaultListableBeanFactory beanFactory) { + if (logger.isDebugEnabled()) { + logger.debug("Register bean definition with name '" + this.beanName + "'"); + } + BeanDefinition beanDefinition = toBeanDefinition(); + if (this.beanName == null) { + throw new IllegalStateException("Bean name not set. Could not register " + beanDefinition); + } + beanFactory.registerBeanDefinition(this.beanName, beanDefinition); + } + + /** + * Return the {@link RootBeanDefinition} defined by this instance. + * @return the bean definition + */ + public RootBeanDefinition toBeanDefinition() { + try { + this.beanDefinition = createBeanDefinition(); + return this.beanDefinition; + } + catch (Exception ex) { + throw new FatalBeanException("Failed to create bean definition for bean with name '" + this.beanName + "'", ex); + } + } + + private RootBeanDefinition createBeanDefinition() { + RootBeanDefinition bd = (RootBeanDefinition) this.builder.getBeanDefinition(); + if (this.beanType != null) { + bd.setTargetType(this.beanType); + } + if (this.instanceCreator instanceof Method) { + bd.setResolvedFactoryMethod((Method) this.instanceCreator); + } + this.customizers.forEach(customizer -> customizer.accept(bd)); + return bd; + } + + private BeanInstanceContext createBeanInstanceContext() { + String resolvedBeanName = this.beanName != null ? this.beanName : createInnerBeanName(); + return new BeanInstanceContext(resolvedBeanName, this.beanClass); + } + + private String createInnerBeanName() { + return "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR + + (this.beanDefinition != null ? ObjectUtils.getIdentityHexString(this.beanDefinition) : 0); + } + + @Nullable + private BeanDefinition resolveBeanDefinition(DefaultListableBeanFactory beanFactory) { + return this.beanDefinition; + } + + private static Constructor getConstructor(Class beanType, Class... parameterTypes) { + try { + return beanType.getDeclaredConstructor(parameterTypes); + } + catch (NoSuchMethodException ex) { + String message = String.format("No constructor with type(s) [%s] found on %s", + toCommaSeparatedNames(parameterTypes), beanType.getName()); + throw new IllegalArgumentException(message, ex); + } + } + + private static Method getMethod(Class declaredType, String methodName, Class... parameterTypes) { + Method method = ReflectionUtils.findMethod(declaredType, methodName, parameterTypes); + if (method == null) { + String message = String.format("No method '%s' with type(s) [%s] found on %s", methodName, + toCommaSeparatedNames(parameterTypes), declaredType.getName()); + throw new IllegalArgumentException(message); + } + return MethodIntrospector.selectInvocableMethod(method, declaredType); + } + + private static String toCommaSeparatedNames(Class... parameterTypes) { + return Arrays.stream(parameterTypes).map(Class::getName).collect(Collectors.joining(", ")); + } + + /** + * Callback interface used by instance suppliers that need to resolve + * dependencies for the {@link Executable} used to create the instance + * as well as any {@link Member} that should be handled by the context. + */ + public final class BeanInstanceContext { + + private final String beanName; + + private final Class beanType; + + private BeanInstanceContext(String beanName, Class beanType) { + this.beanName = beanName; + this.beanType = beanType; + } + + /** + * Return a bean instance using the specified {@code factory}. + * @param beanFactory the bean factory to use + * @param factory a function that returns a bean instance based on + * the resolved attributes required by its instance creator + * @param the type of the bean + * @return the bean instance + */ + public T create(DefaultListableBeanFactory beanFactory, ThrowableFunction factory) { + return resolveInstanceCreator(BeanDefinitionRegistrar.this.instanceCreator).create(beanFactory, factory); + } + + private InjectedElementResolver resolveInstanceCreator(@Nullable Executable instanceCreator) { + if (instanceCreator instanceof Method) { + return new InjectedConstructionResolver(instanceCreator, instanceCreator.getDeclaringClass(), this.beanName, + BeanDefinitionRegistrar.this::resolveBeanDefinition); + } + if (instanceCreator instanceof Constructor) { + return new InjectedConstructionResolver(instanceCreator, this.beanType, this.beanName, + BeanDefinitionRegistrar.this::resolveBeanDefinition); + } + throw new IllegalStateException("No factory method or constructor is set"); + } + + /** + * Create an {@link InjectedElementResolver} for the specified field. + * @param name the name of the field + * @param type the type of the field + * @return a resolved for the specified field + */ + public InjectedElementResolver field(String name, Class type) { + return new InjectedFieldResolver(getField(name, type), this.beanName); + } + + /** + * Create an {@link InjectedElementResolver} for the specified bean method. + * @param name the name of the method on the target bean + * @param parameterTypes the method parameter types + * @return a resolved for the specified bean method + */ + public InjectedElementResolver method(String name, Class... parameterTypes) { + return new InjectedMethodResolver(getMethod(this.beanType, name, parameterTypes), this.beanType, this.beanName); + } + + private Field getField(String fieldName, Class fieldType) { + Field field = ReflectionUtils.findField(this.beanType, fieldName, fieldType); + if (field == null) { + throw new IllegalArgumentException("No field '" + fieldName + "' with type " + fieldType.getName() + " found on " + this.beanType); + } + return field; + } + + } + + /** + * A {@link Consumer} that allows to invoke code that throws a checked exception. + * + * @author Stephane Nicoll + * @param the type of the input to the operation + */ + @FunctionalInterface + public interface ThrowableConsumer extends Consumer { + + void acceptWithException(T t) throws Exception; + + @Override + default void accept(T t) { + try { + acceptWithException(t); + } + catch (RuntimeException ex) { + throw ex; + } + catch (Exception ex) { + throw new RuntimeException(ex.getMessage(), ex); + } + } + + } + + /** + * A {@link Function} that allows to invoke code that throws a checked exception. + * + * @author Stephane Nicoll + * @param the type of the input to the function + * @param the type of the result of the function + */ + @FunctionalInterface + public interface ThrowableFunction extends Function { + + R applyWithException(T t) throws Exception; + + @Override + default R apply(T t) { + try { + return applyWithException(t); + } + catch (RuntimeException ex) { + throw ex; + } + catch (Exception ex) { + throw new RuntimeException(ex.getMessage(), ex); + } + } + } + + /** + * A {@link Supplier} that allows to invoke code that throws a checked exception. + * + * @author Stephane Nicoll + * @param the type of results supplied by this supplier + */ + public interface ThrowableSupplier extends Supplier { + + T getWithException() throws Exception; + + @Override + default T get() { + try { + return getWithException(); + } + catch (RuntimeException ex) { + throw ex; + } + catch (Exception ex) { + throw new RuntimeException(ex.getMessage(), ex); + } + } + } + +} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedConstructionResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedConstructionResolver.java new file mode 100644 index 000000000000..d1257a7eac7d --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedConstructionResolver.java @@ -0,0 +1,175 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator.config; + +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringJoiner; +import java.util.function.Function; +import java.util.function.Supplier; + +import org.springframework.beans.BeansException; +import org.springframework.beans.TypeConverter; +import org.springframework.beans.factory.InjectionPoint; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.UnsatisfiedDependencyException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConstructorArgumentValues; +import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder; +import org.springframework.beans.factory.config.DependencyDescriptor; +import org.springframework.beans.factory.support.BeanDefinitionValueResolver; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.core.CollectionFactory; +import org.springframework.core.MethodParameter; + +/** + * An {@link InjectedElementResolver} for an {@link Executable} that creates + * a bean instance. + * + * @author Stephane Nicoll + */ + +class InjectedConstructionResolver implements InjectedElementResolver { + + private final Executable executable; + + private final Class targetType; + + private final String beanName; + + private final Function beanDefinitionResolver; + + InjectedConstructionResolver(Executable executable, Class targetType, String beanName, + Function beanDefinitionResolver) { + this.executable = executable; + this.targetType = targetType; + this.beanName = beanName; + this.beanDefinitionResolver = beanDefinitionResolver; + } + + + Executable getExecutable() { + return this.executable; + } + + @Override + public InjectedElementAttributes resolve(DefaultListableBeanFactory beanFactory, boolean required) { + int argumentCount = this.executable.getParameterCount(); + List arguments = new ArrayList<>(); + Set autowiredBeans = new LinkedHashSet<>(argumentCount); + TypeConverter typeConverter = beanFactory.getTypeConverter(); + ConstructorArgumentValues argumentValues = resolveArgumentValues(beanFactory); + for (int i = 0; i < argumentCount; i++) { + MethodParameter methodParam = createMethodParameter(i); + ValueHolder valueHolder = argumentValues.getIndexedArgumentValue(i, null); + if (valueHolder != null) { + if (valueHolder.isConverted()) { + arguments.add(valueHolder.getConvertedValue()); + } + else { + Object userValue = beanFactory.getTypeConverter() + .convertIfNecessary(valueHolder.getValue(), methodParam.getParameterType()); + arguments.add(userValue); + } + } + else { + DependencyDescriptor depDescriptor = new DependencyDescriptor(methodParam, true); + depDescriptor.setContainingClass(this.targetType); + try { + Object arg = resolveDependency(() -> beanFactory.resolveDependency( + depDescriptor, this.beanName, autowiredBeans, typeConverter), methodParam.getParameterType()); + arguments.add(arg); + } + catch (BeansException ex) { + throw new UnsatisfiedDependencyException(null, this.beanName, new InjectionPoint(methodParam), ex); + } + } + } + return new InjectedElementAttributes(arguments); + } + + private Object resolveDependency(Supplier resolvedDependency, Class dependencyType) { + try { + return resolvedDependency.get(); + } + catch (NoSuchBeanDefinitionException ex) { + // Single constructor or factory method -> let's return an empty array/collection + // for e.g. a vararg or a non-null List/Set/Map parameter. + if (dependencyType.isArray()) { + return Array.newInstance(dependencyType.getComponentType(), 0); + } + else if (CollectionFactory.isApproximableCollectionType(dependencyType)) { + return CollectionFactory.createCollection(dependencyType, 0); + } + else if (CollectionFactory.isApproximableMapType(dependencyType)) { + return CollectionFactory.createMap(dependencyType, 0); + } + throw ex; + } + } + + private ConstructorArgumentValues resolveArgumentValues(DefaultListableBeanFactory beanFactory) { + ConstructorArgumentValues resolvedValues = new ConstructorArgumentValues(); + BeanDefinition beanDefinition = this.beanDefinitionResolver.apply(beanFactory); + if (beanDefinition == null || !beanDefinition.hasConstructorArgumentValues()) { + return resolvedValues; + } + ConstructorArgumentValues argumentValues = beanDefinition.getConstructorArgumentValues(); + BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(beanFactory, + this.beanName, beanDefinition); + for (Map.Entry entry : argumentValues.getIndexedArgumentValues().entrySet()) { + int index = entry.getKey(); + ValueHolder valueHolder = entry.getValue(); + if (valueHolder.isConverted()) { + resolvedValues.addIndexedArgumentValue(index, valueHolder); + } + else { + Object resolvedValue = + valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue()); + ValueHolder resolvedValueHolder = + new ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName()); + resolvedValueHolder.setSource(valueHolder); + resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder); + } + } + return resolvedValues; + } + + private MethodParameter createMethodParameter(int index) { + if (this.executable instanceof Constructor) { + return new MethodParameter((Constructor) this.executable, index); + } + else { + return new MethodParameter((Method) this.executable, index); + } + } + + @Override + public String toString() { + return new StringJoiner(", ", InjectedConstructionResolver.class.getSimpleName() + "[", "]") + .add("executable=" + this.executable) + .toString(); + } + +} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedElementAttributes.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedElementAttributes.java new file mode 100644 index 000000000000..a8677f2ee140 --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedElementAttributes.java @@ -0,0 +1,93 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator.config; + +import java.util.List; +import java.util.function.Consumer; + +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +/** + * Resolved attributes of an injected element. + * + * @author Stephane Nicoll + * @since 6.0 + */ +public class InjectedElementAttributes { + + @Nullable + private final List attributes; + + + InjectedElementAttributes(@Nullable List attributes) { + this.attributes = attributes; + } + + + /** + * Specify if the attributes have been resolved. + * @return the resolution of the injection + */ + public boolean isResolved() { + return (this.attributes != null); + } + + /** + * Run the specified {@linkplain Runnable task} only if this instance is + * {@link #isResolved() resolved}. + * @param task the task to invoke if attributes are available + */ + public void ifResolved(Runnable task) { + if (isResolved()) { + task.run(); + } + } + + /** + * Invoke the specified {@link Consumer} with the resolved attributes. + * @param attributes the consumer to invoke if this instance is resolved + */ + public void ifResolved(BeanDefinitionRegistrar.ThrowableConsumer attributes) { + ifResolved(() -> attributes.accept(this)); + } + + /** + * Return the resolved attribute at the specified index. + * @param index the attribute index + * @param the type of the attribute + * @return the attribute + */ + @SuppressWarnings("unchecked") + public T get(int index) { + Assert.notNull(this.attributes, "Attributes must not be null"); + return (T) this.attributes.get(index); + } + + /** + * Return the resolved attribute at the specified index. + * @param index the attribute index + * @param type the attribute type + * @param the type of the attribute + * @return the attribute + */ + @SuppressWarnings("unchecked") + public T get(int index, Class type) { + Assert.notNull(this.attributes, "Attributes must not be null"); + return (T) this.attributes.get(index); + } +} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedElementResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedElementResolver.java new file mode 100644 index 000000000000..5e87e10a289c --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedElementResolver.java @@ -0,0 +1,75 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator.config; + +import org.springframework.beans.factory.support.DefaultListableBeanFactory; + +/** + * Resolve the attributes of an injected element such as a {@code Constructor} + * or a factory {@code Method}. + * + * @author Stephane Nicoll + * @since 6.0 + */ +public interface InjectedElementResolver { + + /** + * Resolve the attributes using the specified bean factory. + * @param beanFactory the bean factory to use + * @return the resolved attributes + */ + default InjectedElementAttributes resolve(DefaultListableBeanFactory beanFactory) { + return resolve(beanFactory, true); + } + + /** + * Resolve the attributes using the specified bean factory. + * @param beanFactory the bean factory to use + * @param required whether the injection point is mandatory + * @return the resolved attributes + */ + InjectedElementAttributes resolve(DefaultListableBeanFactory beanFactory, boolean required); + + /** + * Invoke the specified consumer with the resolved + * {@link InjectedElementAttributes attributes}. + * @param beanFactory the bean factory to use to resolve the attributes + * @param attributes a consumer of the resolved attributes + */ + default void invoke(DefaultListableBeanFactory beanFactory, + BeanDefinitionRegistrar.ThrowableConsumer attributes) { + + InjectedElementAttributes elements = resolve(beanFactory); + attributes.accept(elements); + } + + /** + * Create an instance based on the resolved + * {@link InjectedElementAttributes attributes}. + * @param beanFactory the bean factory to use to resolve the attributes + * @param factory a factory to create the instance based on the resolved attributes + * @param the type of the instance + * @return a new instance + */ + default T create(DefaultListableBeanFactory beanFactory, + BeanDefinitionRegistrar.ThrowableFunction factory) { + + InjectedElementAttributes attributes = resolve(beanFactory); + return factory.apply(attributes); + } + +} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedFieldResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedFieldResolver.java new file mode 100644 index 000000000000..a7d35c2ff03d --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedFieldResolver.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator.config; + +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.springframework.beans.BeansException; +import org.springframework.beans.TypeConverter; +import org.springframework.beans.factory.InjectionPoint; +import org.springframework.beans.factory.UnsatisfiedDependencyException; +import org.springframework.beans.factory.config.DependencyDescriptor; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; + +/** + * An {@link InjectedElementResolver} for a {@link Field}. + * + * @author Stephane Nicoll + */ +class InjectedFieldResolver implements InjectedElementResolver { + + private final Field field; + + private final String beanName; + + + /** + * Create a new instance. + * @param field the field to handle + * @param beanName the name of the bean, or {@code null} + */ + InjectedFieldResolver(Field field, String beanName) { + this.field = field; + this.beanName = beanName; + } + + @Override + public InjectedElementAttributes resolve(DefaultListableBeanFactory beanFactory, boolean required) { + DependencyDescriptor desc = new DependencyDescriptor(this.field, required); + desc.setContainingClass(this.field.getType()); + Set autowiredBeanNames = new LinkedHashSet<>(1); + TypeConverter typeConverter = beanFactory.getTypeConverter(); + try { + Object value = beanFactory.resolveDependency(desc, this.beanName, autowiredBeanNames, typeConverter); + if (value == null && !required) { + return new InjectedElementAttributes(null); + } + return new InjectedElementAttributes(Collections.singletonList(value)); + } + catch (BeansException ex) { + throw new UnsatisfiedDependencyException(null, this.beanName, new InjectionPoint(this.field), ex); + } + } + +} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedMethodResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedMethodResolver.java new file mode 100644 index 000000000000..c58d61673428 --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/InjectedMethodResolver.java @@ -0,0 +1,86 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator.config; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.springframework.beans.BeansException; +import org.springframework.beans.TypeConverter; +import org.springframework.beans.factory.InjectionPoint; +import org.springframework.beans.factory.UnsatisfiedDependencyException; +import org.springframework.beans.factory.config.DependencyDescriptor; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.core.MethodParameter; + +/** + * An {@link InjectedElementResolver} for a {@link Method}. + * + * @author Stephane Nicoll + */ +class InjectedMethodResolver implements InjectedElementResolver { + + private final Method method; + + private final Class target; + + private final String beanName; + + + /** + * Create a new instance. + * @param method the method to handle + * @param target the type on which the method is declared + * @param beanName the name of the bean, or {@code null} + */ + InjectedMethodResolver(Method method, Class target, String beanName) { + this.method = method; + this.target = target; + this.beanName = beanName; + } + + + @Override + public InjectedElementAttributes resolve(DefaultListableBeanFactory beanFactory, boolean required) { + int argumentCount = this.method.getParameterCount(); + List arguments = new ArrayList<>(); + Set autowiredBeans = new LinkedHashSet<>(argumentCount); + TypeConverter typeConverter = beanFactory.getTypeConverter(); + for (int i = 0; i < argumentCount; i++) { + MethodParameter methodParam = new MethodParameter(this.method, i); + DependencyDescriptor depDescriptor = new DependencyDescriptor(methodParam, required); + depDescriptor.setContainingClass(this.target); + try { + Object arg = beanFactory.resolveDependency(depDescriptor, this.beanName, autowiredBeans, typeConverter); + if (arg == null && !required) { + arguments = null; + break; + } + arguments.add(arg); + } + catch (BeansException ex) { + throw new UnsatisfiedDependencyException(null, this.beanName, new InjectionPoint(methodParam), ex); + } + } + return new InjectedElementAttributes(arguments); + } + +} + diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/package-info.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/package-info.java new file mode 100644 index 000000000000..821c57180f6c --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/package-info.java @@ -0,0 +1,9 @@ +/** + * Classes used in generated code to ease bean registration. + */ +@NonNullApi +@NonNullFields +package org.springframework.beans.factory.generator.config; + +import org.springframework.lang.NonNullApi; +import org.springframework.lang.NonNullFields; diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/generator/BeanParameterGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/generator/BeanParameterGeneratorTests.java new file mode 100644 index 000000000000..8e85c3cdf075 --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/beans/factory/generator/BeanParameterGeneratorTests.java @@ -0,0 +1,264 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator; + +import java.io.StringWriter; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.time.temporal.ChronoUnit; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import org.springframework.beans.factory.config.BeanReference; +import org.springframework.beans.factory.support.ManagedList; +import org.springframework.beans.factory.support.ManagedSet; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.core.ResolvableType; +import org.springframework.core.io.ResourceLoader; +import org.springframework.javapoet.support.CodeSnippet; +import org.springframework.util.ReflectionUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link BeanParameterGenerator}. + * + * @author Stephane Nicoll + */ +class BeanParameterGeneratorTests { + + private final BeanParameterGenerator generator = new BeanParameterGenerator(); + + @Test + void writeCharArray() { + char[] value = new char[] { 'v', 'a', 'l', 'u', 'e' }; + assertThat(write(value, ResolvableType.forArrayComponent(ResolvableType.forClass(char.class)))) + .isEqualTo("new char[] { 'v', 'a', 'l', 'u', 'e' }"); + } + + @Test + void writeStringArray() { + String[] value = new String[] { "a", "test" }; + assertThat(write(value, ResolvableType.forArrayComponent(ResolvableType.forClass(String.class)))) + .isEqualTo("new String[] { \"a\", \"test\" }"); + } + + @Test + void writeStringList() { + List value = List.of("a", "test"); + CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(List.class, String.class)); + assertThat(code.getSnippet()).isEqualTo( + "List.of(\"a\", \"test\")"); + assertThat(code.hasImport(List.class)).isTrue(); + } + + @Test + void writeStringManagedList() { + ManagedList value = ManagedList.of("a", "test"); + CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(List.class, String.class)); + assertThat(code.getSnippet()).isEqualTo( + "ManagedList.of(\"a\", \"test\")"); + assertThat(code.hasImport(ManagedList.class)).isTrue(); + } + + @Test + void writeEmptyList() { + List value = List.of(); + CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(List.class, String.class)); + assertThat(code.getSnippet()).isEqualTo("Collections.emptyList()"); + assertThat(code.hasImport(Collections.class)).isTrue(); + } + + @Test + void writeStringSet() { + Set value = Set.of("a", "test"); + CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(Set.class, String.class)); + assertThat(code.getSnippet()).startsWith("Set.of(").contains("a").contains("test"); + assertThat(code.hasImport(Set.class)).isTrue(); + } + + @Test + void writeStringManagedSet() { + Set value = ManagedSet.of("a", "test"); + CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(Set.class, String.class)); + assertThat(code.getSnippet()).isEqualTo( + "ManagedSet.of(\"a\", \"test\")"); + assertThat(code.hasImport(ManagedSet.class)).isTrue(); + } + + @Test + void writeEmptySet() { + Set value = Set.of(); + CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(Set.class, String.class)); + assertThat(code.getSnippet()).isEqualTo("Collections.emptySet()"); + assertThat(code.hasImport(Collections.class)).isTrue(); + } + + @Test + void writeMap() { + Map value = new LinkedHashMap<>(); + value.put("name", "Hello"); + value.put("counter", 42); + assertThat(write(value)).isEqualTo("Map.of(\"name\", \"Hello\", \"counter\", 42)"); + } + + @Test + void writeMapWithEnum() { + Map value = new HashMap<>(); + value.put("unit", ChronoUnit.DAYS); + assertThat(write(value)).isEqualTo("Map.of(\"unit\", ChronoUnit.DAYS)"); + } + + @Test + void writeEmptyMap() { + assertThat(write(Map.of())).isEqualTo("Map.of()"); + } + + @Test + void writeString() { + assertThat(write("test", ResolvableType.forClass(String.class))).isEqualTo("\"test\""); + } + + @Test + void writeCharEscapeBackslash() { + assertThat(write('\\', ResolvableType.forType(char.class))).isEqualTo("'\\\\'"); + } + + @ParameterizedTest + @MethodSource("primitiveValues") + void writePrimitiveValue(Object value, String parameter) { + assertThat(write(value, ResolvableType.forClass(value.getClass()))).isEqualTo(parameter); + } + + private static Stream primitiveValues() { + return Stream.of(Arguments.of((short) 0, "0"), Arguments.of((1), "1"), Arguments.of(2L, "2"), + Arguments.of(2.5d, "2.5"), Arguments.of(2.7f, "2.7"), Arguments.of('c', "'c'"), + Arguments.of((byte) 1, "1"), Arguments.of(true, "true")); + } + + @Test + void writeEnum() { + assertThat(write(ChronoUnit.DAYS, ResolvableType.forClass(ChronoUnit.class))) + .isEqualTo("ChronoUnit.DAYS"); + } + + @Test + void writeClass() { + assertThat(write(Integer.class, ResolvableType.forClass(Class.class))) + .isEqualTo("Integer.class"); + } + + @Test + void writeResolvableType() { + ResolvableType type = ResolvableType.forClassWithGenerics(Consumer.class, Integer.class); + assertThat(write(type, type)) + .isEqualTo("ResolvableType.forClassWithGenerics(Consumer.class, Integer.class)"); + } + + @Test + void writeExecutableParameterTypesWithConstructor() { + Constructor constructor = TestSample.class.getDeclaredConstructors()[0]; + assertThat(CodeSnippet.process(this.generator.writeExecutableParameterTypes(constructor))) + .isEqualTo("String.class, ResourceLoader.class"); + } + + @Test + void writeExecutableParameterTypesWithNoArgConstructor() { + Constructor constructor = BeanParameterGeneratorTests.class.getDeclaredConstructors()[0]; + assertThat(CodeSnippet.process(this.generator.writeExecutableParameterTypes(constructor))) + .isEmpty(); + } + + @Test + void writeExecutableParameterTypesWithMethod() { + Method method = ReflectionUtils.findMethod(TestSample.class, "createBean", String.class, Integer.class); + assertThat(CodeSnippet.process(this.generator.writeExecutableParameterTypes(method))) + .isEqualTo("String.class, Integer.class"); + } + + @Test + void writeNull() { + assertThat(write(null)).isEqualTo("null"); + } + + @Test + void writeBeanReference() { + BeanReference beanReference = mock(BeanReference.class); + given(beanReference.getBeanName()).willReturn("testBean"); + assertThat(write(beanReference)).isEqualTo("new RuntimeBeanReference(\"testBean\")"); + } + + @Test + void writeBeanDefinitionCallsConsumer() { + BeanParameterGenerator customGenerator = new BeanParameterGenerator( + ((beanDefinition, builder) -> builder.add("test"))); + assertThat(CodeSnippet.process(customGenerator.writeParameterValue(new RootBeanDefinition()))).isEqualTo("test"); + } + + @Test + void writeBeanDefinitionWithoutConsumerFails() { + BeanParameterGenerator customGenerator = new BeanParameterGenerator(); + assertThatIllegalStateException().isThrownBy(() -> customGenerator + .writeParameterValue(new RootBeanDefinition())); + } + + @Test + void writeUnsupportedParameter() { + assertThatIllegalArgumentException().isThrownBy(() -> write(new StringWriter())) + .withMessageContaining(StringWriter.class.getName()); + } + + private String write(Object value) { + return CodeSnippet.process(this.generator.writeParameterValue(value)); + } + + private String write(Object value, ResolvableType resolvableType) { + return codeSnippet(value, resolvableType).getSnippet(); + } + + private CodeSnippet codeSnippet(Object value, ResolvableType resolvableType) { + return CodeSnippet.of(this.generator.writeParameterValue(value, () -> resolvableType)); + } + + + @SuppressWarnings("unused") + static class TestSample { + + public TestSample(String test, ResourceLoader resourceLoader) { + } + + String createBean(String name, Integer counter) { + return "test"; + } + } + +} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGeneratorTests.java new file mode 100644 index 000000000000..d780d868145c --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGeneratorTests.java @@ -0,0 +1,255 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.function.Consumer; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.generator.CodeContribution; +import org.springframework.aot.hint.ExecutableHint; +import org.springframework.aot.hint.ExecutableMode; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.TypeHint; +import org.springframework.aot.hint.TypeReference; +import org.springframework.beans.testfixture.beans.TestBean; +import org.springframework.beans.testfixture.beans.factory.generator.InnerComponentConfiguration.EnvironmentAwareComponent; +import org.springframework.beans.testfixture.beans.factory.generator.InnerComponentConfiguration.NoDependencyComponent; +import org.springframework.beans.testfixture.beans.factory.generator.SimpleConfiguration; +import org.springframework.beans.testfixture.beans.factory.generator.factory.NumberHolderFactoryBean; +import org.springframework.beans.testfixture.beans.factory.generator.factory.SampleFactory; +import org.springframework.beans.testfixture.beans.factory.generator.injection.InjectionComponent; +import org.springframework.beans.testfixture.beans.factory.generator.visibility.ProtectedConstructorComponent; +import org.springframework.beans.testfixture.beans.factory.generator.visibility.ProtectedFactoryMethod; +import org.springframework.javapoet.CodeBlock; +import org.springframework.javapoet.support.CodeSnippet; +import org.springframework.lang.Nullable; +import org.springframework.util.ReflectionUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DefaultBeanInstanceGenerator}. + * + * @author Stephane Nicoll + */ +class DefaultBeanInstanceGeneratorTests { + + @Test + void generateUsingDefaultConstructorUsesMethodReference() { + CodeContribution contribution = generate(SimpleConfiguration.class.getDeclaredConstructors()[0]); + assertThat(code(contribution)).isEqualTo("SimpleConfiguration::new"); + assertThat(reflectionHints(contribution, SimpleConfiguration.class)).isNull(); + } + + @Test + void generateUsingConstructorWithoutParameterAndMultipleCandidatesDoesNotUseMethodReference() throws NoSuchMethodException { + CodeContribution contribution = generate(TestBean.class.getConstructor()); + assertThat(code(contribution)).isEqualTo("() -> new TestBean()"); + assertThat(reflectionHints(contribution, TestBean.class)).isNull(); + } + + @Test + void generateUsingConstructorWithParameter() { + Constructor constructor = InjectionComponent.class.getDeclaredConstructors()[0]; + CodeContribution contribution = generate(constructor); + assertThat(code(contribution).lines()).containsOnly( + "(instanceContext) -> instanceContext.create(beanFactory, (attributes) -> " + + "new InjectionComponent(attributes.get(0)))"); + assertThat(reflectionHints(contribution, InjectionComponent.class)) + .satisfies(hasSingleQueryConstructor(constructor)); + } + + @Test + void generateUsingConstructorWithInnerClassAndNoExtraArg() { + CodeContribution contribution = generate(NoDependencyComponent.class.getDeclaredConstructors()[0]); + assertThat(code(contribution).lines()).containsOnly( + "() -> beanFactory.getBean(InnerComponentConfiguration.class).new NoDependencyComponent()"); + assertThat(reflectionHints(contribution, NoDependencyComponent.class)).isNull(); + } + + @Test + void generateUsingConstructorWithInnerClassAndExtraArg() { + Constructor constructor = EnvironmentAwareComponent.class.getDeclaredConstructors()[0]; + CodeContribution contribution = generate(constructor); + assertThat(code(contribution).lines()).containsOnly( + "(instanceContext) -> instanceContext.create(beanFactory, (attributes) -> " + + "beanFactory.getBean(InnerComponentConfiguration.class).new EnvironmentAwareComponent(attributes.get(1)))"); + assertThat(reflectionHints(contribution, EnvironmentAwareComponent.class)) + .satisfies(hasSingleQueryConstructor(constructor)); + } + + @Test + void generateUsingConstructorOfTypeWithGeneric() { + CodeContribution contribution = generate(NumberHolderFactoryBean.class.getDeclaredConstructors()[0]); + assertThat(code(contribution)).isEqualTo("NumberHolderFactoryBean::new"); + assertThat(reflectionHints(contribution, NumberHolderFactoryBean.class)).isNull(); + } + + @Test + void generateUsingNoArgConstructorAndContributorsDoesNotUseMethodReference() { + CodeContribution contribution = generate(SimpleConfiguration.class.getDeclaredConstructors()[0], + contrib -> contrib.statements().add(CodeBlock.of("// hello\n")), + BeanInstanceContributor.NO_OP); + assertThat(code(contribution)).isEqualTo(""" + (instanceContext) -> { + SimpleConfiguration bean = new SimpleConfiguration(); + // hello + return bean; + }"""); + } + + @Test + void generateUsingContributorsRegisterHints() { + CodeContribution contribution = generate(SimpleConfiguration.class.getDeclaredConstructors()[0], + contrib -> { + contrib.statements().add(CodeBlock.of("// hello\n")); + contrib.runtimeHints().resources().registerPattern("com/example/*.properties"); + }, + contrib -> contrib.runtimeHints().reflection().registerType(TypeReference.of(String.class), + hint -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS))); + assertThat(code(contribution)).isEqualTo(""" + (instanceContext) -> { + SimpleConfiguration bean = new SimpleConfiguration(); + // hello + return bean; + }"""); + assertThat(contribution.runtimeHints().resources().resourcePatterns()).singleElement().satisfies(hint -> + assertThat(hint.getIncludes()).containsOnly("com/example/*.properties")); + assertThat(contribution.runtimeHints().reflection().getTypeHint(String.class)).satisfies(hint -> { + assertThat(hint.getType()).isEqualTo(TypeReference.of(String.class)); + assertThat(hint.getMemberCategories()).containsOnly(MemberCategory.INVOKE_PUBLIC_METHODS); + }); + } + + @Test + void generateUsingMethodWithNoArg() { + Method method = method(SimpleConfiguration.class, "stringBean"); + CodeContribution contribution = generate(method); + assertThat(code(contribution)).isEqualTo("() -> beanFactory.getBean(SimpleConfiguration.class).stringBean()"); + assertThat(reflectionHints(contribution, SimpleConfiguration.class)) + .satisfies(hasSingleQueryMethod(method)); + } + + @Test + void generateUsingStaticMethodWithNoArg() { + Method method = method(SampleFactory.class, "integerBean"); + CodeContribution contribution = generate(method); + assertThat(code(contribution)).isEqualTo("() -> SampleFactory.integerBean()"); + assertThat(reflectionHints(contribution, SampleFactory.class)) + .satisfies(hasSingleQueryMethod(method)); + } + + @Test + void generateUsingMethodWithArg() { + Method method = method(SampleFactory.class, "create", Number.class, String.class); + CodeContribution contribution = generate(method); + assertThat(code(contribution)).isEqualTo("(instanceContext) -> instanceContext.create(beanFactory, (attributes) -> " + + "SampleFactory.create(attributes.get(0), attributes.get(1)))"); + assertThat(reflectionHints(contribution, SampleFactory.class)) + .satisfies(hasSingleQueryMethod(method)); + } + + @Test + void generateUsingMethodAndContributors() { + CodeContribution contribution = generate(method(SimpleConfiguration.class, "stringBean"), + contrib -> { + contrib.statements().add(CodeBlock.of("// hello\n")); + contrib.runtimeHints().resources().registerPattern("com/example/*.properties"); + }, + contrib -> contrib.runtimeHints().reflection().registerType(TypeReference.of(String.class), + hint -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS))); + assertThat(code(contribution)).isEqualTo(""" + (instanceContext) -> { + String bean = beanFactory.getBean(SimpleConfiguration.class).stringBean(); + // hello + return bean; + }"""); + assertThat(contribution.runtimeHints().resources().resourcePatterns()).singleElement().satisfies(hint -> + assertThat(hint.getIncludes()).containsOnly("com/example/*.properties")); + assertThat(contribution.runtimeHints().reflection().getTypeHint(String.class)).satisfies(hint -> { + assertThat(hint.getType()).isEqualTo(TypeReference.of(String.class)); + assertThat(hint.getMemberCategories()).containsOnly(MemberCategory.INVOKE_PUBLIC_METHODS); + }); + } + + @Test + void generateUsingProtectedConstructorRegistersProtectedAccess() { + CodeContribution contribution = generate(ProtectedConstructorComponent.class.getDeclaredConstructors()[0]); + assertThat(contribution.protectedAccess().isAccessible("com.example")).isFalse(); + assertThat(contribution.protectedAccess().getPrivilegedPackageName("com.example")) + .isEqualTo(ProtectedConstructorComponent.class.getPackageName()); + } + + @Test + void generateUsingProtectedMethodRegistersProtectedAccess() { + CodeContribution contribution = generate(method(ProtectedFactoryMethod.class, "testBean", Integer.class)); + assertThat(contribution.protectedAccess().isAccessible("com.example")).isFalse(); + assertThat(contribution.protectedAccess().getPrivilegedPackageName("com.example")) + .isEqualTo(ProtectedFactoryMethod.class.getPackageName()); + } + + private String code(CodeContribution contribution) { + return CodeSnippet.process(contribution.statements().toCodeBlock()); + } + + @Nullable + private TypeHint reflectionHints(CodeContribution contribution, Class type) { + return contribution.runtimeHints().reflection().getTypeHint(type); + } + + private Consumer hasSingleQueryConstructor(Constructor constructor) { + return typeHint -> assertThat(typeHint.constructors()).singleElement() + .satisfies(match(constructor, "", ExecutableMode.INTROSPECT)); + } + + private Consumer hasSingleQueryMethod(Method method) { + return typeHint -> assertThat(typeHint.methods()).singleElement() + .satisfies(match(method, method.getName(), ExecutableMode.INTROSPECT)); + } + + private Consumer match(Executable executable, String name, ExecutableMode... modes) { + return hint -> { + assertThat(hint.getName()).isEqualTo(name); + assertThat(hint.getParameterTypes()).hasSameSizeAs(executable.getParameterTypes()); + for (int i = 0; i < hint.getParameterTypes().size(); i++) { + assertThat(hint.getParameterTypes().get(i)) + .isEqualTo(TypeReference.of(executable.getParameterTypes()[i])); + } + assertThat(hint.getModes()).containsOnly(modes); + }; + } + + private CodeContribution generate(Executable executable, + BeanInstanceContributor... beanInstanceContributors) { + DefaultBeanInstanceGenerator generator = new DefaultBeanInstanceGenerator(executable, + Arrays.asList(beanInstanceContributors)); + return generator.generateBeanInstance(new RuntimeHints()); + } + + private static Method method(Class type, String methodName, Class... parameterTypes) { + Method method = ReflectionUtils.findMethod(type, methodName, parameterTypes); + assertThat(method).isNotNull(); + return method; + } + +} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/generator/InjectionGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/generator/InjectionGeneratorTests.java new file mode 100644 index 000000000000..910e66b6db6c --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/beans/factory/generator/InjectionGeneratorTests.java @@ -0,0 +1,269 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.generator.InjectionGeneratorTests.SimpleConstructorBean.InnerClass; +import org.springframework.javapoet.support.CodeSnippet; +import org.springframework.util.ReflectionUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link InjectionGenerator}. + * + * @author Stephane Nicoll + */ +class InjectionGeneratorTests { + + @Test + void writeInstantiationForConstructorWithNoArgUseShortcut() { + Constructor constructor = SimpleBean.class.getDeclaredConstructors()[0]; + assertThat(writeInstantiation(constructor).lines()) + .containsExactly("new InjectionGeneratorTests.SimpleBean()"); + } + + @Test + void writeInstantiationForConstructorWithNonGenericParameter() { + Constructor constructor = SimpleConstructorBean.class.getDeclaredConstructors()[0]; + assertThat(writeInstantiation(constructor).lines()).containsExactly( + "instanceContext.create(beanFactory, (attributes) -> new InjectionGeneratorTests.SimpleConstructorBean(attributes.get(0), attributes.get(1)))"); + } + + @Test + void writeInstantiationForConstructorWithGenericParameter() { + Constructor constructor = GenericConstructorBean.class.getDeclaredConstructors()[0]; + assertThat(writeInstantiation(constructor).lines()).containsExactly( + "instanceContext.create(beanFactory, (attributes) -> new InjectionGeneratorTests.GenericConstructorBean(attributes.get(0)))"); + } + + @Test + void writeInstantiationForAmbiguousConstructor() throws Exception { + Constructor constructor = AmbiguousConstructorBean.class.getDeclaredConstructor(String.class, Number.class); + assertThat(writeInstantiation(constructor).lines()).containsExactly( + "instanceContext.create(beanFactory, (attributes) -> new InjectionGeneratorTests.AmbiguousConstructorBean(attributes.get(0, String.class), attributes.get(1, Number.class)))"); + } + + @Test + void writeInstantiationForConstructorInInnerClass() { + Constructor constructor = InnerClass.class.getDeclaredConstructors()[0]; + assertThat(writeInstantiation(constructor).lines()).containsExactly( + "beanFactory.getBean(InjectionGeneratorTests.SimpleConstructorBean.class).new InnerClass()"); + } + + @Test + void writeInstantiationForMethodWithNoArgUseShortcut() { + assertThat(writeInstantiation(method(SimpleBean.class, "name")).lines()).containsExactly( + "beanFactory.getBean(InjectionGeneratorTests.SimpleBean.class).name()"); + } + + @Test + void writeInstantiationForStaticMethodWithNoArgUseShortcut() { + assertThat(writeInstantiation(method(SimpleBean.class, "number")).lines()).containsExactly( + "InjectionGeneratorTests.SimpleBean.number()"); + } + + @Test + void writeInstantiationForMethodWithNonGenericParameter() { + assertThat(writeInstantiation(method(SampleBean.class, "source", Integer.class)).lines()).containsExactly( + "instanceContext.create(beanFactory, (attributes) -> beanFactory.getBean(InjectionGeneratorTests.SampleBean.class).source(attributes.get(0)))"); + } + + @Test + void writeInstantiationForStaticMethodWithNonGenericParameter() { + assertThat(writeInstantiation(method(SampleBean.class, "staticSource", Integer.class)).lines()).containsExactly( + "instanceContext.create(beanFactory, (attributes) -> InjectionGeneratorTests.SampleBean.staticSource(attributes.get(0)))"); + } + + @Test + void writeInstantiationForMethodWithGenericParameters() { + assertThat(writeInstantiation(method(SampleBean.class, "source", ObjectProvider.class)).lines()).containsExactly( + "instanceContext.create(beanFactory, (attributes) -> beanFactory.getBean(InjectionGeneratorTests.SampleBean.class).source(attributes.get(0)))"); + } + + @Test + void writeInjectionForUnsupportedMember() { + assertThatIllegalArgumentException().isThrownBy(() -> writeInjection(mock(Member.class), false)); + } + + @Test + void writeInjectionForNonRequiredMethodWithNonGenericParameters() { + Method method = method(SampleBean.class, "sourceAndCounter", String.class, Integer.class); + assertThat(writeInjection(method, false)).isEqualTo(""" + instanceContext.method("sourceAndCounter", String.class, Integer.class) + .resolve(beanFactory, false).ifResolved((attributes) -> bean.sourceAndCounter(attributes.get(0), attributes.get(1)))"""); + } + + @Test + void writeInjectionForRequiredMethodWithGenericParameter() { + Method method = method(SampleBean.class, "nameAndCounter", String.class, ObjectProvider.class); + assertThat(writeInjection(method, true)).isEqualTo(""" + instanceContext.method("nameAndCounter", String.class, ObjectProvider.class) + .invoke(beanFactory, (attributes) -> bean.nameAndCounter(attributes.get(0), attributes.get(1)))"""); + } + + @Test + void writeInjectionForNonRequiredMethodWithGenericParameter() { + Method method = method(SampleBean.class, "nameAndCounter", String.class, ObjectProvider.class); + assertThat(writeInjection(method, false)).isEqualTo(""" + instanceContext.method("nameAndCounter", String.class, ObjectProvider.class) + .resolve(beanFactory, false).ifResolved((attributes) -> bean.nameAndCounter(attributes.get(0), attributes.get(1)))"""); + } + + @Test + void writeInjectionForRequiredField() { + Field field = field(SampleBean.class, "counter"); + assertThat(writeInjection(field, true)).isEqualTo(""" + instanceContext.field("counter", Integer.class) + .invoke(beanFactory, (attributes) -> bean.counter = attributes.get(0))"""); + } + + @Test + void writeInjectionForNonRequiredField() { + Field field = field(SampleBean.class, "counter"); + assertThat(writeInjection(field, false)).isEqualTo(""" + instanceContext.field("counter", Integer.class) + .resolve(beanFactory, false).ifResolved((attributes) -> bean.counter = attributes.get(0))"""); + } + + @Test + void writeInjectionForRequiredPrivateField() { + Field field = field(SampleBean.class, "source"); + assertThat(writeInjection(field, true)).isEqualTo(""" + instanceContext.field("source", String.class) + .invoke(beanFactory, (attributes) -> { + Field sourceField = ReflectionUtils.findField(InjectionGeneratorTests.SampleBean.class, "source", String.class); + ReflectionUtils.makeAccessible(sourceField); + ReflectionUtils.setField(sourceField, bean, attributes.get(0)); + })"""); + } + + + private Method method(Class type, String name, Class... parameterTypes) { + Method method = ReflectionUtils.findMethod(type, name, parameterTypes); + assertThat(method).isNotNull(); + return method; + } + + private Field field(Class type, String name) { + Field field = ReflectionUtils.findField(type, name); + assertThat(field).isNotNull(); + return field; + } + + private String writeInstantiation(Executable creator) { + return CodeSnippet.process(code -> code.add(new InjectionGenerator().writeInstantiation(creator))); + } + + private String writeInjection(Member member, boolean required) { + return CodeSnippet.process(code -> code.add(new InjectionGenerator().writeInjection(member, required))); + } + + @SuppressWarnings("unused") + static class SampleBean { + + private String source; + + Integer counter; + + + void sourceAndCounter(String source, Integer counter) { + + } + + void nameAndCounter(String name, ObjectProvider counter) { + + } + + String source(Integer counter) { + return "source" + counter; + } + + String source(ObjectProvider counter) { + return "source" + counter.getIfAvailable(() -> 0); + } + + static String staticSource(Integer counter) { + return counter + "source"; + } + + } + + @SuppressWarnings("unused") + static class SimpleBean { + + String name() { + return "test"; + } + + static Integer number() { + return 42; + } + + } + + @SuppressWarnings("unused") + static class SimpleConstructorBean { + + private final String source; + + private final Integer counter; + + public SimpleConstructorBean(String source, Integer counter) { + this.source = source; + this.counter = counter; + } + + class InnerClass { + + } + + } + + @SuppressWarnings("unused") + static class GenericConstructorBean { + + private final ObjectProvider counter; + + GenericConstructorBean(ObjectProvider counter) { + this.counter = counter; + } + + } + + static class AmbiguousConstructorBean { + + AmbiguousConstructorBean(String first, String second) { + + } + + AmbiguousConstructorBean(String first, Number second) { + + } + + } +} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/BeanDefinitionRegistrarTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/BeanDefinitionRegistrarTests.java new file mode 100644 index 000000000000..8c97229f6d61 --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/BeanDefinitionRegistrarTests.java @@ -0,0 +1,458 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator.config; + +import java.io.IOException; +import java.lang.reflect.Field; + +import org.junit.jupiter.api.Test; +import org.mockito.InOrder; + +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.generator.config.BeanDefinitionRegistrar.BeanInstanceContext; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.core.ResolvableType; +import org.springframework.core.env.Environment; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.ReflectionUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link BeanDefinitionRegistrar}. + * + * @author Stephane Nicoll + */ +class BeanDefinitionRegistrarTests { + + @Test + void beanDefinitionWithBeanClassDoesNotSetTargetType() { + RootBeanDefinition beanDefinition = BeanDefinitionRegistrar.of("test", String.class).toBeanDefinition(); + assertThat(beanDefinition.getBeanClass()).isEqualTo(String.class); + assertThat(beanDefinition.getTargetType()).isNull(); + } + + @Test + void beanDefinitionWithResolvableTypeSetsTargetType() { + ResolvableType targetType = ResolvableType.forClassWithGenerics(NumberHolder.class, Integer.class); + RootBeanDefinition beanDefinition = BeanDefinitionRegistrar.of("test", targetType).toBeanDefinition(); + assertThat(beanDefinition.getTargetType()).isNotNull().isEqualTo(NumberHolder.class); + } + + @Test + void registerWithSimpleInstanceSupplier() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + BeanDefinitionRegistrar.of("test", InjectionSample.class) + .instanceSupplier(InjectionSample::new).register(beanFactory); + assertBeanFactory(beanFactory, () -> { + assertThat(beanFactory.containsBean("test")).isTrue(); + assertThat(beanFactory.getBean(InjectionSample.class)).isNotNull(); + }); + } + + @Test + void registerWithSimpleInstanceSupplierThatThrowsRuntimeException() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + Exception exception = new IllegalArgumentException("test exception"); + BeanDefinitionRegistrar.of("testBean", InjectionSample.class) + .instanceSupplier(() -> { + throw exception; + }).register(beanFactory); + assertThatThrownBy(() -> beanFactory.getBean("testBean")).isInstanceOf(BeanCreationException.class) + .getRootCause().isEqualTo(exception); + } + + @Test + void registerWithSimpleInstanceSupplierThatThrowsCheckedException() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + Exception exception = new IOException("test exception"); + BeanDefinitionRegistrar.of("testBean", InjectionSample.class) + .instanceSupplier(() -> { + throw exception; + }).register(beanFactory); + assertThatThrownBy(() -> beanFactory.getBean("testBean")).isInstanceOf(BeanCreationException.class) + .getRootCause().isEqualTo(exception); + } + + @Test + void registerWithoutBeanNameFails() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + BeanDefinitionRegistrar registrar = BeanDefinitionRegistrar.inner(InjectionSample.class) + .instanceSupplier(InjectionSample::new); + assertThatIllegalStateException().isThrownBy(() -> registrar.register(beanFactory)) + .withMessageContaining("Bean name not set."); + } + + @Test + @SuppressWarnings("unchecked") + void registerWithCustomizer() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + BeanDefinitionRegistrar.ThrowableConsumer first = mock(BeanDefinitionRegistrar.ThrowableConsumer.class); + BeanDefinitionRegistrar.ThrowableConsumer second = mock(BeanDefinitionRegistrar.ThrowableConsumer.class); + BeanDefinitionRegistrar.of("test", InjectionSample.class) + .instanceSupplier(InjectionSample::new).customize(first).customize(second).register(beanFactory); + assertBeanFactory(beanFactory, () -> { + assertThat(beanFactory.containsBean("test")).isTrue(); + InOrder ordered = inOrder(first, second); + ordered.verify(first).accept(any(RootBeanDefinition.class)); + ordered.verify(second).accept(any(RootBeanDefinition.class)); + }); + } + + @Test + void registerWithCustomizerThatThrowsRuntimeException() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + Exception exception = new RuntimeException("test exception"); + BeanDefinitionRegistrar registrar = BeanDefinitionRegistrar.of("test", InjectionSample.class) + .instanceSupplier(InjectionSample::new).customize(bd -> { + throw exception; + }); + assertThatThrownBy(() -> registrar.register(beanFactory)).isInstanceOf(FatalBeanException.class) + .hasMessageContaining("Failed to create bean definition for bean with name 'test'") + .hasMessageContaining("test exception") + .hasCause(exception); + } + + @Test + void registerWithCustomizerThatThrowsCheckedException() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + Exception exception = new IOException("test exception"); + BeanDefinitionRegistrar registrar = BeanDefinitionRegistrar.of("test", InjectionSample.class) + .instanceSupplier(InjectionSample::new).customize(bd -> { + throw exception; + }); + assertThatThrownBy(() -> registrar.register(beanFactory)).isInstanceOf(FatalBeanException.class) + .hasMessageContaining("Failed to create bean definition for bean with name 'test'") + .hasMessageContaining("test exception"); + } + + @Test + void registerWithConstructorInstantiation() { + ResourceLoader resourceLoader = new DefaultResourceLoader(); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerResolvableDependency(ResourceLoader.class, resourceLoader); + BeanDefinitionRegistrar.of("test", ConstructorSample.class).withConstructor(ResourceLoader.class) + .instanceSupplier(instanceContext -> instanceContext.create(beanFactory, attributes -> + new ConstructorSample(attributes.get(0)))).register(beanFactory); + assertBeanFactory(beanFactory, () -> { + assertThat(beanFactory.containsBean("test")).isTrue(); + assertThat(beanFactory.getBean(ConstructorSample.class).resourceLoader).isEqualTo(resourceLoader); + }); + } + + @Test + void registerWithConstructorInstantiationThatThrowsRuntimeException() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + Exception exception = new RuntimeException("test exception"); + BeanDefinitionRegistrar.of("test", ConstructorSample.class).withConstructor(ResourceLoader.class) + .instanceSupplier(instanceContext -> { + throw exception; + }).register(beanFactory); + assertThatThrownBy(() -> beanFactory.getBean("test")).isInstanceOf(BeanCreationException.class) + .getRootCause().isEqualTo(exception); + } + + @Test + void registerWithConstructorInstantiationThatThrowsCheckedException() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + Exception exception = new IOException("test exception"); + BeanDefinitionRegistrar.of("test", ConstructorSample.class).withConstructor(ResourceLoader.class) + .instanceSupplier(instanceContext -> { + throw exception; + }).register(beanFactory); + assertThatThrownBy(() -> beanFactory.getBean("test")).isInstanceOf(BeanCreationException.class) + .getRootCause().isEqualTo(exception); + } + + @Test + void registerWithConstructorOnInnerClass() { + Environment environment = mock(Environment.class); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("environment", environment); + beanFactory.registerBeanDefinition("sample", BeanDefinitionBuilder.rootBeanDefinition(InnerClassSample.class).getBeanDefinition()); + BeanDefinitionRegistrar.of("test", InnerClassSample.Inner.class).withConstructor(InnerClassSample.class, Environment.class) + .instanceSupplier(instanceContext -> instanceContext.create(beanFactory, attributes -> + beanFactory.getBean(InnerClassSample.class).new Inner(attributes.get(1)))) + .register(beanFactory); + assertBeanFactory(beanFactory, () -> { + assertThat(beanFactory.containsBean("test")).isTrue(); + InnerClassSample.Inner bean = beanFactory.getBean(InnerClassSample.Inner.class); + assertThat(bean.environment).isEqualTo(environment); + }); + } + + @Test + void registerWithInvalidConstructor() { + assertThatThrownBy(() -> BeanDefinitionRegistrar.of("test", ConstructorSample.class).withConstructor(Object.class)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("No constructor with type(s) [java.lang.Object] found on") + .hasMessageContaining(ConstructorSample.class.getName()); + } + + @Test + void registerWithFactoryMethod() { + ResourceLoader resourceLoader = new DefaultResourceLoader(); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerResolvableDependency(ResourceLoader.class, resourceLoader); + BeanDefinitionRegistrar.of("configuration", ConfigurationSample.class).instanceSupplier(ConfigurationSample::new) + .register(beanFactory); + BeanDefinitionRegistrar.of("test", ConstructorSample.class) + .withFactoryMethod(ConfigurationSample.class, "sampleBean", ResourceLoader.class) + .instanceSupplier(instanceContext -> instanceContext.create(beanFactory, attributes -> + beanFactory.getBean(ConfigurationSample.class).sampleBean(attributes.get(0)))) + .register(beanFactory); + assertBeanFactory(beanFactory, () -> { + assertThat(beanFactory.containsBean("configuration")).isTrue(); + assertThat(beanFactory.containsBean("test")).isTrue(); + assertThat(beanFactory.getBean(ConstructorSample.class).resourceLoader).isEqualTo(resourceLoader); + RootBeanDefinition bd = (RootBeanDefinition) beanFactory.getBeanDefinition("test"); + assertThat(bd.getResolvedFactoryMethod()).isNotNull().isEqualTo( + ReflectionUtils.findMethod(ConfigurationSample.class, "sampleBean", ResourceLoader.class)); + }); + } + + @Test + void registerWithCreateShortcutWithoutFactoryMethod() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + BeanDefinitionRegistrar.of("configuration", ConfigurationSample.class).instanceSupplier(ConfigurationSample::new) + .register(beanFactory); + BeanDefinitionRegistrar.of("test", ConstructorSample.class) + .instanceSupplier(instanceContext -> instanceContext.create(beanFactory, attributes -> + beanFactory.getBean(ConfigurationSample.class).sampleBean(attributes.get(0)))) + .register(beanFactory); + assertThatThrownBy(() -> beanFactory.getBean("test")).isInstanceOf(BeanCreationException.class) + .hasMessageContaining("No factory method or constructor is set"); + } + + @Test + void registerWithInjectedField() { + Environment environment = mock(Environment.class); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("environment", environment); + BeanDefinitionRegistrar.of("test", InjectionSample.class).instanceSupplier(instanceContext -> { + InjectionSample bean = new InjectionSample(); + instanceContext.field("environment", Environment.class).invoke(beanFactory, + attributes -> bean.environment = (attributes.get(0))); + return bean; + }).register(beanFactory); + assertBeanFactory(beanFactory, () -> { + assertThat(beanFactory.containsBean("test")).isTrue(); + assertThat(beanFactory.getBean(InjectionSample.class).environment).isEqualTo(environment); + }); + } + + @Test + void registerWithInvalidField() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + BeanDefinitionRegistrar.of("test", InjectionSample.class).instanceSupplier(instanceContext -> + instanceContext.field("doesNotExist", Object.class).resolve(beanFactory)).register(beanFactory); + assertThatThrownBy(() -> beanFactory.getBean(InjectionSample.class) + ).isInstanceOf(BeanCreationException.class) + .hasMessageContaining("No field '%s' with type %s found", "doesNotExist", Object.class.getName()) + .hasMessageContaining(InjectionSample.class.getName()); + } + + @Test + void registerWithInjectedMethod() { + Environment environment = mock(Environment.class); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("environment", environment); + BeanDefinitionRegistrar.of("test", InjectionSample.class).instanceSupplier(instanceContext -> { + InjectionSample bean = new InjectionSample(); + instanceContext.method("setEnvironment", Environment.class).invoke(beanFactory, + attributes -> bean.setEnvironment(attributes.get(0))); + return bean; + }).register(beanFactory); + assertBeanFactory(beanFactory, () -> { + assertThat(beanFactory.containsBean("test")).isTrue(); + assertThat(beanFactory.getBean(InjectionSample.class).environment).isEqualTo(environment); + }); + } + + @Test + void registerWithInvalidMethod() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + assertThatThrownBy(() -> { + BeanDefinitionRegistrar.of("test", InjectionSample.class).instanceSupplier(instanceContext -> + instanceContext.method("setEnvironment", Object.class).resolve(beanFactory)).register(beanFactory); + beanFactory.getBean(InjectionSample.class); + } + ).isInstanceOf(BeanCreationException.class) + .hasMessageContaining("No method '%s' with type(s) [%s] found", "setEnvironment", Object.class.getName()) + .hasMessageContaining(InjectionSample.class.getName()); + } + + @Test + void innerBeanDefinitionWithClass() { + RootBeanDefinition beanDefinition = BeanDefinitionRegistrar.inner(ConfigurationSample.class) + .customize(bd -> bd.setSynthetic(true)).toBeanDefinition(); + assertThat(beanDefinition).isNotNull(); + assertThat(beanDefinition.getResolvableType().resolve()).isEqualTo(ConfigurationSample.class); + assertThat(beanDefinition.isSynthetic()).isTrue(); + } + + @Test + void innerBeanDefinitionWithResolvableType() { + RootBeanDefinition beanDefinition = BeanDefinitionRegistrar.inner(ResolvableType.forClass(ConfigurationSample.class)) + .customize(bd -> bd.setDescription("test")).toBeanDefinition(); + assertThat(beanDefinition).isNotNull(); + assertThat(beanDefinition.getResolvableType().resolve()).isEqualTo(ConfigurationSample.class); + assertThat(beanDefinition.getDescription()).isEqualTo("test"); + } + + @Test + void innerBeanDefinitionHasInnerBeanNameInInstanceSupplier() { + RootBeanDefinition beanDefinition = BeanDefinitionRegistrar.inner(String.class) + .instanceSupplier(instanceContext -> { + Field field = ReflectionUtils.findField(BeanInstanceContext.class, "beanName", String.class); + ReflectionUtils.makeAccessible(field); + return ReflectionUtils.getField(field, instanceContext); + }).toBeanDefinition(); + assertThat(beanDefinition).isNotNull(); + String beanName = (String) beanDefinition.getInstanceSupplier().get(); + assertThat(beanName).isNotNull().startsWith("(inner bean)#"); + } + + + private void assertBeanFactory(DefaultListableBeanFactory beanFactory, Runnable assertions) { + assertions.run(); + } + + + static class ConfigurationSample { + + ConstructorSample sampleBean(ResourceLoader resourceLoader) { + return new ConstructorSample(resourceLoader); + } + + } + + static class ConstructorSample { + private final ResourceLoader resourceLoader; + + ConstructorSample(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + } + + static class MultiArgConstructorSample { + + private final String name; + + private final Integer counter; + + public MultiArgConstructorSample(String name, Integer counter) { + this.name = name; + this.counter = counter; + } + + } + + static class InjectionSample { + + private Environment environment; + + private String name; + + private Integer counter; + + void setEnvironment(Environment environment) { + this.environment = environment; + } + + void setNameAndCounter(@Value("${test.name:test}") String name, @Value("${test.counter:42}") Integer counter) { + this.name = name; + this.counter = counter; + } + + } + + static class InnerClassSample { + + class Inner { + + private Environment environment; + + Inner(Environment environment) { + this.environment = environment; + } + + } + + } + + static class GenericFactoryBeanConfiguration { + + FactoryBean> integerHolderFactory() { + return new GenericFactoryBean<>(integerHolder()); + } + + NumberHolder integerHolder() { + return new NumberHolder<>(42); + } + + } + + static class GenericFactoryBean implements FactoryBean { + + private final T value; + + public GenericFactoryBean(T value) { + this.value = value; + } + + @Override + public T getObject() { + return this.value; + } + + @Override + public Class getObjectType() { + return this.value.getClass(); + } + } + + static class NumberHolder { + + private final N number; + + public NumberHolder(N number) { + this.number = number; + } + + } + + static class NumberHolderSample { + + @Autowired + private NumberHolder numberHolder; + + } + +} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedConstructionResolverTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedConstructionResolverTests.java new file mode 100644 index 000000000000..ff599eb4ff10 --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedConstructionResolverTests.java @@ -0,0 +1,476 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator.config; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import org.assertj.core.util.Arrays; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.UnsatisfiedDependencyException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.core.env.Environment; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.ReflectionUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.entry; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link InjectedConstructionResolver}. + * + * @author Stephane Nicoll + */ +class InjectedConstructionResolverTests { + + @Test + void resolveNoArgConstructor() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + InjectedElementAttributes attributes = createResolverForConstructor( + InjectedConstructionResolverTests.class).resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + } + + @ParameterizedTest + @MethodSource("singleArgConstruction") + void resolveSingleArgConstructor(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("one", "1"); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + assertThat((String) attributes.get(0)).isEqualTo("1"); + } + + @ParameterizedTest + @MethodSource("singleArgConstruction") + void resolveRequiredDependencyNotPresentThrowsUnsatisfiedDependencyException(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + assertThatThrownBy(() -> resolver.resolve(beanFactory)) + .isInstanceOfSatisfying(UnsatisfiedDependencyException.class, ex -> { + assertThat(ex.getBeanName()).isEqualTo("test"); + assertThat(ex.getInjectionPoint()).isNotNull(); + assertThat(ex.getInjectionPoint().getMember()).isEqualTo(resolver.getExecutable()); + }); + } + + @ParameterizedTest + @MethodSource("arrayOfBeansConstruction") + void resolveArrayOfBeans(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("one", "1"); + beanFactory.registerSingleton("two", "2"); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + Object attribute = attributes.get(0); + assertThat(Arrays.isArray(attribute)).isTrue(); + assertThat((Object[]) attribute).containsExactly("1", "2"); + } + + @ParameterizedTest + @MethodSource("arrayOfBeansConstruction") + void resolveRequiredArrayOfBeansInjectEmptyArray(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + Object attribute = attributes.get(0); + assertThat(Arrays.isArray(attribute)).isTrue(); + assertThat((Object[]) attribute).isEmpty(); + + } + + static Stream arrayOfBeansConstruction() { + return Stream.of(Arguments.of(createResolverForConstructor(BeansCollectionConstructor.class, String[].class)), + Arguments.of(createResolverForFactoryMethod(BeansCollectionFactory.class, "array", String[].class))); + } + + @ParameterizedTest + @MethodSource("listOfBeansConstruction") + void resolveListOfBeans(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("one", "1"); + beanFactory.registerSingleton("two", "2"); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + Object attribute = attributes.get(0); + assertThat(attribute).isInstanceOf(List.class).asList().containsExactly("1", "2"); + } + + @ParameterizedTest + @MethodSource("listOfBeansConstruction") + void resolveRequiredListOfBeansInjectEmptyList(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + Object attribute = attributes.get(0); + assertThat(attribute).isInstanceOf(List.class); + assertThat((List) attribute).isEmpty(); + } + + static Stream listOfBeansConstruction() { + return Stream.of(Arguments.of(createResolverForConstructor(BeansCollectionConstructor.class, List.class)), + Arguments.of(createResolverForFactoryMethod(BeansCollectionFactory.class, "list", List.class))); + } + + @ParameterizedTest + @MethodSource("setOfBeansConstruction") + @SuppressWarnings("unchecked") + void resolveSetOfBeans(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("one", "1"); + beanFactory.registerSingleton("two", "2"); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + Object attribute = attributes.get(0); + assertThat(attribute).isInstanceOf(Set.class); + assertThat((Set) attribute).containsExactly("1", "2"); + } + + @ParameterizedTest + @MethodSource("setOfBeansConstruction") + void resolveRequiredSetOfBeansInjectEmptySet(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + Object attribute = attributes.get(0); + assertThat(attribute).isInstanceOf(Set.class); + assertThat((Set) attribute).isEmpty(); + } + + static Stream setOfBeansConstruction() { + return Stream.of(Arguments.of(createResolverForConstructor(BeansCollectionConstructor.class, Set.class)), + Arguments.of(createResolverForFactoryMethod(BeansCollectionFactory.class, "set", Set.class))); + } + + @ParameterizedTest + @MethodSource("mapOfBeansConstruction") + @SuppressWarnings("unchecked") + void resolveMapOfBeans(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("one", "1"); + beanFactory.registerSingleton("two", "2"); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + Object attribute = attributes.get(0); + assertThat(attribute).isInstanceOf(Map.class); + assertThat((Map) attribute).containsExactly(entry("one", "1"), entry("two", "2")); + } + + @ParameterizedTest + @MethodSource("mapOfBeansConstruction") + void resolveRequiredMapOfBeansInjectEmptySet(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + Object attribute = attributes.get(0); + assertThat(attribute).isInstanceOf(Map.class); + assertThat((Map) attribute).isEmpty(); + } + + static Stream mapOfBeansConstruction() { + return Stream.of(Arguments.of(createResolverForConstructor(BeansCollectionConstructor.class, Map.class)), + Arguments.of(createResolverForFactoryMethod(BeansCollectionFactory.class, "map", Map.class))); + } + + @ParameterizedTest + @MethodSource("multiArgsConstruction") + void resolveMultiArgsConstructor(InjectedConstructionResolver resolver) { + ResourceLoader resourceLoader = new DefaultResourceLoader(); + Environment environment = mock(Environment.class); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerResolvableDependency(ResourceLoader.class, resourceLoader); + beanFactory.registerSingleton("environment", environment); + beanFactory.registerSingleton("one", "1"); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + assertThat((ResourceLoader) attributes.get(0)).isEqualTo(resourceLoader); + assertThat((Environment) attributes.get(1)).isEqualTo(environment); + ObjectProvider provider = attributes.get(2); + assertThat(provider.getIfAvailable()).isEqualTo("1"); + } + + @ParameterizedTest + @MethodSource("mixedArgsConstruction") + void resolveMixedArgsConstructorWithUserValue(InjectedConstructionResolver resolver) { + ResourceLoader resourceLoader = new DefaultResourceLoader(); + Environment environment = mock(Environment.class); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerResolvableDependency(ResourceLoader.class, resourceLoader); + beanFactory.registerSingleton("environment", environment); + AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(MixedArgsConstructor.class) + .setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR).getBeanDefinition(); + beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(1, "user-value"); + beanFactory.registerBeanDefinition("test", beanDefinition); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + assertThat((ResourceLoader) attributes.get(0)).isEqualTo(resourceLoader); + assertThat((String) attributes.get(1)).isEqualTo("user-value"); + assertThat((Environment) attributes.get(2)).isEqualTo(environment); + } + + @ParameterizedTest + @MethodSource("mixedArgsConstruction") + void resolveMixedArgsConstructorWithUserBeanReference(InjectedConstructionResolver resolver) { + ResourceLoader resourceLoader = new DefaultResourceLoader(); + Environment environment = mock(Environment.class); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerResolvableDependency(ResourceLoader.class, resourceLoader); + beanFactory.registerSingleton("environment", environment); + beanFactory.registerSingleton("one", "1"); + beanFactory.registerSingleton("two", "2"); + AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(MixedArgsConstructor.class) + .setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR).getBeanDefinition(); + beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(1, new RuntimeBeanReference("two")); + beanFactory.registerBeanDefinition("test", beanDefinition); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + assertThat((ResourceLoader) attributes.get(0)).isEqualTo(resourceLoader); + assertThat((String) attributes.get(1)).isEqualTo("2"); + assertThat((Environment) attributes.get(2)).isEqualTo(environment); + } + + @Test + void resolveUserValueWithTypeConversionRequired() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(CharDependency.class) + .setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR).getBeanDefinition(); + beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, "\\"); + beanFactory.registerBeanDefinition("test", beanDefinition); + InjectedElementAttributes attributes = createResolverForConstructor(CharDependency.class, char.class).resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + Object attribute = attributes.get(0); + assertThat(attribute).isInstanceOf(Character.class); + assertThat((Character) attribute).isEqualTo('\\'); + } + + @ParameterizedTest + @MethodSource("singleArgConstruction") + void resolveUserValueWithBeanReference(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("stringBean", "string"); + beanFactory.registerBeanDefinition("test", BeanDefinitionBuilder.rootBeanDefinition(SingleArgConstructor.class) + .addConstructorArgReference("stringBean").getBeanDefinition()); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + Object attribute = attributes.get(0); + assertThat(attribute).isEqualTo("string"); + } + + @ParameterizedTest + @MethodSource("singleArgConstruction") + void resolveUserValueWithBeanDefinition(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + AbstractBeanDefinition userValue = BeanDefinitionBuilder.rootBeanDefinition(String.class, () -> "string").getBeanDefinition(); + beanFactory.registerBeanDefinition("test", BeanDefinitionBuilder.rootBeanDefinition(SingleArgConstructor.class) + .addConstructorArgValue(userValue).getBeanDefinition()); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + Object attribute = attributes.get(0); + assertThat(attribute).isEqualTo("string"); + } + + @ParameterizedTest + @MethodSource("singleArgConstruction") + void resolveUserValueThatIsAlreadyResolved(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(SingleArgConstructor.class).getBeanDefinition(); + ValueHolder valueHolder = new ValueHolder('a'); + valueHolder.setConvertedValue("this is an a"); + beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, valueHolder); + beanFactory.registerBeanDefinition("test", beanDefinition); + InjectedElementAttributes attributes = resolver.resolve(beanFactory); + assertThat(attributes.isResolved()).isTrue(); + Object attribute = attributes.get(0); + assertThat(attribute).isEqualTo("this is an a"); + } + + @ParameterizedTest + @MethodSource("singleArgConstruction") + void createInvokeFactory(InjectedConstructionResolver resolver) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("one", "1"); + String instance = resolver.create(beanFactory, attributes -> attributes.get(0)); + assertThat(instance).isEqualTo("1"); + } + + private static InjectedConstructionResolver createResolverForConstructor(Class beanType, Class... parameterTypes) { + try { + Constructor executable = beanType.getDeclaredConstructor(parameterTypes); + return new InjectedConstructionResolver(executable, beanType, "test", + InjectedConstructionResolverTests::safeGetBeanDefinition); + } + catch (NoSuchMethodException ex) { + throw new IllegalStateException(ex); + } + } + + private static InjectedConstructionResolver createResolverForFactoryMethod(Class targetType, + String methodName, Class... parameterTypes) { + Method executable = ReflectionUtils.findMethod(targetType, methodName, parameterTypes); + return new InjectedConstructionResolver(executable, targetType, "test", + InjectedConstructionResolverTests::safeGetBeanDefinition); + } + + private static BeanDefinition safeGetBeanDefinition(DefaultListableBeanFactory beanFactory) { + try { + return beanFactory.getBeanDefinition("test"); + } + catch (NoSuchBeanDefinitionException ex) { + return null; + } + } + + static Stream singleArgConstruction() { + return Stream.of(Arguments.of(createResolverForConstructor(SingleArgConstructor.class, String.class)), + Arguments.of(createResolverForFactoryMethod(SingleArgFactory.class, "single", String.class))); + } + + @SuppressWarnings("unused") + static class SingleArgConstructor { + + public SingleArgConstructor(String s) { + } + + } + + @SuppressWarnings("unused") + static class SingleArgFactory { + + String single(String s) { + return s; + } + + } + + @SuppressWarnings("unused") + static class BeansCollectionConstructor { + + public BeansCollectionConstructor(String[] beans) { + + } + + public BeansCollectionConstructor(List beans) { + + } + + public BeansCollectionConstructor(Set beans) { + + } + + public BeansCollectionConstructor(Map beans) { + + } + + } + + @SuppressWarnings("unused") + static class BeansCollectionFactory { + + public String array(String[] beans) { + return "test"; + } + + public String list(List beans) { + return "test"; + } + + public String set(Set beans) { + return "test"; + } + + public String map(Map beans) { + return "test"; + } + + } + + static Stream multiArgsConstruction() { + return Stream.of( + Arguments.of(createResolverForConstructor(MultiArgsConstructor.class, ResourceLoader.class, + Environment.class, ObjectProvider.class)), + Arguments.of(createResolverForFactoryMethod(MultiArgsFactory.class, "multiArgs", ResourceLoader.class, + Environment.class, ObjectProvider.class))); + } + + @SuppressWarnings("unused") + static class MultiArgsConstructor { + + public MultiArgsConstructor(ResourceLoader resourceLoader, Environment environment, ObjectProvider provider) { + } + } + + @SuppressWarnings("unused") + static class MultiArgsFactory { + + String multiArgs(ResourceLoader resourceLoader, Environment environment, ObjectProvider provider) { + return "test"; + } + } + + static Stream mixedArgsConstruction() { + return Stream.of( + Arguments.of(createResolverForConstructor(MixedArgsConstructor.class, ResourceLoader.class, + String.class, Environment.class)), + Arguments.of(createResolverForFactoryMethod(MixedArgsFactory.class, "mixedArgs", ResourceLoader.class, + String.class, Environment.class))); + } + + @SuppressWarnings("unused") + static class MixedArgsConstructor { + + public MixedArgsConstructor(ResourceLoader resourceLoader, String test, Environment environment) { + + } + + } + + @SuppressWarnings("unused") + static class MixedArgsFactory { + + String mixedArgs(ResourceLoader resourceLoader, String test, Environment environment) { + return "test"; + } + + } + + @SuppressWarnings("unused") + static class CharDependency { + + CharDependency(char escapeChar) { + } + + } + +} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedElementAttributesTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedElementAttributesTests.java new file mode 100644 index 000000000000..f2f66811b926 --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedElementAttributesTests.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator.config; + +import java.util.Collections; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; + +/** + * Tests for {@link InjectedElementAttributes}. + * + * @author Stephane Nicoll + */ +class InjectedElementAttributesTests { + + private static final InjectedElementAttributes unresolved = new InjectedElementAttributes(null); + + private static final InjectedElementAttributes resolved = new InjectedElementAttributes(Collections.singletonList("test")); + + @Test + void isResolvedWithUnresolvedAttributes() { + assertThat(unresolved.isResolved()).isFalse(); + } + + @Test + void isResolvedWithResoledAttributes() { + assertThat(resolved.isResolved()).isTrue(); + } + + @Test + void ifResolvedWithUnresolvedAttributesDoesNotInvokeRunnable() { + Runnable runnable = mock(Runnable.class); + unresolved.ifResolved(runnable); + verifyNoInteractions(runnable); + } + + @Test + void ifResolvedWithResolvedAttributesInvokesRunnable() { + Runnable runnable = mock(Runnable.class); + resolved.ifResolved(runnable); + verify(runnable).run(); + } + + @Test + @SuppressWarnings("unchecked") + void ifResolvedWithUnresolvedAttributesDoesNotInvokeConsumer() { + BeanDefinitionRegistrar.ThrowableConsumer consumer = mock(BeanDefinitionRegistrar.ThrowableConsumer.class); + unresolved.ifResolved(consumer); + verifyNoInteractions(consumer); + } + + @Test + @SuppressWarnings("unchecked") + void ifResolvedWithResolvedAttributesInvokesConsumer() { + BeanDefinitionRegistrar.ThrowableConsumer consumer = mock(BeanDefinitionRegistrar.ThrowableConsumer.class); + resolved.ifResolved(consumer); + verify(consumer).accept(resolved); + } + + @Test + void getWithAvailableAttribute() { + InjectedElementAttributes attributes = new InjectedElementAttributes(Collections.singletonList("test")); + assertThat((String) attributes.get(0)).isEqualTo("test"); + } + + @Test + void getWithTypeAndAvailableAttribute() { + InjectedElementAttributes attributes = new InjectedElementAttributes(Collections.singletonList("test")); + assertThat(attributes.get(0, String.class)).isEqualTo("test"); + } + +} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedFieldResolverTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedFieldResolverTests.java new file mode 100644 index 000000000000..39f90cca7f8e --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedFieldResolverTests.java @@ -0,0 +1,78 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator.config; + +import java.lang.reflect.Field; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.UnsatisfiedDependencyException; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.util.ReflectionUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Tests for {@link InjectedFieldResolver}. + * + * @author Stephane Nicoll + */ +class InjectedFieldResolverTests { + + @Test + void resolveDependency() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("one", "1"); + InjectedElementAttributes attributes = createResolver(TestBean.class, "string", + String.class).resolve(beanFactory, true); + assertThat(attributes.isResolved()).isTrue(); + assertThat((String) attributes.get(0)).isEqualTo("1"); + } + + @Test + void resolveRequiredDependencyNotPresentThrowsUnsatisfiedDependencyException() { + Field field = ReflectionUtils.findField(TestBean.class, "string", String.class); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + assertThatThrownBy(() -> createResolver(TestBean.class, "string", String.class).resolve(beanFactory)) + .isInstanceOfSatisfying(UnsatisfiedDependencyException.class, ex -> { + assertThat(ex.getBeanName()).isEqualTo("test"); + assertThat(ex.getInjectionPoint()).isNotNull(); + assertThat(ex.getInjectionPoint().getField()).isEqualTo(field); + }); + } + + @Test + void resolveNonRequiredDependency() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + InjectedElementAttributes attributes = createResolver(TestBean.class, "string", String.class).resolve(beanFactory, false); + assertThat(attributes.isResolved()).isFalse(); + } + + private InjectedFieldResolver createResolver(Class beanType, String fieldName, Class fieldType) { + Field field = ReflectionUtils.findField(beanType, fieldName, fieldType); + assertThat(field).isNotNull(); + return new InjectedFieldResolver(field, "test"); + } + + static class TestBean { + + private String string; + + } + +} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedMethodResolverTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedMethodResolverTests.java new file mode 100644 index 000000000000..d9b9e2aee24f --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/beans/factory/generator/config/InjectedMethodResolverTests.java @@ -0,0 +1,124 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator.config; + +import java.lang.reflect.Method; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.UnsatisfiedDependencyException; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.core.env.Environment; +import org.springframework.util.ReflectionUtils; + +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.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; + +/** + * Tests for {@link InjectedMethodResolver}. + * + * @author Stephane Nicoll + */ +class InjectedMethodResolverTests { + + @Test + void resolveSingleDependency() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("test", "testValue"); + InjectedElementAttributes attributes = createResolver(TestBean.class, "injectString", String.class) + .resolve(beanFactory, true); + assertThat(attributes.isResolved()).isTrue(); + assertThat((String) attributes.get(0)).isEqualTo("testValue"); + } + + @Test + void resolveRequiredDependencyNotPresentThrowsUnsatisfiedDependencyException() { + Method method = ReflectionUtils.findMethod(TestBean.class, "injectString", String.class); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + assertThatThrownBy(() -> createResolver(TestBean.class, "injectString", String.class) + .resolve(beanFactory)).isInstanceOfSatisfying(UnsatisfiedDependencyException.class, ex -> { + assertThat(ex.getBeanName()).isEqualTo("test"); + assertThat(ex.getInjectionPoint()).isNotNull(); + assertThat(ex.getInjectionPoint().getMember()).isEqualTo(method); + }); + } + + @Test + void resolveNonRequiredDependency() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + InjectedElementAttributes attributes = createResolver(TestBean.class, "injectString", String.class) + .resolve(beanFactory, false); + assertThat(attributes.isResolved()).isFalse(); + } + + @Test + void resolveDependencyAndEnvironment() { + Environment environment = mock(Environment.class); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("environment", environment); + beanFactory.registerSingleton("test", "testValue"); + InjectedElementAttributes attributes = createResolver(TestBean.class, "injectStringAndEnvironment", + String.class, Environment.class).resolve(beanFactory, true); + assertThat(attributes.isResolved()).isTrue(); + String string = attributes.get(0); + assertThat(string).isEqualTo("testValue"); + assertThat((Environment) attributes.get(1)).isEqualTo(environment); + } + + @Test + @SuppressWarnings("unchecked") + void createWithUnresolvedAttributesDoesNotInvokeCallback() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + BeanDefinitionRegistrar.ThrowableFunction callback = mock(BeanDefinitionRegistrar.ThrowableFunction.class); + assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() -> + createResolver(TestBean.class, "injectString", String.class).create(beanFactory, callback)); + verifyNoInteractions(callback); + } + + @Test + @SuppressWarnings("unchecked") + void invokeWithUnresolvedAttributesDoesNotInvokeCallback() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + BeanDefinitionRegistrar.ThrowableConsumer callback = mock(BeanDefinitionRegistrar.ThrowableConsumer.class); + assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() -> + createResolver(TestBean.class, "injectString", String.class).invoke(beanFactory, callback)); + verifyNoInteractions(callback); + } + + private InjectedMethodResolver createResolver(Class beanType, String methodName, Class... parameterTypes) { + Method method = ReflectionUtils.findMethod(beanType, methodName, parameterTypes); + assertThat(method).isNotNull(); + return new InjectedMethodResolver(method, beanType, "test"); + } + + @SuppressWarnings("unused") + static class TestBean { + + public void injectString(String string) { + + } + + public void injectStringAndEnvironment(String string, Environment environment) { + + } + + } + +} diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/InnerComponentConfiguration.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/InnerComponentConfiguration.java new file mode 100644 index 000000000000..28188b2a52a0 --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/InnerComponentConfiguration.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator; + +import org.springframework.core.env.Environment; + +public class InnerComponentConfiguration { + + public class NoDependencyComponent { + + public NoDependencyComponent() { + + } + } + + public class EnvironmentAwareComponent { + + public EnvironmentAwareComponent(Environment environment) { + + } + } +} diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/SimpleConfiguration.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/SimpleConfiguration.java new file mode 100644 index 000000000000..0f5ba99ad057 --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/SimpleConfiguration.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator; + +public class SimpleConfiguration { + + public SimpleConfiguration() { + } + + public String stringBean() { + return "Hello"; + } + + public Integer integerBean() { + return 42; + } + +} diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/factory/NumberHolder.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/factory/NumberHolder.java new file mode 100644 index 000000000000..d49475656e17 --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/factory/NumberHolder.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.factory; + +import java.io.Serializable; + +/** + * A sample object with a generic type. + * + * @param the number type + * @author Stephane Nicoll + */ +@SuppressWarnings("serial") +public class NumberHolder implements Serializable { + + private final T number; + + public NumberHolder(T number) { + this.number = number; + } + +} diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/factory/NumberHolderFactoryBean.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/factory/NumberHolderFactoryBean.java new file mode 100644 index 000000000000..a837a8dcaf53 --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/factory/NumberHolderFactoryBean.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.factory; + +import org.springframework.beans.factory.FactoryBean; + +/** + * A sample factory bean with a generic type. + * + * @param the type of the number generated by this factory bean + * @author Stephane Nicoll + */ +public class NumberHolderFactoryBean implements FactoryBean> { + + private T number; + + public void setNumber(T number) { + this.number = number; + } + + @Override + public NumberHolder getObject() { + return new NumberHolder<>(this.number); + } + + @Override + public Class getObjectType() { + return NumberHolder.class; + } + +} diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/factory/SampleFactory.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/factory/SampleFactory.java new file mode 100644 index 000000000000..eca5e0d7bfdf --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/factory/SampleFactory.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.factory; + +public abstract class SampleFactory { + + public static String create(String testBean) { + return testBean; + } + + public static String create(char character) { + return String.valueOf(character); + } + + public static String create(Number number, String test) { + return number + test; + } + + public static String create(Class type) { + return type.getName(); + } + + public static Integer integerBean() { + return 42; + } + +} diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/injection/InjectionComponent.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/injection/InjectionComponent.java new file mode 100644 index 000000000000..9d772ade5a34 --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/injection/InjectionComponent.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.injection; + +import org.springframework.beans.factory.annotation.Autowired; + +@SuppressWarnings("unused") +public class InjectionComponent { + + private final String bean; + + private Integer counter; + + public InjectionComponent(String bean) { + this.bean = bean; + } + + @Autowired(required = false) + public void setCounter(Integer counter) { + this.counter = counter; + } + +} diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/property/ConfigurableBean.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/property/ConfigurableBean.java new file mode 100644 index 000000000000..0a8319223b36 --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/property/ConfigurableBean.java @@ -0,0 +1,33 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.property; + +public class ConfigurableBean { + + private String name; + + private Integer counter; + + public void setName(String name) { + this.name = name; + } + + public void setCounter(Integer counter) { + this.counter = counter; + } + +} diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/visibility/ProtectedConstructorComponent.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/visibility/ProtectedConstructorComponent.java new file mode 100644 index 000000000000..5b27a375cdd2 --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/visibility/ProtectedConstructorComponent.java @@ -0,0 +1,24 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.visibility; + +public class ProtectedConstructorComponent { + + ProtectedConstructorComponent() { + + } +} diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/visibility/ProtectedFactoryMethod.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/visibility/ProtectedFactoryMethod.java new file mode 100644 index 000000000000..7d2fd2b5574d --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/visibility/ProtectedFactoryMethod.java @@ -0,0 +1,25 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.visibility; + +public class ProtectedFactoryMethod { + + String testBean(Integer number) { + return "test-" + number; + } + +} diff --git a/spring-core/src/main/java/org/springframework/aot/generator/ResolvableTypeGenerator.java b/spring-core/src/main/java/org/springframework/aot/generator/ResolvableTypeGenerator.java new file mode 100644 index 000000000000..339a993bf95b --- /dev/null +++ b/spring-core/src/main/java/org/springframework/aot/generator/ResolvableTypeGenerator.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.aot.generator; + +import java.util.Arrays; + +import org.springframework.core.ResolvableType; +import org.springframework.javapoet.CodeBlock; +import org.springframework.javapoet.support.MultiCodeBlock; +import org.springframework.util.ClassUtils; + +/** + * Code generator for {@link ResolvableType}. + * + * @author Stephane Nicoll + * @since 6.0 + */ +public final class ResolvableTypeGenerator { + + /** + * Generate a type signature for the specified {@link ResolvableType}. + * @param target the type to generate + * @return the representation of that type + */ + public CodeBlock generateTypeFor(ResolvableType target) { + CodeBlock.Builder code = CodeBlock.builder(); + generate(code, target, false); + return code.build(); + } + + private void generate(CodeBlock.Builder code, ResolvableType target, boolean forceResolvableType) { + Class type = ClassUtils.getUserClass(target.toClass()); + if (!target.hasGenerics()) { + if (forceResolvableType) { + code.add("$T.forClass($T.class)", ResolvableType.class, type); + } + else { + code.add("$T.class", type); + } + } + else { + code.add("$T.forClassWithGenerics($T.class, ", ResolvableType.class, type); + ResolvableType[] generics = target.getGenerics(); + boolean hasGenericParameter = Arrays.stream(generics).anyMatch(ResolvableType::hasGenerics); + MultiCodeBlock multi = new MultiCodeBlock(); + for (int i = 0; i < generics.length; i++) { + ResolvableType parameter = target.getGeneric(i); + multi.add(parameterCode -> generate(parameterCode, parameter, hasGenericParameter)); + } + code.add(multi.join(", ")).add(")"); + } + } + +} diff --git a/spring-core/src/main/java/org/springframework/aot/hint/ReflectionHints.java b/spring-core/src/main/java/org/springframework/aot/hint/ReflectionHints.java index f459c6a25822..1f7be98f33fe 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/ReflectionHints.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/ReflectionHints.java @@ -29,6 +29,7 @@ import java.util.stream.Stream; import org.springframework.aot.hint.TypeHint.Builder; +import org.springframework.lang.Nullable; /** * Gather the need for reflection at runtime. @@ -49,6 +50,28 @@ public Stream typeHints() { return this.types.values().stream().map(TypeHint.Builder::build); } + /** + * Return the reflection hints for the type defined by the specified + * {@link TypeReference}. + * @param type the type to inspect + * @return the reflection hints for this type, or {@code null} + */ + @Nullable + public TypeHint getTypeHint(TypeReference type) { + Builder typeHintBuilder = this.types.get(type); + return (typeHintBuilder != null ? typeHintBuilder.build() : null); + } + + /** + * Return the reflection hints for the specified type. + * @param type the type to inspect + * @return the reflection hints for this type, or {@code null} + */ + @Nullable + public TypeHint getTypeHint(Class type) { + return getTypeHint(TypeReference.of(type)); + } + /** * Register or customize reflection hints for the type defined by the * specified {@link TypeReference}. diff --git a/spring-core/src/main/java/org/springframework/javapoet/support/MultiStatement.java b/spring-core/src/main/java/org/springframework/javapoet/support/MultiStatement.java index 04bd02071e26..2442b8585004 100644 --- a/spring-core/src/main/java/org/springframework/javapoet/support/MultiStatement.java +++ b/spring-core/src/main/java/org/springframework/javapoet/support/MultiStatement.java @@ -47,41 +47,48 @@ public boolean isEmpty() { /** * Add the specified {@link CodeBlock codeblock} rendered as-is. * @param codeBlock the code block to add + * @return {@code this}, to facilitate method chaining * @see #addStatement(CodeBlock) to add a code block that represents * a statement */ - public void add(CodeBlock codeBlock) { + public MultiStatement add(CodeBlock codeBlock) { this.statements.add(Statement.of(codeBlock)); + return this; } /** * Add a {@link CodeBlock} rendered as-is using the specified callback. * @param code the callback to use + * @return {@code this}, to facilitate method chaining * @see #addStatement(CodeBlock) to add a code block that represents * a statement */ - public void add(Consumer code) { + public MultiStatement add(Consumer code) { CodeBlock.Builder builder = CodeBlock.builder(); code.accept(builder); add(builder.build()); + return this; } /** * Add a statement. * @param statement the statement to add + * @return {@code this}, to facilitate method chaining */ - public void addStatement(CodeBlock statement) { + public MultiStatement addStatement(CodeBlock statement) { this.statements.add(Statement.ofStatement(statement)); + return this; } /** * Add a statement using the specified callback. * @param code the callback to use + * @return {@code this}, to facilitate method chaining */ - public void addStatement(Consumer code) { + public MultiStatement addStatement(Consumer code) { CodeBlock.Builder builder = CodeBlock.builder(); code.accept(builder); - addStatement(builder.build()); + return addStatement(builder.build()); } /** @@ -89,10 +96,11 @@ public void addStatement(Consumer code) { * arguments. * @param code the code of the statement * @param args the arguments for placeholders + * @return {@code this}, to facilitate method chaining * @see CodeBlock#of(String, Object...) */ - public void addStatement(String code, Object... args) { - addStatement(CodeBlock.of(code, args)); + public MultiStatement addStatement(String code, Object... args) { + return addStatement(CodeBlock.of(code, args)); } /** @@ -101,9 +109,11 @@ public void addStatement(String code, Object... args) { * @param items the items to handle, each item is represented as a statement * @param itemGenerator the item generator * @param the type of the item + * @return {@code this}, to facilitate method chaining */ - public void addAll(Iterable items, Function itemGenerator) { + public MultiStatement addAll(Iterable items, Function itemGenerator) { items.forEach(element -> addStatement(itemGenerator.apply(element))); + return this; } /** diff --git a/spring-core/src/test/java/org/springframework/aot/generator/ResolvableTypeGeneratorTests.java b/spring-core/src/test/java/org/springframework/aot/generator/ResolvableTypeGeneratorTests.java new file mode 100644 index 000000000000..34ab0f867111 --- /dev/null +++ b/spring-core/src/test/java/org/springframework/aot/generator/ResolvableTypeGeneratorTests.java @@ -0,0 +1,62 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.aot.generator; + +import java.util.function.Function; +import java.util.function.Supplier; + +import org.junit.jupiter.api.Test; + +import org.springframework.core.ResolvableType; +import org.springframework.javapoet.support.CodeSnippet; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ResolvableTypeGenerator}. + * + * @author Stephane Nicoll + */ +class ResolvableTypeGeneratorTests { + + @Test + void generateTypeForResolvableTypeWithGenericParameter() { + assertThat(generateTypeFor( + ResolvableType.forClassWithGenerics(Function.class, + ResolvableType.forClassWithGenerics(Supplier.class, String.class), + ResolvableType.forClassWithGenerics(Supplier.class, Integer.class)))) + .isEqualTo("ResolvableType.forClassWithGenerics(Function.class, " + + "ResolvableType.forClassWithGenerics(Supplier.class, String.class), " + + "ResolvableType.forClassWithGenerics(Supplier.class, Integer.class))"); + } + + @Test + void generateTypeForResolvableTypeWithMixedParameter() { + assertThat(generateTypeFor( + ResolvableType.forClassWithGenerics(Function.class, + ResolvableType.forClassWithGenerics(Supplier.class, String.class), + ResolvableType.forClass(Integer.class)))) + .isEqualTo("ResolvableType.forClassWithGenerics(Function.class, " + + "ResolvableType.forClassWithGenerics(Supplier.class, String.class), " + + "ResolvableType.forClass(Integer.class))"); + } + + private String generateTypeFor(ResolvableType type) { + return CodeSnippet.process(new ResolvableTypeGenerator().generateTypeFor(type)); + } + +} 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 6b0f57d85cdc..8d96f72190a8 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 @@ -16,10 +16,13 @@ package org.springframework.aot.hint; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.function.Consumer; import org.junit.jupiter.api.Test; +import org.springframework.lang.Nullable; import org.springframework.util.ReflectionUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -41,11 +44,34 @@ void registerType() { typeWithMemberCategories(String.class, MemberCategory.DECLARED_FIELDS)); } + @Test + void getTypeUsingType() { + this.reflectionHints.registerType(TypeReference.of(String.class), + hint -> hint.withMembers(MemberCategory.DECLARED_FIELDS)); + assertThat(this.reflectionHints.getTypeHint(String.class)).satisfies( + typeWithMemberCategories(String.class, MemberCategory.DECLARED_FIELDS)); + } + + @Test + void getTypeUsingTypeReference() { + this.reflectionHints.registerType(String.class, + hint -> hint.withMembers(MemberCategory.DECLARED_FIELDS)); + assertThat(this.reflectionHints.getTypeHint(TypeReference.of(String.class))).satisfies( + typeWithMemberCategories(String.class, MemberCategory.DECLARED_FIELDS)); + } + + @Test + void getTypeForNonExistingType() { + assertThat(this.reflectionHints.getTypeHint(String.class)).isNull(); + } + @Test void registerTypeReuseBuilder() { this.reflectionHints.registerType(TypeReference.of(String.class), typeHint -> typeHint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)); - this.reflectionHints.registerField(ReflectionUtils.findField(String.class, "value")); + Field field = ReflectionUtils.findField(String.class, "value"); + assertThat(field).isNotNull(); + this.reflectionHints.registerField(field); assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(typeHint -> { assertThat(typeHint.getType().getCanonicalName()).isEqualTo(String.class.getCanonicalName()); assertThat(typeHint.fields()).singleElement().satisfies(fieldHint -> assertThat(fieldHint.getName()).isEqualTo("value")); @@ -63,7 +89,9 @@ void registerClass() { @Test void registerField() { - this.reflectionHints.registerField(ReflectionUtils.findField(TestType.class, "field")); + Field field = ReflectionUtils.findField(TestType.class, "field"); + assertThat(field).isNotNull(); + this.reflectionHints.registerField(field); assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(typeHint -> { assertThat(typeHint.getType().getCanonicalName()).isEqualTo(TestType.class.getCanonicalName()); assertThat(typeHint.fields()).singleElement().satisfies(fieldHint -> @@ -92,7 +120,9 @@ void registerConstructor() { @Test void registerMethod() { - this.reflectionHints.registerMethod(ReflectionUtils.findMethod(TestType.class, "setName", String.class)); + Method method = ReflectionUtils.findMethod(TestType.class, "setName", String.class); + assertThat(method).isNotNull(); + this.reflectionHints.registerMethod(method); assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(typeHint -> { assertThat(typeHint.getType().getCanonicalName()).isEqualTo(TestType.class.getCanonicalName()); assertThat(typeHint.fields()).isEmpty(); @@ -119,6 +149,7 @@ private Consumer typeWithMemberCategories(Class type, MemberCategor @SuppressWarnings("unused") static class TestType { + @Nullable private String field; void setName(String name) { From f004bb1b64cd9f39d58adc181607a1d5f3034b29 Mon Sep 17 00:00:00 2001 From: Ivan Zbykovskyi <> Date: Thu, 3 Feb 2022 13:34:02 +0200 Subject: [PATCH 688/735] Add formatting for SockJS GoAway frame Prevents infinite loop for xhr-polling and xhr-streaming transports. See gh-28000 --- .../handler/AbstractHttpSendingTransportHandler.java | 4 +++- .../sockjs/transport/session/AbstractHttpSockJsSession.java | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpSendingTransportHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpSendingTransportHandler.java index ef566c7f8db1..73aac7449e4d 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpSendingTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpSendingTransportHandler.java @@ -79,9 +79,11 @@ else if (sockJsSession.isClosed()) { if (logger.isDebugEnabled()) { logger.debug("Connection already closed (but not removed yet) for " + sockJsSession); } + SockJsFrameFormat frameFormat = this.getFrameFormat(request); SockJsFrame frame = SockJsFrame.closeFrameGoAway(); + String formattedFrame = frameFormat.format(frame); try { - response.getBody().write(frame.getContentBytes()); + response.getBody().write(formattedFrame.getBytes(SockJsFrame.CHARSET)); } catch (IOException ex) { throw new SockJsException("Failed to send " + frame, sockJsSession.getId(), ex); diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java index a3d492ecf564..ab90363c7f1c 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java @@ -257,7 +257,8 @@ public void handleSuccessiveRequest(ServerHttpRequest request, ServerHttpRespons synchronized (this.responseLock) { try { if (isClosed()) { - response.getBody().write(SockJsFrame.closeFrameGoAway().getContentBytes()); + String formattedFrame = frameFormat.format(SockJsFrame.closeFrameGoAway()); + response.getBody().write(formattedFrame.getBytes(SockJsFrame.CHARSET)); return; } this.response = response; From 11cb93823270e8c7003c6bf21909bef0601f062d Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Mon, 14 Feb 2022 16:34:40 +0000 Subject: [PATCH 689/735] Polishing contribution Closes gh-28000 --- .../AbstractHttpSendingTransportHandler.java | 32 +++++++++---------- .../session/AbstractHttpSockJsSession.java | 2 +- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpSendingTransportHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpSendingTransportHandler.java index 73aac7449e4d..9a2f75d1ba08 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpSendingTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpSendingTransportHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,15 +79,7 @@ else if (sockJsSession.isClosed()) { if (logger.isDebugEnabled()) { logger.debug("Connection already closed (but not removed yet) for " + sockJsSession); } - SockJsFrameFormat frameFormat = this.getFrameFormat(request); - SockJsFrame frame = SockJsFrame.closeFrameGoAway(); - String formattedFrame = frameFormat.format(frame); - try { - response.getBody().write(formattedFrame.getBytes(SockJsFrame.CHARSET)); - } - catch (IOException ex) { - throw new SockJsException("Failed to send " + frame, sockJsSession.getId(), ex); - } + writeFrame(SockJsFrame.closeFrameGoAway(), request, response, sockJsSession); } else if (!sockJsSession.isActive()) { if (logger.isTraceEnabled()) { @@ -99,13 +91,19 @@ else if (!sockJsSession.isActive()) { if (logger.isDebugEnabled()) { logger.debug("Another " + getTransportType() + " connection still open for " + sockJsSession); } - String formattedFrame = getFrameFormat(request).format(SockJsFrame.closeFrameAnotherConnectionOpen()); - try { - response.getBody().write(formattedFrame.getBytes(SockJsFrame.CHARSET)); - } - catch (IOException ex) { - throw new SockJsException("Failed to send " + formattedFrame, sockJsSession.getId(), ex); - } + writeFrame(SockJsFrame.closeFrameAnotherConnectionOpen(), request, response, sockJsSession); + } + } + + private void writeFrame(SockJsFrame frame, ServerHttpRequest request, ServerHttpResponse response, + AbstractHttpSockJsSession sockJsSession) { + + String formattedFrame = getFrameFormat(request).format(frame); + try { + response.getBody().write(formattedFrame.getBytes(SockJsFrame.CHARSET)); + } + catch (IOException ex) { + throw new SockJsException("Failed to send " + formattedFrame, sockJsSession.getId(), ex); } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java index ab90363c7f1c..04372fb52bf5 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2022 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. From ec03e8830ed0edb3cffbda1395c491127c0353b6 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Mon, 14 Feb 2022 20:50:38 +0000 Subject: [PATCH 690/735] Remove path variables from pathWithinMapping Closes gh-27913 --- .../web/servlet/handler/AbstractUrlHandlerMapping.java | 8 ++++---- .../web/servlet/handler/SimpleUrlHandlerMappingTests.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java index 2f7be313ca98..812060198e63 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,6 @@ import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; -import org.springframework.http.server.PathContainer; import org.springframework.http.server.RequestPath; import org.springframework.lang.Nullable; import org.springframework.util.AntPathMatcher; @@ -216,8 +215,9 @@ protected Object lookupHandler( handler = obtainApplicationContext().getBean(handlerName); } validateHandler(handler, request); - PathContainer pathWithinMapping = pattern.extractPathWithinPattern(path.pathWithinApplication()); - return buildPathExposingHandler(handler, pattern.getPatternString(), pathWithinMapping.value(), null); + String pathWithinMapping = pattern.extractPathWithinPattern(path.pathWithinApplication()).value(); + pathWithinMapping = UrlPathHelper.defaultInstance.removeSemicolonContent(pathWithinMapping); + return buildPathExposingHandler(handler, pattern.getPatternString(), pathWithinMapping, null); } /** diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMappingTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMappingTests.java index d3cace663e37..c47a5e04485e 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMappingTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMappingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -102,7 +102,7 @@ void checkMappings(String beanName) throws Exception { assertThat(request.getAttribute(PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).isEqualTo("/welcome.html"); assertThat(request.getAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE)).isEqualTo(bean); - request = PathPatternsTestUtils.initRequest("GET", "/welcome.x", usePathPatterns); + request = PathPatternsTestUtils.initRequest("GET", "/welcome.x;jsessionid=123", usePathPatterns); chain = getHandler(hm, request); assertThat(chain.getHandler()).isSameAs(otherBean); assertThat(request.getAttribute(PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).isEqualTo("welcome.x"); From 5bbc7dbce237f049a53291d47d6b1e5f6f897907 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 15 Feb 2022 13:15:20 +0100 Subject: [PATCH 691/735] Polish ProtectedAccess options This commit improves how protected access analysis operates. Rather than providing a static boolean, a function callback for the member to analyse is used. This permits to change the decision whether reflection can be used, or if the return type is assigned. Both of those are already applicable, with InjectionGenerator relying on reflection for private fields, and DefaultBeanInstanceGenerator assigning the bean instance if additional contributors are present. This commit also moves the logic of computing the options where the code is actually generated. See gh-28030 --- .../DefaultBeanInstanceGenerator.java | 8 +- .../factory/generator/InjectionGenerator.java | 28 +++- .../generator/InjectionGeneratorTests.java | 62 +++++++- .../aot/generator/ProtectedAccess.java | 103 +++++++++---- .../aot/generator/ProtectedAccessTests.java | 136 +++++++++--------- 5 files changed, 237 insertions(+), 100 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGenerator.java index 8c5006150f5c..b513aea16efa 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGenerator.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGenerator.java @@ -39,19 +39,21 @@ */ class DefaultBeanInstanceGenerator { - private static final Options BEAN_INSTANCE_OPTIONS = new Options(false, true); - private final Executable instanceCreator; private final List contributors; private final InjectionGenerator injectionGenerator; + private final Options beanInstanceOptions; + DefaultBeanInstanceGenerator(Executable instanceCreator, List contributors) { this.instanceCreator = instanceCreator; this.contributors = List.copyOf(contributors); this.injectionGenerator = new InjectionGenerator(); + this.beanInstanceOptions = Options.defaults().useReflection(member -> false) + .assignReturnType(member -> !this.contributors.isEmpty()).build(); } /** @@ -62,7 +64,7 @@ class DefaultBeanInstanceGenerator { */ public CodeContribution generateBeanInstance(RuntimeHints runtimeHints) { DefaultCodeContribution contribution = new DefaultCodeContribution(runtimeHints); - contribution.protectedAccess().analyze(this.instanceCreator, BEAN_INSTANCE_OPTIONS); + contribution.protectedAccess().analyze(this.instanceCreator, this.beanInstanceOptions); if (this.instanceCreator instanceof Constructor constructor) { writeBeanInstantiation(contribution, constructor); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/InjectionGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/InjectionGenerator.java index c4845b339b73..ce8c94818d05 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/generator/InjectionGenerator.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/InjectionGenerator.java @@ -28,6 +28,8 @@ import java.util.List; import java.util.function.Consumer; +import org.springframework.aot.generator.ProtectedAccess; +import org.springframework.aot.generator.ProtectedAccess.Options; import org.springframework.beans.factory.generator.config.BeanDefinitionRegistrar.BeanInstanceContext; import org.springframework.javapoet.CodeBlock; import org.springframework.javapoet.CodeBlock.Builder; @@ -51,6 +53,12 @@ */ public class InjectionGenerator { + private static final Options FIELD_INJECTION_OPTIONS = Options.defaults() + .useReflection(member -> Modifier.isPrivate(member.getModifiers())).build(); + + private static final Options METHOD_INJECTION_OPTIONS = Options.defaults() + .useReflection(member -> false).build(); + private final BeanParameterGenerator parameterGenerator = new BeanParameterGenerator(); @@ -77,7 +85,8 @@ public CodeBlock writeInstantiation(Executable creator) { * in the specified {@link Member}. * @param member the field or method to inject * @param required whether the value is required - * @return a statement that injects a value to the specified membmer + * @return a statement that injects a value to the specified member + * @see #getProtectedAccessInjectionOptions(Member) */ public CodeBlock writeInjection(Member member, boolean required) { if (member instanceof Method method) { @@ -89,6 +98,23 @@ public CodeBlock writeInjection(Member member, boolean required) { throw new IllegalArgumentException("Could not handle member " + member); } + /** + * Return the {@link Options} to use if protected access analysis is + * required for the specified {@link Member}. + * @param member the field or method to handle + * @return the options to use to analyse protected access + * @see ProtectedAccess + */ + public Options getProtectedAccessInjectionOptions(Member member) { + if (member instanceof Method) { + return METHOD_INJECTION_OPTIONS; + } + if (member instanceof Field) { + return FIELD_INJECTION_OPTIONS; + } + throw new IllegalArgumentException("Could not handle member " + member); + } + private CodeBlock write(Constructor creator) { Builder code = CodeBlock.builder(); Class declaringType = ClassUtils.getUserClass(creator.getDeclaringClass()); diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/generator/InjectionGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/generator/InjectionGeneratorTests.java index 910e66b6db6c..e782db598bc7 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/generator/InjectionGeneratorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/generator/InjectionGeneratorTests.java @@ -24,6 +24,8 @@ import org.junit.jupiter.api.Test; +import org.springframework.aot.generator.ProtectedAccess; +import org.springframework.aot.generator.ProtectedAccess.Options; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.generator.InjectionGeneratorTests.SimpleConstructorBean.InnerClass; import org.springframework.javapoet.support.CodeSnippet; @@ -40,6 +42,8 @@ */ class InjectionGeneratorTests { + private final ProtectedAccess protectedAccess = new ProtectedAccess(); + @Test void writeInstantiationForConstructorWithNoArgUseShortcut() { Constructor constructor = SimpleBean.class.getDeclaredConstructors()[0]; @@ -162,6 +166,42 @@ void writeInjectionForRequiredPrivateField() { })"""); } + @Test + void getProtectedAccessInjectionOptionsForUnsupportedMember() { + assertThatIllegalArgumentException().isThrownBy(() -> + getProtectedAccessInjectionOptions(mock(Member.class))); + } + + @Test + void getProtectedAccessInjectionOptionsForPackagePublicField() { + analyzeProtectedAccess(field(SampleBean.class, "enabled")); + assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); + } + + @Test + void getProtectedAccessInjectionOptionsForPackageProtectedField() { + analyzeProtectedAccess(field(SampleBean.class, "counter")); + assertPrivilegedAccess(SampleBean.class); + } + + @Test + void getProtectedAccessInjectionOptionsForPrivateField() { + analyzeProtectedAccess(field(SampleBean.class, "source")); + assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); + } + + @Test + void getProtectedAccessInjectionOptionsForPublicMethod() { + analyzeProtectedAccess(method(SampleBean.class, "setEnabled", Boolean.class)); + assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); + } + + @Test + void getProtectedAccessInjectionOptionsForPackageProtectedMethod() { + analyzeProtectedAccess(method(SampleBean.class, "sourceAndCounter", String.class, Integer.class)); + assertPrivilegedAccess(SampleBean.class); + } + private Method method(Class type, String name, Class... parameterTypes) { Method method = ReflectionUtils.findMethod(type, name, parameterTypes); @@ -183,14 +223,34 @@ private String writeInjection(Member member, boolean required) { return CodeSnippet.process(code -> code.add(new InjectionGenerator().writeInjection(member, required))); } + private void analyzeProtectedAccess(Member member) { + this.protectedAccess.analyze(member, getProtectedAccessInjectionOptions(member)); + } + + private Options getProtectedAccessInjectionOptions(Member member) { + return new InjectionGenerator().getProtectedAccessInjectionOptions(member); + } + + private void assertPrivilegedAccess(Class target) { + assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); + assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")).isEqualTo(target.getPackageName()); + assertThat(this.protectedAccess.isAccessible(target.getPackageName())).isTrue(); + } + @SuppressWarnings("unused") - static class SampleBean { + public static class SampleBean { + + public Boolean enabled; private String source; Integer counter; + public void setEnabled(Boolean enabled) { + + } + void sourceAndCounter(String source, Integer counter) { } diff --git a/spring-core/src/main/java/org/springframework/aot/generator/ProtectedAccess.java b/spring-core/src/main/java/org/springframework/aot/generator/ProtectedAccess.java index 337be6f44202..f0fc6c84a2dc 100644 --- a/spring-core/src/main/java/org/springframework/aot/generator/ProtectedAccess.java +++ b/spring-core/src/main/java/org/springframework/aot/generator/ProtectedAccess.java @@ -33,7 +33,7 @@ import org.springframework.util.ClassUtils; /** - * Gather the need of non-public access and determine the priviledged package + * Gather the need of non-public access and determine the privileged package * to use, if necessary. * * @author Stephane Nicoll @@ -104,15 +104,6 @@ public void analyze(ResolvableType type) { } } - /** - * Analyze accessing the specified {@link Member} using the default - * {@linkplain Options#DEFAULTS options}. - * @param member the member to analyze - */ - public void analyze(Member member) { - analyze(member, Options.DEFAULTS); - } - /** * Analyze accessing the specified {@link Member} using the specified * {@link Options options}. @@ -123,12 +114,12 @@ public void analyze(Member member, Options options) { if (isProtected(member.getDeclaringClass())) { registerProtectedType(member.getDeclaringClass(), member); } - if (!options.useReflection && isProtected(member.getModifiers())) { + if (isProtected(member.getModifiers()) && !options.useReflection.apply(member)) { registerProtectedType(member.getDeclaringClass(), member); } if (member instanceof Field field) { ResolvableType fieldType = ResolvableType.forField(field); - if (options.assignReturnType && isProtected(fieldType)) { + if (isProtected(fieldType) && options.assignReturnType.apply(field)) { registerProtectedType(fieldType, field); } } @@ -138,7 +129,7 @@ else if (member instanceof Constructor constructor) { } else if (member instanceof Method method) { ResolvableType returnType = ResolvableType.forMethodReturnType(method); - if (!options.assignReturnType && isProtected(returnType)) { + if (isProtected(returnType) && options.assignReturnType.apply(method)) { registerProtectedType(returnType, method); } analyzeParameterTypes(method, i -> ResolvableType.forMethodParameter(method, i)); @@ -204,32 +195,82 @@ private void registerProtectedType(Class type, Member member) { * Options to use to analyze if invoking a {@link Member} requires * privileged access. */ - public static class Options { + public static final class Options { - /** - * Default options that does fallback to reflection and does not - * assign the default type. - */ - public static final Options DEFAULTS = new Options(); + private final Function assignReturnType; + + private final Function useReflection; - private final boolean useReflection; - private final boolean assignReturnType; + private Options(Builder builder) { + this.assignReturnType = builder.assignReturnType; + this.useReflection = builder.useReflection; + } /** - * Create a new instance with the specified options. - * @param useReflection whether the writer can automatically use - * reflection to invoke a protected member if it is not public - * @param assignReturnType whether the writer needs to assign the - * return type, or if it is irrelevant + * Initialize a {@link Builder} with default options, that is use + * reflection if the member is private and does not assign the + * return type. + * @return an options builder */ - public Options(boolean useReflection, boolean assignReturnType) { - this.useReflection = useReflection; - this.assignReturnType = assignReturnType; + public static Builder defaults() { + return new Builder(member -> false, + member -> Modifier.isPrivate(member.getModifiers())); } - private Options() { - this(true, false); + public static final class Builder { + + private Function assignReturnType; + + private Function useReflection; + + private Builder(Function assignReturnType, + Function useReflection) { + this.assignReturnType = assignReturnType; + this.useReflection = useReflection; + } + + /** + * Specify if the return type is assigned so that its type can be + * analyzed if necessary. + * @param assignReturnType whether the return type is assigned + * @return {@code this}, to facilitate method chaining + */ + public Builder assignReturnType(boolean assignReturnType) { + return assignReturnType(member -> assignReturnType); + } + + /** + * Specify a function that determines whether the return type is + * assigned so that its type can be analyzed. + * @param assignReturnType whether the return type is assigned + * @return {@code this}, to facilitate method chaining + */ + public Builder assignReturnType(Function assignReturnType) { + this.assignReturnType = assignReturnType; + return this; + } + + /** + * Specify a function that determines whether reflection can be + * used for a given {@link Member}. + * @param useReflection whether reflection can be used + * @return {@code this}, to facilitate method chaining + */ + public Builder useReflection(Function useReflection) { + this.useReflection = useReflection; + return this; + } + + /** + * Build an {@link Options} instance based on the state of this + * builder. + * @return a new options instance + */ + public Options build() { + return new Options(this); + } + } } diff --git a/spring-core/src/test/java/org/springframework/aot/generator/ProtectedAccessTests.java b/spring-core/src/test/java/org/springframework/aot/generator/ProtectedAccessTests.java index 5a996272ebc6..9c1cc19897a1 100644 --- a/spring-core/src/test/java/org/springframework/aot/generator/ProtectedAccessTests.java +++ b/spring-core/src/test/java/org/springframework/aot/generator/ProtectedAccessTests.java @@ -16,8 +16,10 @@ package org.springframework.aot.generator; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import org.junit.jupiter.api.Test; @@ -37,128 +39,126 @@ */ class ProtectedAccessTests { + public static final Options DEFAULT_OPTIONS = Options.defaults().build(); + private final ProtectedAccess protectedAccess = new ProtectedAccess(); @Test void analyzeWithPublicConstructor() throws NoSuchMethodException { - this.protectedAccess.analyze(PublicClass.class.getConstructor()); + this.protectedAccess.analyze(PublicClass.class.getConstructor(), DEFAULT_OPTIONS); assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); } @Test - void analyzeWithPackagePrivateConstructorAndDefaultOptions() { - this.protectedAccess.analyze(ProtectedAccessor.class.getDeclaredConstructors()[0]); - assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); - assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")).isNull(); + void analyzeWithPackagePrivateConstructor() { + this.protectedAccess.analyze(ProtectedAccessor.class.getDeclaredConstructors()[0], + DEFAULT_OPTIONS); + assertPrivilegedAccess(ProtectedAccessor.class); } @Test - void analyzeWithPackagePrivateConstructorAndReflectionDisabled() { - this.protectedAccess.analyze(ProtectedAccessor.class.getDeclaredConstructors()[0], - new Options(false, true)); - assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); - assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")) - .isEqualTo(ProtectedAccessor.class.getPackageName()); - assertThat(this.protectedAccess.isAccessible(ProtectedAccessor.class.getPackageName())).isTrue(); + void analyzeWithPackagePrivateConstructorAndReflectionEnabled() { + Constructor constructor = ProtectedAccessor.class.getDeclaredConstructors()[0]; + this.protectedAccess.analyze(constructor, + Options.defaults().useReflection(member -> member.equals(constructor)).build()); + assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); } @Test void analyzeWithPackagePrivateClass() { - this.protectedAccess.analyze(ProtectedClass.class.getDeclaredConstructors()[0]); - assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); - assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")) - .isEqualTo(ProtectedClass.class.getPackageName()); - assertThat(this.protectedAccess.isAccessible(ProtectedClass.class.getPackageName())).isTrue(); + this.protectedAccess.analyze(ProtectedClass.class.getDeclaredConstructors()[0], DEFAULT_OPTIONS); + assertPrivilegedAccess(ProtectedClass.class); } @Test void analyzeWithPackagePrivateDeclaringType() { - this.protectedAccess.analyze(method(ProtectedClass.class, "stringBean")); - assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); - assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")) - .isEqualTo(ProtectedClass.class.getPackageName()); - assertThat(this.protectedAccess.isAccessible(ProtectedClass.class.getPackageName())).isTrue(); + this.protectedAccess.analyze(method(ProtectedClass.class, "stringBean"), DEFAULT_OPTIONS); + assertPrivilegedAccess(ProtectedClass.class); } @Test void analyzeWithPackagePrivateConstructorParameter() { - this.protectedAccess.analyze(ProtectedParameter.class.getConstructors()[0]); - assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); - assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")) - .isEqualTo(ProtectedParameter.class.getPackageName()); - assertThat(this.protectedAccess.isAccessible(ProtectedParameter.class.getPackageName())).isTrue(); + this.protectedAccess.analyze(ProtectedParameter.class.getConstructors()[0], DEFAULT_OPTIONS); + assertPrivilegedAccess(ProtectedParameter.class); } @Test void analyzeWithPackagePrivateMethod() { - this.protectedAccess.analyze(method(PublicClass.class, "getProtectedMethod")); - assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); + this.protectedAccess.analyze(method(PublicClass.class, "getProtectedMethod"), DEFAULT_OPTIONS); + assertPrivilegedAccess(PublicClass.class); } @Test - void analyzeWithPackagePrivateMethodAndReflectionDisabled() { + void analyzeWithPackagePrivateMethodAndReflectionEnabled() { this.protectedAccess.analyze(method(PublicClass.class, "getProtectedMethod"), - new Options(false, false)); - assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); + Options.defaults().useReflection(member -> !Modifier.isPublic(member.getModifiers())).build()); + assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); } @Test void analyzeWithPackagePrivateMethodReturnType() { - this.protectedAccess.analyze(method(ProtectedAccessor.class, "methodWithProtectedReturnType")); - assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); - assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")) - .isEqualTo(ProtectedAccessor.class.getPackageName()); - assertThat(this.protectedAccess.isAccessible(ProtectedAccessor.class.getPackageName())).isTrue(); + this.protectedAccess.analyze(method(ProtectedAccessor.class, "methodWithProtectedReturnType"), DEFAULT_OPTIONS); + assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); + } + + @Test + void analyzeWithPackagePrivateMethodReturnTypeAndAssignReturnTypeFunction() { + this.protectedAccess.analyze(method(ProtectedAccessor.class, "methodWithProtectedReturnType"), + Options.defaults().assignReturnType(member -> false).build()); + assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); + } + + @Test + void analyzeWithPackagePrivateMethodReturnTypeAndAssignReturnType() { + this.protectedAccess.analyze(method(ProtectedAccessor.class, "methodWithProtectedReturnType"), + Options.defaults().assignReturnType(true).build()); + assertPrivilegedAccess(ProtectedAccessor.class); } @Test void analyzeWithPackagePrivateMethodParameter() { this.protectedAccess.analyze(method(ProtectedAccessor.class, "methodWithProtectedParameter", - ProtectedClass.class)); - assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); - assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")) - .isEqualTo(ProtectedClass.class.getPackageName()); - assertThat(this.protectedAccess.isAccessible(ProtectedClass.class.getPackageName())).isTrue(); + ProtectedClass.class), DEFAULT_OPTIONS); + assertPrivilegedAccess(ProtectedAccessor.class); } @Test void analyzeWithPackagePrivateField() { - this.protectedAccess.analyze(field(PublicClass.class, "protectedField")); - assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); + this.protectedAccess.analyze(field(PublicClass.class, "protectedField"), DEFAULT_OPTIONS); + assertPrivilegedAccess(PublicClass.class); } @Test - void analyzeWithPackagePrivateFieldAndReflectionDisabled() { + void analyzeWithPackagePrivateFieldAndReflectionEnabled() { this.protectedAccess.analyze(field(PublicClass.class, "protectedField"), - new Options(false, true)); - assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); - assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")) - .isEqualTo(PublicClass.class.getPackageName()); - assertThat(this.protectedAccess.isAccessible(PublicClass.class.getPackageName())).isTrue(); + Options.defaults().useReflection(member -> true).build()); + assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); } @Test void analyzeWithPublicFieldAndProtectedType() { + this.protectedAccess.analyze(field(PublicClass.class, "protectedClassField"), DEFAULT_OPTIONS); + assertThat(this.protectedAccess.isAccessible("com.example")).isTrue(); + } + + @Test + void analyzeWithPublicFieldAndProtectedTypeAssigned() { this.protectedAccess.analyze(field(PublicClass.class, "protectedClassField"), - new Options(false, true)); - assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); - assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")) - .isEqualTo(ProtectedClass.class.getPackageName()); - assertThat(this.protectedAccess.isAccessible(ProtectedClass.class.getPackageName())).isTrue(); + Options.defaults().assignReturnType(true).build()); + assertPrivilegedAccess(ProtectedClass.class); } @Test void analyzeWithPackagePrivateGenericArgument() { - this.protectedAccess.analyze(method(PublicFactoryBean.class, "protectedTypeFactoryBean")); - assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); - assertThat(this.protectedAccess.isAccessible(PublicFactoryBean.class.getPackageName())).isTrue(); + this.protectedAccess.analyze(method(PublicFactoryBean.class, "protectedTypeFactoryBean"), + Options.defaults().assignReturnType(true).build()); + assertPrivilegedAccess(PublicFactoryBean.class); } @Test void analyzeTypeWithProtectedGenericArgument() { this.protectedAccess.analyze(PublicFactoryBean.resolveToProtectedGenericParameter()); - assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); - assertThat(this.protectedAccess.isAccessible(PublicFactoryBean.class.getPackageName())).isTrue(); + assertPrivilegedAccess(PublicFactoryBean.class); } @Test @@ -169,13 +169,14 @@ void analyzeWithRecursiveType() { @Test void getProtectedPackageWithPublicAccess() throws NoSuchMethodException { - this.protectedAccess.analyze(PublicClass.class.getConstructor()); + this.protectedAccess.analyze(PublicClass.class.getConstructor(), DEFAULT_OPTIONS); assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")).isNull(); } @Test void getProtectedPackageWithProtectedAccessInOnePackage() { - this.protectedAccess.analyze(method(PublicFactoryBean.class, "protectedTypeFactoryBean")); + this.protectedAccess.analyze(method(PublicFactoryBean.class, "protectedTypeFactoryBean"), + Options.defaults().assignReturnType(true).build()); assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")) .isEqualTo(PublicFactoryBean.class.getPackageName()); } @@ -185,14 +186,21 @@ void getProtectedPackageWithProtectedAccessInSeveralPackages() { Method protectedMethodFirstPackage = method(PublicFactoryBean.class, "protectedTypeFactoryBean"); Method protectedMethodSecondPackage = method(ProtectedAccessor.class, "methodWithProtectedParameter", ProtectedClass.class); - this.protectedAccess.analyze(protectedMethodFirstPackage); - this.protectedAccess.analyze(protectedMethodSecondPackage); + this.protectedAccess.analyze(protectedMethodFirstPackage, + Options.defaults().assignReturnType(true).build()); + this.protectedAccess.analyze(protectedMethodSecondPackage, DEFAULT_OPTIONS); assertThatThrownBy(() -> this.protectedAccess.getPrivilegedPackageName("com.example")) .isInstanceOfSatisfying(ProtectedAccessException.class, ex -> assertThat(ex.getProtectedElements().stream().map(ProtectedElement::getMember)) .containsOnly(protectedMethodFirstPackage, protectedMethodSecondPackage)); } + private void assertPrivilegedAccess(Class target) { + assertThat(this.protectedAccess.isAccessible("com.example")).isFalse(); + assertThat(this.protectedAccess.getPrivilegedPackageName("com.example")).isEqualTo(target.getPackageName()); + assertThat(this.protectedAccess.isAccessible(target.getPackageName())).isTrue(); + } + private static Method method(Class type, String name, Class... parameterTypes) { Method method = ReflectionUtils.findMethod(type, name, parameterTypes); assertThat(method).isNotNull(); From 2141373c432dfc18bb665ec4f54b1e3c3b121c99 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 15 Feb 2022 09:00:47 +0100 Subject: [PATCH 692/735] Introduce AOT variant of BeanPostProcessor This commit introduces an optional interface that a BeanPostProcessor can implement to opt-in for providing a generated code equivalent of what it does with a regular runtime. This commit has a first implementation of this interface with AutowiredAnnotationBeanPostProcessor replacing its processing of autowired annotations by generated code. Closes gh-27921 --- .../AutowiredAnnotationBeanPostProcessor.java | 71 +++++++- .../factory/annotation/InjectionMetadata.java | 10 +- .../BeanInstanceAotPostProcessor.java | 46 +++++ ...nnotationBeanInstanceContributorTests.java | 167 ++++++++++++++++++ 4 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceAotPostProcessor.java create mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanInstanceContributorTests.java diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index 9e7fabe5c33f..dd644c9dd98a 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -22,10 +22,12 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashSet; @@ -37,6 +39,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.aot.generator.CodeContribution; +import org.springframework.aot.hint.ExecutableMode; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; @@ -48,9 +52,13 @@ import org.springframework.beans.factory.InjectionPoint; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.UnsatisfiedDependencyException; +import org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.DependencyDescriptor; import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor; +import org.springframework.beans.factory.generator.BeanInstanceAotPostProcessor; +import org.springframework.beans.factory.generator.BeanInstanceContributor; +import org.springframework.beans.factory.generator.InjectionGenerator; import org.springframework.beans.factory.support.LookupOverride; import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor; import org.springframework.beans.factory.support.RootBeanDefinition; @@ -65,6 +73,7 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; @@ -131,7 +140,7 @@ * @see Value */ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, - MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { + MergedBeanDefinitionPostProcessor, BeanInstanceAotPostProcessor, PriorityOrdered, BeanFactoryAware { protected final Log logger = LogFactory.getLog(getClass()); @@ -255,8 +264,22 @@ public void setBeanFactory(BeanFactory beanFactory) { @Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) { + findInjectionMetadata(beanName, beanType, beanDefinition); + } + + @Override + public BeanInstanceContributor buildAotContributor(RootBeanDefinition beanDefinition, Class beanType, String beanName) { + InjectionMetadata metadata = findInjectionMetadata(beanName, beanType, beanDefinition); + Collection injectedElements = metadata.getInjectedElements(); + return (!ObjectUtils.isEmpty(injectedElements) + ? new AutowiredAnnotationBeanInstanceContributor(injectedElements) + : BeanInstanceContributor.NO_OP); + } + + private InjectionMetadata findInjectionMetadata(String beanName, Class beanType, RootBeanDefinition beanDefinition) { InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); + return metadata; } @Override @@ -798,6 +821,52 @@ private Object[] resolveMethodArguments(Method method, Object bean, @Nullable St } } + private static final class AutowiredAnnotationBeanInstanceContributor implements BeanInstanceContributor { + + private final Collection injectedElements; + + private final InjectionGenerator generator; + + AutowiredAnnotationBeanInstanceContributor(Collection injectedElements) { + this.injectedElements = injectedElements; + this.generator = new InjectionGenerator(); + } + + @Override + public void contribute(CodeContribution contribution) { + this.injectedElements.forEach(element -> { + boolean isRequired = isRequired(element); + Member member = element.getMember(); + analyzeMember(contribution, member); + contribution.statements().addStatement(this.generator.writeInjection(member, isRequired)); + }); + } + + private boolean isRequired(InjectedElement element) { + if (element instanceof AutowiredMethodElement injectedMethod) { + return injectedMethod.required; + } + else if (element instanceof AutowiredFieldElement injectedField) { + return injectedField.required; + } + return true; + } + + private void analyzeMember(CodeContribution contribution, Member member) { + if (member instanceof Method method) { + contribution.runtimeHints().reflection().registerMethod(method, + hint -> hint.setModes(ExecutableMode.INTROSPECT)); + contribution.protectedAccess().analyze(member, + this.generator.getProtectedAccessInjectionOptions(member)); + } + else if (member instanceof Field field) { + contribution.runtimeHints().reflection().registerField(field); + contribution.protectedAccess().analyze(member, + this.generator.getProtectedAccessInjectionOptions(member)); + } + } + + } /** * DependencyDescriptor variant with a pre-resolved target bean name. diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java index 4e205558523d..8898dea97a40 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -88,6 +88,14 @@ public InjectionMetadata(Class targetClass, Collection eleme } + /** + * Return the {@link InjectedElement elements} to inject. + * @return the elements to inject + */ + public Collection getInjectedElements() { + return Collections.unmodifiableCollection(this.injectedElements); + } + /** * Determine whether this metadata instance needs to be refreshed. * @param clazz the current target class diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceAotPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceAotPostProcessor.java new file mode 100644 index 000000000000..af2e87620d42 --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceAotPostProcessor.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.generator; + +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.beans.factory.support.RootBeanDefinition; + +/** + * Strategy interface to be implemented by a {@link BeanPostProcessor} that + * participates in a bean instance setup and can provide an equivalent setup + * using generated code. + * + *

    Contrary to other bean post processors, implementations of this interface + * are instantiated at build-time and should not rely on other beans in the + * context. + * + * @author Stephane Nicoll + * @since 6.0 + */ +@FunctionalInterface +public interface BeanInstanceAotPostProcessor extends BeanPostProcessor { + + /** + * Build a {@link BeanInstanceContributor} for the given bean definition. + * @param beanDefinition the merged bean definition for the bean + * @param beanType the actual type of the managed bean instance + * @param beanName the name of the bean + * @return the contributor to use + */ + BeanInstanceContributor buildAotContributor(RootBeanDefinition beanDefinition, Class beanType, String beanName); + +} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanInstanceContributorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanInstanceContributorTests.java new file mode 100644 index 000000000000..f0d1b7aa591e --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanInstanceContributorTests.java @@ -0,0 +1,167 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.annotation; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.generator.CodeContribution; +import org.springframework.aot.generator.DefaultCodeContribution; +import org.springframework.aot.hint.ExecutableMode; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.TypeReference; +import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessorTests.ResourceInjectionBean; +import org.springframework.beans.factory.generator.BeanInstanceContributor; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.testfixture.beans.TestBean; +import org.springframework.core.env.Environment; +import org.springframework.javapoet.support.CodeSnippet; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for code contribution of {@link AutowiredAnnotationBeanPostProcessor}. + * + * @author Stephane Nicoll + */ +class AutowiredAnnotationBeanInstanceContributorTests { + + @Test + void buildAotContributorWithPackageProtectedFieldInjection() { + CodeContribution contribution = contribute(PackageProtectedFieldInjectionSample.class); + assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo(""" + instanceContext.field("environment", Environment.class) + .invoke(beanFactory, (attributes) -> bean.environment = attributes.get(0))"""); + assertThat(contribution.runtimeHints().reflection().typeHints()).singleElement().satisfies(typeHint -> { + assertThat(typeHint.getType()).isEqualTo(TypeReference.of(PackageProtectedFieldInjectionSample.class)); + assertThat(typeHint.fields()).singleElement().satisfies(fieldHint -> { + assertThat(fieldHint.getName()).isEqualTo("environment"); + assertThat(fieldHint.isAllowWrite()).isTrue(); + assertThat(fieldHint.isAllowUnsafeAccess()).isFalse(); + }); + }); + assertThat(contribution.protectedAccess().getPrivilegedPackageName("com.example")) + .isEqualTo(PackageProtectedFieldInjectionSample.class.getPackageName()); + } + + @Test + void buildAotContributorWithPrivateFieldInjection() { + CodeContribution contribution = contribute(PrivateFieldInjectionSample.class); + assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo(""" + instanceContext.field("environment", Environment.class) + .invoke(beanFactory, (attributes) -> { + Field environmentField = ReflectionUtils.findField(AutowiredAnnotationBeanInstanceContributorTests.PrivateFieldInjectionSample.class, "environment", Environment.class); + ReflectionUtils.makeAccessible(environmentField); + ReflectionUtils.setField(environmentField, bean, attributes.get(0)); + })"""); + assertThat(contribution.runtimeHints().reflection().typeHints()).singleElement().satisfies(typeHint -> { + assertThat(typeHint.getType()).isEqualTo(TypeReference.of(PrivateFieldInjectionSample.class)); + assertThat(typeHint.fields()).singleElement().satisfies(fieldHint -> { + assertThat(fieldHint.getName()).isEqualTo("environment"); + assertThat(fieldHint.isAllowWrite()).isTrue(); + assertThat(fieldHint.isAllowUnsafeAccess()).isFalse(); + }); + }); + assertThat(contribution.protectedAccess().isAccessible("com.example")).isTrue(); + } + + @Test + void buildAotContributorWithPublicMethodInjection() { + CodeContribution contribution = contribute(PublicMethodInjectionSample.class); + assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo(""" + instanceContext.method("setTestBean", TestBean.class) + .invoke(beanFactory, (attributes) -> bean.setTestBean(attributes.get(0)))"""); + assertThat(contribution.runtimeHints().reflection().typeHints()).singleElement().satisfies(typeHint -> { + assertThat(typeHint.getType()).isEqualTo(TypeReference.of(PublicMethodInjectionSample.class)); + assertThat(typeHint.methods()).singleElement().satisfies(methodHint -> { + assertThat(methodHint.getName()).isEqualTo("setTestBean"); + assertThat(methodHint.getModes()).contains(ExecutableMode.INTROSPECT); + }); + }); + assertThat(contribution.protectedAccess().isAccessible("com.example")).isTrue(); + } + + @Test + void buildAotContributorWithInjectionPoints() { + CodeContribution contribution = contribute(ResourceInjectionBean.class); + assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo(""" + instanceContext.field("testBean", TestBean.class) + .resolve(beanFactory, false).ifResolved((attributes) -> { + Field testBeanField = ReflectionUtils.findField(AutowiredAnnotationBeanPostProcessorTests.ResourceInjectionBean.class, "testBean", TestBean.class); + ReflectionUtils.makeAccessible(testBeanField); + ReflectionUtils.setField(testBeanField, bean, attributes.get(0)); + }); + instanceContext.method("setTestBean2", TestBean.class) + .invoke(beanFactory, (attributes) -> bean.setTestBean2(attributes.get(0)));"""); + assertThat(contribution.runtimeHints().reflection().typeHints()).singleElement().satisfies(typeHint -> { + assertThat(typeHint.fields()).singleElement().satisfies(fieldHint -> + assertThat(fieldHint.getName()).isEqualTo("testBean")); + assertThat(typeHint.methods()).singleElement().satisfies(methodHint -> + assertThat(methodHint.getName()).isEqualTo("setTestBean2")); + }); + assertThat(contribution.protectedAccess().isAccessible("com.example")).isTrue(); + } + + @Test + void buildAotContributorWithoutInjectionPoints() { + BeanInstanceContributor contributor = createAotContributor(String.class); + assertThat(contributor).isNotNull().isSameAs(BeanInstanceContributor.NO_OP); + } + + private DefaultCodeContribution contribute(Class type) { + BeanInstanceContributor contributor = createAotContributor(type); + assertThat(contributor).isNotNull(); + DefaultCodeContribution contribution = new DefaultCodeContribution(new RuntimeHints()); + contributor.contribute(contribution); + return contribution; + } + + private BeanInstanceContributor createAotContributor(Class type) { + AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); + RootBeanDefinition beanDefinition = new RootBeanDefinition(type); + return bpp.buildAotContributor(beanDefinition, type, "test"); + } + + + public static class PackageProtectedFieldInjectionSample { + + @Autowired + Environment environment; + + } + + public static class PrivateFieldInjectionSample { + + @Autowired + private Environment environment; + + } + + public static class PublicMethodInjectionSample { + + @Autowired + public void setTestBean(TestBean testBean) { + + } + + public void setUnrelated(String unrelated) { + + } + + } + + +} From 3ea540adbce6fd61ee745b7b7a103f3a16ef95ec Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 15 Feb 2022 13:37:08 +0100 Subject: [PATCH 693/735] Upgrade to Reactor 2020.0.16 Closes gh-28039 --- build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index e126405cff45..7ef36356d006 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ configure(allprojects) { project -> imports { mavenBom "com.fasterxml.jackson:jackson-bom:2.12.6" mavenBom "io.netty:netty-bom:4.1.73.Final" - mavenBom "io.projectreactor:reactor-bom:2020.0.16-SNAPSHOT" + mavenBom "io.projectreactor:reactor-bom:2020.0.16" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR12" mavenBom "io.rsocket:rsocket-bom:1.1.1" mavenBom "org.eclipse.jetty:jetty-bom:9.4.44.v20210927" @@ -292,7 +292,6 @@ configure(allprojects) { project -> repositories { mavenCentral() maven { url "https://repo.spring.io/libs-spring-framework-build" } - maven { url "https://repo.spring.io/snapshot" } // reactor } } configurations.all { From 3188c0f7db54cffdb95e7127e2adde959dd078f9 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 15 Feb 2022 13:47:03 +0100 Subject: [PATCH 694/735] Ensure fix for gh-28012 is actually tested In 3ec612aaf8, I accidentally removed tests that verified support for non-synthesizable merged annotations for recursive annotations in Kotlin. This commit reinstates those non-synthesizable tests while retaining the synthesizable tests. --- .../springframework/core/annotation/Filter.kt | 4 -- .../KotlinMergedAnnotationsTests.kt | 68 ++++++++++++++++++- .../springframework/core/annotation/Person.kt | 4 -- .../core/annotation/SynthesizableFilter.kt | 35 ++++++++++ .../core/annotation/SynthesizableFilters.kt | 29 ++++++++ .../core/annotation/SynthesizablePerson.kt | 35 ++++++++++ 6 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 spring-core/src/test/kotlin/org/springframework/core/annotation/SynthesizableFilter.kt create mode 100644 spring-core/src/test/kotlin/org/springframework/core/annotation/SynthesizableFilters.kt create mode 100644 spring-core/src/test/kotlin/org/springframework/core/annotation/SynthesizablePerson.kt diff --git a/spring-core/src/test/kotlin/org/springframework/core/annotation/Filter.kt b/spring-core/src/test/kotlin/org/springframework/core/annotation/Filter.kt index 2755ba4d9b2f..9a05b5ba1adc 100644 --- a/spring-core/src/test/kotlin/org/springframework/core/annotation/Filter.kt +++ b/spring-core/src/test/kotlin/org/springframework/core/annotation/Filter.kt @@ -24,12 +24,8 @@ package org.springframework.core.annotation @Retention(AnnotationRetention.RUNTIME) public annotation class Filter( - @get:AliasFor("name") val value: String = "", - @get:AliasFor("value") - val name: String = "", - val and: Filters = Filters() ) diff --git a/spring-core/src/test/kotlin/org/springframework/core/annotation/KotlinMergedAnnotationsTests.kt b/spring-core/src/test/kotlin/org/springframework/core/annotation/KotlinMergedAnnotationsTests.kt index dedd3ced4166..fa32cfe3650d 100644 --- a/spring-core/src/test/kotlin/org/springframework/core/annotation/KotlinMergedAnnotationsTests.kt +++ b/spring-core/src/test/kotlin/org/springframework/core/annotation/KotlinMergedAnnotationsTests.kt @@ -41,6 +41,34 @@ class KotlinMergedAnnotationsTests { val mergedAnnotation = MergedAnnotation.from(method.getAnnotation(Person::class.java)) assertThat(mergedAnnotation).isNotNull(); + // NON-Synthesized Annotations + val jane = mergedAnnotation.synthesize() + assertThat(jane).isNotInstanceOf(SynthesizedAnnotation::class.java) + assertThat(jane.name).isEqualTo("jane") + val synthesizedFriends = jane.friends + assertThat(synthesizedFriends).hasSize(2) + + val john = synthesizedFriends[0] + assertThat(john).isNotInstanceOf(SynthesizedAnnotation::class.java) + assertThat(john.name).isEqualTo("john") + + val sally = synthesizedFriends[1] + assertThat(sally).isNotInstanceOf(SynthesizedAnnotation::class.java) + assertThat(sally.name).isEqualTo("sally") + } + + @Test // gh-28012 + fun recursiveAnnotationWithAttributeAliases() { + val method = javaClass.getMethod("synthesizablePersonMethod") + + // MergedAnnotations + val mergedAnnotations = MergedAnnotations.from(method) + assertThat(mergedAnnotations.isPresent(SynthesizablePerson::class.java)).isTrue(); + + // MergedAnnotation + val mergedAnnotation = MergedAnnotation.from(method.getAnnotation(SynthesizablePerson::class.java)) + assertThat(mergedAnnotation).isNotNull(); + // Synthesized Annotations val jane = mergedAnnotation.synthesize() assertThat(jane).isInstanceOf(SynthesizedAnnotation::class.java) @@ -72,6 +100,36 @@ class KotlinMergedAnnotationsTests { val mergedAnnotation = MergedAnnotation.from(method.getAnnotation(Filter::class.java)) assertThat(mergedAnnotation).isNotNull(); + // NON-Synthesized Annotations + val fooFilter = mergedAnnotation.synthesize() + assertThat(fooFilter).isNotInstanceOf(SynthesizedAnnotation::class.java) + assertThat(fooFilter.value).isEqualTo("foo") + val filters = fooFilter.and + assertThat(filters.value).hasSize(2) + + val barFilter = filters.value[0] + assertThat(barFilter).isNotInstanceOf(SynthesizedAnnotation::class.java) + assertThat(barFilter.value).isEqualTo("bar") + assertThat(barFilter.and.value).isEmpty() + + val bazFilter = filters.value[1] + assertThat(bazFilter).isNotInstanceOf(SynthesizedAnnotation::class.java) + assertThat(bazFilter.value).isEqualTo("baz") + assertThat(bazFilter.and.value).isEmpty() + } + + @Test // gh-28012 + fun recursiveNestedAnnotationWithAttributeAliases() { + val method = javaClass.getMethod("synthesizableFilterMethod") + + // MergedAnnotations + val mergedAnnotations = MergedAnnotations.from(method) + assertThat(mergedAnnotations.isPresent(SynthesizableFilter::class.java)).isTrue(); + + // MergedAnnotation + val mergedAnnotation = MergedAnnotation.from(method.getAnnotation(SynthesizableFilter::class.java)) + assertThat(mergedAnnotation).isNotNull(); + // Synthesized Annotations val fooFilter = mergedAnnotation.synthesize() assertThat(fooFilter).isInstanceOf(SynthesizedAnnotation::class.java) @@ -94,12 +152,20 @@ class KotlinMergedAnnotationsTests { } - @Person("jane", friends = [Person("john"), Person("sally")]) + @Person(name = "jane", friends = [Person(name = "john"), Person(name = "sally")]) fun personMethod() { } + @SynthesizablePerson(name = "jane", friends = [SynthesizablePerson(name = "john"), SynthesizablePerson(name = "sally")]) + fun synthesizablePersonMethod() { + } + @Filter("foo", and = Filters(Filter("bar"), Filter("baz"))) fun filterMethod() { } + @SynthesizableFilter("foo", and = SynthesizableFilters(SynthesizableFilter("bar"), SynthesizableFilter("baz"))) + fun synthesizableFilterMethod() { + } + } diff --git a/spring-core/src/test/kotlin/org/springframework/core/annotation/Person.kt b/spring-core/src/test/kotlin/org/springframework/core/annotation/Person.kt index 28d67c4a2364..4ae45e5feb0c 100644 --- a/spring-core/src/test/kotlin/org/springframework/core/annotation/Person.kt +++ b/spring-core/src/test/kotlin/org/springframework/core/annotation/Person.kt @@ -24,10 +24,6 @@ package org.springframework.core.annotation @Retention(AnnotationRetention.RUNTIME) public annotation class Person( - @get:AliasFor("name") - val value: String = "", - - @get:AliasFor("value") val name: String = "", vararg val friends: Person = [] diff --git a/spring-core/src/test/kotlin/org/springframework/core/annotation/SynthesizableFilter.kt b/spring-core/src/test/kotlin/org/springframework/core/annotation/SynthesizableFilter.kt new file mode 100644 index 000000000000..b10a970fdc6d --- /dev/null +++ b/spring-core/src/test/kotlin/org/springframework/core/annotation/SynthesizableFilter.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.annotation + +/** + * @author Sam Brannen + * @since 5.3.16 + */ +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +public annotation class SynthesizableFilter( + + @get:AliasFor("name") + val value: String = "", + + @get:AliasFor("value") + val name: String = "", + + val and: SynthesizableFilters = SynthesizableFilters() + +) diff --git a/spring-core/src/test/kotlin/org/springframework/core/annotation/SynthesizableFilters.kt b/spring-core/src/test/kotlin/org/springframework/core/annotation/SynthesizableFilters.kt new file mode 100644 index 000000000000..b961de1abe7a --- /dev/null +++ b/spring-core/src/test/kotlin/org/springframework/core/annotation/SynthesizableFilters.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.annotation + +/** + * @author Sam Brannen + * @since 5.3.16 + */ +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +public annotation class SynthesizableFilters( + + vararg val value: SynthesizableFilter + +) diff --git a/spring-core/src/test/kotlin/org/springframework/core/annotation/SynthesizablePerson.kt b/spring-core/src/test/kotlin/org/springframework/core/annotation/SynthesizablePerson.kt new file mode 100644 index 000000000000..01d6f870c7cb --- /dev/null +++ b/spring-core/src/test/kotlin/org/springframework/core/annotation/SynthesizablePerson.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.annotation + +/** + * @author Sam Brannen + * @since 5.3.16 + */ +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +public annotation class SynthesizablePerson( + + @get:AliasFor("name") + val value: String = "", + + @get:AliasFor("value") + val name: String = "", + + vararg val friends: SynthesizablePerson = [] + +) From 685a195ba17be18479ab682f808b14d8c586b3fa Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 15 Feb 2022 14:28:50 +0100 Subject: [PATCH 695/735] Deprecate SocketUtils SocketUtils was introduced in Spring Framework 4.0, primarily to assist in writing integration tests which start an external server on an available random port. However, these utilities make no guarantee about the subsequent availability of a given port and are therefore unreliable. Instead of using SocketUtils to find an available local port for a server, it is recommended that users rely on a server's ability to start on a random port that it selects or is assigned by the operating system. To interact with that server, the user should query the server for the port it is currently using. SocketUtils is now deprecated in 5.3.16 and will be removed in 6.0. Closes gh-28052 --- .../access/MBeanClientInterceptorTests.java | 6 +- .../RemoteMBeanClientInterceptorTests.java | 7 +-- .../ConnectorServerFactoryBeanTests.java | 6 +- ...MBeanServerConnectionFactoryBeanTests.java | 6 +- .../org/springframework/util/SocketUtils.java | 14 ++++- .../util/SocketUtilsTests.java | 63 ++++++++++--------- .../ReactorNettyTcpStompClientTests.java | 6 +- ...erRelayMessageHandlerIntegrationTests.java | 6 +- .../remoting/caucho/CauchoRemotingTests.java | 5 +- .../client/WebClientIntegrationTests.java | 6 +- 10 files changed, 69 insertions(+), 56 deletions(-) diff --git a/spring-context/src/test/java/org/springframework/jmx/access/MBeanClientInterceptorTests.java b/spring-context/src/test/java/org/springframework/jmx/access/MBeanClientInterceptorTests.java index f98384c231ac..f9863819b447 100644 --- a/spring-context/src/test/java/org/springframework/jmx/access/MBeanClientInterceptorTests.java +++ b/spring-context/src/test/java/org/springframework/jmx/access/MBeanClientInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -39,7 +39,6 @@ import org.springframework.jmx.JmxTestBean; import org.springframework.jmx.export.MBeanExporter; import org.springframework.jmx.export.assembler.AbstractReflectiveMBeanInfoAssembler; -import org.springframework.util.SocketUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -177,7 +176,8 @@ void invokeUnexposedMethodWithException() throws Exception { void lazyConnectionToRemote() throws Exception { assumeTrue(runTests); - final int port = SocketUtils.findAvailableTcpPort(); + @SuppressWarnings("deprecation") + final int port = org.springframework.util.SocketUtils.findAvailableTcpPort(); JMXServiceURL url = new JMXServiceURL("service:jmx:jmxmp://localhost:" + port); JMXConnectorServer connector = JMXConnectorServerFactory.newJMXConnectorServer(url, null, getServer()); diff --git a/spring-context/src/test/java/org/springframework/jmx/access/RemoteMBeanClientInterceptorTests.java b/spring-context/src/test/java/org/springframework/jmx/access/RemoteMBeanClientInterceptorTests.java index 5c4c4a3c0820..a617803188d7 100644 --- a/spring-context/src/test/java/org/springframework/jmx/access/RemoteMBeanClientInterceptorTests.java +++ b/spring-context/src/test/java/org/springframework/jmx/access/RemoteMBeanClientInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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,6 @@ import org.junit.jupiter.api.AfterEach; -import org.springframework.util.SocketUtils; - /** * @author Rob Harrop * @author Chris Beams @@ -37,7 +35,8 @@ */ class RemoteMBeanClientInterceptorTests extends MBeanClientInterceptorTests { - private final int servicePort = SocketUtils.findAvailableTcpPort(); + @SuppressWarnings("deprecation") + private final int servicePort = org.springframework.util.SocketUtils.findAvailableTcpPort(); private final String serviceUrl = "service:jmx:jmxmp://localhost:" + servicePort; diff --git a/spring-context/src/test/java/org/springframework/jmx/support/ConnectorServerFactoryBeanTests.java b/spring-context/src/test/java/org/springframework/jmx/support/ConnectorServerFactoryBeanTests.java index 111721d749b1..fad3ed40ec00 100644 --- a/spring-context/src/test/java/org/springframework/jmx/support/ConnectorServerFactoryBeanTests.java +++ b/spring-context/src/test/java/org/springframework/jmx/support/ConnectorServerFactoryBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,6 @@ import org.junit.jupiter.api.Test; import org.springframework.jmx.AbstractMBeanServerTests; -import org.springframework.util.SocketUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -47,7 +46,8 @@ class ConnectorServerFactoryBeanTests extends AbstractMBeanServerTests { private static final String OBJECT_NAME = "spring:type=connector,name=test"; - private final String serviceUrl = "service:jmx:jmxmp://localhost:" + SocketUtils.findAvailableTcpPort(); + @SuppressWarnings("deprecation") + private final String serviceUrl = "service:jmx:jmxmp://localhost:" + org.springframework.util.SocketUtils.findAvailableTcpPort(); @Test diff --git a/spring-context/src/test/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBeanTests.java b/spring-context/src/test/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBeanTests.java index faee0ae016c2..64159c6e5146 100644 --- a/spring-context/src/test/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBeanTests.java +++ b/spring-context/src/test/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import org.springframework.aop.support.AopUtils; import org.springframework.jmx.AbstractMBeanServerTests; -import org.springframework.util.SocketUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -39,7 +38,8 @@ */ class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTests { - private final String serviceUrl = "service:jmx:jmxmp://localhost:" + SocketUtils.findAvailableTcpPort(); + @SuppressWarnings("deprecation") + private final String serviceUrl = "service:jmx:jmxmp://localhost:" + org.springframework.util.SocketUtils.findAvailableTcpPort(); @Test diff --git a/spring-core/src/main/java/org/springframework/util/SocketUtils.java b/spring-core/src/main/java/org/springframework/util/SocketUtils.java index 557173e7e59c..a100bc6d8685 100644 --- a/spring-core/src/main/java/org/springframework/util/SocketUtils.java +++ b/spring-core/src/main/java/org/springframework/util/SocketUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -32,13 +32,25 @@ *

    Within this class, a TCP port refers to a port for a {@link ServerSocket}; * whereas, a UDP port refers to a port for a {@link DatagramSocket}. * + *

    {@code SocketUtils} was introduced in Spring Framework 4.0, primarily to + * assist in writing integration tests which start an external server on an + * available random port. However, these utilities make no guarantee about the + * subsequent availability of a given port and are therefore unreliable. Instead + * of using {@code SocketUtils} to find an available local port for a server, it + * is recommended that you rely on a server's ability to start on a random port + * that it selects or is assigned by the operating system. To interact with that + * server, you should query the server for the port it is currently using. + * * @author Sam Brannen * @author Ben Hale * @author Arjen Poutsma * @author Gunnar Hillert * @author Gary Russell * @since 4.0 + * @deprecated as of Spring Framework 5.3.16, to be removed in 6.0; see + * {@link SocketUtils class-level Javadoc} for details. */ +@Deprecated public class SocketUtils { /** diff --git a/spring-core/src/test/java/org/springframework/util/SocketUtilsTests.java b/spring-core/src/test/java/org/springframework/util/SocketUtilsTests.java index d13e78e6c61b..c0f8748195be 100644 --- a/spring-core/src/test/java/org/springframework/util/SocketUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/SocketUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.springframework.util.SocketUtils.PORT_RANGE_MAX; -import static org.springframework.util.SocketUtils.PORT_RANGE_MIN; /** * Unit tests for {@link SocketUtils}. @@ -37,6 +35,7 @@ * @author Sam Brannen * @author Gary Russell */ +@SuppressWarnings("deprecation") class SocketUtilsTests { @Test @@ -44,7 +43,7 @@ void canBeInstantiated() { // Just making sure somebody doesn't try to make SocketUtils abstract, // since that would be a breaking change due to the intentional public // constructor. - new SocketUtils(); + new org.springframework.util.SocketUtils(); } // TCP @@ -52,36 +51,37 @@ void canBeInstantiated() { @Test void findAvailableTcpPortWithZeroMinPort() { assertThatIllegalArgumentException().isThrownBy(() -> - SocketUtils.findAvailableTcpPort(0)); + org.springframework.util.SocketUtils.findAvailableTcpPort(0)); } @Test void findAvailableTcpPortWithNegativeMinPort() { assertThatIllegalArgumentException().isThrownBy(() -> - SocketUtils.findAvailableTcpPort(-500)); + org.springframework.util.SocketUtils.findAvailableTcpPort(-500)); } @Test void findAvailableTcpPort() { - int port = SocketUtils.findAvailableTcpPort(); - assertPortInRange(port, PORT_RANGE_MIN, PORT_RANGE_MAX); + int port = org.springframework.util.SocketUtils.findAvailableTcpPort(); + assertPortInRange(port, org.springframework.util.SocketUtils.PORT_RANGE_MIN, + org.springframework.util.SocketUtils.PORT_RANGE_MAX); } @Test void findAvailableTcpPortWithMinPortEqualToMaxPort() { - int minMaxPort = SocketUtils.findAvailableTcpPort(); - int port = SocketUtils.findAvailableTcpPort(minMaxPort, minMaxPort); + int minMaxPort = org.springframework.util.SocketUtils.findAvailableTcpPort(); + int port = org.springframework.util.SocketUtils.findAvailableTcpPort(minMaxPort, minMaxPort); assertThat(port).isEqualTo(minMaxPort); } @Test void findAvailableTcpPortWhenPortOnLoopbackInterfaceIsNotAvailable() throws Exception { - int port = SocketUtils.findAvailableTcpPort(); + int port = org.springframework.util.SocketUtils.findAvailableTcpPort(); try (ServerSocket socket = ServerSocketFactory.getDefault().createServerSocket(port, 1, InetAddress.getByName("localhost"))) { assertThat(socket).isNotNull(); // will only look for the exact port assertThatIllegalStateException().isThrownBy(() -> - SocketUtils.findAvailableTcpPort(port, port)) + org.springframework.util.SocketUtils.findAvailableTcpPort(port, port)) .withMessageStartingWith("Could not find an available TCP port") .withMessageEndingWith("after 1 attempts"); } @@ -89,15 +89,15 @@ void findAvailableTcpPortWhenPortOnLoopbackInterfaceIsNotAvailable() throws Exce @Test void findAvailableTcpPortWithMin() { - int port = SocketUtils.findAvailableTcpPort(50000); - assertPortInRange(port, 50000, PORT_RANGE_MAX); + int port = org.springframework.util.SocketUtils.findAvailableTcpPort(50000); + assertPortInRange(port, 50000, org.springframework.util.SocketUtils.PORT_RANGE_MAX); } @Test void findAvailableTcpPortInRange() { int minPort = 20000; int maxPort = minPort + 1000; - int port = SocketUtils.findAvailableTcpPort(minPort, maxPort); + int port = org.springframework.util.SocketUtils.findAvailableTcpPort(minPort, maxPort); assertPortInRange(port, minPort, maxPort); } @@ -133,29 +133,30 @@ void findAvailableTcpPortsWithRequestedNumberGreaterThanSizeOfRange() { @Test void findAvailableUdpPortWithZeroMinPort() { assertThatIllegalArgumentException().isThrownBy(() -> - SocketUtils.findAvailableUdpPort(0)); + org.springframework.util.SocketUtils.findAvailableUdpPort(0)); } @Test void findAvailableUdpPortWithNegativeMinPort() { assertThatIllegalArgumentException().isThrownBy(() -> - SocketUtils.findAvailableUdpPort(-500)); + org.springframework.util.SocketUtils.findAvailableUdpPort(-500)); } @Test void findAvailableUdpPort() { - int port = SocketUtils.findAvailableUdpPort(); - assertPortInRange(port, PORT_RANGE_MIN, PORT_RANGE_MAX); + int port = org.springframework.util.SocketUtils.findAvailableUdpPort(); + assertPortInRange(port, org.springframework.util.SocketUtils.PORT_RANGE_MIN, + org.springframework.util.SocketUtils.PORT_RANGE_MAX); } @Test void findAvailableUdpPortWhenPortOnLoopbackInterfaceIsNotAvailable() throws Exception { - int port = SocketUtils.findAvailableUdpPort(); + int port = org.springframework.util.SocketUtils.findAvailableUdpPort(); try (DatagramSocket socket = new DatagramSocket(port, InetAddress.getByName("localhost"))) { assertThat(socket).isNotNull(); // will only look for the exact port assertThatIllegalStateException().isThrownBy(() -> - SocketUtils.findAvailableUdpPort(port, port)) + org.springframework.util.SocketUtils.findAvailableUdpPort(port, port)) .withMessageStartingWith("Could not find an available UDP port") .withMessageEndingWith("after 1 attempts"); } @@ -163,15 +164,15 @@ void findAvailableUdpPortWhenPortOnLoopbackInterfaceIsNotAvailable() throws Exce @Test void findAvailableUdpPortWithMin() { - int port = SocketUtils.findAvailableUdpPort(50000); - assertPortInRange(port, 50000, PORT_RANGE_MAX); + int port = org.springframework.util.SocketUtils.findAvailableUdpPort(50000); + assertPortInRange(port, 50000, org.springframework.util.SocketUtils.PORT_RANGE_MAX); } @Test void findAvailableUdpPortInRange() { int minPort = 20000; int maxPort = minPort + 1000; - int port = SocketUtils.findAvailableUdpPort(minPort, maxPort); + int port = org.springframework.util.SocketUtils.findAvailableUdpPort(minPort, maxPort); assertPortInRange(port, minPort, maxPort); } @@ -205,22 +206,24 @@ void findAvailableUdpPortsWithRequestedNumberGreaterThanSizeOfRange() { // Helpers private void findAvailableTcpPorts(int numRequested) { - SortedSet ports = SocketUtils.findAvailableTcpPorts(numRequested); - assertAvailablePorts(ports, numRequested, PORT_RANGE_MIN, PORT_RANGE_MAX); + SortedSet ports = org.springframework.util.SocketUtils.findAvailableTcpPorts(numRequested); + assertAvailablePorts(ports, numRequested, org.springframework.util.SocketUtils.PORT_RANGE_MIN, + org.springframework.util.SocketUtils.PORT_RANGE_MAX); } private void findAvailableTcpPorts(int numRequested, int minPort, int maxPort) { - SortedSet ports = SocketUtils.findAvailableTcpPorts(numRequested, minPort, maxPort); + SortedSet ports = org.springframework.util.SocketUtils.findAvailableTcpPorts(numRequested, minPort, maxPort); assertAvailablePorts(ports, numRequested, minPort, maxPort); } private void findAvailableUdpPorts(int numRequested) { - SortedSet ports = SocketUtils.findAvailableUdpPorts(numRequested); - assertAvailablePorts(ports, numRequested, PORT_RANGE_MIN, PORT_RANGE_MAX); + SortedSet ports = org.springframework.util.SocketUtils.findAvailableUdpPorts(numRequested); + assertAvailablePorts(ports, numRequested, org.springframework.util.SocketUtils.PORT_RANGE_MIN, + org.springframework.util.SocketUtils.PORT_RANGE_MAX); } private void findAvailableUdpPorts(int numRequested, int minPort, int maxPort) { - SortedSet ports = SocketUtils.findAvailableUdpPorts(numRequested, minPort, maxPort); + SortedSet ports = org.springframework.util.SocketUtils.findAvailableUdpPorts(numRequested, minPort, maxPort); assertAvailablePorts(ports, numRequested, minPort, maxPort); } private void assertPortInRange(int port, int minPort, int maxPort) { diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClientTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClientTests.java index 90985f35d79b..502969e4d5de 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClientTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,6 @@ import org.springframework.messaging.simp.stomp.StompSession.Subscription; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.util.Assert; -import org.springframework.util.SocketUtils; import org.springframework.util.concurrent.ListenableFuture; import static org.assertj.core.api.Assertions.assertThat; @@ -61,7 +60,8 @@ public class ReactorNettyTcpStompClientTests { public void setup(TestInfo testInfo) throws Exception { logger.debug("Setting up before '" + testInfo.getTestMethod().get().getName() + "'"); - int port = SocketUtils.findAvailableTcpPort(61613); + @SuppressWarnings("deprecation") + int port = org.springframework.util.SocketUtils.findAvailableTcpPort(61613); this.activeMQBroker = new BrokerService(); this.activeMQBroker.addConnector("stomp://127.0.0.1:" + port); diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerIntegrationTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerIntegrationTests.java index c3c0d0293466..835cb47f769d 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerIntegrationTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,6 @@ import org.springframework.messaging.support.ExecutorSubscribableChannel; import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.Assert; -import org.springframework.util.SocketUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -75,10 +74,11 @@ public class StompBrokerRelayMessageHandlerIntegrationTests { @BeforeEach + @SuppressWarnings("deprecation") public void setup(TestInfo testInfo) throws Exception { logger.debug("Setting up before '" + testInfo.getTestMethod().get().getName() + "'"); - this.port = SocketUtils.findAvailableTcpPort(61613); + this.port = org.springframework.util.SocketUtils.findAvailableTcpPort(61613); this.responseChannel = new ExecutorSubscribableChannel(); this.responseHandler = new TestMessageHandler(); this.responseChannel.subscribe(this.responseHandler); diff --git a/spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java b/spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java index 58d1846bcf4a..e76b992d2c33 100644 --- a/spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java +++ b/spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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,7 +27,6 @@ import org.springframework.beans.testfixture.beans.ITestBean; import org.springframework.beans.testfixture.beans.TestBean; import org.springframework.remoting.RemoteAccessException; -import org.springframework.util.SocketUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -109,7 +108,7 @@ public void hessianProxyFactoryBeanWithCustomProxyFactory() throws Exception { @Test @SuppressWarnings("deprecation") public void simpleHessianServiceExporter() throws IOException { - final int port = SocketUtils.findAvailableTcpPort(); + final int port = org.springframework.util.SocketUtils.findAvailableTcpPort(); TestBean tb = new TestBean("tb"); SimpleHessianServiceExporter exporter = new SimpleHessianServiceExporter(); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java index e7fa002ff51b..4410e2102266 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -69,7 +69,6 @@ import org.springframework.http.client.reactive.HttpComponentsClientHttpConnector; import org.springframework.http.client.reactive.JettyClientHttpConnector; import org.springframework.http.client.reactive.ReactorClientHttpConnector; -import org.springframework.util.SocketUtils; import org.springframework.web.reactive.function.BodyExtractors; import org.springframework.web.reactive.function.client.WebClient.ResponseSpec; import org.springframework.web.testfixture.xml.Pojo; @@ -1245,7 +1244,8 @@ void malformedResponseChunksOnEntityWithBody(ClientHttpConnector connector) { private Mono doMalformedChunkedResponseTest( ClientHttpConnector connector, Function> handler) { - int port = SocketUtils.findAvailableTcpPort(); + @SuppressWarnings("deprecation") + int port = org.springframework.util.SocketUtils.findAvailableTcpPort(); Thread serverThread = new Thread(() -> { // No way to simulate a malformed chunked response through MockWebServer. From 552e02cb4421ea071bc119c0da3dcebaba0be5ac Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 15 Feb 2022 14:44:46 +0100 Subject: [PATCH 696/735] Polishing --- .../function/client/WebClientIntegrationTests.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java index 311603aa9773..4fd096fa1c13 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java @@ -1259,10 +1259,13 @@ private Mono doMalformedChunkedResponseTest( is.read(new byte[4096]); OutputStream os = socket.getOutputStream(); - os.write("HTTP/1.1 200 OK\r\n".getBytes(StandardCharsets.UTF_8)); - os.write("Transfer-Encoding: chunked\r\n".getBytes(StandardCharsets.UTF_8)); - os.write("\r\n".getBytes(StandardCharsets.UTF_8)); - os.write("lskdu018973t09sylgasjkfg1][]'./.sdlv".getBytes(StandardCharsets.UTF_8)); + os.write(""" + HTTP/1.1 200 OK + Transfer-Encoding: chunked + + lskdu018973t09sylgasjkfg1][]'./.sdlv""" + .replace("\n", "\r\n").getBytes(StandardCharsets.UTF_8)); + socket.close(); } catch (IOException ex) { @@ -1322,4 +1325,5 @@ public void setContainerValue(T containerValue) { this.containerValue = containerValue; } } + } From c42023f20e6f06f9be55e70102818b3f2e9dbe84 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 15 Feb 2022 14:59:09 +0100 Subject: [PATCH 697/735] Stop using SocketUtils in WebClientIntegrationTests See gh-28052 --- .../function/client/WebClientIntegrationTests.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java index 4fd096fa1c13..d48d17a82155 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java @@ -34,6 +34,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; @@ -1246,12 +1247,12 @@ void malformedResponseChunksOnEntityWithBody(ClientHttpConnector connector) { private Mono doMalformedChunkedResponseTest( ClientHttpConnector connector, Function> handler) { - @SuppressWarnings("deprecation") - int port = org.springframework.util.SocketUtils.findAvailableTcpPort(); + AtomicInteger port = new AtomicInteger(); Thread serverThread = new Thread(() -> { // No way to simulate a malformed chunked response through MockWebServer. - try (ServerSocket serverSocket = new ServerSocket(port)) { + try (ServerSocket serverSocket = new ServerSocket(0)) { + port.set(serverSocket.getLocalPort()); Socket socket = serverSocket.accept(); InputStream is = socket.getInputStream(); From d2d54c826f22e885d0401aeccc07c8838cd219c6 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 15 Feb 2022 14:57:56 +0100 Subject: [PATCH 698/735] Increase max memory for Gradle to 2048m --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 886369712793..22e37de470b7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ version=6.0.0-SNAPSHOT -org.gradle.jvmargs=-Xmx1536M +org.gradle.jvmargs=-Xmx2048m org.gradle.caching=true org.gradle.parallel=true kotlin.stdlib.default.dependency=false From 5fbd01f28f17965a0fa4661ee31dab3b929ec092 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 15 Feb 2022 15:25:45 +0100 Subject: [PATCH 699/735] Polish --- .../java/org/springframework/aot/hint/TypeHint.java | 11 +++++++++++ .../org/springframework/aot/hint/TypeHintTests.java | 8 +++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java b/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java index 8c62db8ff69e..ff7a1956541d 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java @@ -23,10 +23,12 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.StringJoiner; import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -39,6 +41,7 @@ public final class TypeHint { private final TypeReference type; + @Nullable private final TypeReference reachableType; private final Set fields; @@ -83,6 +86,7 @@ public TypeReference getType() { * {@code null} if this hint should always been applied. * @return the reachable type, if any */ + @Nullable public TypeReference getReachableType() { return this.reachableType; } @@ -119,6 +123,12 @@ public Set getMemberCategories() { return this.memberCategories; } + @Override + public String toString() { + return new StringJoiner(", ", TypeHint.class.getSimpleName() + "[", "]") + .add("type=" + this.type) + .toString(); + } /** * Builder for {@link TypeHint}. @@ -127,6 +137,7 @@ public static class Builder { private final TypeReference type; + @Nullable private TypeReference reachableType; private final Map fields = new HashMap<>(); diff --git a/spring-core/src/test/java/org/springframework/aot/hint/TypeHintTests.java b/spring-core/src/test/java/org/springframework/aot/hint/TypeHintTests.java index 89b1ad05826d..d6922c26bd76 100644 --- a/spring-core/src/test/java/org/springframework/aot/hint/TypeHintTests.java +++ b/spring-core/src/test/java/org/springframework/aot/hint/TypeHintTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -137,4 +137,10 @@ void createWithMemberCategory() { assertThat(hint.getMemberCategories()).containsOnly(MemberCategory.DECLARED_FIELDS); } + @Test + void typeHintHasAppropriateToString() { + TypeHint hint = TypeHint.of(TypeReference.of(String.class)).build(); + assertThat(hint).hasToString("TypeHint[type=java.lang.String]"); + } + } From bbd35ded9161f34c7f9a3d70f640a78d1258febc Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 15 Feb 2022 15:53:43 +0100 Subject: [PATCH 700/735] Stop using SocketUtils in ActiveMQ STOMP broker tests See gh-28052 --- .../ReactorNettyTcpStompClientTests.java | 16 +++++++++++----- ...erRelayMessageHandlerIntegrationTests.java | 19 ++++++++++++++++--- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClientTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClientTests.java index 502969e4d5de..ee2ee306f521 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClientTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClientTests.java @@ -17,6 +17,7 @@ package org.springframework.messaging.simp.stomp; import java.lang.reflect.Type; +import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -24,6 +25,7 @@ import java.util.concurrent.TimeUnit; import org.apache.activemq.broker.BrokerService; +import org.apache.activemq.broker.TransportConnector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.AfterEach; @@ -60,11 +62,9 @@ public class ReactorNettyTcpStompClientTests { public void setup(TestInfo testInfo) throws Exception { logger.debug("Setting up before '" + testInfo.getTestMethod().get().getName() + "'"); - @SuppressWarnings("deprecation") - int port = org.springframework.util.SocketUtils.findAvailableTcpPort(61613); - + TransportConnector stompConnector = createStompConnector(); this.activeMQBroker = new BrokerService(); - this.activeMQBroker.addConnector("stomp://127.0.0.1:" + port); + this.activeMQBroker.addConnector(stompConnector); this.activeMQBroker.setStartAsync(false); this.activeMQBroker.setPersistent(false); this.activeMQBroker.setUseJmx(false); @@ -75,11 +75,17 @@ public void setup(TestInfo testInfo) throws Exception { ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); taskScheduler.afterPropertiesSet(); - this.client = new ReactorNettyTcpStompClient("127.0.0.1", port); + this.client = new ReactorNettyTcpStompClient("127.0.0.1", stompConnector.getServer().getSocketAddress().getPort()); this.client.setMessageConverter(new StringMessageConverter()); this.client.setTaskScheduler(taskScheduler); } + private TransportConnector createStompConnector() throws Exception { + TransportConnector connector = new TransportConnector(); + connector.setUri(new URI("stomp://127.0.0.1:0")); + return connector; + } + @AfterEach public void shutdown() throws Exception { try { diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerIntegrationTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerIntegrationTests.java index 835cb47f769d..4eb0416973b1 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerIntegrationTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerIntegrationTests.java @@ -16,6 +16,7 @@ package org.springframework.messaging.simp.stomp; +import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; @@ -26,6 +27,7 @@ import java.util.concurrent.TimeUnit; import org.apache.activemq.broker.BrokerService; +import org.apache.activemq.broker.TransportConnector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.AfterEach; @@ -70,7 +72,8 @@ public class StompBrokerRelayMessageHandlerIntegrationTests { private TestEventPublisher eventPublisher; - private int port; + // initial value of zero implies that a random ephemeral port should be used + private int port = 0; @BeforeEach @@ -78,7 +81,6 @@ public class StompBrokerRelayMessageHandlerIntegrationTests { public void setup(TestInfo testInfo) throws Exception { logger.debug("Setting up before '" + testInfo.getTestMethod().get().getName() + "'"); - this.port = org.springframework.util.SocketUtils.findAvailableTcpPort(61613); this.responseChannel = new ExecutorSubscribableChannel(); this.responseHandler = new TestMessageHandler(); this.responseChannel.subscribe(this.responseHandler); @@ -88,14 +90,25 @@ public void setup(TestInfo testInfo) throws Exception { } private void startActiveMQBroker() throws Exception { + TransportConnector stompConnector = createStompConnector(this.port); this.activeMQBroker = new BrokerService(); - this.activeMQBroker.addConnector("stomp://localhost:" + this.port); + this.activeMQBroker.addConnector(stompConnector); this.activeMQBroker.setStartAsync(false); this.activeMQBroker.setPersistent(false); this.activeMQBroker.setUseJmx(false); this.activeMQBroker.getSystemUsage().getMemoryUsage().setLimit(1024 * 1024 * 5); this.activeMQBroker.getSystemUsage().getTempUsage().setLimit(1024 * 1024 * 5); this.activeMQBroker.start(); + + // Reuse existing ephemeral port on restart (i.e., the next time this method + // is invoked) since it will already be configured in the relay + this.port = (this.port != 0 ? this.port : stompConnector.getServer().getSocketAddress().getPort()); + } + + private TransportConnector createStompConnector(int port) throws Exception { + TransportConnector connector = new TransportConnector(); + connector.setUri(new URI("stomp://localhost:" + port)); + return connector; } private void createAndStartRelay() throws InterruptedException { From 2cee63491d1fbb6e21a9044715d98838fec9a51b Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 15 Feb 2022 16:19:11 +0100 Subject: [PATCH 701/735] Remove deprecated SocketUtils Closes gh-28052 --- .../access/MBeanClientInterceptorTests.java | 3 +- .../RemoteMBeanClientInterceptorTests.java | 4 +- .../ConnectorServerFactoryBeanTests.java | 3 +- ...MBeanServerConnectionFactoryBeanTests.java | 3 +- .../org/springframework/util/SocketUtils.java | 319 ------------------ .../util/SocketUtilsTests.java | 241 ------------- .../core/testfixture/net/TestSocketUtils.java | 140 ++++++++ 7 files changed, 149 insertions(+), 564 deletions(-) delete mode 100644 spring-core/src/main/java/org/springframework/util/SocketUtils.java delete mode 100644 spring-core/src/test/java/org/springframework/util/SocketUtilsTests.java create mode 100644 spring-core/src/testFixtures/java/org/springframework/core/testfixture/net/TestSocketUtils.java diff --git a/spring-context/src/test/java/org/springframework/jmx/access/MBeanClientInterceptorTests.java b/spring-context/src/test/java/org/springframework/jmx/access/MBeanClientInterceptorTests.java index f9863819b447..65b3d032bed7 100644 --- a/spring-context/src/test/java/org/springframework/jmx/access/MBeanClientInterceptorTests.java +++ b/spring-context/src/test/java/org/springframework/jmx/access/MBeanClientInterceptorTests.java @@ -34,6 +34,7 @@ import org.junit.jupiter.api.Test; import org.springframework.aop.framework.ProxyFactory; +import org.springframework.core.testfixture.net.TestSocketUtils; import org.springframework.jmx.AbstractMBeanServerTests; import org.springframework.jmx.IJmxTestBean; import org.springframework.jmx.JmxTestBean; @@ -177,7 +178,7 @@ void lazyConnectionToRemote() throws Exception { assumeTrue(runTests); @SuppressWarnings("deprecation") - final int port = org.springframework.util.SocketUtils.findAvailableTcpPort(); + final int port = TestSocketUtils.findAvailableTcpPort(); JMXServiceURL url = new JMXServiceURL("service:jmx:jmxmp://localhost:" + port); JMXConnectorServer connector = JMXConnectorServerFactory.newJMXConnectorServer(url, null, getServer()); diff --git a/spring-context/src/test/java/org/springframework/jmx/access/RemoteMBeanClientInterceptorTests.java b/spring-context/src/test/java/org/springframework/jmx/access/RemoteMBeanClientInterceptorTests.java index a617803188d7..f315bd46e113 100644 --- a/spring-context/src/test/java/org/springframework/jmx/access/RemoteMBeanClientInterceptorTests.java +++ b/spring-context/src/test/java/org/springframework/jmx/access/RemoteMBeanClientInterceptorTests.java @@ -28,6 +28,8 @@ import org.junit.jupiter.api.AfterEach; +import org.springframework.core.testfixture.net.TestSocketUtils; + /** * @author Rob Harrop * @author Chris Beams @@ -36,7 +38,7 @@ class RemoteMBeanClientInterceptorTests extends MBeanClientInterceptorTests { @SuppressWarnings("deprecation") - private final int servicePort = org.springframework.util.SocketUtils.findAvailableTcpPort(); + private final int servicePort = TestSocketUtils.findAvailableTcpPort(); private final String serviceUrl = "service:jmx:jmxmp://localhost:" + servicePort; diff --git a/spring-context/src/test/java/org/springframework/jmx/support/ConnectorServerFactoryBeanTests.java b/spring-context/src/test/java/org/springframework/jmx/support/ConnectorServerFactoryBeanTests.java index fad3ed40ec00..5f349774451f 100644 --- a/spring-context/src/test/java/org/springframework/jmx/support/ConnectorServerFactoryBeanTests.java +++ b/spring-context/src/test/java/org/springframework/jmx/support/ConnectorServerFactoryBeanTests.java @@ -30,6 +30,7 @@ import org.junit.jupiter.api.Test; +import org.springframework.core.testfixture.net.TestSocketUtils; import org.springframework.jmx.AbstractMBeanServerTests; import static org.assertj.core.api.Assertions.assertThat; @@ -47,7 +48,7 @@ class ConnectorServerFactoryBeanTests extends AbstractMBeanServerTests { private static final String OBJECT_NAME = "spring:type=connector,name=test"; @SuppressWarnings("deprecation") - private final String serviceUrl = "service:jmx:jmxmp://localhost:" + org.springframework.util.SocketUtils.findAvailableTcpPort(); + private final String serviceUrl = "service:jmx:jmxmp://localhost:" + TestSocketUtils.findAvailableTcpPort(); @Test diff --git a/spring-context/src/test/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBeanTests.java b/spring-context/src/test/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBeanTests.java index 64159c6e5146..6391f607f93c 100644 --- a/spring-context/src/test/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBeanTests.java +++ b/spring-context/src/test/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBeanTests.java @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test; import org.springframework.aop.support.AopUtils; +import org.springframework.core.testfixture.net.TestSocketUtils; import org.springframework.jmx.AbstractMBeanServerTests; import static org.assertj.core.api.Assertions.assertThat; @@ -39,7 +40,7 @@ class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTests { @SuppressWarnings("deprecation") - private final String serviceUrl = "service:jmx:jmxmp://localhost:" + org.springframework.util.SocketUtils.findAvailableTcpPort(); + private final String serviceUrl = "service:jmx:jmxmp://localhost:" + TestSocketUtils.findAvailableTcpPort(); @Test diff --git a/spring-core/src/main/java/org/springframework/util/SocketUtils.java b/spring-core/src/main/java/org/springframework/util/SocketUtils.java deleted file mode 100644 index a100bc6d8685..000000000000 --- a/spring-core/src/main/java/org/springframework/util/SocketUtils.java +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright 2002-2022 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util; - -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.util.Random; -import java.util.SortedSet; -import java.util.TreeSet; - -import javax.net.ServerSocketFactory; - -/** - * Simple utility methods for working with network sockets — for example, - * for finding available ports on {@code localhost}. - * - *

    Within this class, a TCP port refers to a port for a {@link ServerSocket}; - * whereas, a UDP port refers to a port for a {@link DatagramSocket}. - * - *

    {@code SocketUtils} was introduced in Spring Framework 4.0, primarily to - * assist in writing integration tests which start an external server on an - * available random port. However, these utilities make no guarantee about the - * subsequent availability of a given port and are therefore unreliable. Instead - * of using {@code SocketUtils} to find an available local port for a server, it - * is recommended that you rely on a server's ability to start on a random port - * that it selects or is assigned by the operating system. To interact with that - * server, you should query the server for the port it is currently using. - * - * @author Sam Brannen - * @author Ben Hale - * @author Arjen Poutsma - * @author Gunnar Hillert - * @author Gary Russell - * @since 4.0 - * @deprecated as of Spring Framework 5.3.16, to be removed in 6.0; see - * {@link SocketUtils class-level Javadoc} for details. - */ -@Deprecated -public class SocketUtils { - - /** - * The default minimum value for port ranges used when finding an available - * socket port. - */ - public static final int PORT_RANGE_MIN = 1024; - - /** - * The default maximum value for port ranges used when finding an available - * socket port. - */ - public static final int PORT_RANGE_MAX = 65535; - - - private static final Random random = new Random(System.nanoTime()); - - - /** - * Although {@code SocketUtils} consists solely of static utility methods, - * this constructor is intentionally {@code public}. - *

    Rationale

    - *

    Static methods from this class may be invoked from within XML - * configuration files using the Spring Expression Language (SpEL) and the - * following syntax. - *

    <bean id="bean1" ... p:port="#{T(org.springframework.util.SocketUtils).findAvailableTcpPort(12000)}" />
    - * If this constructor were {@code private}, you would be required to supply - * the fully qualified class name to SpEL's {@code T()} function for each usage. - * Thus, the fact that this constructor is {@code public} allows you to reduce - * boilerplate configuration with SpEL as can be seen in the following example. - *
    <bean id="socketUtils" class="org.springframework.util.SocketUtils" />
    -	 * <bean id="bean1" ... p:port="#{socketUtils.findAvailableTcpPort(12000)}" />
    -	 * <bean id="bean2" ... p:port="#{socketUtils.findAvailableTcpPort(30000)}" />
    - */ - public SocketUtils() { - } - - - /** - * Find an available TCP port randomly selected from the range - * [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. - * @return an available TCP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableTcpPort() { - return findAvailableTcpPort(PORT_RANGE_MIN); - } - - /** - * Find an available TCP port randomly selected from the range - * [{@code minPort}, {@value #PORT_RANGE_MAX}]. - * @param minPort the minimum port number - * @return an available TCP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableTcpPort(int minPort) { - return findAvailableTcpPort(minPort, PORT_RANGE_MAX); - } - - /** - * Find an available TCP port randomly selected from the range - * [{@code minPort}, {@code maxPort}]. - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return an available TCP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableTcpPort(int minPort, int maxPort) { - return SocketType.TCP.findAvailablePort(minPort, maxPort); - } - - /** - * Find the requested number of available TCP ports, each randomly selected - * from the range [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. - * @param numRequested the number of available ports to find - * @return a sorted set of available TCP port numbers - * @throws IllegalStateException if the requested number of available ports could not be found - */ - public static SortedSet findAvailableTcpPorts(int numRequested) { - return findAvailableTcpPorts(numRequested, PORT_RANGE_MIN, PORT_RANGE_MAX); - } - - /** - * Find the requested number of available TCP ports, each randomly selected - * from the range [{@code minPort}, {@code maxPort}]. - * @param numRequested the number of available ports to find - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return a sorted set of available TCP port numbers - * @throws IllegalStateException if the requested number of available ports could not be found - */ - public static SortedSet findAvailableTcpPorts(int numRequested, int minPort, int maxPort) { - return SocketType.TCP.findAvailablePorts(numRequested, minPort, maxPort); - } - - /** - * Find an available UDP port randomly selected from the range - * [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. - * @return an available UDP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableUdpPort() { - return findAvailableUdpPort(PORT_RANGE_MIN); - } - - /** - * Find an available UDP port randomly selected from the range - * [{@code minPort}, {@value #PORT_RANGE_MAX}]. - * @param minPort the minimum port number - * @return an available UDP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableUdpPort(int minPort) { - return findAvailableUdpPort(minPort, PORT_RANGE_MAX); - } - - /** - * Find an available UDP port randomly selected from the range - * [{@code minPort}, {@code maxPort}]. - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return an available UDP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableUdpPort(int minPort, int maxPort) { - return SocketType.UDP.findAvailablePort(minPort, maxPort); - } - - /** - * Find the requested number of available UDP ports, each randomly selected - * from the range [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. - * @param numRequested the number of available ports to find - * @return a sorted set of available UDP port numbers - * @throws IllegalStateException if the requested number of available ports could not be found - */ - public static SortedSet findAvailableUdpPorts(int numRequested) { - return findAvailableUdpPorts(numRequested, PORT_RANGE_MIN, PORT_RANGE_MAX); - } - - /** - * Find the requested number of available UDP ports, each randomly selected - * from the range [{@code minPort}, {@code maxPort}]. - * @param numRequested the number of available ports to find - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return a sorted set of available UDP port numbers - * @throws IllegalStateException if the requested number of available ports could not be found - */ - public static SortedSet findAvailableUdpPorts(int numRequested, int minPort, int maxPort) { - return SocketType.UDP.findAvailablePorts(numRequested, minPort, maxPort); - } - - - private enum SocketType { - - TCP { - @Override - protected boolean isPortAvailable(int port) { - try { - ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket( - port, 1, InetAddress.getByName("localhost")); - serverSocket.close(); - return true; - } - catch (Exception ex) { - return false; - } - } - }, - - UDP { - @Override - protected boolean isPortAvailable(int port) { - try { - DatagramSocket socket = new DatagramSocket(port, InetAddress.getByName("localhost")); - socket.close(); - return true; - } - catch (Exception ex) { - return false; - } - } - }; - - /** - * Determine if the specified port for this {@code SocketType} is - * currently available on {@code localhost}. - */ - protected abstract boolean isPortAvailable(int port); - - /** - * Find a pseudo-random port number within the range - * [{@code minPort}, {@code maxPort}]. - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return a random port number within the specified range - */ - private int findRandomPort(int minPort, int maxPort) { - int portRange = maxPort - minPort; - return minPort + random.nextInt(portRange + 1); - } - - /** - * Find an available port for this {@code SocketType}, randomly selected - * from the range [{@code minPort}, {@code maxPort}]. - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return an available port number for this socket type - * @throws IllegalStateException if no available port could be found - */ - int findAvailablePort(int minPort, int maxPort) { - Assert.isTrue(minPort > 0, "'minPort' must be greater than 0"); - Assert.isTrue(maxPort >= minPort, "'maxPort' must be greater than or equal to 'minPort'"); - Assert.isTrue(maxPort <= PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + PORT_RANGE_MAX); - - int portRange = maxPort - minPort; - int candidatePort; - int searchCounter = 0; - do { - if (searchCounter > portRange) { - throw new IllegalStateException(String.format( - "Could not find an available %s port in the range [%d, %d] after %d attempts", - name(), minPort, maxPort, searchCounter)); - } - candidatePort = findRandomPort(minPort, maxPort); - searchCounter++; - } - while (!isPortAvailable(candidatePort)); - - return candidatePort; - } - - /** - * Find the requested number of available ports for this {@code SocketType}, - * each randomly selected from the range [{@code minPort}, {@code maxPort}]. - * @param numRequested the number of available ports to find - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return a sorted set of available port numbers for this socket type - * @throws IllegalStateException if the requested number of available ports could not be found - */ - SortedSet findAvailablePorts(int numRequested, int minPort, int maxPort) { - Assert.isTrue(minPort > 0, "'minPort' must be greater than 0"); - Assert.isTrue(maxPort > minPort, "'maxPort' must be greater than 'minPort'"); - Assert.isTrue(maxPort <= PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + PORT_RANGE_MAX); - Assert.isTrue(numRequested > 0, "'numRequested' must be greater than 0"); - Assert.isTrue((maxPort - minPort) >= numRequested, - "'numRequested' must not be greater than 'maxPort' - 'minPort'"); - - SortedSet availablePorts = new TreeSet<>(); - int attemptCount = 0; - while ((++attemptCount <= numRequested + 100) && availablePorts.size() < numRequested) { - availablePorts.add(findAvailablePort(minPort, maxPort)); - } - - if (availablePorts.size() != numRequested) { - throw new IllegalStateException(String.format( - "Could not find %d available %s ports in the range [%d, %d]", - numRequested, name(), minPort, maxPort)); - } - - return availablePorts; - } - } - -} diff --git a/spring-core/src/test/java/org/springframework/util/SocketUtilsTests.java b/spring-core/src/test/java/org/springframework/util/SocketUtilsTests.java deleted file mode 100644 index c0f8748195be..000000000000 --- a/spring-core/src/test/java/org/springframework/util/SocketUtilsTests.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2002-2022 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util; - -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.util.SortedSet; - -import javax.net.ServerSocketFactory; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Unit tests for {@link SocketUtils}. - * - * @author Sam Brannen - * @author Gary Russell - */ -@SuppressWarnings("deprecation") -class SocketUtilsTests { - - @Test - void canBeInstantiated() { - // Just making sure somebody doesn't try to make SocketUtils abstract, - // since that would be a breaking change due to the intentional public - // constructor. - new org.springframework.util.SocketUtils(); - } - - // TCP - - @Test - void findAvailableTcpPortWithZeroMinPort() { - assertThatIllegalArgumentException().isThrownBy(() -> - org.springframework.util.SocketUtils.findAvailableTcpPort(0)); - } - - @Test - void findAvailableTcpPortWithNegativeMinPort() { - assertThatIllegalArgumentException().isThrownBy(() -> - org.springframework.util.SocketUtils.findAvailableTcpPort(-500)); - } - - @Test - void findAvailableTcpPort() { - int port = org.springframework.util.SocketUtils.findAvailableTcpPort(); - assertPortInRange(port, org.springframework.util.SocketUtils.PORT_RANGE_MIN, - org.springframework.util.SocketUtils.PORT_RANGE_MAX); - } - - @Test - void findAvailableTcpPortWithMinPortEqualToMaxPort() { - int minMaxPort = org.springframework.util.SocketUtils.findAvailableTcpPort(); - int port = org.springframework.util.SocketUtils.findAvailableTcpPort(minMaxPort, minMaxPort); - assertThat(port).isEqualTo(minMaxPort); - } - - @Test - void findAvailableTcpPortWhenPortOnLoopbackInterfaceIsNotAvailable() throws Exception { - int port = org.springframework.util.SocketUtils.findAvailableTcpPort(); - try (ServerSocket socket = ServerSocketFactory.getDefault().createServerSocket(port, 1, InetAddress.getByName("localhost"))) { - assertThat(socket).isNotNull(); - // will only look for the exact port - assertThatIllegalStateException().isThrownBy(() -> - org.springframework.util.SocketUtils.findAvailableTcpPort(port, port)) - .withMessageStartingWith("Could not find an available TCP port") - .withMessageEndingWith("after 1 attempts"); - } - } - - @Test - void findAvailableTcpPortWithMin() { - int port = org.springframework.util.SocketUtils.findAvailableTcpPort(50000); - assertPortInRange(port, 50000, org.springframework.util.SocketUtils.PORT_RANGE_MAX); - } - - @Test - void findAvailableTcpPortInRange() { - int minPort = 20000; - int maxPort = minPort + 1000; - int port = org.springframework.util.SocketUtils.findAvailableTcpPort(minPort, maxPort); - assertPortInRange(port, minPort, maxPort); - } - - @Test - void find4AvailableTcpPorts() { - findAvailableTcpPorts(4); - } - - @Test - void find50AvailableTcpPorts() { - findAvailableTcpPorts(50); - } - - @Test - void find4AvailableTcpPortsInRange() { - findAvailableTcpPorts(4, 30000, 35000); - } - - @Test - void find50AvailableTcpPortsInRange() { - findAvailableTcpPorts(50, 40000, 45000); - } - - @Test - void findAvailableTcpPortsWithRequestedNumberGreaterThanSizeOfRange() { - assertThatIllegalArgumentException().isThrownBy(() -> - findAvailableTcpPorts(50, 45000, 45010)); - } - - - // UDP - - @Test - void findAvailableUdpPortWithZeroMinPort() { - assertThatIllegalArgumentException().isThrownBy(() -> - org.springframework.util.SocketUtils.findAvailableUdpPort(0)); - } - - @Test - void findAvailableUdpPortWithNegativeMinPort() { - assertThatIllegalArgumentException().isThrownBy(() -> - org.springframework.util.SocketUtils.findAvailableUdpPort(-500)); - } - - @Test - void findAvailableUdpPort() { - int port = org.springframework.util.SocketUtils.findAvailableUdpPort(); - assertPortInRange(port, org.springframework.util.SocketUtils.PORT_RANGE_MIN, - org.springframework.util.SocketUtils.PORT_RANGE_MAX); - } - - @Test - void findAvailableUdpPortWhenPortOnLoopbackInterfaceIsNotAvailable() throws Exception { - int port = org.springframework.util.SocketUtils.findAvailableUdpPort(); - try (DatagramSocket socket = new DatagramSocket(port, InetAddress.getByName("localhost"))) { - assertThat(socket).isNotNull(); - // will only look for the exact port - assertThatIllegalStateException().isThrownBy(() -> - org.springframework.util.SocketUtils.findAvailableUdpPort(port, port)) - .withMessageStartingWith("Could not find an available UDP port") - .withMessageEndingWith("after 1 attempts"); - } - } - - @Test - void findAvailableUdpPortWithMin() { - int port = org.springframework.util.SocketUtils.findAvailableUdpPort(50000); - assertPortInRange(port, 50000, org.springframework.util.SocketUtils.PORT_RANGE_MAX); - } - - @Test - void findAvailableUdpPortInRange() { - int minPort = 20000; - int maxPort = minPort + 1000; - int port = org.springframework.util.SocketUtils.findAvailableUdpPort(minPort, maxPort); - assertPortInRange(port, minPort, maxPort); - } - - @Test - void find4AvailableUdpPorts() { - findAvailableUdpPorts(4); - } - - @Test - void find50AvailableUdpPorts() { - findAvailableUdpPorts(50); - } - - @Test - void find4AvailableUdpPortsInRange() { - findAvailableUdpPorts(4, 30000, 35000); - } - - @Test - void find50AvailableUdpPortsInRange() { - findAvailableUdpPorts(50, 40000, 45000); - } - - @Test - void findAvailableUdpPortsWithRequestedNumberGreaterThanSizeOfRange() { - assertThatIllegalArgumentException().isThrownBy(() -> - findAvailableUdpPorts(50, 45000, 45010)); - } - - - // Helpers - - private void findAvailableTcpPorts(int numRequested) { - SortedSet ports = org.springframework.util.SocketUtils.findAvailableTcpPorts(numRequested); - assertAvailablePorts(ports, numRequested, org.springframework.util.SocketUtils.PORT_RANGE_MIN, - org.springframework.util.SocketUtils.PORT_RANGE_MAX); - } - - private void findAvailableTcpPorts(int numRequested, int minPort, int maxPort) { - SortedSet ports = org.springframework.util.SocketUtils.findAvailableTcpPorts(numRequested, minPort, maxPort); - assertAvailablePorts(ports, numRequested, minPort, maxPort); - } - - private void findAvailableUdpPorts(int numRequested) { - SortedSet ports = org.springframework.util.SocketUtils.findAvailableUdpPorts(numRequested); - assertAvailablePorts(ports, numRequested, org.springframework.util.SocketUtils.PORT_RANGE_MIN, - org.springframework.util.SocketUtils.PORT_RANGE_MAX); - } - - private void findAvailableUdpPorts(int numRequested, int minPort, int maxPort) { - SortedSet ports = org.springframework.util.SocketUtils.findAvailableUdpPorts(numRequested, minPort, maxPort); - assertAvailablePorts(ports, numRequested, minPort, maxPort); - } - private void assertPortInRange(int port, int minPort, int maxPort) { - assertThat(port >= minPort).as("port [" + port + "] >= " + minPort).isTrue(); - assertThat(port <= maxPort).as("port [" + port + "] <= " + maxPort).isTrue(); - } - - private void assertAvailablePorts(SortedSet ports, int numRequested, int minPort, int maxPort) { - assertThat(ports.size()).as("number of ports requested").isEqualTo(numRequested); - for (int port : ports) { - assertPortInRange(port, minPort, maxPort); - } - } - -} diff --git a/spring-core/src/testFixtures/java/org/springframework/core/testfixture/net/TestSocketUtils.java b/spring-core/src/testFixtures/java/org/springframework/core/testfixture/net/TestSocketUtils.java new file mode 100644 index 000000000000..ca94026b0dc2 --- /dev/null +++ b/spring-core/src/testFixtures/java/org/springframework/core/testfixture/net/TestSocketUtils.java @@ -0,0 +1,140 @@ +/* + * Copyright 2002-2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.testfixture.net; + +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.util.Random; + +import javax.net.ServerSocketFactory; + +import org.springframework.util.Assert; + +/** + * Removed from spring-core and introduced as an internal test utility in + * spring-context in Spring Framework 6.0. + * + *

    Simple utility methods for working with network sockets — for example, + * for finding available ports on {@code localhost}. + * + *

    Within this class, a TCP port refers to a port for a {@link ServerSocket}; + * whereas, a UDP port refers to a port for a {@link DatagramSocket}. + * + *

    {@code SocketUtils} was introduced in Spring Framework 4.0, primarily to + * assist in writing integration tests which start an external server on an + * available random port. However, these utilities make no guarantee about the + * subsequent availability of a given port and are therefore unreliable. Instead + * of using {@code SocketUtils} to find an available local port for a server, it + * is recommended that you rely on a server's ability to start on a random port + * that it selects or is assigned by the operating system. To interact with that + * server, you should query the server for the port it is currently using. + * + * @author Sam Brannen + * @author Ben Hale + * @author Arjen Poutsma + * @author Gunnar Hillert + * @author Gary Russell + * @since 4.0 + */ +public class TestSocketUtils { + + /** + * The default minimum value for port ranges used when finding an available + * socket port. + */ + private static final int PORT_RANGE_MIN = 1024; + + /** + * The default maximum value for port ranges used when finding an available + * socket port. + */ + private static final int PORT_RANGE_MAX = 65535; + + + private static final Random random = new Random(System.nanoTime()); + + + /** + * Find an available TCP port randomly selected from the range + * [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. + * @return an available TCP port number + * @throws IllegalStateException if no available port could be found + */ + public static int findAvailableTcpPort() { + return findAvailablePort(PORT_RANGE_MIN, PORT_RANGE_MAX); + } + + /** + * Find an available port for this {@code SocketType}, randomly selected + * from the range [{@code minPort}, {@code maxPort}]. + * @param minPort the minimum port number + * @param maxPort the maximum port number + * @return an available port number for this socket type + * @throws IllegalStateException if no available port could be found + */ + private static int findAvailablePort(int minPort, int maxPort) { + Assert.isTrue(minPort > 0, "'minPort' must be greater than 0"); + Assert.isTrue(maxPort >= minPort, "'maxPort' must be greater than or equal to 'minPort'"); + Assert.isTrue(maxPort <= PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + PORT_RANGE_MAX); + + int portRange = maxPort - minPort; + int candidatePort; + int searchCounter = 0; + do { + if (searchCounter > portRange) { + throw new IllegalStateException(String.format( + "Could not find an available TCP port in the range [%d, %d] after %d attempts", + minPort, maxPort, searchCounter)); + } + candidatePort = findRandomPort(minPort, maxPort); + searchCounter++; + } + while (!isPortAvailable(candidatePort)); + + return candidatePort; + } + + /** + * Find a pseudo-random port number within the range + * [{@code minPort}, {@code maxPort}]. + * @param minPort the minimum port number + * @param maxPort the maximum port number + * @return a random port number within the specified range + */ + private static int findRandomPort(int minPort, int maxPort) { + int portRange = maxPort - minPort; + return minPort + random.nextInt(portRange + 1); + } + + /** + * Determine if the specified port for this {@code SocketType} is + * currently available on {@code localhost}. + */ + private static boolean isPortAvailable(int port) { + try { + ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket( + port, 1, InetAddress.getByName("localhost")); + serverSocket.close(); + return true; + } + catch (Exception ex) { + return false; + } + } + +} From 18b8e4ec5c00c526cc03be70e8e3e283bf801f63 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 15 Feb 2022 15:06:43 -0800 Subject: [PATCH 702/735] Add mavenCentral() to pluginManagement repositories Update the pluginManagement repositories used by Grade to include `mavenCentral()` since `gradlePluginPortal()` has been suffering from timeouts recently. --- settings.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/settings.gradle b/settings.gradle index 6913d57d47dd..e1638d26c9ad 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,6 @@ pluginManagement { repositories { + mavenCentral() gradlePluginPortal() maven { url "https://repo.spring.io/release" } } From b3306f4e3d9ea78c10a2620568707ed08f75b7b0 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 15 Feb 2022 15:10:27 -0800 Subject: [PATCH 703/735] Suppress deprecation warning in WebAsyncManagerTests See gh-27959 --- .../web/context/request/async/WebAsyncManagerTests.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTests.java b/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTests.java index 2a88cd9566b3..caa2b02e2977 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. @@ -380,6 +380,7 @@ public Object call() throws Exception { private static class SyncTaskExecutor extends SimpleAsyncTaskExecutor { @Override + @SuppressWarnings("deprecation") public void execute(Runnable task, long startTimeout) { task.run(); } From 7276752e7cbc87aead678ae84ec8a83e7603a141 Mon Sep 17 00:00:00 2001 From: vikey Date: Sat, 12 Feb 2022 18:51:24 +0800 Subject: [PATCH 704/735] Fix CronExpression issue with DST This commit fixes an issue with CronExpression fails to calculate next execution on the day of daylight saving time. Closes gh-28038 --- .../springframework/scheduling/support/CronField.java | 9 +++++++-- .../scheduling/support/CronExpressionTests.java | 8 ++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java b/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java index bed950663452..e01e00b63229 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java @@ -260,7 +260,7 @@ public > T elapseUntil(T temporal, in * Roll forward the give temporal until it reaches the next higher * order field. Calling this method is equivalent to calling * {@link #elapseUntil(Temporal, int)} with goal set to the - * minimum value of this field's range. + * minimum value of this field's range, except for daylight saving. * @param temporal the temporal to roll forward * @param the type of temporal * @return the rolled forward temporal @@ -269,7 +269,12 @@ public > T rollForward(T temporal) { int current = get(temporal); ValueRange range = temporal.range(this.field); long amount = range.getMaximum() - current + 1; - return this.field.getBaseUnit().addTo(temporal, amount); + T result = this.field.getBaseUnit().addTo(temporal, amount); + //adjust daylight saving + if (get(result) != range.getMinimum()) { + result = this.field.adjustInto(result,result.range(this.field).getMinimum()); + } + return result; } /** diff --git a/spring-context/src/test/java/org/springframework/scheduling/support/CronExpressionTests.java b/spring-context/src/test/java/org/springframework/scheduling/support/CronExpressionTests.java index 5abce9e2de30..5de5362fc1dd 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/support/CronExpressionTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/support/CronExpressionTests.java @@ -1336,6 +1336,14 @@ public void daylightSaving() { actual = cronExpression.next(last); assertThat(actual).isNotNull(); assertThat(actual).isEqualTo(expected); + + cronExpression = CronExpression.parse("0 5 0 * * *"); + + last = ZonedDateTime.parse("2021-03-28T01:00:00+01:00[Europe/Amsterdam]"); + expected = ZonedDateTime.parse("2021-03-29T00:05+02:00[Europe/Amsterdam]"); + actual = cronExpression.next(last); + assertThat(actual).isNotNull(); + assertThat(actual).isEqualTo(expected); } @Test From 5ab966fbdefc33840ff2ac4c12b26a6c306b59cf Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 16 Feb 2022 11:16:27 +0100 Subject: [PATCH 705/735] Polish contribution See gh-28038 --- .../scheduling/support/CronField.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java b/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java index e01e00b63229..adc2c2ffe5d6 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java @@ -260,7 +260,7 @@ public > T elapseUntil(T temporal, in * Roll forward the give temporal until it reaches the next higher * order field. Calling this method is equivalent to calling * {@link #elapseUntil(Temporal, int)} with goal set to the - * minimum value of this field's range, except for daylight saving. + * minimum value of this field's range. * @param temporal the temporal to roll forward * @param the type of temporal * @return the rolled forward temporal @@ -269,10 +269,12 @@ public > T rollForward(T temporal) { int current = get(temporal); ValueRange range = temporal.range(this.field); long amount = range.getMaximum() - current + 1; - T result = this.field.getBaseUnit().addTo(temporal, amount); - //adjust daylight saving - if (get(result) != range.getMinimum()) { - result = this.field.adjustInto(result,result.range(this.field).getMinimum()); + T result = this.field.getBaseUnit().addTo(temporal, amount); + current = get(result); + range = result.range(this.field); + // adjust for daylight savings + if (current != range.getMinimum()) { + result = this.field.adjustInto(result, range.getMinimum()); } return result; } From e3ceb9b23dacbed3db0811b7535cbe07ccda58cb Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 16 Feb 2022 12:01:14 +0100 Subject: [PATCH 706/735] Polish @Target declarations for stereotype annotations --- .../main/java/org/springframework/stereotype/Controller.java | 4 ++-- .../main/java/org/springframework/stereotype/Repository.java | 4 ++-- .../src/main/java/org/springframework/stereotype/Service.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/stereotype/Controller.java b/spring-context/src/main/java/org/springframework/stereotype/Controller.java index ef4167c13714..6629feea4b3e 100644 --- a/spring-context/src/main/java/org/springframework/stereotype/Controller.java +++ b/spring-context/src/main/java/org/springframework/stereotype/Controller.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2022 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. @@ -39,7 +39,7 @@ * @see org.springframework.web.bind.annotation.RequestMapping * @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner */ -@Target({ElementType.TYPE}) +@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component diff --git a/spring-context/src/main/java/org/springframework/stereotype/Repository.java b/spring-context/src/main/java/org/springframework/stereotype/Repository.java index 97cb1358080b..d44864877011 100644 --- a/spring-context/src/main/java/org/springframework/stereotype/Repository.java +++ b/spring-context/src/main/java/org/springframework/stereotype/Repository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2022 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. @@ -55,7 +55,7 @@ * @see org.springframework.dao.DataAccessException * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor */ -@Target({ElementType.TYPE}) +@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component diff --git a/spring-context/src/main/java/org/springframework/stereotype/Service.java b/spring-context/src/main/java/org/springframework/stereotype/Service.java index 18e61c53d283..5c714540bbca 100644 --- a/spring-context/src/main/java/org/springframework/stereotype/Service.java +++ b/spring-context/src/main/java/org/springframework/stereotype/Service.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2022 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 @@ * @see Component * @see Repository */ -@Target({ElementType.TYPE}) +@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component From 3ac60147f3b9a37f136f25fcd60d145c49110251 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 16 Feb 2022 12:11:33 +0100 Subject: [PATCH 707/735] Improve documentation for uri(URI) method in WebTestClient Prior to this commit, it was not clear that a configured base URI would not be applied when invoking uri(URI). This commit adds a note to the Javadoc to clarify that behavior. Closes gh-28058 --- .../test/web/reactive/server/WebTestClient.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java index 481a8d999e88..ece5800cc5ec 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java @@ -526,14 +526,19 @@ interface Builder { interface UriSpec> { /** - * Specify the URI using an absolute, fully constructed {@link URI}. + * Specify the URI using an absolute, fully constructed {@link java.net.URI}. + *

    If a {@link UriBuilderFactory} was configured for the client with + * a base URI, that base URI will not be applied to the + * supplied {@code java.net.URI}. If you wish to have a base URI applied to a + * {@code java.net.URI} you must invoke either {@link #uri(String, Object...)} + * or {@link #uri(String, Map)} — for example, {@code uri(myUri.toString())}. * @return spec to add headers or perform the exchange */ S uri(URI uri); /** * Specify the URI for the request using a URI template and URI variables. - * If a {@link UriBuilderFactory} was configured for the client (e.g. + *

    If a {@link UriBuilderFactory} was configured for the client (e.g. * with a base URI) it will be used to expand the URI template. * @return spec to add headers or perform the exchange */ @@ -541,7 +546,7 @@ interface UriSpec> { /** * Specify the URI for the request using a URI template and URI variables. - * If a {@link UriBuilderFactory} was configured for the client (e.g. + *

    If a {@link UriBuilderFactory} was configured for the client (e.g. * with a base URI) it will be used to expand the URI template. * @return spec to add headers or perform the exchange */ From 36dc4e4c5f3827cf9f13a691c8007cc5f2a46f17 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 15 Feb 2022 15:06:43 -0800 Subject: [PATCH 708/735] Add mavenCentral() to pluginManagement repositories Update the pluginManagement repositories used by Grade to include `mavenCentral()` since `gradlePluginPortal()` has been suffering from timeouts recently. --- settings.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/settings.gradle b/settings.gradle index 6913d57d47dd..e1638d26c9ad 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,6 @@ pluginManagement { repositories { + mavenCentral() gradlePluginPortal() maven { url "https://repo.spring.io/release" } } From 1166577d2c7f1a2b2dba84ba3f1026f5b3ca9b2a Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 16 Feb 2022 20:04:27 +0100 Subject: [PATCH 709/735] Upgrade to Netty 4.1.74, Jetty 9.4.45, Undertow 2.2.16, Hibernate Validator 6.2.2, Apache Johnzon 1.2.16, EclipseLink 2.7.10 --- build.gradle | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 7ef36356d006..58352ec87409 100644 --- a/build.gradle +++ b/build.gradle @@ -28,11 +28,11 @@ configure(allprojects) { project -> dependencyManagement { imports { mavenBom "com.fasterxml.jackson:jackson-bom:2.12.6" - mavenBom "io.netty:netty-bom:4.1.73.Final" + mavenBom "io.netty:netty-bom:4.1.74.Final" mavenBom "io.projectreactor:reactor-bom:2020.0.16" mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR12" mavenBom "io.rsocket:rsocket-bom:1.1.1" - mavenBom "org.eclipse.jetty:jetty-bom:9.4.44.v20210927" + mavenBom "org.eclipse.jetty:jetty-bom:9.4.45.v20220203" mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.32" mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2" mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2" @@ -83,7 +83,7 @@ configure(allprojects) { project -> exclude group: "xpp3", name: "xpp3_min" exclude group: "xmlpull", name: "xmlpull" } - dependency "org.apache.johnzon:johnzon-jsonb:1.2.15" + dependency "org.apache.johnzon:johnzon-jsonb:1.2.16" dependency("org.codehaus.jettison:jettison:1.3.8") { exclude group: "stax", name: "stax-api" } @@ -124,7 +124,7 @@ configure(allprojects) { project -> dependency "org.ehcache:jcache:1.0.1" dependency "org.ehcache:ehcache:3.4.0" dependency "org.hibernate:hibernate-core:5.4.33.Final" - dependency "org.hibernate:hibernate-validator:6.2.1.Final" + dependency "org.hibernate:hibernate-validator:6.2.2.Final" dependency "org.webjars:webjars-locator-core:0.48" dependency "org.webjars:underscorejs:1.8.3" @@ -139,7 +139,7 @@ configure(allprojects) { project -> entry 'tomcat-embed-core' entry 'tomcat-embed-websocket' } - dependencySet(group: 'io.undertow', version: '2.2.14.Final') { + dependencySet(group: 'io.undertow', version: '2.2.16.Final') { entry 'undertow-core' entry('undertow-servlet') { exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_4.0_spec" @@ -238,7 +238,7 @@ configure(allprojects) { project -> dependency "com.ibm.websphere:uow:6.0.2.17" dependency "com.jamonapi:jamon:2.82" dependency "joda-time:joda-time:2.10.13" - dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.9" + dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.10" dependency "org.javamoney:moneta:1.3" dependency "com.sun.activation:javax.activation:1.2.0" From f8a59c267f318e06522fdfa968c9b251cf1b07d9 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 16 Feb 2022 20:04:51 +0100 Subject: [PATCH 710/735] Polishing --- .../annotation/AbstractAspectJAdvisorFactoryTests.java | 10 +++++----- .../aop/aspectj/annotation/AspectMetadataTests.java | 7 +++---- 2 files changed, 8 insertions(+), 9 deletions(-) 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 9aeeef0f1564..3f5a7b562c5b 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 @@ -98,7 +98,7 @@ void rejectsPerCflowBelowAspect() { } @Test - void perTargetAspect() throws SecurityException, NoSuchMethodException { + void perTargetAspect() throws Exception { TestBean target = new TestBean(); int realAge = 65; target.setAge(realAge); @@ -130,7 +130,7 @@ void perTargetAspect() throws SecurityException, NoSuchMethodException { } @Test - void multiplePerTargetAspects() throws SecurityException, NoSuchMethodException { + void multiplePerTargetAspects() throws Exception { TestBean target = new TestBean(); int realAge = 65; target.setAge(realAge); @@ -158,7 +158,7 @@ void multiplePerTargetAspects() throws SecurityException, NoSuchMethodException } @Test - void multiplePerTargetAspectsWithOrderAnnotation() throws SecurityException, NoSuchMethodException { + void multiplePerTargetAspectsWithOrderAnnotation() throws Exception { TestBean target = new TestBean(); int realAge = 65; target.setAge(realAge); @@ -184,7 +184,7 @@ void multiplePerTargetAspectsWithOrderAnnotation() throws SecurityException, NoS } @Test - void perThisAspect() throws SecurityException, NoSuchMethodException { + void perThisAspect() throws Exception { TestBean target = new TestBean(); int realAge = 65; target.setAge(realAge); @@ -220,7 +220,7 @@ void perThisAspect() throws SecurityException, NoSuchMethodException { } @Test - void perTypeWithinAspect() throws SecurityException, NoSuchMethodException { + void perTypeWithinAspect() throws Exception { TestBean target = new TestBean(); int realAge = 65; target.setAge(realAge); diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectMetadataTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectMetadataTests.java index 637baa2450a8..2554895430fb 100644 --- a/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectMetadataTests.java +++ b/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectMetadataTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,6 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; /** - * @since 2.0 * @author Rod Johnson * @author Chris Beams * @author Sam Brannen @@ -56,7 +55,7 @@ void perTargetAspect() { assertThat(am.getAjType().getPerClause().getKind()).isEqualTo(PerClauseKind.PERTARGET); assertThat(am.getPerClausePointcut()).isInstanceOf(AspectJExpressionPointcut.class); assertThat(((AspectJExpressionPointcut) am.getPerClausePointcut()).getExpression()) - .isEqualTo("execution(* *.getSpouse())"); + .isEqualTo("execution(* *.getSpouse())"); } @Test @@ -67,7 +66,7 @@ void perThisAspect() { assertThat(am.getAjType().getPerClause().getKind()).isEqualTo(PerClauseKind.PERTHIS); assertThat(am.getPerClausePointcut()).isInstanceOf(AspectJExpressionPointcut.class); assertThat(((AspectJExpressionPointcut) am.getPerClausePointcut()).getExpression()) - .isEqualTo("execution(* *.getSpouse())"); + .isEqualTo("execution(* *.getSpouse())"); } } From 3c0a5fd0630c1cf9edb1646aabc24d41e704010b Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 16 Feb 2022 20:12:59 +0100 Subject: [PATCH 711/735] Upgrade to POI 5.2 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 574e8b87b657..733fe830322a 100644 --- a/build.gradle +++ b/build.gradle @@ -104,7 +104,7 @@ configure(allprojects) { project -> entry 'derby' entry 'derbyclient' } - dependency "org.apache.poi:poi-ooxml:5.1.0" + dependency "org.apache.poi:poi-ooxml:5.2.0" dependency "org.apache-extras.beanshell:bsh:2.0b6" dependency "org.freemarker:freemarker:2.3.31" dependency "org.hsqldb:hsqldb:2.5.2" From 4571626839a00c924d7e38b8d0b02cb2518345b5 Mon Sep 17 00:00:00 2001 From: Spring Builds Date: Thu, 17 Feb 2022 07:45:38 +0000 Subject: [PATCH 712/735] Next development version (v5.3.17-SNAPSHOT) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ce5199c44137..c51960841a5e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=5.3.16-SNAPSHOT +version=5.3.17-SNAPSHOT org.gradle.jvmargs=-Xmx1536M org.gradle.caching=true org.gradle.parallel=true From 2ffefbb21116dda66973b920218c79ffe13cbac8 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 17 Feb 2022 09:44:22 +0100 Subject: [PATCH 713/735] Downgrade to concourse-release-scripts 0.3.2 This commit reverts partially "0ab054c7b943d65bb9034d1d7987f556e9d54d05" as 0.3.3 is breaking promition. --- ci/images/setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/images/setup.sh b/ci/images/setup.sh index 3e1e0bc05c2d..6c02f65ef665 100755 --- a/ci/images/setup.sh +++ b/ci/images/setup.sh @@ -14,7 +14,7 @@ rm -rf /var/lib/apt/lists/* curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/concourse-java.sh > /opt/concourse-java.sh -curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.3.3/concourse-release-scripts-0.3.3.jar +curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.3.2/concourse-release-scripts-0.3.2.jar ########################################################### # JAVA From ff20a06876209e6dafd519e732801f292230f9d9 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Thu, 17 Feb 2022 11:51:14 +0100 Subject: [PATCH 714/735] Added .sdkmanrc file This commit adds a .sdkmanrc file, so that we can automatically switch to JDK 8 when building the 5.3. branch. --- .sdkmanrc | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .sdkmanrc diff --git a/.sdkmanrc b/.sdkmanrc new file mode 100644 index 000000000000..a59545673245 --- /dev/null +++ b/.sdkmanrc @@ -0,0 +1,3 @@ +# Enable auto-env through the sdkman_auto_env config +# Add key=value pairs of SDKs to use below +java=8.0.322-librca From 85067786088306452a762f74396f5c5937d0c7f0 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Thu, 17 Feb 2022 11:55:25 +0100 Subject: [PATCH 715/735] Use JDK 17 on main branch in .sdkmanrc This commit makes sure that JDK 17 is used on the main branch. --- .sdkmanrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.sdkmanrc b/.sdkmanrc index a59545673245..347a6808efc3 100644 --- a/.sdkmanrc +++ b/.sdkmanrc @@ -1,3 +1,3 @@ # Enable auto-env through the sdkman_auto_env config # Add key=value pairs of SDKs to use below -java=8.0.322-librca +java=17.0.2-librca From 41ee23345d72623d18accb9484ce5119403c39d5 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 17 Feb 2022 18:14:09 +0100 Subject: [PATCH 716/735] Support for registering multiple init/destroy methods on AbstractBeanDefinition Closes gh-28013 --- .../AbstractAutowireCapableBeanFactory.java | 19 +-- .../support/AbstractBeanDefinition.java | 78 ++++++++++--- .../support/DisposableBeanAdapter.java | 103 ++++++++++------- .../DefaultListableBeanFactoryTests.java | 53 ++++++++- .../support/ScriptFactoryPostProcessor.java | 4 +- .../Spr3775InitDestroyLifecycleTests.java | 108 ++++++++---------- 6 files changed, 229 insertions(+), 136 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 2fb13145124b..a013c2bdce16 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -74,7 +74,6 @@ import org.springframework.core.PriorityOrdered; import org.springframework.core.ResolvableType; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; @@ -1789,11 +1788,15 @@ protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBea } if (mbd != null && bean.getClass() != NullBean.class) { - String initMethodName = mbd.getInitMethodName(); - if (StringUtils.hasLength(initMethodName) && - !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && - !mbd.isExternallyManagedInitMethod(initMethodName)) { - invokeCustomInitMethod(beanName, bean, mbd); + String[] initMethodNames = mbd.getInitMethodNames(); + if (initMethodNames != null) { + for (String initMethodName : initMethodNames) { + if (StringUtils.hasLength(initMethodName) && + !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && + !mbd.isExternallyManagedInitMethod(initMethodName)) { + invokeCustomInitMethod(beanName, bean, mbd, initMethodName); + } + } } } } @@ -1805,11 +1808,9 @@ protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBea * methods with arguments. * @see #invokeInitMethods */ - protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd) + protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd, String initMethodName) throws Throwable { - String initMethodName = mbd.getInitMethodName(); - Assert.state(initMethodName != null, "No init method set"); Method initMethod = (mbd.isNonPublicAccessAllowed() ? BeanUtils.findMethod(bean.getClass(), initMethodName) : ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName)); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java index 847574dbd2ec..0176af001a95 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -184,10 +184,10 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess private MethodOverrides methodOverrides = new MethodOverrides(); @Nullable - private String initMethodName; + private String[] initMethodNames; @Nullable - private String destroyMethodName; + private String[] destroyMethodNames; private boolean enforceInitMethod = true; @@ -262,9 +262,9 @@ protected AbstractBeanDefinition(BeanDefinition original) { setInstanceSupplier(originalAbd.getInstanceSupplier()); setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed()); setLenientConstructorResolution(originalAbd.isLenientConstructorResolution()); - setInitMethodName(originalAbd.getInitMethodName()); + setInitMethodNames(originalAbd.getInitMethodNames()); setEnforceInitMethod(originalAbd.isEnforceInitMethod()); - setDestroyMethodName(originalAbd.getDestroyMethodName()); + setDestroyMethodNames(originalAbd.getDestroyMethodNames()); setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod()); setSynthetic(originalAbd.isSynthetic()); setResource(originalAbd.getResource()); @@ -338,12 +338,12 @@ public void overrideFrom(BeanDefinition other) { setInstanceSupplier(otherAbd.getInstanceSupplier()); setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed()); setLenientConstructorResolution(otherAbd.isLenientConstructorResolution()); - if (otherAbd.getInitMethodName() != null) { - setInitMethodName(otherAbd.getInitMethodName()); + if (otherAbd.getInitMethodNames() != null) { + setInitMethodNames(otherAbd.getInitMethodNames()); setEnforceInitMethod(otherAbd.isEnforceInitMethod()); } - if (otherAbd.getDestroyMethodName() != null) { - setDestroyMethodName(otherAbd.getDestroyMethodName()); + if (otherAbd.getDestroyMethodNames() != null) { + setDestroyMethodNames(otherAbd.getDestroyMethodNames()); setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod()); } setSynthetic(otherAbd.isSynthetic()); @@ -918,22 +918,42 @@ public boolean hasMethodOverrides() { return !this.methodOverrides.isEmpty(); } + /** + * Specify the names of multiple initializer methods. + *

    The default is {@code null} in which case there are no initializer methods. + * @since 6.0 + * @see #setInitMethodName + */ + public void setInitMethodNames(@Nullable String... initMethodNames) { + this.initMethodNames = initMethodNames; + } + + /** + * Return the names of the initializer methods. + * @since 6.0 + */ + @Nullable + public String[] getInitMethodNames() { + return this.initMethodNames; + } + /** * Set the name of the initializer method. *

    The default is {@code null} in which case there is no initializer method. + * @see #setInitMethodNames */ @Override public void setInitMethodName(@Nullable String initMethodName) { - this.initMethodName = initMethodName; + this.initMethodNames = (initMethodName != null ? new String[] {initMethodName} : null); } /** - * Return the name of the initializer method. + * Return the name of the initializer method (the first one in case of multiple methods). */ @Override @Nullable public String getInitMethodName() { - return this.initMethodName; + return (!ObjectUtils.isEmpty(this.initMethodNames) ? this.initMethodNames[0] : null); } /** @@ -957,22 +977,42 @@ public boolean isEnforceInitMethod() { return this.enforceInitMethod; } + /** + * Specify the names of multiple destroy methods. + *

    The default is {@code null} in which case there are no destroy methods. + * @since 6.0 + * @see #setDestroyMethodName + */ + public void setDestroyMethodNames(@Nullable String... destroyMethodNames) { + this.destroyMethodNames = destroyMethodNames; + } + + /** + * Return the names of the destroy methods. + * @since 6.0 + */ + @Nullable + public String[] getDestroyMethodNames() { + return this.destroyMethodNames; + } + /** * Set the name of the destroy method. *

    The default is {@code null} in which case there is no destroy method. + * @see #setDestroyMethodNames */ @Override public void setDestroyMethodName(@Nullable String destroyMethodName) { - this.destroyMethodName = destroyMethodName; + this.destroyMethodNames = (destroyMethodName != null ? new String[] {destroyMethodName} : null); } /** - * Return the name of the destroy method. + * Return the name of the destroy method (the first one in case of multiple methods). */ @Override @Nullable public String getDestroyMethodName() { - return this.destroyMethodName; + return (!ObjectUtils.isEmpty(this.destroyMethodNames) ? this.destroyMethodNames[0] : null); } /** @@ -1189,9 +1229,9 @@ public boolean equals(@Nullable Object other) { ObjectUtils.nullSafeEquals(this.methodOverrides, that.methodOverrides) && ObjectUtils.nullSafeEquals(this.factoryBeanName, that.factoryBeanName) && ObjectUtils.nullSafeEquals(this.factoryMethodName, that.factoryMethodName) && - ObjectUtils.nullSafeEquals(this.initMethodName, that.initMethodName) && + ObjectUtils.nullSafeEquals(this.initMethodNames, that.initMethodNames) && this.enforceInitMethod == that.enforceInitMethod && - ObjectUtils.nullSafeEquals(this.destroyMethodName, that.destroyMethodName) && + ObjectUtils.nullSafeEquals(this.destroyMethodNames, that.destroyMethodNames) && this.enforceDestroyMethod == that.enforceDestroyMethod && this.synthetic == that.synthetic && this.role == that.role && @@ -1241,8 +1281,8 @@ public String toString() { sb.append("; primary=").append(this.primary); sb.append("; factoryBeanName=").append(this.factoryBeanName); sb.append("; factoryMethodName=").append(this.factoryMethodName); - sb.append("; initMethodName=").append(this.initMethodName); - sb.append("; destroyMethodName=").append(this.destroyMethodName); + sb.append("; initMethodNames=").append(this.initMethodNames); + sb.append("; destroyMethodNames=").append(this.destroyMethodNames); if (this.resource != null) { sb.append("; defined in ").append(this.resource.getDescription()); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java index 0f1b5ecd4673..23354b6cccb2 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java @@ -32,6 +32,7 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; @@ -51,7 +52,7 @@ * @see AbstractBeanFactory * @see org.springframework.beans.factory.DisposableBean * @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor - * @see AbstractBeanDefinition#getDestroyMethodName() + * @see AbstractBeanDefinition#getDestroyMethodNames() */ @SuppressWarnings("serial") class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -76,10 +77,10 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { private boolean invokeAutoCloseable; @Nullable - private String destroyMethodName; + private String[] destroyMethodNames; @Nullable - private transient Method destroyMethod; + private transient Method[] destroyMethods; @Nullable private final List beanPostProcessors; @@ -103,36 +104,42 @@ public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition be this.invokeDisposableBean = (bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod(DESTROY_METHOD_NAME)); - String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition); - if (destroyMethodName != null && - !(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodName)) && - !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) { + String[] destroyMethodNames = inferDestroyMethodsIfNecessary(bean, beanDefinition); + if (!ObjectUtils.isEmpty(destroyMethodNames) && + !(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodNames[0])) && + !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodNames[0])) { - this.invokeAutoCloseable = (bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodName)); + this.invokeAutoCloseable = + (bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodNames[0])); if (!this.invokeAutoCloseable) { - this.destroyMethodName = destroyMethodName; - Method destroyMethod = determineDestroyMethod(destroyMethodName); - if (destroyMethod == null) { - if (beanDefinition.isEnforceDestroyMethod()) { - throw new BeanDefinitionValidationException("Could not find a destroy method named '" + - destroyMethodName + "' on bean with name '" + beanName + "'"); - } - } - else { - if (destroyMethod.getParameterCount() > 0) { - Class[] paramTypes = destroyMethod.getParameterTypes(); - if (paramTypes.length > 1) { - throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + - beanName + "' has more than one parameter - not supported as destroy method"); + this.destroyMethodNames = destroyMethodNames; + Method[] destroyMethods = new Method[destroyMethodNames.length]; + for (int i = 0; i < destroyMethodNames.length; i++) { + String destroyMethodName = destroyMethodNames[i]; + Method destroyMethod = determineDestroyMethod(destroyMethodName); + if (destroyMethod == null) { + if (beanDefinition.isEnforceDestroyMethod()) { + throw new BeanDefinitionValidationException("Could not find a destroy method named '" + + destroyMethodName + "' on bean with name '" + beanName + "'"); } - else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) { - throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + - beanName + "' has a non-boolean parameter - not supported as destroy method"); + } + else { + if (destroyMethod.getParameterCount() > 0) { + Class[] paramTypes = destroyMethod.getParameterTypes(); + if (paramTypes.length > 1) { + throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + + beanName + "' has more than one parameter - not supported as destroy method"); + } + else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) { + throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + + beanName + "' has a non-boolean parameter - not supported as destroy method"); + } } + destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod, bean.getClass()); } - destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod, bean.getClass()); + destroyMethods[i] = destroyMethod; } - this.destroyMethod = destroyMethod; + this.destroyMethods = destroyMethods; } } @@ -158,7 +165,7 @@ public DisposableBeanAdapter(Object bean, List postProcessors) { this.bean = bean; @@ -166,7 +173,7 @@ private DisposableBeanAdapter(Object bean, String beanName, boolean nonPublicAcc this.nonPublicAccessAllowed = nonPublicAccessAllowed; this.invokeDisposableBean = invokeDisposableBean; this.invokeAutoCloseable = invokeAutoCloseable; - this.destroyMethodName = destroyMethodName; + this.destroyMethodNames = destroyMethodNames; this.beanPostProcessors = postProcessors; } @@ -219,13 +226,18 @@ public void destroy() { } } } - else if (this.destroyMethod != null) { - invokeCustomDestroyMethod(this.destroyMethod); + else if (this.destroyMethods != null) { + for (Method destroyMethod : this.destroyMethods) { + invokeCustomDestroyMethod(destroyMethod); + } } - else if (this.destroyMethodName != null) { - Method destroyMethod = determineDestroyMethod(this.destroyMethodName); - if (destroyMethod != null) { - invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(destroyMethod, this.bean.getClass())); + else if (this.destroyMethodNames != null) { + for (String destroyMethodName: this.destroyMethodNames) { + Method destroyMethod = determineDestroyMethod(destroyMethodName); + if (destroyMethod != null) { + invokeCustomDestroyMethod( + ClassUtils.getInterfaceMethodIfPossible(destroyMethod, this.bean.getClass())); + } } } } @@ -255,14 +267,14 @@ private Method findDestroyMethod(String name) { * for a method with a single boolean argument (passing in "true", * assuming a "force" parameter), else logging an error. */ - private void invokeCustomDestroyMethod(final Method destroyMethod) { + private void invokeCustomDestroyMethod(Method destroyMethod) { int paramCount = destroyMethod.getParameterCount(); final Object[] args = new Object[paramCount]; if (paramCount == 1) { args[0] = Boolean.TRUE; } if (logger.isTraceEnabled()) { - logger.trace("Invoking custom destroy method '" + this.destroyMethodName + + logger.trace("Invoking custom destroy method '" + destroyMethod.getName() + "' on bean with name '" + this.beanName + "'"); } try { @@ -270,7 +282,7 @@ private void invokeCustomDestroyMethod(final Method destroyMethod) { destroyMethod.invoke(this.bean, args); } catch (InvocationTargetException ex) { - String msg = "Custom destroy method '" + this.destroyMethodName + "' on bean with name '" + + String msg = "Custom destroy method '" + destroyMethod.getName() + "' on bean with name '" + this.beanName + "' threw an exception"; if (logger.isDebugEnabled()) { logger.warn(msg, ex.getTargetException()); @@ -280,7 +292,7 @@ private void invokeCustomDestroyMethod(final Method destroyMethod) { } } catch (Throwable ex) { - logger.warn("Failed to invoke custom destroy method '" + this.destroyMethodName + + logger.warn("Failed to invoke custom destroy method '" + destroyMethod.getName() + "' on bean with name '" + this.beanName + "'", ex); } } @@ -302,7 +314,7 @@ protected Object writeReplace() { } return new DisposableBeanAdapter( this.bean, this.beanName, this.nonPublicAccessAllowed, this.invokeDisposableBean, - this.invokeAutoCloseable, this.destroyMethodName, serializablePostProcessors); + this.invokeAutoCloseable, this.destroyMethodNames, serializablePostProcessors); } @@ -312,7 +324,7 @@ protected Object writeReplace() { * @param beanDefinition the corresponding bean definition */ public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) { - return (bean instanceof DisposableBean || inferDestroyMethodIfNecessary(bean, beanDefinition) != null); + return (bean instanceof DisposableBean || inferDestroyMethodsIfNecessary(bean, beanDefinition) != null); } @@ -330,7 +342,12 @@ public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefin * interfaces, reflectively calling the "close" method on implementing beans as well. */ @Nullable - private static String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinition beanDefinition) { + private static String[] inferDestroyMethodsIfNecessary(Object bean, RootBeanDefinition beanDefinition) { + String[] destroyMethodNames = beanDefinition.getDestroyMethodNames(); + if (destroyMethodNames != null && destroyMethodNames.length > 1) { + return destroyMethodNames; + } + String destroyMethodName = beanDefinition.resolvedDestroyMethodName; if (destroyMethodName == null) { destroyMethodName = beanDefinition.getDestroyMethodName(); @@ -361,7 +378,7 @@ private static String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinit } beanDefinition.resolvedDestroyMethodName = (destroyMethodName != null ? destroyMethodName : ""); } - return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null); + return (StringUtils.hasLength(destroyMethodName) ? new String[] {destroyMethodName} : null); } /** 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 db7454073cf1..accf86ef058b 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 @@ -22,6 +22,7 @@ import java.net.MalformedURLException; import java.text.NumberFormat; import java.text.ParseException; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; @@ -2333,6 +2334,19 @@ void prototypeWithArrayConversionForFactoryMethod() { assertThat(tb2.getBeanName()).isEqualTo("myBeanName"); } + @Test + void multipleInitAndDestroyMethods() { + RootBeanDefinition bd = new RootBeanDefinition(BeanWithInitAndDestroyMethods.class); + bd.setInitMethodNames("init1", "init2"); + bd.setDestroyMethodNames("destroy2", "destroy1"); + lbf.registerBeanDefinition("test", bd); + BeanWithInitAndDestroyMethods bean = lbf.getBean("test", BeanWithInitAndDestroyMethods.class); + assertThat(bean.initMethods).containsExactly("init", "init1", "init2"); + assertThat(bean.destroyMethods).isEmpty(); + lbf.destroySingletons(); + assertThat(bean.destroyMethods).containsExactly("destroy", "destroy2", "destroy1"); + } + @Test void beanPostProcessorWithWrappedObjectAndDisposableBean() { RootBeanDefinition bd = new RootBeanDefinition(BeanWithDisposableBean.class); @@ -2758,9 +2772,42 @@ public ConstructorDependencyWithClassResolution() { } + static class BeanWithInitAndDestroyMethods implements InitializingBean, DisposableBean { + + final List initMethods = new ArrayList<>(); + final List destroyMethods = new ArrayList<>(); + + @Override + public void afterPropertiesSet() { + initMethods.add("init"); + } + + void init1() { + initMethods.add("init1"); + } + + void init2() { + initMethods.add("init2"); + } + + @Override + public void destroy() { + destroyMethods.add("destroy"); + } + + void destroy1() { + destroyMethods.add("destroy1"); + } + + void destroy2() { + destroyMethods.add("destroy2"); + } + } + + public static class BeanWithDisposableBean implements DisposableBean { - private static boolean closed; + static boolean closed; @Override public void destroy() { @@ -2771,7 +2818,7 @@ public void destroy() { public static class BeanWithCloseable implements Closeable { - private static boolean closed; + static boolean closed; @Override public void close() { @@ -2788,7 +2835,7 @@ public static abstract class BaseClassWithDestroyMethod { public static class BeanWithDestroyMethod extends BaseClassWithDestroyMethod { - private static int closeCount = 0; + static int closeCount = 0; @SuppressWarnings("unused") private BeanWithDestroyMethod inner; diff --git a/spring-context/src/main/java/org/springframework/scripting/support/ScriptFactoryPostProcessor.java b/spring-context/src/main/java/org/springframework/scripting/support/ScriptFactoryPostProcessor.java index 39772475c057..949da723710a 100644 --- a/spring-context/src/main/java/org/springframework/scripting/support/ScriptFactoryPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/scripting/support/ScriptFactoryPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -510,7 +510,7 @@ protected Class createConfigInterface(BeanDefinition bd, @Nullable Class[] Signature signature = new Signature(setterName, Type.VOID_TYPE, new Type[] {Type.getType(propertyType)}); maker.add(signature, new Type[0]); } - if (bd.getInitMethodName() != null) { + if (StringUtils.hasText(bd.getInitMethodName())) { Signature signature = new Signature(bd.getInitMethodName(), Type.VOID_TYPE, new Type[0]); maker.add(signature, new Type[0]); } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/Spr3775InitDestroyLifecycleTests.java b/spring-context/src/test/java/org/springframework/context/annotation/Spr3775InitDestroyLifecycleTests.java index 82caf5254e98..821fffffcf57 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/Spr3775InitDestroyLifecycleTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/Spr3775InitDestroyLifecycleTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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,6 @@ import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.DisposableBean; @@ -35,15 +33,12 @@ import static org.assertj.core.api.Assertions.assertThat; /** - *

    - * JUnit-3.8-based unit test which verifies expected init and - * destroy bean lifecycle behavior as requested in init and destroy + * bean lifecycle behavior as requested in + * SPR-3775. - *

    - *

    - * Specifically, combinations of the following are tested: - *

    + * + *

    Specifically, combinations of the following are tested: *

      *
    • {@link InitializingBean} & {@link DisposableBean} interfaces
    • *
    • Custom {@link RootBeanDefinition#getInitMethodName() init} & @@ -57,26 +52,17 @@ */ public class Spr3775InitDestroyLifecycleTests { - private static final Log logger = LogFactory.getLog(Spr3775InitDestroyLifecycleTests.class); - - /** LIFECYCLE_TEST_BEAN. */ private static final String LIFECYCLE_TEST_BEAN = "lifecycleTestBean"; - private void debugMethods(Class clazz, String category, List methodNames) { - if (logger.isDebugEnabled()) { - logger.debug(clazz.getSimpleName() + ": " + category + ": " + methodNames); - } + private void assertMethodOrdering(String category, List expectedMethods, List actualMethods) { + assertThat(ObjectUtils.nullSafeEquals(expectedMethods, actualMethods)). + as("Verifying " + category + ": expected<" + expectedMethods + "> but got<" + actualMethods + ">.").isTrue(); } - private void assertMethodOrdering(Class clazz, String category, List expectedMethods, - List actualMethods) { - debugMethods(clazz, category, actualMethods); - assertThat(ObjectUtils.nullSafeEquals(expectedMethods, actualMethods)).as("Verifying " + category + ": expected<" + expectedMethods + "> but got<" + actualMethods + ">.").isTrue(); - } + private DefaultListableBeanFactory createBeanFactoryAndRegisterBean( + Class beanClass, String initMethodName, String destroyMethodName) { - private DefaultListableBeanFactory createBeanFactoryAndRegisterBean(final Class beanClass, - final String initMethodName, final String destroyMethodName) { DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass); beanDefinition.setInitMethodName(initMethodName); @@ -88,75 +74,77 @@ private DefaultListableBeanFactory createBeanFactoryAndRegisterBean(final Class< @Test public void testInitDestroyMethods() { - final Class beanClass = InitDestroyBean.class; - final DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, + Class beanClass = InitDestroyBean.class; + DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "afterPropertiesSet", "destroy"); - final InitDestroyBean bean = (InitDestroyBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN); - assertMethodOrdering(beanClass, "init-methods", Arrays.asList("afterPropertiesSet"), bean.initMethods); + InitDestroyBean bean = (InitDestroyBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN); + assertMethodOrdering("init-methods", Arrays.asList("afterPropertiesSet"), bean.initMethods); beanFactory.destroySingletons(); - assertMethodOrdering(beanClass, "destroy-methods", Arrays.asList("destroy"), bean.destroyMethods); + assertMethodOrdering("destroy-methods", Arrays.asList("destroy"), bean.destroyMethods); } @Test public void testInitializingDisposableInterfaces() { - final Class beanClass = CustomInitializingDisposableBean.class; - final DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit", + Class beanClass = CustomInitializingDisposableBean.class; + DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit", "customDestroy"); - final CustomInitializingDisposableBean bean = (CustomInitializingDisposableBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN); - assertMethodOrdering(beanClass, "init-methods", Arrays.asList("afterPropertiesSet", "customInit"), + CustomInitializingDisposableBean bean = (CustomInitializingDisposableBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN); + assertMethodOrdering("init-methods", Arrays.asList("afterPropertiesSet", "customInit"), bean.initMethods); beanFactory.destroySingletons(); - assertMethodOrdering(beanClass, "destroy-methods", Arrays.asList("destroy", "customDestroy"), + assertMethodOrdering("destroy-methods", Arrays.asList("destroy", "customDestroy"), bean.destroyMethods); } @Test public void testInitializingDisposableInterfacesWithShadowedMethods() { - final Class beanClass = InitializingDisposableWithShadowedMethodsBean.class; - final DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, + Class beanClass = InitializingDisposableWithShadowedMethodsBean.class; + DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "afterPropertiesSet", "destroy"); - final InitializingDisposableWithShadowedMethodsBean bean = (InitializingDisposableWithShadowedMethodsBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN); - assertMethodOrdering(beanClass, "init-methods", Arrays.asList("InitializingBean.afterPropertiesSet"), + InitializingDisposableWithShadowedMethodsBean bean = + (InitializingDisposableWithShadowedMethodsBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN); + assertMethodOrdering("init-methods", Arrays.asList("InitializingBean.afterPropertiesSet"), bean.initMethods); beanFactory.destroySingletons(); - assertMethodOrdering(beanClass, "destroy-methods", Arrays.asList("DisposableBean.destroy"), bean.destroyMethods); + assertMethodOrdering("destroy-methods", Arrays.asList("DisposableBean.destroy"), bean.destroyMethods); } @Test public void testJsr250Annotations() { - final Class beanClass = CustomAnnotatedInitDestroyBean.class; - final DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit", + Class beanClass = CustomAnnotatedInitDestroyBean.class; + DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit", "customDestroy"); - final CustomAnnotatedInitDestroyBean bean = (CustomAnnotatedInitDestroyBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN); - assertMethodOrdering(beanClass, "init-methods", Arrays.asList("postConstruct", "afterPropertiesSet", + CustomAnnotatedInitDestroyBean bean = (CustomAnnotatedInitDestroyBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN); + assertMethodOrdering("init-methods", Arrays.asList("postConstruct", "afterPropertiesSet", "customInit"), bean.initMethods); beanFactory.destroySingletons(); - assertMethodOrdering(beanClass, "destroy-methods", Arrays.asList("preDestroy", "destroy", "customDestroy"), + assertMethodOrdering("destroy-methods", Arrays.asList("preDestroy", "destroy", "customDestroy"), bean.destroyMethods); } @Test public void testJsr250AnnotationsWithShadowedMethods() { - final Class beanClass = CustomAnnotatedInitDestroyWithShadowedMethodsBean.class; - final DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit", + Class beanClass = CustomAnnotatedInitDestroyWithShadowedMethodsBean.class; + DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit", "customDestroy"); - final CustomAnnotatedInitDestroyWithShadowedMethodsBean bean = (CustomAnnotatedInitDestroyWithShadowedMethodsBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN); - assertMethodOrdering(beanClass, "init-methods", + CustomAnnotatedInitDestroyWithShadowedMethodsBean bean = + (CustomAnnotatedInitDestroyWithShadowedMethodsBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN); + assertMethodOrdering("init-methods", Arrays.asList("@PostConstruct.afterPropertiesSet", "customInit"), bean.initMethods); beanFactory.destroySingletons(); - assertMethodOrdering(beanClass, "destroy-methods", Arrays.asList("@PreDestroy.destroy", "customDestroy"), + assertMethodOrdering("destroy-methods", Arrays.asList("@PreDestroy.destroy", "customDestroy"), bean.destroyMethods); } @Test public void testAllLifecycleMechanismsAtOnce() { - final Class beanClass = AllInOneBean.class; - final DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, + Class beanClass = AllInOneBean.class; + DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "afterPropertiesSet", "destroy"); - final AllInOneBean bean = (AllInOneBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN); - assertMethodOrdering(beanClass, "init-methods", Arrays.asList("afterPropertiesSet"), bean.initMethods); + AllInOneBean bean = (AllInOneBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN); + assertMethodOrdering("init-methods", Arrays.asList("afterPropertiesSet"), bean.initMethods); beanFactory.destroySingletons(); - assertMethodOrdering(beanClass, "destroy-methods", Arrays.asList("destroy"), bean.destroyMethods); + assertMethodOrdering("destroy-methods", Arrays.asList("destroy"), bean.destroyMethods); } @@ -165,7 +153,6 @@ public static class InitDestroyBean { final List initMethods = new ArrayList<>(); final List destroyMethods = new ArrayList<>(); - public void afterPropertiesSet() throws Exception { this.initMethods.add("afterPropertiesSet"); } @@ -175,8 +162,9 @@ public void destroy() throws Exception { } } - public static class InitializingDisposableWithShadowedMethodsBean extends InitDestroyBean implements - InitializingBean, DisposableBean { + + public static class InitializingDisposableWithShadowedMethodsBean extends InitDestroyBean + implements InitializingBean, DisposableBean { @Override public void afterPropertiesSet() throws Exception { @@ -255,14 +243,14 @@ public static class AllInOneBean implements InitializingBean, DisposableBean { final List initMethods = new ArrayList<>(); final List destroyMethods = new ArrayList<>(); - @Override @PostConstruct + @Override public void afterPropertiesSet() throws Exception { this.initMethods.add("afterPropertiesSet"); } - @Override @PreDestroy + @Override public void destroy() throws Exception { this.destroyMethods.add("destroy"); } From 4a470e0a37f44f084f79422fd3252cab3e86ff29 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 17 Feb 2022 22:37:34 +0100 Subject: [PATCH 717/735] Prevent @Bean method overloading by default (with enforceUniqueMethods flag) Closes gh-22609 --- .../context/annotation/Configuration.java | 14 ++++++- .../annotation/ConfigurationClass.java | 33 +++++++++++++++- .../annotation/ConfigurationClassParser.java | 11 ++---- .../BeanMethodPolymorphismTests.java | 38 ++++++++++--------- .../ConfigurationClassProcessingTests.java | 4 +- 5 files changed, 71 insertions(+), 29 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java b/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java index c228da0ddb17..54b089b53dcb 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -460,4 +460,16 @@ */ boolean proxyBeanMethods() default true; + /** + * Specify whether {@code @Bean} methods need to have unique method names, + * raising an exception otherwise in order to prevent accidental overloading. + *

      The default is {@code true}, preventing accidental method overloads which + * get interpreted as overloaded factory methods for the same bean definition + * (as opposed to separate bean definitions with individual conditions etc). + * Switch this flag to {@code false} in order to allow for method overloading + * according to those semantics, accepting the risk for accidental overlaps. + * @since 6.0 + */ + boolean enforceUniqueMethods() default true; + } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java index b6155f6d7bfa..58293278b46c 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ import org.springframework.core.io.DescriptiveResource; import org.springframework.core.io.Resource; import org.springframework.core.type.AnnotationMetadata; +import org.springframework.core.type.MethodMetadata; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -210,8 +211,9 @@ Map> getImportedResources() { } void validate(ProblemReporter problemReporter) { - // A configuration class may not be final (CGLIB limitation) unless it declares proxyBeanMethods=false Map attributes = this.metadata.getAnnotationAttributes(Configuration.class.getName()); + + // A configuration class may not be final (CGLIB limitation) unless it declares proxyBeanMethods=false if (attributes != null && (Boolean) attributes.get("proxyBeanMethods")) { if (this.metadata.isFinal()) { problemReporter.error(new FinalConfigurationProblem()); @@ -220,6 +222,18 @@ void validate(ProblemReporter problemReporter) { beanMethod.validate(problemReporter); } } + + // A configuration class may not contain overloaded bean methods unless it declares enforceUniqueMethods=false + if (attributes != null && (Boolean) attributes.get("enforceUniqueMethods")) { + Map beanMethodsByName = new LinkedHashMap<>(); + for (BeanMethod beanMethod : this.beanMethods) { + MethodMetadata current = beanMethod.getMetadata(); + MethodMetadata existing = beanMethodsByName.put(current.getMethodName(), current); + if (existing != null && existing.getDeclaringClassName().equals(current.getDeclaringClassName())) { + problemReporter.error(new BeanMethodOverloadingProblem(existing.getMethodName())); + } + } + } } @Override @@ -250,4 +264,19 @@ private class FinalConfigurationProblem extends Problem { } } + + /** + * Configuration classes are not allowed to contain overloaded bean methods + * by default (as of 6.0). + */ + private class BeanMethodOverloadingProblem extends Problem { + + BeanMethodOverloadingProblem(String methodName) { + super(String.format("@Configuration class '%s' contains overloaded @Bean methods with name '%s'. Use " + + "unique method names for separate bean definitions (with individual conditions etc) " + + "or switch '@Configuration.enforceUniqueMethods' to 'false'.", + getSimpleName(), methodName), new Location(getResource(), getMetadata())); + } + } + } 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 423078625f97..204b54ec23a5 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -967,8 +967,7 @@ public ConfigurationClass asConfigClass(ConfigurationClass importedBy) { public Collection getMemberClasses() throws IOException { Object sourceToProcess = this.source; - if (sourceToProcess instanceof Class) { - Class sourceClass = (Class) sourceToProcess; + if (sourceToProcess instanceof Class sourceClass) { try { Class[] declaredClasses = sourceClass.getDeclaredClasses(); List members = new ArrayList<>(declaredClasses.length); @@ -1013,8 +1012,7 @@ public SourceClass getSuperClass() throws IOException { public Set getInterfaces() throws IOException { Set result = new LinkedHashSet<>(); - if (this.source instanceof Class) { - Class sourceClass = (Class) this.source; + if (this.source instanceof Class sourceClass) { for (Class ifcClass : sourceClass.getInterfaces()) { result.add(asSourceClass(ifcClass, DEFAULT_EXCLUSION_FILTER)); } @@ -1029,8 +1027,7 @@ public Set getInterfaces() throws IOException { public Set getAnnotations() { Set result = new LinkedHashSet<>(); - if (this.source instanceof Class) { - Class sourceClass = (Class) this.source; + if (this.source instanceof Class sourceClass) { for (Annotation ann : sourceClass.getDeclaredAnnotations()) { Class annType = ann.annotationType(); if (!annType.getName().startsWith("java")) { diff --git a/spring-context/src/test/java/org/springframework/context/annotation/BeanMethodPolymorphismTests.java b/spring-context/src/test/java/org/springframework/context/annotation/BeanMethodPolymorphismTests.java index 170a02cc961f..4e62e4212c5d 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/BeanMethodPolymorphismTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/BeanMethodPolymorphismTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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 @@ public class BeanMethodPolymorphismTests { @Test public void beanMethodDetectedOnSuperClass() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class); - assertThat(ctx.getBean("testBean", TestBean.class)).isNotNull(); + assertThat(ctx.getBean("testBean", BaseTestBean.class)).isNotNull(); } @Test @@ -51,7 +51,7 @@ public void beanMethodOverriding() { ctx.setAllowBeanDefinitionOverriding(false); ctx.refresh(); assertThat(ctx.getDefaultListableBeanFactory().containsSingleton("testBean")).isFalse(); - assertThat(ctx.getBean("testBean", TestBean.class).toString()).isEqualTo("overridden"); + assertThat(ctx.getBean("testBean", BaseTestBean.class).toString()).isEqualTo("overridden"); assertThat(ctx.getDefaultListableBeanFactory().containsSingleton("testBean")).isTrue(); } @@ -62,7 +62,7 @@ public void beanMethodOverridingOnASM() { ctx.setAllowBeanDefinitionOverriding(false); ctx.refresh(); assertThat(ctx.getDefaultListableBeanFactory().containsSingleton("testBean")).isFalse(); - assertThat(ctx.getBean("testBean", TestBean.class).toString()).isEqualTo("overridden"); + assertThat(ctx.getBean("testBean", BaseTestBean.class).toString()).isEqualTo("overridden"); assertThat(ctx.getDefaultListableBeanFactory().containsSingleton("testBean")).isTrue(); } @@ -73,7 +73,7 @@ public void beanMethodOverridingWithNarrowedReturnType() { ctx.setAllowBeanDefinitionOverriding(false); ctx.refresh(); assertThat(ctx.getDefaultListableBeanFactory().containsSingleton("testBean")).isFalse(); - assertThat(ctx.getBean("testBean", TestBean.class).toString()).isEqualTo("overridden"); + assertThat(ctx.getBean("testBean", BaseTestBean.class).toString()).isEqualTo("overridden"); assertThat(ctx.getDefaultListableBeanFactory().containsSingleton("testBean")).isTrue(); } @@ -84,7 +84,7 @@ public void beanMethodOverridingWithNarrowedReturnTypeOnASM() { ctx.setAllowBeanDefinitionOverriding(false); ctx.refresh(); assertThat(ctx.getDefaultListableBeanFactory().containsSingleton("testBean")).isFalse(); - assertThat(ctx.getBean("testBean", TestBean.class).toString()).isEqualTo("overridden"); + assertThat(ctx.getBean("testBean", BaseTestBean.class).toString()).isEqualTo("overridden"); assertThat(ctx.getDefaultListableBeanFactory().containsSingleton("testBean")).isTrue(); } @@ -171,7 +171,15 @@ public void beanMethodThroughAopProxy() { ctx.register(AnnotationAwareAspectJAutoProxyCreator.class); ctx.register(TestAdvisor.class); ctx.refresh(); - ctx.getBean("testBean", TestBean.class); + ctx.getBean("testBean", BaseTestBean.class); + } + + + static class BaseTestBean { + } + + + static class ExtendedTestBean extends BaseTestBean { } @@ -179,8 +187,8 @@ public void beanMethodThroughAopProxy() { static class BaseConfig { @Bean - public TestBean testBean() { - return new TestBean(); + public BaseTestBean testBean() { + return new BaseTestBean(); } } @@ -195,8 +203,8 @@ static class OverridingConfig extends BaseConfig { @Bean @Lazy @Override - public TestBean testBean() { - return new TestBean() { + public BaseTestBean testBean() { + return new BaseTestBean() { @Override public String toString() { return "overridden"; @@ -206,10 +214,6 @@ public String toString() { } - static class ExtendedTestBean extends TestBean { - } - - @Configuration static class NarrowedOverridingConfig extends BaseConfig { @@ -226,7 +230,7 @@ public String toString() { } - @Configuration + @Configuration(enforceUniqueMethods = false) static class ConfigWithOverloading { @Bean @@ -241,7 +245,7 @@ String aString(Integer dependency) { } - @Configuration + @Configuration(enforceUniqueMethods = false) static class ConfigWithOverloadingAndAdditionalMetadata { @Bean @Lazy diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java index 491617d0bfe8..d4ceff45574e 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -626,7 +626,7 @@ public ApplicationListener listener() { } - @Configuration + @Configuration(enforceUniqueMethods = false) public static class OverloadedBeanMismatch { @Bean(name = "other") From 94af2ca06bf711de03286999b1c64a703d6de552 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 18 Feb 2022 15:31:59 +0100 Subject: [PATCH 718/735] Recover from error during SpEL MIXED mode compilation Prior to this commit, SpEL was able to recover from an error that occurred while running a CompiledExpression; however, SpEL was not able to recover from an error that occurred while compiling the expression (such as a java.lang.VerifyError). The latter can occur when multiple threads concurrently change types involved in the expression, such as the concrete type of a custom variable registered via EvaluationContext.setVariable(...), which can result in SpEL generating invalid bytecode. This commit addresses this issue by catching exceptions thrown while compiling an expression and updating the `failedAttempts` and `interpretedCount` counters accordingly. If an exception is caught while operating in SpelCompilerMode.IMMEDIATE mode, the exception will be propagated via a SpelEvaluationException with a new SpelMessage.EXCEPTION_COMPILING_EXPRESSION error category. Closes gh-28043 --- .../expression/spel/SpelMessage.java | 11 ++++-- .../spel/standard/SpelCompiler.java | 5 ++- .../spel/standard/SpelExpression.java | 36 ++++++++++++----- .../spel/standard/SpelCompilerTests.java | 39 +++++++++++++++++++ 4 files changed, 77 insertions(+), 14 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java b/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java index 3a03cfd9a1a4..b8f5f92d0554 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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,11 @@ *

      When a message is formatted, it will have this kind of form, capturing the prefix * and the error kind: * - *

      EL1004E: Type cannot be found 'String'
      + *
      EL1005E: Type cannot be found 'String'
      * * @author Andy Clement * @author Juergen Hoeller + * @author Sam Brannen * @since 3.0 */ public enum SpelMessage { @@ -255,7 +256,11 @@ public enum SpelMessage { /** @since 4.3.17 */ FLAWED_PATTERN(Kind.ERROR, 1073, - "Failed to efficiently evaluate pattern ''{0}'': consider redesigning it"); + "Failed to efficiently evaluate pattern ''{0}'': consider redesigning it"), + + /** @since 5.3.16 */ + EXCEPTION_COMPILING_EXPRESSION(Kind.ERROR, 1074, + "An exception occurred while compiling an expression"); private final Kind kind; diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelCompiler.java b/spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelCompiler.java index f2a225952a0d..d94c18ea5c7f 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelCompiler.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -110,7 +110,8 @@ public CompiledExpression compile(SpelNodeImpl expression) { return ReflectionUtils.accessibleConstructor(clazz).newInstance(); } catch (Throwable ex) { - throw new IllegalStateException("Failed to instantiate CompiledExpression", ex); + throw new IllegalStateException("Failed to instantiate CompiledExpression for expression: " + + expression.toStringAST(), ex); } } } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelExpression.java b/spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelExpression.java index 86ed383c3892..660fb23ddc11 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelExpression.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelExpression.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,6 +44,7 @@ * * @author Andy Clement * @author Juergen Hoeller + * @author Sam Brannen * @since 3.0 */ public class SpelExpression implements Expression { @@ -522,17 +523,34 @@ public boolean compileExpression() { // Compiled by another thread before this thread got into the sync block return true; } - SpelCompiler compiler = SpelCompiler.getCompiler(this.configuration.getCompilerClassLoader()); - compiledAst = compiler.compile(this.ast); - if (compiledAst != null) { - // Successfully compiled - this.compiledAst = compiledAst; - return true; + try { + SpelCompiler compiler = SpelCompiler.getCompiler(this.configuration.getCompilerClassLoader()); + compiledAst = compiler.compile(this.ast); + if (compiledAst != null) { + // Successfully compiled + this.compiledAst = compiledAst; + return true; + } + else { + // Failed to compile + this.failedAttempts.incrementAndGet(); + return false; + } } - else { + catch (Exception ex) { // Failed to compile this.failedAttempts.incrementAndGet(); - return false; + + // If running in mixed mode, revert to interpreted + if (this.configuration.getCompilerMode() == SpelCompilerMode.MIXED) { + this.compiledAst = null; + this.interpretedCount.set(0); + return false; + } + else { + // Running in SpelCompilerMode.immediate mode - propagate exception to caller + throw new SpelEvaluationException(ex, SpelMessage.EXCEPTION_COMPILING_EXPRESSION); + } } } } diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/standard/SpelCompilerTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/standard/SpelCompilerTests.java index 5046f58189aa..a3ee9cb08355 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/standard/SpelCompilerTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/standard/SpelCompilerTests.java @@ -76,6 +76,21 @@ void defaultMethodInvocation() { assertThat(expression.getValue(context)).asInstanceOf(BOOLEAN).isTrue(); } + @Test // gh-28043 + void changingRegisteredVariableTypeDoesNotResultInFailureInMixedMode() { + SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.MIXED, null); + SpelExpressionParser parser = new SpelExpressionParser(config); + Expression sharedExpression = parser.parseExpression("#bean.value"); + StandardEvaluationContext context = new StandardEvaluationContext(); + + Object[] beans = new Object[] {new Bean1(), new Bean2(), new Bean3(), new Bean4()}; + + IntStream.rangeClosed(1, 1_000_000).parallel().forEach(count -> { + context.setVariable("bean", beans[count % 4]); + assertThat(sharedExpression.getValue(context)).asString().startsWith("1"); + }); + } + static class OrderedComponent implements Ordered { @@ -121,4 +136,28 @@ default boolean isEditable2() { boolean hasSomeProperty(); } + public static class Bean1 { + public String getValue() { + return "11"; + } + } + + public static class Bean2 { + public Integer getValue() { + return 111; + } + } + + public static class Bean3 { + public Float getValue() { + return 1.23f; + } + } + + public static class Bean4 { + public Character getValue() { + return '1'; + } + } + } From 071c2988d55b1ad823b79fd4be8908666fc466a8 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 18 Feb 2022 16:18:13 +0100 Subject: [PATCH 719/735] Suppress deprecation warnings in tests in build --- .../orm/jpa/support/OpenEntityManagerInViewTests.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewTests.java index 70360c26dea6..6d8c3157bf46 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/support/OpenEntityManagerInViewTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -419,6 +419,7 @@ private static class TestTaskExecutor extends SimpleAsyncTaskExecutor { private final CountDownLatch latch = new CountDownLatch(1); @Override + @SuppressWarnings("deprecation") public void execute(Runnable task, long startTimeout) { Runnable decoratedTask = () -> { try { From 8c5a407a7d40c397a46110ed2c29c93cd4542331 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 18 Feb 2022 16:22:43 +0100 Subject: [PATCH 720/735] Suppress deprecation warnings in tests in build --- .../core/DefaultDatabaseClientUnitTests.java | 41 ++++++++----------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/DefaultDatabaseClientUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/DefaultDatabaseClientUnitTests.java index 1456a86b6f76..530cfdb043d9 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/DefaultDatabaseClientUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/DefaultDatabaseClientUnitTests.java @@ -249,9 +249,10 @@ void selectShouldEmitFirstValue() { MockRowMetadata metadata = MockRowMetadata.builder().columnMetadata( MockColumnMetadata.builder().name("name").javaType(String.class).build()).build(); - MockResult.Builder resultBuilder = MockResult.builder().rowMetadata(metadata); - MockResult result = resultBuilder.row(MockRow.builder().identified(0, Object.class, "Walter").build()) - .row(MockRow.builder().identified(0, Object.class, "White").build()).build(); + MockResult result = MockResult.builder().row( + MockRow.builder().identified(0, Object.class, "Walter").metadata(metadata).build(), + MockRow.builder().identified(0, Object.class, "White").metadata(metadata).build() + ).build(); mockStatementFor("SELECT * FROM person", result); @@ -269,9 +270,10 @@ void selectShouldEmitAllValues() { MockRowMetadata metadata = MockRowMetadata.builder().columnMetadata( MockColumnMetadata.builder().name("name").javaType(String.class).build()).build(); - MockResult.Builder resultBuilder = MockResult.builder().rowMetadata(metadata); - MockResult result = resultBuilder.row(MockRow.builder().identified(0, Object.class, "Walter").build()) - .row(MockRow.builder().identified(0, Object.class, "White").build()).build(); + MockResult result = MockResult.builder().row( + MockRow.builder().identified(0, Object.class, "Walter").metadata(metadata).build(), + MockRow.builder().identified(0, Object.class, "White").metadata(metadata).build() + ).build(); mockStatementFor("SELECT * FROM person", result); @@ -287,13 +289,13 @@ void selectShouldEmitAllValues() { @Test void selectOneShouldFailWithException() { - MockRowMetadata metadata = MockRowMetadata.builder().columnMetadata( MockColumnMetadata.builder().name("name").javaType(String.class).build()).build(); - MockResult.Builder resultBuilder = MockResult.builder().rowMetadata(metadata); - MockResult result = resultBuilder.row(MockRow.builder().identified(0, Object.class, "Walter").build()) - .row(MockRow.builder().identified(0, Object.class, "White").build()).build(); + MockResult result = MockResult.builder().row( + MockRow.builder().identified(0, Object.class, "Walter").metadata(metadata).build(), + MockRow.builder().identified(0, Object.class, "White").metadata(metadata).build() + ).build(); mockStatementFor("SELECT * FROM person", result); @@ -307,7 +309,6 @@ void selectOneShouldFailWithException() { @Test void shouldApplyExecuteFunction() { - Statement statement = mockStatement(); MockResult result = mockSingleColumnResult( MockRow.builder().identified(0, Object.class, "Walter")); @@ -323,7 +324,6 @@ void shouldApplyExecuteFunction() { @Test void shouldApplyPreparedOperation() { - MockResult result = mockSingleColumnResult( MockRow.builder().identified(0, Object.class, "Walter")); Statement statement = mockStatementFor("SELECT * FROM person", result); @@ -354,10 +354,7 @@ public void bindTo(BindTarget target) { @Test void shouldApplyStatementFilterFunctions() { - - MockRowMetadata metadata = MockRowMetadata.builder().columnMetadata( - MockColumnMetadata.builder().name("name").javaType(String.class).build()).build(); - MockResult result = MockResult.builder().rowMetadata(metadata).build(); + MockResult result = MockResult.builder().build(); Statement statement = mockStatement(result); @@ -378,7 +375,6 @@ void shouldApplyStatementFilterFunctions() { @Test void shouldApplySimpleStatementFilterFunctions() { - MockResult result = mockSingleColumnEmptyResult(); Statement statement = mockStatement(result); @@ -410,7 +406,6 @@ private Statement mockStatementFor(String sql) { } private Statement mockStatementFor(@Nullable String sql, @Nullable Result result) { - Statement statement = mock(Statement.class); when(connection.createStatement(sql == null ? anyString() : eq(sql))).thenReturn( statement); @@ -432,13 +427,11 @@ private MockResult mockSingleColumnEmptyResult() { * row is provided. */ private MockResult mockSingleColumnResult(@Nullable MockRow.Builder row) { - - MockRowMetadata metadata = MockRowMetadata.builder().columnMetadata( - MockColumnMetadata.builder().name("name").javaType(String.class).build()).build(); - - MockResult.Builder resultBuilder = MockResult.builder().rowMetadata(metadata); + MockResult.Builder resultBuilder = MockResult.builder(); if (row != null) { - resultBuilder = resultBuilder.row(row.build()); + MockRowMetadata metadata = MockRowMetadata.builder().columnMetadata( + MockColumnMetadata.builder().name("name").javaType(String.class).build()).build(); + resultBuilder = resultBuilder.row(row.metadata(metadata).build()); } return resultBuilder.build(); } From 42d114534bfdb42c41c42d9e65f3148ccf1aff62 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Fri, 18 Feb 2022 00:50:00 +0100 Subject: [PATCH 721/735] Polish BeanDefinitionRegistrar --- .../config/BeanDefinitionRegistrar.java | 46 ++++++++----------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/BeanDefinitionRegistrar.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/BeanDefinitionRegistrar.java index 149ddcc906af..ce38e3292cda 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/BeanDefinitionRegistrar.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/config/BeanDefinitionRegistrar.java @@ -40,7 +40,9 @@ import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.core.MethodIntrospector; import org.springframework.core.ResolvableType; +import org.springframework.core.log.LogMessage; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; @@ -66,8 +68,6 @@ public final class BeanDefinitionRegistrar { @Nullable private final ResolvableType beanType; - private final BeanDefinitionBuilder builder; - private final List> customizers; @Nullable @@ -81,11 +81,9 @@ private BeanDefinitionRegistrar(@Nullable String beanName, Class beanClass, @ this.beanName = beanName; this.beanClass = beanClass; this.beanType = beanType; - this.builder = BeanDefinitionBuilder.rootBeanDefinition(beanClass); this.customizers = new ArrayList<>(); } - /** * Initialize the registration of a bean with the specified name and type. * @param beanName the name of the bean @@ -124,16 +122,6 @@ public static BeanDefinitionRegistrar inner(Class beanType) { return new BeanDefinitionRegistrar(null, beanType, null); } - /** - * Customize the {@link RootBeanDefinition} using the specified consumer. - * @param bd a consumer for the bean definition - * @return {@code this}, to facilitate method chaining - */ - public BeanDefinitionRegistrar customize(ThrowableConsumer bd) { - this.customizers.add(bd); - return this; - } - /** * Specify the factory method to use to instantiate the bean. * @param declaredType the {@link Method#getDeclaringClass() declared type} @@ -177,19 +165,25 @@ public BeanDefinitionRegistrar instanceSupplier(ThrowableSupplier instanceSup return customize(beanDefinition -> beanDefinition.setInstanceSupplier(instanceSupplier)); } + /** + * Customize the {@link RootBeanDefinition} using the specified consumer. + * @param bd a consumer for the bean definition + * @return {@code this}, to facilitate method chaining + */ + public BeanDefinitionRegistrar customize(ThrowableConsumer bd) { + this.customizers.add(bd); + return this; + } + /** * Register the {@link RootBeanDefinition} defined by this instance to * the specified bean factory. * @param beanFactory the bean factory to use */ public void register(DefaultListableBeanFactory beanFactory) { - if (logger.isDebugEnabled()) { - logger.debug("Register bean definition with name '" + this.beanName + "'"); - } BeanDefinition beanDefinition = toBeanDefinition(); - if (this.beanName == null) { - throw new IllegalStateException("Bean name not set. Could not register " + beanDefinition); - } + Assert.state(this.beanName != null, () -> "Bean name not set. Could not register " + beanDefinition); + logger.debug(LogMessage.format("Register bean definition with name '%s'", this.beanName)); beanFactory.registerBeanDefinition(this.beanName, beanDefinition); } @@ -208,7 +202,8 @@ public RootBeanDefinition toBeanDefinition() { } private RootBeanDefinition createBeanDefinition() { - RootBeanDefinition bd = (RootBeanDefinition) this.builder.getBeanDefinition(); + RootBeanDefinition bd = (RootBeanDefinition) BeanDefinitionBuilder + .rootBeanDefinition(this.beanClass).getBeanDefinition(); if (this.beanType != null) { bd.setTargetType(this.beanType); } @@ -259,6 +254,7 @@ private static String toCommaSeparatedNames(Class... parameterTypes) { return Arrays.stream(parameterTypes).map(Class::getName).collect(Collectors.joining(", ")); } + /** * Callback interface used by instance suppliers that need to resolve * dependencies for the {@link Executable} used to create the instance @@ -276,9 +272,9 @@ private BeanInstanceContext(String beanName, Class beanType) { } /** - * Return a bean instance using the specified {@code factory}. + * Return the bean instance using the {@code factory}. * @param beanFactory the bean factory to use - * @param factory a function that returns a bean instance based on + * @param factory a function that returns the bean instance based on * the resolved attributes required by its instance creator * @param the type of the bean * @return the bean instance @@ -321,9 +317,7 @@ public InjectedElementResolver method(String name, Class... parameterTypes) { private Field getField(String fieldName, Class fieldType) { Field field = ReflectionUtils.findField(this.beanType, fieldName, fieldType); - if (field == null) { - throw new IllegalArgumentException("No field '" + fieldName + "' with type " + fieldType.getName() + " found on " + this.beanType); - } + Assert.notNull(field, () -> "No field '" + fieldName + "' with type " + fieldType.getName() + " found on " + this.beanType); return field; } From c5c926726dc46f5135645d79ddc12c4027e1d061 Mon Sep 17 00:00:00 2001 From: "a.yazychyan" Date: Mon, 7 Feb 2022 20:51:32 +0300 Subject: [PATCH 722/735] Use enhanced switch expressions where feasible Closes gh-28014 --- .../aspectj/annotation/AspectMetadata.java | 18 ++++---- ...ntiationModelAwarePointcutAdvisorImpl.java | 15 +++---- .../ReflectiveAspectJAdvisorFactory.java | 34 +++++++-------- .../AbstractPropertyAccessorBenchmark.java | 20 ++++----- .../mail/javamail/MimeMessageHelper.java | 20 ++++----- .../CachingConfigurationSelector.java | 12 ++---- .../context/annotation/TypeFilterUtils.java | 28 +++++-------- .../standard/DateTimeFormatterRegistrar.java | 10 ++--- .../AsyncConfigurationSelector.java | 16 +++---- .../org/springframework/asm/TypePath.java | 23 ++++------ .../core/annotation/AnnotationsScanner.java | 41 +++++++----------- .../core/env/ProfilesParser.java | 23 +++++----- .../core/io/buffer/DataBufferUtils.java | 13 +++--- .../ListenableFutureCallbackRegistry.java | 28 ++++--------- .../expression/spel/SpelMessage.java | 6 +-- .../expression/spel/ast/OpDivide.java | 21 +++------- .../expression/spel/ast/OpMinus.java | 42 ++++++------------- .../expression/spel/ast/OpModulus.java | 21 +++------- .../expression/spel/ast/OpMultiply.java | 21 +++------- .../expression/spel/ast/OpPlus.java | 21 +++------- .../expression/spel/ast/Selection.java | 12 +++--- .../apache/commons/logging/LogAdapter.java | 29 ++++++------- .../MarshallingMessageConverter.java | 13 +++--- .../DefaultSubscriptionRegistryBenchmark.java | 15 +++---- .../RSocketFrameTypeMessageCondition.java | 24 +++++------ .../orm/jpa/SharedEntityManagerCreator.java | 9 ++-- .../vendor/EclipseLinkJpaVendorAdapter.java | 26 ++++++------ .../jpa/vendor/HibernateJpaVendorAdapter.java | 28 ++++++------- .../connection/R2dbcTransactionManager.java | 18 ++++---- .../mock/web/MockPageContext.java | 38 +++++------------ .../HeuristicCompletionException.java | 16 +++---- .../jta/SpringJtaSynchronizationAdapter.java | 11 ++--- .../http/codec/json/Jackson2Tokenizer.java | 16 ++----- .../client/DefaultResponseErrorHandler.java | 9 ++-- .../testfixture/servlet/MockPageContext.java | 38 +++++------------ .../ViewControllerBeanDefinitionParser.java | 19 ++++----- .../ConcurrentWebSocketSessionDecorator.java | 11 ++--- .../session/AbstractSockJsSession.java | 19 ++++----- 38 files changed, 291 insertions(+), 493 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java index 048cc603ccc1..64bb2fe1d0a8 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java @@ -101,24 +101,22 @@ public AspectMetadata(Class aspectClass, String aspectName) { this.ajType = ajType; switch (this.ajType.getPerClause().getKind()) { - case SINGLETON: + case SINGLETON -> { this.perClausePointcut = Pointcut.TRUE; - return; - case PERTARGET: - case PERTHIS: + } + case PERTARGET, PERTHIS -> { AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); ajexp.setLocation(aspectClass.getName()); ajexp.setExpression(findPerClause(aspectClass)); ajexp.setPointcutDeclarationScope(aspectClass); this.perClausePointcut = ajexp; - return; - case PERTYPEWITHIN: + } + case PERTYPEWITHIN -> { // Works with a type pattern this.perClausePointcut = new ComposablePointcut(new TypePatternClassFilter(findPerClause(aspectClass))); - return; - default: - throw new AopConfigException( - "PerClause " + ajType.getPerClause().getKind() + " not supported by Spring AOP for " + aspectClass); + } + default -> throw new AopConfigException( + "PerClause " + ajType.getPerClause().getKind() + " not supported by Spring AOP for " + aspectClass); } } diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java index 7d89175c8c2d..ea5705cf8e4b 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java @@ -220,21 +220,18 @@ private void determineAdviceType() { } else { switch (aspectJAnnotation.getAnnotationType()) { - case AtPointcut: - case AtAround: + case AtPointcut, AtAround -> { this.isBeforeAdvice = false; this.isAfterAdvice = false; - break; - case AtBefore: + } + case AtBefore -> { this.isBeforeAdvice = true; this.isAfterAdvice = false; - break; - case AtAfter: - case AtAfterReturning: - case AtAfterThrowing: + } + case AtAfter, AtAfterReturning, AtAfterThrowing -> { this.isBeforeAdvice = false; this.isAfterAdvice = true; - break; + } } } } diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java index c1c10c946ed6..f24e2ac7a0a3 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java @@ -261,42 +261,36 @@ public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut AbstractAspectJAdvice springAdvice; switch (aspectJAnnotation.getAnnotationType()) { - case AtPointcut: + case AtPointcut -> { if (logger.isDebugEnabled()) { logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'"); } return null; - case AtAround: - springAdvice = new AspectJAroundAdvice( - candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); - break; - case AtBefore: - springAdvice = new AspectJMethodBeforeAdvice( - candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); - break; - case AtAfter: - springAdvice = new AspectJAfterAdvice( - candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); - break; - case AtAfterReturning: + } + case AtAround -> springAdvice = new AspectJAroundAdvice( + candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); + case AtBefore -> springAdvice = new AspectJMethodBeforeAdvice( + candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); + case AtAfter -> springAdvice = new AspectJAfterAdvice( + candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); + case AtAfterReturning -> { springAdvice = new AspectJAfterReturningAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterReturningAnnotation.returning())) { springAdvice.setReturningName(afterReturningAnnotation.returning()); } - break; - case AtAfterThrowing: + } + case AtAfterThrowing -> { springAdvice = new AspectJAfterThrowingAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterThrowingAnnotation.throwing())) { springAdvice.setThrowingName(afterThrowingAnnotation.throwing()); } - break; - default: - throw new UnsupportedOperationException( - "Unsupported advice type on method: " + candidateAdviceMethod); + } + default -> throw new UnsupportedOperationException( + "Unsupported advice type on method: " + candidateAdviceMethod); } // Now to configure the advice... diff --git a/spring-beans/src/jmh/java/org/springframework/beans/AbstractPropertyAccessorBenchmark.java b/spring-beans/src/jmh/java/org/springframework/beans/AbstractPropertyAccessorBenchmark.java index d407318f103c..d71837d6b75b 100644 --- a/spring-beans/src/jmh/java/org/springframework/beans/AbstractPropertyAccessorBenchmark.java +++ b/spring-beans/src/jmh/java/org/springframework/beans/AbstractPropertyAccessorBenchmark.java @@ -61,18 +61,14 @@ public void setup() { this.propertyAccessor = new BeanWrapperImpl(this.target); } switch (this.customEditor) { - case "stringTrimmer": - this.propertyAccessor.registerCustomEditor(String.class, new StringTrimmerEditor(false)); - break; - case "numberOnPath": - this.propertyAccessor.registerCustomEditor(int.class, "array.somePath", new CustomNumberEditor(Integer.class, false)); - break; - case "numberOnNestedPath": - this.propertyAccessor.registerCustomEditor(int.class, "array[0].somePath", new CustomNumberEditor(Integer.class, false)); - break; - case "numberOnType": - this.propertyAccessor.registerCustomEditor(int.class, new CustomNumberEditor(Integer.class, false)); - break; + case "stringTrimmer" -> this.propertyAccessor.registerCustomEditor(String.class, + new StringTrimmerEditor(false)); + case "numberOnPath" -> this.propertyAccessor.registerCustomEditor(int.class, "array.somePath", + new CustomNumberEditor(Integer.class, false)); + case "numberOnNestedPath" -> this.propertyAccessor.registerCustomEditor(int.class, "array[0].somePath", + new CustomNumberEditor(Integer.class, false)); + case "numberOnType" -> this.propertyAccessor.registerCustomEditor(int.class, + new CustomNumberEditor(Integer.class, false)); } } diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java index 3d7bf4c7b0dc..23eaee1dd207 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java @@ -333,20 +333,18 @@ public final MimeMessage getMimeMessage() { */ protected void createMimeMultiparts(MimeMessage mimeMessage, int multipartMode) throws MessagingException { switch (multipartMode) { - case MULTIPART_MODE_NO: - setMimeMultiparts(null, null); - break; - case MULTIPART_MODE_MIXED: + case MULTIPART_MODE_NO -> setMimeMultiparts(null, null); + case MULTIPART_MODE_MIXED -> { MimeMultipart mixedMultipart = new MimeMultipart(MULTIPART_SUBTYPE_MIXED); mimeMessage.setContent(mixedMultipart); setMimeMultiparts(mixedMultipart, mixedMultipart); - break; - case MULTIPART_MODE_RELATED: + } + case MULTIPART_MODE_RELATED -> { MimeMultipart relatedMultipart = new MimeMultipart(MULTIPART_SUBTYPE_RELATED); mimeMessage.setContent(relatedMultipart); setMimeMultiparts(relatedMultipart, relatedMultipart); - break; - case MULTIPART_MODE_MIXED_RELATED: + } + case MULTIPART_MODE_MIXED_RELATED -> { MimeMultipart rootMixedMultipart = new MimeMultipart(MULTIPART_SUBTYPE_MIXED); mimeMessage.setContent(rootMixedMultipart); MimeMultipart nestedRelatedMultipart = new MimeMultipart(MULTIPART_SUBTYPE_RELATED); @@ -354,9 +352,9 @@ protected void createMimeMultiparts(MimeMessage mimeMessage, int multipartMode) relatedBodyPart.setContent(nestedRelatedMultipart); rootMixedMultipart.addBodyPart(relatedBodyPart); setMimeMultiparts(rootMixedMultipart, nestedRelatedMultipart); - break; - default: - throw new IllegalArgumentException("Only multipart modes MIXED_RELATED, RELATED and NO supported"); + } + default -> throw new IllegalArgumentException( + "Only multipart modes MIXED_RELATED, RELATED and NO supported"); } } diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurationSelector.java b/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurationSelector.java index 3c55c95d5992..1af81080ebb8 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurationSelector.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurationSelector.java @@ -68,14 +68,10 @@ public class CachingConfigurationSelector extends AdviceModeImportSelector getProxyImports(); + case ASPECTJ -> getAspectJImports(); + }; } /** diff --git a/spring-context/src/main/java/org/springframework/context/annotation/TypeFilterUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/TypeFilterUtils.java index 340c232f60f1..4f02a7ebb129 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/TypeFilterUtils.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/TypeFilterUtils.java @@ -78,38 +78,32 @@ public static List createTypeFiltersFor(AnnotationAttributes filterA for (Class filterClass : filterAttributes.getClassArray("classes")) { switch (filterType) { - case ANNOTATION: + case ANNOTATION -> { Assert.isAssignable(Annotation.class, filterClass, "@ComponentScan ANNOTATION type filter requires an annotation type"); @SuppressWarnings("unchecked") Class annotationType = (Class) filterClass; typeFilters.add(new AnnotationTypeFilter(annotationType)); - break; - case ASSIGNABLE_TYPE: - typeFilters.add(new AssignableTypeFilter(filterClass)); - break; - case CUSTOM: + } + case ASSIGNABLE_TYPE -> typeFilters.add(new AssignableTypeFilter(filterClass)); + case CUSTOM -> { Assert.isAssignable(TypeFilter.class, filterClass, "@ComponentScan CUSTOM type filter requires a TypeFilter implementation"); TypeFilter filter = ParserStrategyUtils.instantiateClass(filterClass, TypeFilter.class, environment, resourceLoader, registry); typeFilters.add(filter); - break; - default: - throw new IllegalArgumentException("Filter type not supported with Class value: " + filterType); + } + default -> throw new IllegalArgumentException( + "Filter type not supported with Class value: " + filterType); } } for (String expression : filterAttributes.getStringArray("pattern")) { switch (filterType) { - case ASPECTJ: - typeFilters.add(new AspectJTypeFilter(expression, resourceLoader.getClassLoader())); - break; - case REGEX: - typeFilters.add(new RegexPatternTypeFilter(Pattern.compile(expression))); - break; - default: - throw new IllegalArgumentException("Filter type not supported with String pattern: " + filterType); + case ASPECTJ -> typeFilters.add(new AspectJTypeFilter(expression, resourceLoader.getClassLoader())); + case REGEX -> typeFilters.add(new RegexPatternTypeFilter(Pattern.compile(expression))); + default -> throw new IllegalArgumentException( + "Filter type not supported with String pattern: " + filterType); } } diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java index ec4964b0e149..0d35e95cd4ca 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java @@ -209,11 +209,11 @@ private DateTimeFormatter getFormatter(Type type) { } private DateTimeFormatter getFallbackFormatter(Type type) { - switch (type) { - case DATE: return DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT); - case TIME: return DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT); - default: return DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT); - } + return switch (type) { + case DATE -> DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT); + case TIME -> DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT); + case DATE_TIME -> DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT); + }; } } diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncConfigurationSelector.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncConfigurationSelector.java index 76c338090feb..0acc985d3ea0 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncConfigurationSelector.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncConfigurationSelector.java @@ -18,7 +18,7 @@ import org.springframework.context.annotation.AdviceMode; import org.springframework.context.annotation.AdviceModeImportSelector; -import org.springframework.lang.Nullable; +import org.springframework.lang.NonNull; /** * Selects which implementation of {@link AbstractAsyncConfiguration} should @@ -43,16 +43,12 @@ public class AsyncConfigurationSelector extends AdviceModeImportSelector new String[]{ProxyAsyncConfiguration.class.getName()}; + case ASPECTJ -> new String[]{ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME}; + }; } } diff --git a/spring-core/src/main/java/org/springframework/asm/TypePath.java b/spring-core/src/main/java/org/springframework/asm/TypePath.java index b7cf845e7a4d..be95d3a55fac 100644 --- a/spring-core/src/main/java/org/springframework/asm/TypePath.java +++ b/spring-core/src/main/java/org/springframework/asm/TypePath.java @@ -163,22 +163,13 @@ public String toString() { int length = getLength(); StringBuilder result = new StringBuilder(length * 2); for (int i = 0; i < length; ++i) { - switch (getStep(i)) { - case ARRAY_ELEMENT: - result.append('['); - break; - case INNER_TYPE: - result.append('.'); - break; - case WILDCARD_BOUND: - result.append('*'); - break; - case TYPE_ARGUMENT: - result.append(getStepArgument(i)).append(';'); - break; - default: - throw new AssertionError(); - } + switch (getStep(i)) { + case ARRAY_ELEMENT -> result.append('['); + case INNER_TYPE -> result.append('.'); + case WILDCARD_BOUND -> result.append('*'); + case TYPE_ARGUMENT -> result.append(getStepArgument(i)).append(';'); + default -> throw new AssertionError(); + } } return result.toString(); } diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java index 19d520c3c14a..88e65703a0e4 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java @@ -95,19 +95,13 @@ private static R process(C context, AnnotatedElement source, private static R processClass(C context, Class source, SearchStrategy searchStrategy, AnnotationsProcessor processor) { - switch (searchStrategy) { - case DIRECT: - return processElement(context, source, processor); - case INHERITED_ANNOTATIONS: - return processClassInheritedAnnotations(context, source, searchStrategy, processor); - case SUPERCLASS: - return processClassHierarchy(context, source, processor, false, false); - case TYPE_HIERARCHY: - return processClassHierarchy(context, source, processor, true, false); - case TYPE_HIERARCHY_AND_ENCLOSING_CLASSES: - return processClassHierarchy(context, source, processor, true, true); - } - throw new IllegalStateException("Unsupported search strategy " + searchStrategy); + return switch (searchStrategy) { + case DIRECT -> processElement(context, source, processor); + case INHERITED_ANNOTATIONS -> processClassInheritedAnnotations(context, source, searchStrategy, processor); + case SUPERCLASS -> processClassHierarchy(context, source, processor, false, false); + case TYPE_HIERARCHY -> processClassHierarchy(context, source, processor, true, false); + case TYPE_HIERARCHY_AND_ENCLOSING_CLASSES -> processClassHierarchy(context, source, processor, true, true); + }; } @Nullable @@ -238,19 +232,14 @@ private static R processClassHierarchy(C context, int[] aggregateIndex, C private static R processMethod(C context, Method source, SearchStrategy searchStrategy, AnnotationsProcessor processor) { - switch (searchStrategy) { - case DIRECT: - case INHERITED_ANNOTATIONS: - return processMethodInheritedAnnotations(context, source, processor); - case SUPERCLASS: - return processMethodHierarchy(context, new int[] {0}, source.getDeclaringClass(), - processor, source, false); - case TYPE_HIERARCHY: - case TYPE_HIERARCHY_AND_ENCLOSING_CLASSES: - return processMethodHierarchy(context, new int[] {0}, source.getDeclaringClass(), - processor, source, true); - } - throw new IllegalStateException("Unsupported search strategy " + searchStrategy); + return switch (searchStrategy) { + case DIRECT, INHERITED_ANNOTATIONS -> processMethodInheritedAnnotations(context, source, processor); + case SUPERCLASS -> processMethodHierarchy(context, new int[]{0}, source.getDeclaringClass(), + processor, source, false); + case TYPE_HIERARCHY, TYPE_HIERARCHY_AND_ENCLOSING_CLASSES -> processMethodHierarchy(context, new int[]{0}, + source.getDeclaringClass(), + processor, source, true); + }; } @Nullable diff --git a/spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java b/spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java index 5d4dd0c86b41..b8f030dd52a4 100644 --- a/spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java +++ b/spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java @@ -70,25 +70,23 @@ private static Profiles parseTokens(String expression, StringTokenizer tokens, C continue; } switch (token) { - case "(": + case "(" -> { Profiles contents = parseTokens(expression, tokens, Context.BRACKET); if (context == Context.INVERT) { return contents; } elements.add(contents); - break; - case "&": + } + case "&" -> { assertWellFormed(expression, operator == null || operator == Operator.AND); operator = Operator.AND; - break; - case "|": + } + case "|" -> { assertWellFormed(expression, operator == null || operator == Operator.OR); operator = Operator.OR; - break; - case "!": - elements.add(not(parseTokens(expression, tokens, Context.INVERT))); - break; - case ")": + } + case "!" -> elements.add(not(parseTokens(expression, tokens, Context.INVERT))); + case ")" -> { Profiles merged = merge(expression, elements, operator); if (context == Context.BRACKET) { return merged; @@ -96,13 +94,14 @@ private static Profiles parseTokens(String expression, StringTokenizer tokens, C elements.clear(); elements.add(merged); operator = null; - break; - default: + } + default -> { Profiles value = equals(token); if (context == Context.INVERT) { return value; } elements.add(value); + } } } return merge(expression, elements, operator); diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java index d97a59fe45e0..73f4579c1a84 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java @@ -608,14 +608,11 @@ public static Matcher matcher(byte[]... delimiters) { private static NestedMatcher createMatcher(byte[] delimiter) { Assert.isTrue(delimiter.length > 0, "Delimiter must not be empty"); - switch (delimiter.length) { - case 1: - return (delimiter[0] == 10 ? SingleByteMatcher.NEWLINE_MATCHER : new SingleByteMatcher(delimiter)); - case 2: - return new TwoByteMatcher(delimiter); - default: - return new KnuthMorrisPrattMatcher(delimiter); - } + return switch (delimiter.length) { + case 1 -> (delimiter[0] == 10 ? SingleByteMatcher.NEWLINE_MATCHER : new SingleByteMatcher(delimiter)); + case 2 -> new TwoByteMatcher(delimiter); + default -> new KnuthMorrisPrattMatcher(delimiter); + }; } diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java index d3be92bbcd56..343e81c07164 100644 --- a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java +++ b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java @@ -56,16 +56,12 @@ public void addCallback(ListenableFutureCallback callback) { Assert.notNull(callback, "'callback' must not be null"); synchronized (this.mutex) { switch (this.state) { - case NEW: + case NEW -> { this.successCallbacks.add(callback); this.failureCallbacks.add(callback); - break; - case SUCCESS: - notifySuccess(callback); - break; - case FAILURE: - notifyFailure(callback); - break; + } + case SUCCESS -> notifySuccess(callback); + case FAILURE -> notifyFailure(callback); } } } @@ -99,12 +95,8 @@ public void addSuccessCallback(SuccessCallback callback) { Assert.notNull(callback, "'callback' must not be null"); synchronized (this.mutex) { switch (this.state) { - case NEW: - this.successCallbacks.add(callback); - break; - case SUCCESS: - notifySuccess(callback); - break; + case NEW -> this.successCallbacks.add(callback); + case SUCCESS -> notifySuccess(callback); } } } @@ -118,12 +110,8 @@ public void addFailureCallback(FailureCallback callback) { Assert.notNull(callback, "'callback' must not be null"); synchronized (this.mutex) { switch (this.state) { - case NEW: - this.failureCallbacks.add(callback); - break; - case FAILURE: - notifyFailure(callback); - break; + case NEW -> this.failureCallbacks.add(callback); + case FAILURE -> notifyFailure(callback); } } } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java b/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java index b8f5f92d0554..381a67ae3361 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java @@ -287,10 +287,8 @@ public enum SpelMessage { public String formatMessage(Object... inserts) { StringBuilder formattedMessage = new StringBuilder(); formattedMessage.append("EL").append(this.code); - switch (this.kind) { - case ERROR: - formattedMessage.append('E'); - break; + if (this.kind == Kind.ERROR) { + formattedMessage.append('E'); } formattedMessage.append(": "); formattedMessage.append(MessageFormat.format(this.message, inserts)); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java index f555d75f3209..7ade8deaee24 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java @@ -115,21 +115,12 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) { cf.exitCompilationScope(); CodeFlow.insertNumericUnboxOrPrimitiveTypeCoercion(mv, rightDesc, targetDesc); switch (targetDesc) { - case 'I': - mv.visitInsn(IDIV); - break; - case 'J': - mv.visitInsn(LDIV); - break; - case 'F': - mv.visitInsn(FDIV); - break; - case 'D': - mv.visitInsn(DDIV); - break; - default: - throw new IllegalStateException( - "Unrecognized exit type descriptor: '" + this.exitTypeDescriptor + "'"); + case 'I' -> mv.visitInsn(IDIV); + case 'J' -> mv.visitInsn(LDIV); + case 'F' -> mv.visitInsn(FDIV); + case 'D' -> mv.visitInsn(DDIV); + default -> throw new IllegalStateException( + "Unrecognized exit type descriptor: '" + this.exitTypeDescriptor + "'"); } } cf.pushDescriptor(this.exitTypeDescriptor); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java index ddbc9c7d6f67..9d69f0a6fa0c 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java @@ -184,40 +184,22 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) { cf.exitCompilationScope(); CodeFlow.insertNumericUnboxOrPrimitiveTypeCoercion(mv, rightDesc, targetDesc); switch (targetDesc) { - case 'I': - mv.visitInsn(ISUB); - break; - case 'J': - mv.visitInsn(LSUB); - break; - case 'F': - mv.visitInsn(FSUB); - break; - case 'D': - mv.visitInsn(DSUB); - break; - default: - throw new IllegalStateException( - "Unrecognized exit type descriptor: '" + this.exitTypeDescriptor + "'"); + case 'I' -> mv.visitInsn(ISUB); + case 'J' -> mv.visitInsn(LSUB); + case 'F' -> mv.visitInsn(FSUB); + case 'D' -> mv.visitInsn(DSUB); + default -> throw new IllegalStateException( + "Unrecognized exit type descriptor: '" + this.exitTypeDescriptor + "'"); } } else { switch (targetDesc) { - case 'I': - mv.visitInsn(INEG); - break; - case 'J': - mv.visitInsn(LNEG); - break; - case 'F': - mv.visitInsn(FNEG); - break; - case 'D': - mv.visitInsn(DNEG); - break; - default: - throw new IllegalStateException( - "Unrecognized exit type descriptor: '" + this.exitTypeDescriptor + "'"); + case 'I' -> mv.visitInsn(INEG); + case 'J' -> mv.visitInsn(LNEG); + case 'F' -> mv.visitInsn(FNEG); + case 'D' -> mv.visitInsn(DNEG); + default -> throw new IllegalStateException( + "Unrecognized exit type descriptor: '" + this.exitTypeDescriptor + "'"); } } cf.pushDescriptor(this.exitTypeDescriptor); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java index 51385a3603ea..3d229cedd68a 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java @@ -112,21 +112,12 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) { cf.exitCompilationScope(); CodeFlow.insertNumericUnboxOrPrimitiveTypeCoercion(mv, rightDesc, targetDesc); switch (targetDesc) { - case 'I': - mv.visitInsn(IREM); - break; - case 'J': - mv.visitInsn(LREM); - break; - case 'F': - mv.visitInsn(FREM); - break; - case 'D': - mv.visitInsn(DREM); - break; - default: - throw new IllegalStateException( - "Unrecognized exit type descriptor: '" + this.exitTypeDescriptor + "'"); + case 'I' -> mv.visitInsn(IREM); + case 'J' -> mv.visitInsn(LREM); + case 'F' -> mv.visitInsn(FREM); + case 'D' -> mv.visitInsn(DREM); + default -> throw new IllegalStateException( + "Unrecognized exit type descriptor: '" + this.exitTypeDescriptor + "'"); } } cf.pushDescriptor(this.exitTypeDescriptor); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java index 83c406e01d09..3db753c15a64 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java @@ -140,21 +140,12 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) { cf.exitCompilationScope(); CodeFlow.insertNumericUnboxOrPrimitiveTypeCoercion(mv, rightDesc, targetDesc); switch (targetDesc) { - case 'I': - mv.visitInsn(IMUL); - break; - case 'J': - mv.visitInsn(LMUL); - break; - case 'F': - mv.visitInsn(FMUL); - break; - case 'D': - mv.visitInsn(DMUL); - break; - default: - throw new IllegalStateException( - "Unrecognized exit type descriptor: '" + this.exitTypeDescriptor + "'"); + case 'I' -> mv.visitInsn(IMUL); + case 'J' -> mv.visitInsn(LMUL); + case 'F' -> mv.visitInsn(FMUL); + case 'D' -> mv.visitInsn(DMUL); + default -> throw new IllegalStateException( + "Unrecognized exit type descriptor: '" + this.exitTypeDescriptor + "'"); } } cf.pushDescriptor(this.exitTypeDescriptor); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java index 098f96dca123..f4ff34235f72 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java @@ -226,21 +226,12 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) { cf.exitCompilationScope(); CodeFlow.insertNumericUnboxOrPrimitiveTypeCoercion(mv, rightDesc, targetDesc); switch (targetDesc) { - case 'I': - mv.visitInsn(IADD); - break; - case 'J': - mv.visitInsn(LADD); - break; - case 'F': - mv.visitInsn(FADD); - break; - case 'D': - mv.visitInsn(DADD); - break; - default: - throw new IllegalStateException( - "Unrecognized exit type descriptor: '" + this.exitTypeDescriptor + "'"); + case 'I' -> mv.visitInsn(IADD); + case 'J' -> mv.visitInsn(LADD); + case 'F' -> mv.visitInsn(FADD); + case 'D' -> mv.visitInsn(DADD); + default -> throw new IllegalStateException( + "Unrecognized exit type descriptor: '" + this.exitTypeDescriptor + "'"); } } } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Selection.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Selection.java index d2034ef761b8..63da77012cde 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Selection.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Selection.java @@ -209,12 +209,12 @@ public String toStringAST() { } private String prefix() { - switch (this.variant) { - case ALL: return "?["; - case FIRST: return "^["; - case LAST: return "$["; - } - return ""; + return switch (this.variant) { + case ALL -> "?["; + case FIRST -> "^["; + case LAST -> "$["; + default -> ""; + }; } } diff --git a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java index 09ae22efe052..5ba97293f38c 100644 --- a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java +++ b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java @@ -84,22 +84,19 @@ private LogAdapter() { * @param name the logger name */ public static Log createLog(String name) { - switch (logApi) { - case LOG4J: - return Log4jAdapter.createLog(name); - case SLF4J_LAL: - return Slf4jAdapter.createLocationAwareLog(name); - case SLF4J: - return Slf4jAdapter.createLog(name); - default: - // Defensively use lazy-initializing adapter class here as well since the - // java.logging module is not present by default on JDK 9. We are requiring - // its presence if neither Log4j nor SLF4J is available; however, in the - // case of Log4j or SLF4J, we are trying to prevent early initialization - // of the JavaUtilLog adapter - e.g. by a JVM in debug mode - when eagerly - // trying to parse the bytecode for all the cases of this switch clause. - return JavaUtilAdapter.createLog(name); - } + return switch (logApi) { + case LOG4J -> Log4jAdapter.createLog(name); + case SLF4J_LAL -> Slf4jAdapter.createLocationAwareLog(name); + case SLF4J -> Slf4jAdapter.createLog(name); + default -> + // Defensively use lazy-initializing adapter class here as well since the + // java.logging module is not present by default on JDK 9. We are requiring + // its presence if neither Log4j nor SLF4J is available; however, in the + // case of Log4j or SLF4J, we are trying to prevent early initialization + // of the JavaUtilLog adapter - e.g. by a JVM in debug mode - when eagerly + // trying to parse the bytecode for all the cases of this switch clause. + JavaUtilAdapter.createLog(name); + }; } private static boolean isPresent(String className) { diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java index e8524239e9e4..a6cec5ce4ebc 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java @@ -155,14 +155,11 @@ public void afterPropertiesSet() { public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException { Assert.state(this.marshaller != null, "No Marshaller set"); try { - switch (this.targetType) { - case TEXT: - return marshalToTextMessage(object, session, this.marshaller); - case BYTES: - return marshalToBytesMessage(object, session, this.marshaller); - default: - return marshalToMessage(object, session, this.marshaller, this.targetType); - } + return switch (this.targetType) { + case TEXT -> marshalToTextMessage(object, session, this.marshaller); + case BYTES -> marshalToBytesMessage(object, session, this.marshaller); + default -> marshalToMessage(object, session, this.marshaller, this.targetType); + }; } catch (XmlMappingException | IOException ex) { throw new MessageConversionException("Could not marshal [" + object + "]", ex); diff --git a/spring-messaging/src/jmh/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistryBenchmark.java b/spring-messaging/src/jmh/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistryBenchmark.java index d33412bbab47..c80415c6fbbd 100644 --- a/spring-messaging/src/jmh/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistryBenchmark.java +++ b/spring-messaging/src/jmh/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistryBenchmark.java @@ -145,18 +145,15 @@ public static class FindRequest { @Setup(Level.Trial) public void doSetup(ServerState serverState) { switch (this.contention) { - case "noSubscribers": + case "noSubscribers" -> { this.destination = "someDestination_withNoSubscribers_" + serverState.uniqueIdGenerator.incrementAndGet(); - break; - case "sameDestination": - this.destination = serverState.destinationIds[0]; - break; - case "none": + } + case "sameDestination" -> this.destination = serverState.destinationIds[0]; + case "none" -> { int uniqueNumber = serverState.uniqueIdGenerator.getAndIncrement(); this.destination = serverState.destinationIds[uniqueNumber % serverState.destinationIds.length]; - break; - default: - throw new IllegalStateException(); + } + default -> throw new IllegalStateException(); } } } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java index 12ab2ead21c2..fb09da86c146 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java @@ -192,20 +192,16 @@ public int compareTo(RSocketFrameTypeMessageCondition other, Message message) * @since 5.2.2 */ public static RSocketFrameTypeMessageCondition getCondition(int cardinalityIn, int cardinalityOut) { - switch (cardinalityIn) { - case 0: - case 1: - switch (cardinalityOut) { - case 0: return REQUEST_FNF_OR_RESPONSE_CONDITION; - case 1: return REQUEST_RESPONSE_CONDITION; - case 2: return REQUEST_STREAM_CONDITION; - default: throw new IllegalStateException("Invalid cardinality: " + cardinalityOut); - } - case 2: - return REQUEST_CHANNEL_CONDITION; - default: - throw new IllegalStateException("Invalid cardinality: " + cardinalityIn); - } + return switch (cardinalityIn) { + case 0, 1 -> switch (cardinalityOut) { + case 0 -> REQUEST_FNF_OR_RESPONSE_CONDITION; + case 1 -> REQUEST_RESPONSE_CONDITION; + case 2 -> REQUEST_STREAM_CONDITION; + default -> throw new IllegalStateException("Invalid cardinality: " + cardinalityOut); + }; + case 2 -> REQUEST_CHANNEL_CONDITION; + default -> throw new IllegalStateException("Invalid cardinality: " + cardinalityIn); + }; } } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java index 0fb6acc3bab5..977b71de1398 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java @@ -266,13 +266,14 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl this.targetFactory, this.properties, this.synchronizedWithTransaction); switch (method.getName()) { - case "getTargetEntityManager": + case "getTargetEntityManager" -> { // Handle EntityManagerProxy interface. if (target == null) { throw new IllegalStateException("No transactional EntityManager available"); } return target; - case "unwrap": + } + case "unwrap" -> { Class targetClass = (Class) args[0]; if (targetClass == null) { return (target != null ? target : proxy); @@ -281,8 +282,8 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl if (target == null) { throw new IllegalStateException("No transactional EntityManager available"); } - // Still perform unwrap call on target EntityManager. - break; + } + // Still perform unwrap call on target EntityManager. } if (transactionRequiringMethods.contains(method.getName())) { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java index b64258d9dbf0..2ad8daaff308 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java @@ -94,19 +94,19 @@ public Map getJpaPropertyMap() { */ @Nullable protected String determineTargetDatabaseName(Database database) { - switch (database) { - case DB2: return TargetDatabase.DB2; - case DERBY: return TargetDatabase.Derby; - case HANA: return TargetDatabase.HANA; - case HSQL: return TargetDatabase.HSQL; - case INFORMIX: return TargetDatabase.Informix; - case MYSQL: return TargetDatabase.MySQL; - case ORACLE: return TargetDatabase.Oracle; - case POSTGRESQL: return TargetDatabase.PostgreSQL; - case SQL_SERVER: return TargetDatabase.SQLServer; - case SYBASE: return TargetDatabase.Sybase; - default: return null; - } + return switch (database) { + case DB2 -> TargetDatabase.DB2; + case DERBY -> TargetDatabase.Derby; + case HANA -> TargetDatabase.HANA; + case HSQL -> TargetDatabase.HSQL; + case INFORMIX -> TargetDatabase.Informix; + case MYSQL -> TargetDatabase.MySQL; + case ORACLE -> TargetDatabase.Oracle; + case POSTGRESQL -> TargetDatabase.PostgreSQL; + case SQL_SERVER -> TargetDatabase.SQLServer; + case SYBASE -> TargetDatabase.Sybase; + default -> null; + }; } @Override diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java index 67d86d87e0bb..041f23da5fb3 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java @@ -169,20 +169,20 @@ private Map buildJpaPropertyMap(boolean connectionReleaseOnClose */ @Nullable protected Class determineDatabaseDialectClass(Database database) { - switch (database) { - case DB2: return DB2Dialect.class; - case DERBY: return DerbyTenSevenDialect.class; - case H2: return H2Dialect.class; - case HANA: return HANAColumnStoreDialect.class; - case HSQL: return HSQLDialect.class; - case INFORMIX: return Informix10Dialect.class; - case MYSQL: return MySQL57Dialect.class; - case ORACLE: return Oracle12cDialect.class; - case POSTGRESQL: return PostgreSQL95Dialect.class; - case SQL_SERVER: return SQLServer2012Dialect.class; - case SYBASE: return SybaseDialect.class; - default: return null; - } + return switch (database) { + case DB2 -> DB2Dialect.class; + case DERBY -> DerbyTenSevenDialect.class; + case H2 -> H2Dialect.class; + case HANA -> HANAColumnStoreDialect.class; + case HSQL -> HSQLDialect.class; + case INFORMIX -> Informix10Dialect.class; + case MYSQL -> MySQL57Dialect.class; + case ORACLE -> Oracle12cDialect.class; + case POSTGRESQL -> PostgreSQL95Dialect.class; + case SQL_SERVER -> SQLServer2012Dialect.class; + case SYBASE -> SybaseDialect.class; + default -> null; + }; } @Override diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java index e22c7a1dac9f..fdce9d94e4e8 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java @@ -415,17 +415,13 @@ protected Mono prepareTransactionalConnection( */ @Nullable protected IsolationLevel resolveIsolationLevel(int isolationLevel) { - switch (isolationLevel) { - case TransactionDefinition.ISOLATION_READ_COMMITTED: - return IsolationLevel.READ_COMMITTED; - case TransactionDefinition.ISOLATION_READ_UNCOMMITTED: - return IsolationLevel.READ_UNCOMMITTED; - case TransactionDefinition.ISOLATION_REPEATABLE_READ: - return IsolationLevel.REPEATABLE_READ; - case TransactionDefinition.ISOLATION_SERIALIZABLE: - return IsolationLevel.SERIALIZABLE; - } - return null; + return switch (isolationLevel) { + case TransactionDefinition.ISOLATION_READ_COMMITTED -> IsolationLevel.READ_COMMITTED; + case TransactionDefinition.ISOLATION_READ_UNCOMMITTED -> IsolationLevel.READ_UNCOMMITTED; + case TransactionDefinition.ISOLATION_REPEATABLE_READ -> IsolationLevel.REPEATABLE_READ; + case TransactionDefinition.ISOLATION_SERIALIZABLE -> IsolationLevel.SERIALIZABLE; + default -> null; + }; } /** diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockPageContext.java b/spring-test/src/main/java/org/springframework/mock/web/MockPageContext.java index 9911449917c9..a5feb9e78215 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockPageContext.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockPageContext.java @@ -154,20 +154,11 @@ public void setAttribute(String name, @Nullable Object value) { public void setAttribute(String name, @Nullable Object value, int scope) { Assert.notNull(name, "Attribute name must not be null"); switch (scope) { - case PAGE_SCOPE: - setAttribute(name, value); - break; - case REQUEST_SCOPE: - this.request.setAttribute(name, value); - break; - case SESSION_SCOPE: - this.request.getSession().setAttribute(name, value); - break; - case APPLICATION_SCOPE: - this.servletContext.setAttribute(name, value); - break; - default: - throw new IllegalArgumentException("Invalid scope: " + scope); + case PAGE_SCOPE -> setAttribute(name, value); + case REQUEST_SCOPE -> this.request.setAttribute(name, value); + case SESSION_SCOPE -> this.request.getSession().setAttribute(name, value); + case APPLICATION_SCOPE -> this.servletContext.setAttribute(name, value); + default -> throw new IllegalArgumentException("Invalid scope: " + scope); } } @@ -226,20 +217,11 @@ public void removeAttribute(String name) { public void removeAttribute(String name, int scope) { Assert.notNull(name, "Attribute name must not be null"); switch (scope) { - case PAGE_SCOPE: - this.attributes.remove(name); - break; - case REQUEST_SCOPE: - this.request.removeAttribute(name); - break; - case SESSION_SCOPE: - this.request.getSession().removeAttribute(name); - break; - case APPLICATION_SCOPE: - this.servletContext.removeAttribute(name); - break; - default: - throw new IllegalArgumentException("Invalid scope: " + scope); + case PAGE_SCOPE -> this.attributes.remove(name); + case REQUEST_SCOPE -> this.request.removeAttribute(name); + case SESSION_SCOPE -> this.request.getSession().removeAttribute(name); + case APPLICATION_SCOPE -> this.servletContext.removeAttribute(name); + default -> throw new IllegalArgumentException("Invalid scope: " + scope); } } diff --git a/spring-tx/src/main/java/org/springframework/transaction/HeuristicCompletionException.java b/spring-tx/src/main/java/org/springframework/transaction/HeuristicCompletionException.java index c5b6b71f1853..1d661868df2c 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/HeuristicCompletionException.java +++ b/spring-tx/src/main/java/org/springframework/transaction/HeuristicCompletionException.java @@ -49,16 +49,12 @@ public class HeuristicCompletionException extends TransactionException { public static String getStateString(int state) { - switch (state) { - case STATE_COMMITTED: - return "committed"; - case STATE_ROLLED_BACK: - return "rolled back"; - case STATE_MIXED: - return "mixed"; - default: - return "unknown"; - } + return switch (state) { + case STATE_COMMITTED -> "committed"; + case STATE_ROLLED_BACK -> "rolled back"; + case STATE_MIXED -> "mixed"; + default -> "unknown"; + }; } diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java b/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java index aa718d7aed61..84f54c85a238 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java +++ b/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java @@ -171,14 +171,9 @@ public void afterCompletion(int status) { } // Call afterCompletion with the appropriate status indication. switch (status) { - case Status.STATUS_COMMITTED: - this.springSynchronization.afterCompletion(TransactionSynchronization.STATUS_COMMITTED); - break; - case Status.STATUS_ROLLEDBACK: - this.springSynchronization.afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK); - break; - default: - this.springSynchronization.afterCompletion(TransactionSynchronization.STATUS_UNKNOWN); + case Status.STATUS_COMMITTED -> this.springSynchronization.afterCompletion(TransactionSynchronization.STATUS_COMMITTED); + case Status.STATUS_ROLLEDBACK -> this.springSynchronization.afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK); + default -> this.springSynchronization.afterCompletion(TransactionSynchronization.STATUS_UNKNOWN); } } diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java index 43f380719a52..75458f488a67 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java @@ -154,18 +154,10 @@ else if (token == null ) { // !previousNull private void updateDepth(JsonToken token) { switch (token) { - case START_OBJECT: - this.objectDepth++; - break; - case END_OBJECT: - this.objectDepth--; - break; - case START_ARRAY: - this.arrayDepth++; - break; - case END_ARRAY: - this.arrayDepth--; - break; + case START_OBJECT -> this.objectDepth++; + case END_OBJECT -> this.objectDepth--; + case START_ARRAY -> this.arrayDepth++; + case END_ARRAY -> this.arrayDepth--; } } diff --git a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java index 70664a2e4c27..2ac7fac2acb6 100644 --- a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java @@ -164,12 +164,9 @@ protected void handleError(ClientHttpResponse response, HttpStatus statusCode) t String message = getErrorMessage(statusCode.value(), statusText, body, charset); switch (statusCode.series()) { - case CLIENT_ERROR: - throw HttpClientErrorException.create(message, statusCode, statusText, headers, body, charset); - case SERVER_ERROR: - throw HttpServerErrorException.create(message, statusCode, statusText, headers, body, charset); - default: - throw new UnknownHttpStatusCodeException(message, statusCode.value(), statusText, headers, body, charset); + case CLIENT_ERROR -> throw HttpClientErrorException.create(message, statusCode, statusText, headers, body, charset); + case SERVER_ERROR -> throw HttpServerErrorException.create(message, statusCode, statusText, headers, body, charset); + default -> throw new UnknownHttpStatusCodeException(message, statusCode.value(), statusText, headers, body, charset); } } diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPageContext.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPageContext.java index f45973ef9d03..bab4b1939472 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPageContext.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPageContext.java @@ -154,20 +154,11 @@ public void setAttribute(String name, @Nullable Object value) { public void setAttribute(String name, @Nullable Object value, int scope) { Assert.notNull(name, "Attribute name must not be null"); switch (scope) { - case PAGE_SCOPE: - setAttribute(name, value); - break; - case REQUEST_SCOPE: - this.request.setAttribute(name, value); - break; - case SESSION_SCOPE: - this.request.getSession().setAttribute(name, value); - break; - case APPLICATION_SCOPE: - this.servletContext.setAttribute(name, value); - break; - default: - throw new IllegalArgumentException("Invalid scope: " + scope); + case PAGE_SCOPE -> setAttribute(name, value); + case REQUEST_SCOPE -> this.request.setAttribute(name, value); + case SESSION_SCOPE -> this.request.getSession().setAttribute(name, value); + case APPLICATION_SCOPE -> this.servletContext.setAttribute(name, value); + default -> throw new IllegalArgumentException("Invalid scope: " + scope); } } @@ -226,20 +217,11 @@ public void removeAttribute(String name) { public void removeAttribute(String name, int scope) { Assert.notNull(name, "Attribute name must not be null"); switch (scope) { - case PAGE_SCOPE: - this.attributes.remove(name); - break; - case REQUEST_SCOPE: - this.request.removeAttribute(name); - break; - case SESSION_SCOPE: - this.request.getSession().removeAttribute(name); - break; - case APPLICATION_SCOPE: - this.servletContext.removeAttribute(name); - break; - default: - throw new IllegalArgumentException("Invalid scope: " + scope); + case PAGE_SCOPE -> this.attributes.remove(name); + case REQUEST_SCOPE -> this.request.removeAttribute(name); + case SESSION_SCOPE -> this.request.getSession().removeAttribute(name); + case APPLICATION_SCOPE -> this.servletContext.removeAttribute(name); + default -> throw new IllegalArgumentException("Invalid scope: " + scope); } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java index f08152d3f652..8660adf04c58 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java @@ -82,24 +82,23 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { String name = element.getLocalName(); switch (name) { - case "view-controller": + case "view-controller" -> { if (element.hasAttribute("view-name")) { controller.getPropertyValues().add("viewName", element.getAttribute("view-name")); } if (statusCode != null) { controller.getPropertyValues().add("statusCode", statusCode); } - break; - case "redirect-view-controller": - controller.getPropertyValues().add("view", getRedirectView(element, statusCode, source)); - break; - case "status-controller": + } + case "redirect-view-controller" -> controller.getPropertyValues() + .add("view", getRedirectView(element, statusCode, source)); + case "status-controller" -> { controller.getPropertyValues().add("statusCode", statusCode); controller.getPropertyValues().add("statusOnly", true); - break; - default: - // Should never happen... - throw new IllegalStateException("Unexpected tag name: " + name); + } + default -> + // Should never happen... + throw new IllegalStateException("Unexpected tag name: " + name); } Map urlMap = (Map) hm.getPropertyValues().get("urlMap"); diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/handler/ConcurrentWebSocketSessionDecorator.java b/spring-websocket/src/main/java/org/springframework/web/socket/handler/ConcurrentWebSocketSessionDecorator.java index 46f3149fe852..812b49d377b3 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/handler/ConcurrentWebSocketSessionDecorator.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/handler/ConcurrentWebSocketSessionDecorator.java @@ -210,12 +210,12 @@ private void checkSessionLimits() { } else if (getBufferSize() > getBufferSizeLimit()) { switch (this.overflowStrategy) { - case TERMINATE: + case TERMINATE -> { String format = "Buffer size %d bytes for session '%s' exceeds the allowed limit %d"; String reason = String.format(format, getBufferSize(), getId(), getBufferSizeLimit()); limitExceeded(reason); - break; - case DROP: + } + case DROP -> { int i = 0; while (getBufferSize() > getBufferSizeLimit()) { WebSocketMessage message = this.buffer.poll(); @@ -228,10 +228,7 @@ else if (getBufferSize() > getBufferSizeLimit()) { if (logger.isDebugEnabled()) { logger.debug("Dropped " + i + " messages, buffer size: " + getBufferSize()); } - break; - default: - // Should never happen.. - throw new IllegalStateException("Unexpected OverflowStrategy: " + this.overflowStrategy); + } } } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractSockJsSession.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractSockJsSession.java index 3f33a3de8960..889444609449 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractSockJsSession.java @@ -407,17 +407,14 @@ private void logUndeliveredMessages(int index, String[] messages) { } private static List getUndelivered(String[] messages, int i) { - switch (messages.length - i) { - case 0: - return Collections.emptyList(); - case 1: - return (messages[i].trim().isEmpty() ? - Collections.emptyList() : Collections.singletonList(messages[i])); - default: - return Arrays.stream(Arrays.copyOfRange(messages, i, messages.length)) - .filter(message -> !message.trim().isEmpty()) - .collect(Collectors.toList()); - } + return switch (messages.length - i) { + case 0 -> Collections.emptyList(); + case 1 -> (messages[i].trim().isEmpty() ? + Collections.emptyList() : Collections.singletonList(messages[i])); + default -> Arrays.stream(Arrays.copyOfRange(messages, i, messages.length)) + .filter(message -> !message.trim().isEmpty()) + .collect(Collectors.toList()); + }; } /** From 8c6d59aaaf8d0ff31e7d91c6d0ed7de7cd9f518e Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 19 Feb 2022 14:32:57 +0100 Subject: [PATCH 723/735] Polish contribution See gh-28014 --- .../aspectj/annotation/AspectMetadata.java | 2 +- ...ntiationModelAwarePointcutAdvisorImpl.java | 2 +- .../ReflectiveAspectJAdvisorFactory.java | 2 +- .../AbstractPropertyAccessorBenchmark.java | 20 ++++----- .../mail/javamail/MimeMessageHelper.java | 6 +-- .../CachingConfigurationSelector.java | 2 +- .../context/annotation/TypeFilterUtils.java | 10 ++--- .../standard/DateTimeFormatterRegistrar.java | 2 +- .../AsyncConfigurationSelector.java | 6 +-- .../org/springframework/asm/TypePath.java | 23 +++++++--- .../core/annotation/AnnotationsScanner.java | 2 +- .../core/env/ProfilesParser.java | 2 +- .../core/io/buffer/DataBufferUtils.java | 8 ++-- .../ListenableFutureCallbackRegistry.java | 2 +- .../expression/spel/ast/OpDivide.java | 2 +- .../expression/spel/ast/OpMinus.java | 2 +- .../expression/spel/ast/OpModulus.java | 2 +- .../expression/spel/ast/OpMultiply.java | 2 +- .../expression/spel/ast/OpPlus.java | 2 +- .../expression/spel/ast/Selection.java | 2 +- .../apache/commons/logging/LogAdapter.java | 2 +- .../MarshallingMessageConverter.java | 2 +- .../DefaultSubscriptionRegistryBenchmark.java | 5 +-- .../RSocketFrameTypeMessageCondition.java | 6 +-- .../orm/jpa/SharedEntityManagerCreator.java | 2 +- .../vendor/EclipseLinkJpaVendorAdapter.java | 2 +- .../jpa/vendor/HibernateJpaVendorAdapter.java | 2 +- .../connection/R2dbcTransactionManager.java | 2 +- .../mock/web/MockPageContext.java | 44 ++++++++----------- .../HeuristicCompletionException.java | 2 +- .../jta/SpringJtaSynchronizationAdapter.java | 11 +++-- .../http/codec/json/Jackson2Tokenizer.java | 2 +- .../client/DefaultResponseErrorHandler.java | 11 +++-- .../testfixture/servlet/MockPageContext.java | 44 ++++++++----------- .../ViewControllerBeanDefinitionParser.java | 10 ++--- .../ConcurrentWebSocketSessionDecorator.java | 5 ++- .../session/AbstractSockJsSession.java | 4 +- 37 files changed, 132 insertions(+), 125 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java index 64bb2fe1d0a8..49e31e6beca4 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java index ea5705cf8e4b..33af3adfc309 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java index f24e2ac7a0a3..00e7ad567ef6 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-beans/src/jmh/java/org/springframework/beans/AbstractPropertyAccessorBenchmark.java b/spring-beans/src/jmh/java/org/springframework/beans/AbstractPropertyAccessorBenchmark.java index d71837d6b75b..6cdd116b4cb0 100644 --- a/spring-beans/src/jmh/java/org/springframework/beans/AbstractPropertyAccessorBenchmark.java +++ b/spring-beans/src/jmh/java/org/springframework/beans/AbstractPropertyAccessorBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -61,16 +61,15 @@ public void setup() { this.propertyAccessor = new BeanWrapperImpl(this.target); } switch (this.customEditor) { - case "stringTrimmer" -> this.propertyAccessor.registerCustomEditor(String.class, - new StringTrimmerEditor(false)); - case "numberOnPath" -> this.propertyAccessor.registerCustomEditor(int.class, "array.somePath", - new CustomNumberEditor(Integer.class, false)); - case "numberOnNestedPath" -> this.propertyAccessor.registerCustomEditor(int.class, "array[0].somePath", - new CustomNumberEditor(Integer.class, false)); - case "numberOnType" -> this.propertyAccessor.registerCustomEditor(int.class, - new CustomNumberEditor(Integer.class, false)); + case "stringTrimmer" -> + this.propertyAccessor.registerCustomEditor(String.class, new StringTrimmerEditor(false)); + case "numberOnPath" -> + this.propertyAccessor.registerCustomEditor(int.class, "array.somePath", new CustomNumberEditor(Integer.class, false)); + case "numberOnNestedPath" -> + this.propertyAccessor.registerCustomEditor(int.class, "array[0].somePath", new CustomNumberEditor(Integer.class, false)); + case "numberOnType" -> + this.propertyAccessor.registerCustomEditor(int.class, new CustomNumberEditor(Integer.class, false)); } - } } @@ -94,4 +93,5 @@ public void setArray(int[] array) { this.array = array; } } + } diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java index 23eaee1dd207..84400943ced9 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -353,8 +353,8 @@ protected void createMimeMultiparts(MimeMessage mimeMessage, int multipartMode) rootMixedMultipart.addBodyPart(relatedBodyPart); setMimeMultiparts(rootMixedMultipart, nestedRelatedMultipart); } - default -> throw new IllegalArgumentException( - "Only multipart modes MIXED_RELATED, RELATED and NO supported"); + default -> + throw new IllegalArgumentException("Only multipart modes MIXED_RELATED, RELATED and NO supported"); } } diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurationSelector.java b/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurationSelector.java index 1af81080ebb8..b170593bdcb4 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurationSelector.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurationSelector.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-context/src/main/java/org/springframework/context/annotation/TypeFilterUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/TypeFilterUtils.java index 4f02a7ebb129..6ffb77b42bf3 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/TypeFilterUtils.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/TypeFilterUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -93,8 +93,8 @@ public static List createTypeFiltersFor(AnnotationAttributes filterA environment, resourceLoader, registry); typeFilters.add(filter); } - default -> throw new IllegalArgumentException( - "Filter type not supported with Class value: " + filterType); + default -> + throw new IllegalArgumentException("Filter type not supported with Class value: " + filterType); } } @@ -102,8 +102,8 @@ public static List createTypeFiltersFor(AnnotationAttributes filterA switch (filterType) { case ASPECTJ -> typeFilters.add(new AspectJTypeFilter(expression, resourceLoader.getClassLoader())); case REGEX -> typeFilters.add(new RegexPatternTypeFilter(Pattern.compile(expression))); - default -> throw new IllegalArgumentException( - "Filter type not supported with String pattern: " + filterType); + default -> + throw new IllegalArgumentException("Filter type not supported with String pattern: " + filterType); } } diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java index 0d35e95cd4ca..1a72d4494938 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncConfigurationSelector.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncConfigurationSelector.java index 0acc985d3ea0..c7f50aed70a8 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncConfigurationSelector.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncConfigurationSelector.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2022 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 class AsyncConfigurationSelector extends AdviceModeImportSelector new String[]{ProxyAsyncConfiguration.class.getName()}; - case ASPECTJ -> new String[]{ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME}; + case PROXY -> new String[] {ProxyAsyncConfiguration.class.getName()}; + case ASPECTJ -> new String[] {ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME}; }; } diff --git a/spring-core/src/main/java/org/springframework/asm/TypePath.java b/spring-core/src/main/java/org/springframework/asm/TypePath.java index be95d3a55fac..b7cf845e7a4d 100644 --- a/spring-core/src/main/java/org/springframework/asm/TypePath.java +++ b/spring-core/src/main/java/org/springframework/asm/TypePath.java @@ -163,13 +163,22 @@ public String toString() { int length = getLength(); StringBuilder result = new StringBuilder(length * 2); for (int i = 0; i < length; ++i) { - switch (getStep(i)) { - case ARRAY_ELEMENT -> result.append('['); - case INNER_TYPE -> result.append('.'); - case WILDCARD_BOUND -> result.append('*'); - case TYPE_ARGUMENT -> result.append(getStepArgument(i)).append(';'); - default -> throw new AssertionError(); - } + switch (getStep(i)) { + case ARRAY_ELEMENT: + result.append('['); + break; + case INNER_TYPE: + result.append('.'); + break; + case WILDCARD_BOUND: + result.append('*'); + break; + case TYPE_ARGUMENT: + result.append(getStepArgument(i)).append(';'); + break; + default: + throw new AssertionError(); + } } return result.toString(); } diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java index 88e65703a0e4..5a2666d1b760 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java b/spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java index b8f030dd52a4..8e1e7c5561c9 100644 --- a/spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java +++ b/spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java index 73f4579c1a84..438d7bf082d9 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -607,8 +607,10 @@ public static Matcher matcher(byte[]... delimiters) { } private static NestedMatcher createMatcher(byte[] delimiter) { - Assert.isTrue(delimiter.length > 0, "Delimiter must not be empty"); - return switch (delimiter.length) { + // extract length due to Eclipse IDE compiler error in switch expression + int length = delimiter.length; + Assert.isTrue(length > 0, "Delimiter must not be empty"); + return switch (length) { case 1 -> (delimiter[0] == 10 ? SingleByteMatcher.NEWLINE_MATCHER : new SingleByteMatcher(delimiter)); case 2 -> new TwoByteMatcher(delimiter); default -> new KnuthMorrisPrattMatcher(delimiter); diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java index 343e81c07164..e2a016cc6cb7 100644 --- a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java +++ b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java index 7ade8deaee24..7ac8326eedf3 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java index 9d69f0a6fa0c..1098e15897c7 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java index 3d229cedd68a..a21d5caf529b 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java index 3db753c15a64..d86965acafb3 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java index f4ff34235f72..3bbf0615cdb1 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Selection.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Selection.java index 63da77012cde..9daa3b94aa78 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Selection.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Selection.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java index 5ba97293f38c..8ae19384f5be 100644 --- a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java +++ b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java index a6cec5ce4ebc..c3dd8389ae16 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-messaging/src/jmh/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistryBenchmark.java b/spring-messaging/src/jmh/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistryBenchmark.java index c80415c6fbbd..ebce89c7086b 100644 --- a/spring-messaging/src/jmh/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistryBenchmark.java +++ b/spring-messaging/src/jmh/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistryBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -145,9 +145,8 @@ public static class FindRequest { @Setup(Level.Trial) public void doSetup(ServerState serverState) { switch (this.contention) { - case "noSubscribers" -> { + case "noSubscribers" -> this.destination = "someDestination_withNoSubscribers_" + serverState.uniqueIdGenerator.incrementAndGet(); - } case "sameDestination" -> this.destination = serverState.destinationIds[0]; case "none" -> { int uniqueNumber = serverState.uniqueIdGenerator.getAndIncrement(); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java index fb09da86c146..865a0c0b09d2 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -197,10 +197,10 @@ public static RSocketFrameTypeMessageCondition getCondition(int cardinalityIn, i case 0 -> REQUEST_FNF_OR_RESPONSE_CONDITION; case 1 -> REQUEST_RESPONSE_CONDITION; case 2 -> REQUEST_STREAM_CONDITION; - default -> throw new IllegalStateException("Invalid cardinality: " + cardinalityOut); + default -> throw new IllegalStateException("Invalid response cardinality: " + cardinalityOut); }; case 2 -> REQUEST_CHANNEL_CONDITION; - default -> throw new IllegalStateException("Invalid cardinality: " + cardinalityIn); + default -> throw new IllegalStateException("Invalid request cardinality: " + cardinalityIn); }; } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java index 977b71de1398..f0665ec7e684 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java index 2ad8daaff308..d26bd1e67b57 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java index 041f23da5fb3..1af984c6fde1 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java index fdce9d94e4e8..557427ecb6cf 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockPageContext.java b/spring-test/src/main/java/org/springframework/mock/web/MockPageContext.java index a5feb9e78215..f4a1b9b00483 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockPageContext.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockPageContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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,19 +173,16 @@ public Object getAttribute(String name) { @Nullable public Object getAttribute(String name, int scope) { Assert.notNull(name, "Attribute name must not be null"); - switch (scope) { - case PAGE_SCOPE: - return getAttribute(name); - case REQUEST_SCOPE: - return this.request.getAttribute(name); - case SESSION_SCOPE: + return switch (scope) { + case PAGE_SCOPE -> getAttribute(name); + case REQUEST_SCOPE -> this.request.getAttribute(name); + case SESSION_SCOPE -> { HttpSession session = this.request.getSession(false); - return (session != null ? session.getAttribute(name) : null); - case APPLICATION_SCOPE: - return this.servletContext.getAttribute(name); - default: - throw new IllegalArgumentException("Invalid scope: " + scope); - } + yield (session != null ? session.getAttribute(name) : null); + } + case APPLICATION_SCOPE -> this.servletContext.getAttribute(name); + default -> throw new IllegalArgumentException("Invalid scope: " + scope); + }; } @Override @@ -250,19 +247,16 @@ public Enumeration getAttributeNames() { @Override public Enumeration getAttributeNamesInScope(int scope) { - switch (scope) { - case PAGE_SCOPE: - return getAttributeNames(); - case REQUEST_SCOPE: - return this.request.getAttributeNames(); - case SESSION_SCOPE: + return switch (scope) { + case PAGE_SCOPE -> getAttributeNames(); + case REQUEST_SCOPE -> this.request.getAttributeNames(); + case SESSION_SCOPE -> { HttpSession session = this.request.getSession(false); - return (session != null ? session.getAttributeNames() : Collections.emptyEnumeration()); - case APPLICATION_SCOPE: - return this.servletContext.getAttributeNames(); - default: - throw new IllegalArgumentException("Invalid scope: " + scope); - } + yield (session != null ? session.getAttributeNames() : Collections.emptyEnumeration()); + } + case APPLICATION_SCOPE -> this.servletContext.getAttributeNames(); + default -> throw new IllegalArgumentException("Invalid scope: " + scope); + }; } @Override diff --git a/spring-tx/src/main/java/org/springframework/transaction/HeuristicCompletionException.java b/spring-tx/src/main/java/org/springframework/transaction/HeuristicCompletionException.java index 1d661868df2c..554ecf26305f 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/HeuristicCompletionException.java +++ b/spring-tx/src/main/java/org/springframework/transaction/HeuristicCompletionException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java b/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java index 84f54c85a238..89c5b9a5eee4 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java +++ b/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -171,9 +171,12 @@ public void afterCompletion(int status) { } // Call afterCompletion with the appropriate status indication. switch (status) { - case Status.STATUS_COMMITTED -> this.springSynchronization.afterCompletion(TransactionSynchronization.STATUS_COMMITTED); - case Status.STATUS_ROLLEDBACK -> this.springSynchronization.afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK); - default -> this.springSynchronization.afterCompletion(TransactionSynchronization.STATUS_UNKNOWN); + case Status.STATUS_COMMITTED -> + this.springSynchronization.afterCompletion(TransactionSynchronization.STATUS_COMMITTED); + case Status.STATUS_ROLLEDBACK -> + this.springSynchronization.afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK); + default -> + this.springSynchronization.afterCompletion(TransactionSynchronization.STATUS_UNKNOWN); } } diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java index 75458f488a67..73e87eb0b8bc 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. diff --git a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java index 2ac7fac2acb6..55165060d0a1 100644 --- a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -164,9 +164,12 @@ protected void handleError(ClientHttpResponse response, HttpStatus statusCode) t String message = getErrorMessage(statusCode.value(), statusText, body, charset); switch (statusCode.series()) { - case CLIENT_ERROR -> throw HttpClientErrorException.create(message, statusCode, statusText, headers, body, charset); - case SERVER_ERROR -> throw HttpServerErrorException.create(message, statusCode, statusText, headers, body, charset); - default -> throw new UnknownHttpStatusCodeException(message, statusCode.value(), statusText, headers, body, charset); + case CLIENT_ERROR -> + throw HttpClientErrorException.create(message, statusCode, statusText, headers, body, charset); + case SERVER_ERROR -> + throw HttpServerErrorException.create(message, statusCode, statusText, headers, body, charset); + default -> + throw new UnknownHttpStatusCodeException(message, statusCode.value(), statusText, headers, body, charset); } } diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPageContext.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPageContext.java index bab4b1939472..e3976304882f 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPageContext.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockPageContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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,19 +173,16 @@ public Object getAttribute(String name) { @Nullable public Object getAttribute(String name, int scope) { Assert.notNull(name, "Attribute name must not be null"); - switch (scope) { - case PAGE_SCOPE: - return getAttribute(name); - case REQUEST_SCOPE: - return this.request.getAttribute(name); - case SESSION_SCOPE: + return switch (scope) { + case PAGE_SCOPE -> getAttribute(name); + case REQUEST_SCOPE -> this.request.getAttribute(name); + case SESSION_SCOPE -> { HttpSession session = this.request.getSession(false); - return (session != null ? session.getAttribute(name) : null); - case APPLICATION_SCOPE: - return this.servletContext.getAttribute(name); - default: - throw new IllegalArgumentException("Invalid scope: " + scope); - } + yield (session != null ? session.getAttribute(name) : null); + } + case APPLICATION_SCOPE -> this.servletContext.getAttribute(name); + default -> throw new IllegalArgumentException("Invalid scope: " + scope); + }; } @Override @@ -250,19 +247,16 @@ public Enumeration getAttributeNames() { @Override public Enumeration getAttributeNamesInScope(int scope) { - switch (scope) { - case PAGE_SCOPE: - return getAttributeNames(); - case REQUEST_SCOPE: - return this.request.getAttributeNames(); - case SESSION_SCOPE: + return switch (scope) { + case PAGE_SCOPE -> getAttributeNames(); + case REQUEST_SCOPE -> this.request.getAttributeNames(); + case SESSION_SCOPE -> { HttpSession session = this.request.getSession(false); - return (session != null ? session.getAttributeNames() : Collections.emptyEnumeration()); - case APPLICATION_SCOPE: - return this.servletContext.getAttributeNames(); - default: - throw new IllegalArgumentException("Invalid scope: " + scope); - } + yield (session != null ? session.getAttributeNames() : Collections.emptyEnumeration()); + } + case APPLICATION_SCOPE -> this.servletContext.getAttributeNames(); + default -> throw new IllegalArgumentException("Invalid scope: " + scope); + }; } @Override diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java index 8660adf04c58..b2109def5dc6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2022 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. @@ -90,15 +90,15 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { controller.getPropertyValues().add("statusCode", statusCode); } } - case "redirect-view-controller" -> controller.getPropertyValues() - .add("view", getRedirectView(element, statusCode, source)); + case "redirect-view-controller" -> + controller.getPropertyValues().add("view", getRedirectView(element, statusCode, source)); case "status-controller" -> { controller.getPropertyValues().add("statusCode", statusCode); controller.getPropertyValues().add("statusOnly", true); } default -> - // Should never happen... - throw new IllegalStateException("Unexpected tag name: " + name); + // Should never happen... + throw new IllegalStateException("Unexpected tag name: " + name); } Map urlMap = (Map) hm.getPropertyValues().get("urlMap"); diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/handler/ConcurrentWebSocketSessionDecorator.java b/spring-websocket/src/main/java/org/springframework/web/socket/handler/ConcurrentWebSocketSessionDecorator.java index 812b49d377b3..5e538550a64b 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/handler/ConcurrentWebSocketSessionDecorator.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/handler/ConcurrentWebSocketSessionDecorator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2022 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. @@ -229,6 +229,9 @@ else if (getBufferSize() > getBufferSizeLimit()) { logger.debug("Dropped " + i + " messages, buffer size: " + getBufferSize()); } } + default -> + // Should never happen.. + throw new IllegalStateException("Unexpected OverflowStrategy: " + this.overflowStrategy); } } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractSockJsSession.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractSockJsSession.java index 889444609449..9773f03a6d4d 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractSockJsSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -410,7 +410,7 @@ private static List getUndelivered(String[] messages, int i) { return switch (messages.length - i) { case 0 -> Collections.emptyList(); case 1 -> (messages[i].trim().isEmpty() ? - Collections.emptyList() : Collections.singletonList(messages[i])); + Collections.emptyList() : Collections.singletonList(messages[i])); default -> Arrays.stream(Arrays.copyOfRange(messages, i, messages.length)) .filter(message -> !message.trim().isEmpty()) .collect(Collectors.toList()); From 6a73d2655f15000214912765ce75059b714b5995 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 19 Feb 2022 14:59:54 +0100 Subject: [PATCH 724/735] Polishing --- .../interceptor/AsyncExecutionAspectSupport.java | 6 +++--- .../annotation/BeanFactoryAnnotationUtils.java | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java index 66dbc3042f9c..45221f36744f 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java @@ -156,7 +156,7 @@ public void setBeanFactory(BeanFactory beanFactory) { /** * Determine the specific executor to use when executing the given method. - * Should preferably return an {@link AsyncListenableTaskExecutor} implementation. + *

      Should preferably return an {@link AsyncListenableTaskExecutor} implementation. * @return the executor to use (or {@code null}, but just if no default executor is available) */ @Nullable @@ -184,7 +184,7 @@ protected AsyncTaskExecutor determineAsyncExecutor(Method method) { /** * Return the qualifier or bean name of the executor to be used when executing the * given async method, typically specified in the form of an annotation attribute. - * Returning an empty string or {@code null} indicates that no specific executor has + *

      Returning an empty string or {@code null} indicates that no specific executor has * been specified and that the {@linkplain #setExecutor(Executor) default executor} * should be used. * @param method the method to inspect for executor qualifier metadata @@ -213,7 +213,7 @@ protected Executor findQualifiedExecutor(@Nullable BeanFactory beanFactory, Stri /** * Retrieve or build a default executor for this advice instance. - * An executor returned from here will be cached for further use. + *

      An executor returned from here will be cached for further use. *

      The default implementation searches for a unique {@link TaskExecutor} bean * in the context, or for an {@link Executor} bean named "taskExecutor" otherwise. * If neither of the two is resolvable, this implementation will return {@code null}. diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationUtils.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationUtils.java index 722995aabec4..fd41a5cfe0a1 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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,7 +48,7 @@ public abstract class BeanFactoryAnnotationUtils { /** - * Retrieve all bean of type {@code T} from the given {@code BeanFactory} declaring a + * Retrieve all beans of type {@code T} from the given {@code BeanFactory} declaring a * qualifier (e.g. via {@code } or {@code @Qualifier}) matching the given * qualifier, or having a bean name matching the given qualifier. * @param beanFactory the factory to get the target beans from (also searching ancestors) @@ -90,9 +90,9 @@ public static T qualifiedBeanOfType(BeanFactory beanFactory, Class beanTy Assert.notNull(beanFactory, "BeanFactory must not be null"); - if (beanFactory instanceof ListableBeanFactory) { + if (beanFactory instanceof ListableBeanFactory lbf) { // Full qualifier matching supported. - return qualifiedBeanOfType((ListableBeanFactory) beanFactory, beanType, qualifier); + return qualifiedBeanOfType(lbf, beanType, qualifier); } else if (beanFactory.containsBean(qualifier)) { // Fallback: target bean at least found by bean name. @@ -163,8 +163,8 @@ public static boolean isQualifierMatch( } try { Class beanType = beanFactory.getType(beanName); - if (beanFactory instanceof ConfigurableBeanFactory) { - BeanDefinition bd = ((ConfigurableBeanFactory) beanFactory).getMergedBeanDefinition(beanName); + if (beanFactory instanceof ConfigurableBeanFactory cbf) { + BeanDefinition bd = cbf.getMergedBeanDefinition(beanName); // Explicit qualifier metadata on bean definition? (typically in XML definition) if (bd instanceof AbstractBeanDefinition abd) { AutowireCandidateQualifier candidate = abd.getQualifier(Qualifier.class.getName()); @@ -176,8 +176,8 @@ public static boolean isQualifierMatch( } } // Corresponding qualifier on factory method? (typically in configuration class) - if (bd instanceof RootBeanDefinition) { - Method factoryMethod = ((RootBeanDefinition) bd).getResolvedFactoryMethod(); + if (bd instanceof RootBeanDefinition rbd) { + Method factoryMethod = rbd.getResolvedFactoryMethod(); if (factoryMethod != null) { Qualifier targetAnnotation = AnnotationUtils.getAnnotation(factoryMethod, Qualifier.class); if (targetAnnotation != null) { From 01214b3473c4a9e4db66b2036b3c44d6ed7f1678 Mon Sep 17 00:00:00 2001 From: Guirong Hu Date: Wed, 15 Dec 2021 13:24:45 +0800 Subject: [PATCH 725/735] Allow @Async qualifier to be declared with a placeholder or SpEL expression Closes gh-27818 --- .../AsyncExecutionAspectSupport.java | 8 +++ .../scheduling/annotation/Async.java | 4 +- .../annotation/EnableAsyncTests.java | 61 ++++++++++++++++++- 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java index 45221f36744f..69ec0b65562d 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java @@ -34,6 +34,8 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoUniqueBeanDefinitionException; import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.beans.factory.config.EmbeddedValueResolver; import org.springframework.core.task.AsyncListenableTaskExecutor; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.TaskExecutor; @@ -41,6 +43,7 @@ import org.springframework.lang.Nullable; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; +import org.springframework.util.StringValueResolver; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.function.SingletonSupplier; @@ -208,6 +211,11 @@ protected Executor findQualifiedExecutor(@Nullable BeanFactory beanFactory, Stri throw new IllegalStateException("BeanFactory must be set on " + getClass().getSimpleName() + " to access qualified executor '" + qualifier + "'"); } + if (beanFactory instanceof ConfigurableBeanFactory configurableBeanFactory) { + StringValueResolver embeddedValueResolver = new EmbeddedValueResolver(configurableBeanFactory); + String resolvedValue = embeddedValueResolver.resolveStringValue(qualifier); + qualifier = resolvedValue != null ? resolvedValue : ""; + } return BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, Executor.class, qualifier); } diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java index 40e572f0e8cc..b288c32c0583 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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,6 +57,8 @@ /** * A qualifier value for the specified asynchronous operation(s). + *

      The value support expression such as #{systemProperties.myExecutor} + * or property placeholder such as ${my.app.myExecutor}. *

      May be used to determine the target executor to be used when executing * the asynchronous operation(s), matching the qualifier value (or the bean * name) of a specific {@link java.util.concurrent.Executor Executor} or diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java index e60333950f40..5bde1c950bd1 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Method; +import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -47,6 +48,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Lazy; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.core.Ordered; import org.springframework.lang.Nullable; import org.springframework.scheduling.concurrent.CustomizableThreadFactory; @@ -130,6 +132,29 @@ public void withAsyncBeanWithExecutorQualifiedByName() throws ExecutionException ctx.close(); } + @Test + public void withAsyncBeanWithExecutorQualifiedByExpression() throws ExecutionException, InterruptedException { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + System.getProperties().put("myExecutor", "myExecutor1"); + PropertySourcesPlaceholderConfigurer placeholderConfigurer = new PropertySourcesPlaceholderConfigurer(); + placeholderConfigurer.setProperties(new Properties() {{ + put("my.app.myExecutor", "myExecutor2"); + }}); + placeholderConfigurer.postProcessBeanFactory(context.getBeanFactory()); + + context.register(AsyncWithExecutorQualifiedByExpressionConfig.class); + context.refresh(); + + AsyncBeanWithExecutorQualifiedByExpression asyncBean = context.getBean(AsyncBeanWithExecutorQualifiedByExpression.class); + Future workerThread1 = asyncBean.myWork1(); + assertThat(workerThread1.get().getName()).doesNotStartWith("myExecutor2-").startsWith("myExecutor1-"); + + Future workerThread2 = asyncBean.myWork2(); + assertThat(workerThread2.get().getName()).startsWith("myExecutor2-"); + + context.close(); + } + @Test public void asyncProcessorIsOrderedLowestPrecedenceByDefault() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); @@ -346,6 +371,19 @@ public Future work3() { } } + static class AsyncBeanWithExecutorQualifiedByExpression { + + @Async("#{systemProperties.myExecutor}") + public Future myWork1() { + return new AsyncResult<>(Thread.currentThread()); + } + + @Async("${my.app.myExecutor}") + public Future myWork2() { + return new AsyncResult<>(Thread.currentThread()); + } + } + static class AsyncBean { @@ -475,6 +513,27 @@ public Executor otherExecutor() { } } + @Configuration + @EnableAsync + static class AsyncWithExecutorQualifiedByExpressionConfig { + + @Bean + public AsyncBeanWithExecutorQualifiedByExpression asyncBean() { + return new AsyncBeanWithExecutorQualifiedByExpression(); + } + + @Bean + public Executor myExecutor1() { + return new ThreadPoolTaskExecutor(); + } + + @Bean + @Qualifier("myExecutor") + public Executor myExecutor2() { + return new ThreadPoolTaskExecutor(); + } + } + @Configuration @EnableAsync From be8224a5909f140122a1f25bc02a769b42d11e8f Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 19 Feb 2022 15:55:11 +0100 Subject: [PATCH 726/735] Polish contribution See gh-27818 --- .../AsyncExecutionAspectSupport.java | 6 +-- .../scheduling/annotation/Async.java | 15 ++++--- .../annotation/EnableAsyncTests.java | 44 +++++++++---------- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java index 69ec0b65562d..50a62a0f84a0 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java @@ -43,7 +43,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; -import org.springframework.util.StringValueResolver; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.function.SingletonSupplier; @@ -212,9 +211,8 @@ protected Executor findQualifiedExecutor(@Nullable BeanFactory beanFactory, Stri " to access qualified executor '" + qualifier + "'"); } if (beanFactory instanceof ConfigurableBeanFactory configurableBeanFactory) { - StringValueResolver embeddedValueResolver = new EmbeddedValueResolver(configurableBeanFactory); - String resolvedValue = embeddedValueResolver.resolveStringValue(qualifier); - qualifier = resolvedValue != null ? resolvedValue : ""; + EmbeddedValueResolver embeddedValueResolver = new EmbeddedValueResolver(configurableBeanFactory); + qualifier = embeddedValueResolver.resolveStringValue(qualifier); } return BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, Executor.class, qualifier); } diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java index b288c32c0583..adc9b1359e40 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java @@ -24,7 +24,8 @@ /** * Annotation that marks a method as a candidate for asynchronous execution. - * Can also be used at the type level, in which case all of the type's methods are + * + *

      Can also be used at the type level, in which case all of the type's methods are * considered as asynchronous. Note, however, that {@code @Async} is not supported * on methods declared within a * {@link org.springframework.context.annotation.Configuration @Configuration} class. @@ -41,7 +42,7 @@ * {@code Future} that can be used to track the result of the asynchronous method * execution. However, since the target method needs to implement the same signature, * it will have to return a temporary {@code Future} handle that just passes a value - * through: e.g. Spring's {@link AsyncResult}, EJB 3.1's {@link jakarta.ejb.AsyncResult}, + * through: for example, Spring's {@link AsyncResult}, EJB 3.1's {@link jakarta.ejb.AsyncResult}, * or {@link java.util.concurrent.CompletableFuture#completedFuture(Object)}. * * @author Juergen Hoeller @@ -57,16 +58,18 @@ /** * A qualifier value for the specified asynchronous operation(s). - *

      The value support expression such as #{systemProperties.myExecutor} - * or property placeholder such as ${my.app.myExecutor}. *

      May be used to determine the target executor to be used when executing * the asynchronous operation(s), matching the qualifier value (or the bean * name) of a specific {@link java.util.concurrent.Executor Executor} or * {@link org.springframework.core.task.TaskExecutor TaskExecutor} * bean definition. - *

      When specified on a class-level {@code @Async} annotation, indicates that the + *

      When specified in a class-level {@code @Async} annotation, indicates that the * given executor should be used for all methods within the class. Method-level use - * of {@code Async#value} always overrides any value set at the class level. + * of {@code Async#value} always overrides any qualifier value configured at + * the class level. + *

      The qualifier value will be resolved dynamically if supplied as a SpEL + * expression (for example, {@code "#{environment['myExecutor']}"}) or a + * property placeholder (for example, {@code "${my.app.myExecutor}"}). * @since 3.1.2 */ String value() default ""; diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java index 5bde1c950bd1..08c182785c28 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java @@ -21,7 +21,6 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Method; -import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -42,13 +41,13 @@ import org.springframework.beans.factory.UnsatisfiedDependencyException; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AdviceMode; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Lazy; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.core.Ordered; import org.springframework.lang.Nullable; import org.springframework.scheduling.concurrent.CustomizableThreadFactory; @@ -133,26 +132,25 @@ public void withAsyncBeanWithExecutorQualifiedByName() throws ExecutionException } @Test - public void withAsyncBeanWithExecutorQualifiedByExpression() throws ExecutionException, InterruptedException { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - System.getProperties().put("myExecutor", "myExecutor1"); - PropertySourcesPlaceholderConfigurer placeholderConfigurer = new PropertySourcesPlaceholderConfigurer(); - placeholderConfigurer.setProperties(new Properties() {{ - put("my.app.myExecutor", "myExecutor2"); - }}); - placeholderConfigurer.postProcessBeanFactory(context.getBeanFactory()); + public void withAsyncBeanWithExecutorQualifiedByExpressionOrPlaceholder() throws Exception { + System.setProperty("myExecutor", "myExecutor1"); + System.setProperty("my.app.myExecutor", "myExecutor2"); - context.register(AsyncWithExecutorQualifiedByExpressionConfig.class); - context.refresh(); + Class configClass = AsyncWithExecutorQualifiedByExpressionConfig.class; + try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(configClass)) { + AsyncBeanWithExecutorQualifiedByExpressionOrPlaceholder asyncBean = + context.getBean(AsyncBeanWithExecutorQualifiedByExpressionOrPlaceholder.class); - AsyncBeanWithExecutorQualifiedByExpression asyncBean = context.getBean(AsyncBeanWithExecutorQualifiedByExpression.class); - Future workerThread1 = asyncBean.myWork1(); - assertThat(workerThread1.get().getName()).doesNotStartWith("myExecutor2-").startsWith("myExecutor1-"); + Future workerThread1 = asyncBean.myWork1(); + assertThat(workerThread1.get().getName()).startsWith("myExecutor1-"); - Future workerThread2 = asyncBean.myWork2(); - assertThat(workerThread2.get().getName()).startsWith("myExecutor2-"); - - context.close(); + Future workerThread2 = asyncBean.myWork2(); + assertThat(workerThread2.get().getName()).startsWith("myExecutor2-"); + } + finally { + System.clearProperty("myExecutor"); + System.clearProperty("my.app.myExecutor"); + } } @Test @@ -371,9 +369,9 @@ public Future work3() { } } - static class AsyncBeanWithExecutorQualifiedByExpression { + static class AsyncBeanWithExecutorQualifiedByExpressionOrPlaceholder { - @Async("#{systemProperties.myExecutor}") + @Async("#{environment['myExecutor']}") public Future myWork1() { return new AsyncResult<>(Thread.currentThread()); } @@ -518,8 +516,8 @@ public Executor otherExecutor() { static class AsyncWithExecutorQualifiedByExpressionConfig { @Bean - public AsyncBeanWithExecutorQualifiedByExpression asyncBean() { - return new AsyncBeanWithExecutorQualifiedByExpression(); + public AsyncBeanWithExecutorQualifiedByExpressionOrPlaceholder asyncBean() { + return new AsyncBeanWithExecutorQualifiedByExpressionOrPlaceholder(); } @Bean From 5689395678f57fe967a3b21ed7d9087cfec7b622 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 19 Feb 2022 16:51:00 +0100 Subject: [PATCH 727/735] Deprecate "enclosing classes" search strategy for MergedAnnotations The TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy for MergedAnnotations was originally introduced to support @Nested test classes in JUnit Jupiter (see #23378). However, while implementing #19930, we determined that the TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy unfortunately could not be used since it does not allow the user to control when to recurse up the enclosing class hierarchy. For example, this search strategy will automatically search on enclosing classes for static nested classes as well as for inner classes, when the user probably only wants one such category of "enclosing class" to be searched. Consequently, TestContextAnnotationUtils was introduced in the Spring TestContext Framework to address the shortcomings of the TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy. Since this search strategy is unlikely to be useful to general users, the team has decided to deprecate this search strategy in Spring Framework 5.3.x and remove it in 6.0. Closes gh-28079 --- .../springframework/core/annotation/AnnotationsScanner.java | 5 ++++- .../springframework/core/annotation/MergedAnnotations.java | 2 ++ .../core/annotation/AnnotationsScannerTests.java | 5 ++++- .../core/annotation/MergedAnnotationsTests.java | 2 ++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java index 626413838c9b..70efaeea41c7 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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,6 +92,7 @@ private static R process(C context, AnnotatedElement source, } @Nullable + @SuppressWarnings("deprecation") private static R processClass(C context, Class source, SearchStrategy searchStrategy, AnnotationsProcessor processor) { @@ -235,6 +236,7 @@ private static R processClassHierarchy(C context, int[] aggregateIndex, C } @Nullable + @SuppressWarnings("deprecation") private static R processMethod(C context, Method source, SearchStrategy searchStrategy, AnnotationsProcessor processor) { @@ -510,6 +512,7 @@ static boolean hasPlainJavaAnnotationsOnly(Class type) { return (type.getName().startsWith("java.") || type == Ordered.class); } + @SuppressWarnings("deprecation") private static boolean isWithoutHierarchy(AnnotatedElement source, SearchStrategy searchStrategy) { if (source == Object.class) { return true; diff --git a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java index 55dff9086f74..28f7cf009a99 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java @@ -482,7 +482,9 @@ enum SearchStrategy { * need to be meta-annotated with {@link Inherited @Inherited}. When * searching a {@link Method} source, this strategy is identical to * {@link #TYPE_HIERARCHY}. + * @deprecated as of Spring Framework 5.3.17; to be removed in Spring Framework 6.0 */ + @Deprecated TYPE_HIERARCHY_AND_ENCLOSING_CLASSES } diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationsScannerTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationsScannerTests.java index 83518d9b3846..e848090b1241 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationsScannerTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationsScannerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -421,6 +421,7 @@ void typeHierarchyStrategyOnMethodWithGenericParameterNonOverrideScansAnnotation } @Test + @SuppressWarnings("deprecation") void typeHierarchyWithEnclosedStrategyOnEnclosedStaticClassScansAnnotations() { Class source = AnnotationEnclosingClassSample.EnclosedStatic.EnclosedStaticStatic.class; assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES)) @@ -428,6 +429,7 @@ void typeHierarchyWithEnclosedStrategyOnEnclosedStaticClassScansAnnotations() { } @Test + @SuppressWarnings("deprecation") void typeHierarchyWithEnclosedStrategyOnEnclosedInnerClassScansAnnotations() { Class source = AnnotationEnclosingClassSample.EnclosedInner.EnclosedInnerInner.class; assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES)) @@ -435,6 +437,7 @@ void typeHierarchyWithEnclosedStrategyOnEnclosedInnerClassScansAnnotations() { } @Test + @SuppressWarnings("deprecation") void typeHierarchyWithEnclosedStrategyOnMethodHierarchyUsesTypeHierarchyScan() { Method source = methodFrom(WithHierarchy.class); assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES)).containsExactly( diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java index 02ec8f0980e9..e175e6e030da 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java @@ -712,6 +712,7 @@ void streamTypeHierarchyFromClassWithInterface() throws Exception { } @Test + @SuppressWarnings("deprecation") void streamTypeHierarchyAndEnclosingClassesFromNonAnnotatedInnerClassWithAnnotatedEnclosingClass() { Stream> classes = MergedAnnotations.from(AnnotatedClass.NonAnnotatedInnerClass.class, SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES).stream().map(MergedAnnotation::getType); @@ -719,6 +720,7 @@ void streamTypeHierarchyAndEnclosingClassesFromNonAnnotatedInnerClassWithAnnotat } @Test + @SuppressWarnings("deprecation") void streamTypeHierarchyAndEnclosingClassesFromNonAnnotatedStaticNestedClassWithAnnotatedEnclosingClass() { Stream> classes = MergedAnnotations.from(AnnotatedClass.NonAnnotatedStaticNestedClass.class, SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES).stream().map(MergedAnnotation::getType); From 84b4cebb3913ddd4a803939fdc8dde1b0401ff35 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 19 Feb 2022 16:54:16 +0100 Subject: [PATCH 728/735] Fix (@)since tag in SpelMessage See gh-28043 --- .../java/org/springframework/expression/spel/SpelMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java b/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java index b8f5f92d0554..9c08841158ed 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java @@ -258,7 +258,7 @@ public enum SpelMessage { FLAWED_PATTERN(Kind.ERROR, 1073, "Failed to efficiently evaluate pattern ''{0}'': consider redesigning it"), - /** @since 5.3.16 */ + /** @since 5.3.17 */ EXCEPTION_COMPILING_EXPRESSION(Kind.ERROR, 1074, "An exception occurred while compiling an expression"); From 819d4256b7984fdec58840a56b82e411bc53c9c9 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 19 Feb 2022 17:25:50 +0100 Subject: [PATCH 729/735] Remove deprecated "enclosing classes" search strategy for MergedAnnotations Closes gh-28080 --- .../core/annotation/AnnotationsScanner.java | 47 ++++--------------- .../core/annotation/MergedAnnotations.java | 16 +------ .../annotation/AnnotationsScannerTests.java | 26 ---------- .../annotation/MergedAnnotationsTests.java | 16 ------- 4 files changed, 12 insertions(+), 93 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java index fa90a703b4e8..4b8a86af8084 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java @@ -99,9 +99,8 @@ private static R processClass(C context, Class source, return switch (searchStrategy) { case DIRECT -> processElement(context, source, processor); case INHERITED_ANNOTATIONS -> processClassInheritedAnnotations(context, source, searchStrategy, processor); - case SUPERCLASS -> processClassHierarchy(context, source, processor, false, false); - case TYPE_HIERARCHY -> processClassHierarchy(context, source, processor, true, false); - case TYPE_HIERARCHY_AND_ENCLOSING_CLASSES -> processClassHierarchy(context, source, processor, true, true); + case SUPERCLASS -> processClassHierarchy(context, source, processor, false); + case TYPE_HIERARCHY -> processClassHierarchy(context, source, processor, true); }; } @@ -161,15 +160,14 @@ private static R processClassInheritedAnnotations(C context, Class sou @Nullable private static R processClassHierarchy(C context, Class source, - AnnotationsProcessor processor, boolean includeInterfaces, boolean includeEnclosing) { + AnnotationsProcessor processor, boolean includeInterfaces) { - return processClassHierarchy(context, new int[] {0}, source, processor, - includeInterfaces, includeEnclosing); + return processClassHierarchy(context, new int[] {0}, source, processor, includeInterfaces); } @Nullable private static R processClassHierarchy(C context, int[] aggregateIndex, Class source, - AnnotationsProcessor processor, boolean includeInterfaces, boolean includeEnclosing) { + AnnotationsProcessor processor, boolean includeInterfaces) { try { R result = processor.doWithAggregate(context, aggregateIndex[0]); @@ -188,7 +186,7 @@ private static R processClassHierarchy(C context, int[] aggregateIndex, C if (includeInterfaces) { for (Class interfaceType : source.getInterfaces()) { R interfacesResult = processClassHierarchy(context, aggregateIndex, - interfaceType, processor, true, includeEnclosing); + interfaceType, processor, true); if (interfacesResult != null) { return interfacesResult; } @@ -197,31 +195,11 @@ private static R processClassHierarchy(C context, int[] aggregateIndex, C Class superclass = source.getSuperclass(); if (superclass != Object.class && superclass != null) { R superclassResult = processClassHierarchy(context, aggregateIndex, - superclass, processor, includeInterfaces, includeEnclosing); + superclass, processor, includeInterfaces); if (superclassResult != null) { return superclassResult; } } - if (includeEnclosing) { - // Since merely attempting to load the enclosing class may result in - // automatic loading of sibling nested classes that in turn results - // in an exception such as NoClassDefFoundError, we wrap the following - // in its own dedicated try-catch block in order not to preemptively - // halt the annotation scanning process. - try { - Class enclosingClass = source.getEnclosingClass(); - if (enclosingClass != null) { - R enclosingResult = processClassHierarchy(context, aggregateIndex, - enclosingClass, processor, includeInterfaces, true); - if (enclosingResult != null) { - return enclosingResult; - } - } - } - catch (Throwable ex) { - AnnotationUtils.handleIntrospectionFailure(source, ex); - } - } } catch (Throwable ex) { AnnotationUtils.handleIntrospectionFailure(source, ex); @@ -238,8 +216,7 @@ private static R processMethod(C context, Method source, case DIRECT, INHERITED_ANNOTATIONS -> processMethodInheritedAnnotations(context, source, processor); case SUPERCLASS -> processMethodHierarchy(context, new int[]{0}, source.getDeclaringClass(), processor, source, false); - case TYPE_HIERARCHY, TYPE_HIERARCHY_AND_ENCLOSING_CLASSES -> processMethodHierarchy(context, new int[]{0}, - source.getDeclaringClass(), + case TYPE_HIERARCHY -> processMethodHierarchy(context, new int[]{0}, source.getDeclaringClass(), processor, source, true); }; } @@ -506,12 +483,8 @@ private static boolean isWithoutHierarchy(AnnotatedElement source, SearchStrateg if (source == Object.class) { return true; } - if (source instanceof Class) { - Class sourceClass = (Class) source; - boolean noSuperTypes = (sourceClass.getSuperclass() == Object.class && - sourceClass.getInterfaces().length == 0); - return (searchStrategy == SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES ? noSuperTypes && - sourceClass.getEnclosingClass() == null : noSuperTypes); + if (source instanceof Class sourceClass) { + return (sourceClass.getSuperclass() == Object.class && sourceClass.getInterfaces().length == 0); } if (source instanceof Method sourceMethod) { return (Modifier.isPrivate(sourceMethod.getModifiers()) || diff --git a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java index 28f7cf009a99..a488d29e8751 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -472,20 +472,8 @@ enum SearchStrategy { * superclasses and implemented interfaces. Superclass annotations do * not need to be meta-annotated with {@link Inherited @Inherited}. */ - TYPE_HIERARCHY, + TYPE_HIERARCHY - /** - * Perform a full search of the entire type hierarchy on the source - * and any enclosing classes. This strategy is similar to - * {@link #TYPE_HIERARCHY} except that {@linkplain Class#getEnclosingClass() - * enclosing classes} are also searched. Superclass annotations do not - * need to be meta-annotated with {@link Inherited @Inherited}. When - * searching a {@link Method} source, this strategy is identical to - * {@link #TYPE_HIERARCHY}. - * @deprecated as of Spring Framework 5.3.17; to be removed in Spring Framework 6.0 - */ - @Deprecated - TYPE_HIERARCHY_AND_ENCLOSING_CLASSES } } diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationsScannerTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationsScannerTests.java index e848090b1241..dbbb4f00ceb2 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationsScannerTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationsScannerTests.java @@ -420,32 +420,6 @@ void typeHierarchyStrategyOnMethodWithGenericParameterNonOverrideScansAnnotation assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY)).containsExactly("0:TestAnnotation1"); } - @Test - @SuppressWarnings("deprecation") - void typeHierarchyWithEnclosedStrategyOnEnclosedStaticClassScansAnnotations() { - Class source = AnnotationEnclosingClassSample.EnclosedStatic.EnclosedStaticStatic.class; - assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES)) - .containsExactly("0:EnclosedThree", "1:EnclosedTwo", "2:EnclosedOne"); - } - - @Test - @SuppressWarnings("deprecation") - void typeHierarchyWithEnclosedStrategyOnEnclosedInnerClassScansAnnotations() { - Class source = AnnotationEnclosingClassSample.EnclosedInner.EnclosedInnerInner.class; - assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES)) - .containsExactly("0:EnclosedThree", "1:EnclosedTwo", "2:EnclosedOne"); - } - - @Test - @SuppressWarnings("deprecation") - void typeHierarchyWithEnclosedStrategyOnMethodHierarchyUsesTypeHierarchyScan() { - Method source = methodFrom(WithHierarchy.class); - assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES)).containsExactly( - "0:TestAnnotation1", "1:TestAnnotation5", "1:TestInheritedAnnotation5", - "2:TestAnnotation6", "3:TestAnnotation2", "3:TestInheritedAnnotation2", - "4:TestAnnotation3", "5:TestAnnotation4"); - } - @Test void scanWhenProcessorReturnsFromDoWithAggregateExitsEarly() { String result = AnnotationsScanner.scan(this, WithSingleSuperclass.class, diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java index 53e82bf4a612..5c754da93e0a 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java @@ -710,22 +710,6 @@ void streamTypeHierarchyFromClassWithInterface() throws Exception { Transactional.class)).hasSize(1); } - @Test - @SuppressWarnings("deprecation") - void streamTypeHierarchyAndEnclosingClassesFromNonAnnotatedInnerClassWithAnnotatedEnclosingClass() { - Stream> classes = MergedAnnotations.from(AnnotatedClass.NonAnnotatedInnerClass.class, - SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES).stream().map(MergedAnnotation::getType); - assertThat(classes).containsExactly(Component.class, Indexed.class); - } - - @Test - @SuppressWarnings("deprecation") - void streamTypeHierarchyAndEnclosingClassesFromNonAnnotatedStaticNestedClassWithAnnotatedEnclosingClass() { - Stream> classes = MergedAnnotations.from(AnnotatedClass.NonAnnotatedStaticNestedClass.class, - SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES).stream().map(MergedAnnotation::getType); - assertThat(classes).containsExactly(Component.class, Indexed.class); - } - @Test void getFromMethodWithMethodAnnotationOnLeaf() throws Exception { Method method = Leaf.class.getMethod("annotatedOnLeaf"); From e85001f332bc4627a094cd2b57973e8eea370c81 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 19 Feb 2022 17:32:15 +0100 Subject: [PATCH 730/735] Clean up warnings in test fixture --- .../aot/generator/visibility/PublicFactoryBean.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/spring-core/src/testFixtures/java/org/springframework/core/testfixture/aot/generator/visibility/PublicFactoryBean.java b/spring-core/src/testFixtures/java/org/springframework/core/testfixture/aot/generator/visibility/PublicFactoryBean.java index 9e9bf8d58f18..e4c2a69e7bfc 100644 --- a/spring-core/src/testFixtures/java/org/springframework/core/testfixture/aot/generator/visibility/PublicFactoryBean.java +++ b/spring-core/src/testFixtures/java/org/springframework/core/testfixture/aot/generator/visibility/PublicFactoryBean.java @@ -20,10 +20,7 @@ public class PublicFactoryBean { - private final Class type; - - public PublicFactoryBean(Class type) { - this.type = type; + PublicFactoryBean(Class type) { } public static PublicFactoryBean protectedTypeFactoryBean() { From b4eb895927e55ba92917cc7522dc93606d84f442 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 22 Feb 2022 16:07:52 +0100 Subject: [PATCH 731/735] Polish naming Co-authored-by: Andy Wilkinson --- .../AutowiredAnnotationBeanPostProcessor.java | 16 ++++++++-------- ...ava => AotContributingBeanPostProcessor.java} | 14 +++++++------- ...or.java => BeanInstantiationContributor.java} | 11 +++++------ ...va => DefaultBeanInstantiationGenerator.java} | 13 +++++++------ ...tationBeanInstantiationContributorTests.java} | 14 +++++++------- ... DefaultBeanInstantiationGeneratorTests.java} | 14 +++++++------- 6 files changed, 41 insertions(+), 41 deletions(-) rename spring-beans/src/main/java/org/springframework/beans/factory/generator/{BeanInstanceAotPostProcessor.java => AotContributingBeanPostProcessor.java} (70%) rename spring-beans/src/main/java/org/springframework/beans/factory/generator/{BeanInstanceContributor.java => BeanInstantiationContributor.java} (80%) rename spring-beans/src/main/java/org/springframework/beans/factory/generator/{DefaultBeanInstanceGenerator.java => DefaultBeanInstantiationGenerator.java} (92%) rename spring-beans/src/test/java/org/springframework/beans/factory/annotation/{AutowiredAnnotationBeanInstanceContributorTests.java => AutowiredAnnotationBeanInstantiationContributorTests.java} (92%) rename spring-beans/src/test/java/org/springframework/beans/factory/generator/{DefaultBeanInstanceGeneratorTests.java => DefaultBeanInstantiationGeneratorTests.java} (96%) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index dd644c9dd98a..b0156447762a 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -56,8 +56,8 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.DependencyDescriptor; import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor; -import org.springframework.beans.factory.generator.BeanInstanceAotPostProcessor; -import org.springframework.beans.factory.generator.BeanInstanceContributor; +import org.springframework.beans.factory.generator.AotContributingBeanPostProcessor; +import org.springframework.beans.factory.generator.BeanInstantiationContributor; import org.springframework.beans.factory.generator.InjectionGenerator; import org.springframework.beans.factory.support.LookupOverride; import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor; @@ -140,7 +140,7 @@ * @see Value */ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, - MergedBeanDefinitionPostProcessor, BeanInstanceAotPostProcessor, PriorityOrdered, BeanFactoryAware { + MergedBeanDefinitionPostProcessor, AotContributingBeanPostProcessor, PriorityOrdered, BeanFactoryAware { protected final Log logger = LogFactory.getLog(getClass()); @@ -268,12 +268,12 @@ public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, C } @Override - public BeanInstanceContributor buildAotContributor(RootBeanDefinition beanDefinition, Class beanType, String beanName) { + public BeanInstantiationContributor buildAotContributor(RootBeanDefinition beanDefinition, Class beanType, String beanName) { InjectionMetadata metadata = findInjectionMetadata(beanName, beanType, beanDefinition); Collection injectedElements = metadata.getInjectedElements(); return (!ObjectUtils.isEmpty(injectedElements) - ? new AutowiredAnnotationBeanInstanceContributor(injectedElements) - : BeanInstanceContributor.NO_OP); + ? new AutowiredAnnotationBeanInstantiationContributor(injectedElements) + : BeanInstantiationContributor.NO_OP); } private InjectionMetadata findInjectionMetadata(String beanName, Class beanType, RootBeanDefinition beanDefinition) { @@ -821,13 +821,13 @@ private Object[] resolveMethodArguments(Method method, Object bean, @Nullable St } } - private static final class AutowiredAnnotationBeanInstanceContributor implements BeanInstanceContributor { + private static final class AutowiredAnnotationBeanInstantiationContributor implements BeanInstantiationContributor { private final Collection injectedElements; private final InjectionGenerator generator; - AutowiredAnnotationBeanInstanceContributor(Collection injectedElements) { + AutowiredAnnotationBeanInstantiationContributor(Collection injectedElements) { this.injectedElements = injectedElements; this.generator = new InjectionGenerator(); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceAotPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/AotContributingBeanPostProcessor.java similarity index 70% rename from spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceAotPostProcessor.java rename to spring-beans/src/main/java/org/springframework/beans/factory/generator/AotContributingBeanPostProcessor.java index af2e87620d42..b3197e04d8c0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceAotPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/AotContributingBeanPostProcessor.java @@ -20,9 +20,9 @@ import org.springframework.beans.factory.support.RootBeanDefinition; /** - * Strategy interface to be implemented by a {@link BeanPostProcessor} that - * participates in a bean instance setup and can provide an equivalent setup - * using generated code. + * Specialization of {@link BeanPostProcessor} that contributes to bean + * instantiation ahead of time, providing generated code that is equivalent to + * its runtime behavior. * *

      Contrary to other bean post processors, implementations of this interface * are instantiated at build-time and should not rely on other beans in the @@ -32,15 +32,15 @@ * @since 6.0 */ @FunctionalInterface -public interface BeanInstanceAotPostProcessor extends BeanPostProcessor { +public interface AotContributingBeanPostProcessor extends BeanPostProcessor { /** - * Build a {@link BeanInstanceContributor} for the given bean definition. + * Build a {@link BeanInstantiationContributor} for the given bean definition. * @param beanDefinition the merged bean definition for the bean - * @param beanType the actual type of the managed bean instance + * @param beanType the inferred type of the bean * @param beanName the name of the bean * @return the contributor to use */ - BeanInstanceContributor buildAotContributor(RootBeanDefinition beanDefinition, Class beanType, String beanName); + BeanInstantiationContributor buildAotContributor(RootBeanDefinition beanDefinition, Class beanType, String beanName); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceContributor.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstantiationContributor.java similarity index 80% rename from spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceContributor.java rename to spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstantiationContributor.java index 338334bbd257..83cd1ec698a0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstanceContributor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstantiationContributor.java @@ -19,21 +19,20 @@ import org.springframework.aot.generator.CodeContribution; /** - * Strategy interface to be implemented by components that participates in a - * bean instance setup so that the generated code provides an equivalent - * setup. + * Contributor to the code that instantiates a bean following ahead of time + * processing. * * @author Stephane Nicoll * @since 6.0 */ @FunctionalInterface -public interface BeanInstanceContributor { +public interface BeanInstantiationContributor { /** - * A {@link BeanInstanceContributor} that does not contribute anything + * A {@link BeanInstantiationContributor} that does not contribute anything * to the {@link CodeContribution}. */ - BeanInstanceContributor NO_OP = contribution -> { }; + BeanInstantiationContributor NO_OP = contribution -> { }; /** * Contribute to the specified {@link CodeContribution}. diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGenerator.java similarity index 92% rename from spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGenerator.java rename to spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGenerator.java index b513aea16efa..fe40951b9743 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGenerator.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGenerator.java @@ -36,19 +36,20 @@ * Write the necessary statements to instantiate a bean. * * @author Stephane Nicoll + * @see BeanInstantiationContributor */ -class DefaultBeanInstanceGenerator { +class DefaultBeanInstantiationGenerator { private final Executable instanceCreator; - private final List contributors; + private final List contributors; private final InjectionGenerator injectionGenerator; private final Options beanInstanceOptions; - DefaultBeanInstanceGenerator(Executable instanceCreator, List contributors) { + DefaultBeanInstantiationGenerator(Executable instanceCreator, List contributors) { this.instanceCreator = instanceCreator; this.contributors = List.copyOf(contributors); this.injectionGenerator = new InjectionGenerator(); @@ -62,7 +63,7 @@ class DefaultBeanInstanceGenerator { * @param runtimeHints the runtime hints instance to use * @return a code contribution that provides an initialized bean instance */ - public CodeContribution generateBeanInstance(RuntimeHints runtimeHints) { + public CodeContribution generateBeanInstantiation(RuntimeHints runtimeHints) { DefaultCodeContribution contribution = new DefaultCodeContribution(runtimeHints); contribution.protectedAccess().analyze(this.instanceCreator, this.beanInstanceOptions); if (this.instanceCreator instanceof Constructor constructor) { @@ -109,7 +110,7 @@ private void writeBeanInstantiation(CodeContribution contribution, Constructor { - Field environmentField = ReflectionUtils.findField(AutowiredAnnotationBeanInstanceContributorTests.PrivateFieldInjectionSample.class, "environment", Environment.class); + Field environmentField = ReflectionUtils.findField(AutowiredAnnotationBeanInstantiationContributorTests.PrivateFieldInjectionSample.class, "environment", Environment.class); ReflectionUtils.makeAccessible(environmentField); ReflectionUtils.setField(environmentField, bean, attributes.get(0)); })"""); @@ -117,19 +117,19 @@ void buildAotContributorWithInjectionPoints() { @Test void buildAotContributorWithoutInjectionPoints() { - BeanInstanceContributor contributor = createAotContributor(String.class); - assertThat(contributor).isNotNull().isSameAs(BeanInstanceContributor.NO_OP); + BeanInstantiationContributor contributor = createAotContributor(String.class); + assertThat(contributor).isNotNull().isSameAs(BeanInstantiationContributor.NO_OP); } private DefaultCodeContribution contribute(Class type) { - BeanInstanceContributor contributor = createAotContributor(type); + BeanInstantiationContributor contributor = createAotContributor(type); assertThat(contributor).isNotNull(); DefaultCodeContribution contribution = new DefaultCodeContribution(new RuntimeHints()); contributor.contribute(contribution); return contribution; } - private BeanInstanceContributor createAotContributor(Class type) { + private BeanInstantiationContributor createAotContributor(Class type) { AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); RootBeanDefinition beanDefinition = new RootBeanDefinition(type); return bpp.buildAotContributor(beanDefinition, type, "test"); diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGeneratorTests.java similarity index 96% rename from spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGeneratorTests.java rename to spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGeneratorTests.java index d780d868145c..29f5d49995e5 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstanceGeneratorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGeneratorTests.java @@ -48,11 +48,11 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link DefaultBeanInstanceGenerator}. + * Tests for {@link DefaultBeanInstantiationGenerator}. * * @author Stephane Nicoll */ -class DefaultBeanInstanceGeneratorTests { +class DefaultBeanInstantiationGeneratorTests { @Test void generateUsingDefaultConstructorUsesMethodReference() { @@ -109,7 +109,7 @@ void generateUsingConstructorOfTypeWithGeneric() { void generateUsingNoArgConstructorAndContributorsDoesNotUseMethodReference() { CodeContribution contribution = generate(SimpleConfiguration.class.getDeclaredConstructors()[0], contrib -> contrib.statements().add(CodeBlock.of("// hello\n")), - BeanInstanceContributor.NO_OP); + BeanInstantiationContributor.NO_OP); assertThat(code(contribution)).isEqualTo(""" (instanceContext) -> { SimpleConfiguration bean = new SimpleConfiguration(); @@ -240,10 +240,10 @@ private Consumer match(Executable executable, String name, Execu } private CodeContribution generate(Executable executable, - BeanInstanceContributor... beanInstanceContributors) { - DefaultBeanInstanceGenerator generator = new DefaultBeanInstanceGenerator(executable, - Arrays.asList(beanInstanceContributors)); - return generator.generateBeanInstance(new RuntimeHints()); + BeanInstantiationContributor... beanInstantiationContributors) { + DefaultBeanInstantiationGenerator generator = new DefaultBeanInstantiationGenerator(executable, + Arrays.asList(beanInstantiationContributors)); + return generator.generateBeanInstantiation(new RuntimeHints()); } private static Method method(Class type, String methodName, Class... parameterTypes) { From a28b49ac27738b8b9c62fa220d81485b3c840d16 Mon Sep 17 00:00:00 2001 From: izeye Date: Wed, 23 Feb 2022 20:52:36 +0900 Subject: [PATCH 732/735] Fix library name for JavaPoet in src/docs/dist/license.txt This commit also updates Objenesis version in the file to align with the version that Spring Framework is using. See gh-28100 --- src/docs/dist/license.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/docs/dist/license.txt b/src/docs/dist/license.txt index 2170aa9784a1..89cf3d232fa7 100644 --- a/src/docs/dist/license.txt +++ b/src/docs/dist/license.txt @@ -257,16 +257,16 @@ is included above. >>> JavaPoet 1.13.0 (com.squareup:javapoet:1.13.0): -Per the LICENSE file in the CGLIB JAR distribution downloaded from +Per the LICENSE file in the JavaPoet JAR distribution downloaded from https://github.com/square/javapoet/archive/refs/tags/javapoet-1.13.0.zip, JavaPoet 1.13.0 is licensed under the Apache License, version 2.0, the text of which is included above. ->>> Objenesis 3.1 (org.objenesis:objenesis:3.1): +>>> Objenesis 3.2 (org.objenesis:objenesis:3.2): Per the LICENSE file in the Objenesis ZIP distribution downloaded from -http://objenesis.org/download.html, Objenesis 3.1 is licensed under the +http://objenesis.org/download.html, Objenesis 3.2 is licensed under the Apache License, version 2.0, the text of which is included above. Per the NOTICE file in the Objenesis ZIP distribution downloaded from From 453c6d41f71acc54bb3928f9c7b9787d29e84a43 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 24 Feb 2022 10:54:52 +0100 Subject: [PATCH 733/735] Fix Objenesis version See gh-28100 --- src/docs/dist/license.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/docs/dist/license.txt b/src/docs/dist/license.txt index c68e1154b170..0eb8edb06324 100644 --- a/src/docs/dist/license.txt +++ b/src/docs/dist/license.txt @@ -255,10 +255,10 @@ CGLIB 3.3 is licensed under the Apache License, version 2.0, the text of which is included above. ->>> Objenesis 3.1 (org.objenesis:objenesis:3.1): +>>> Objenesis 3.2 (org.objenesis:objenesis:3.2): Per the LICENSE file in the Objenesis ZIP distribution downloaded from -http://objenesis.org/download.html, Objenesis 3.1 is licensed under the +http://objenesis.org/download.html, Objenesis 3.2 is licensed under the Apache License, version 2.0, the text of which is included above. Per the NOTICE file in the Objenesis ZIP distribution downloaded from From 7e2106b850ea65866dc97d24d108c7fe1ea64c8c Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Thu, 24 Feb 2022 14:46:26 +0100 Subject: [PATCH 734/735] Refactor roll forward in CronField Before this commit, CronField.Type::rollForward added temporal units to reach the higher order field. This caused issues with DST, where the added amount of hours was either too small or too large. This commit refactors the implementation so that it now adds one to the higher order field, and reset the current field to the minimum value. Closes gh-28095 --- .../scheduling/support/CronField.java | 34 ++++++++----------- .../support/CronExpressionTests.java | 8 +++++ 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java b/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java index adc2c2ffe5d6..f794645d654f 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java @@ -18,6 +18,7 @@ import java.time.DateTimeException; import java.time.temporal.ChronoField; +import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.ValueRange; import java.util.function.BiFunction; @@ -168,22 +169,25 @@ protected static > T cast(Temporal te * day-of-month, month, day-of-week. */ protected enum Type { - NANO(ChronoField.NANO_OF_SECOND), - SECOND(ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND), - MINUTE(ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND), - HOUR(ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND), - DAY_OF_MONTH(ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND), - MONTH(ChronoField.MONTH_OF_YEAR, ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND), - DAY_OF_WEEK(ChronoField.DAY_OF_WEEK, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND); + NANO(ChronoField.NANO_OF_SECOND, ChronoUnit.SECONDS), + SECOND(ChronoField.SECOND_OF_MINUTE, ChronoUnit.MINUTES, ChronoField.NANO_OF_SECOND), + MINUTE(ChronoField.MINUTE_OF_HOUR, ChronoUnit.HOURS, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND), + HOUR(ChronoField.HOUR_OF_DAY, ChronoUnit.DAYS, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND), + DAY_OF_MONTH(ChronoField.DAY_OF_MONTH, ChronoUnit.MONTHS, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND), + MONTH(ChronoField.MONTH_OF_YEAR, ChronoUnit.YEARS, ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND), + DAY_OF_WEEK(ChronoField.DAY_OF_WEEK, ChronoUnit.WEEKS, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND); private final ChronoField field; + private final ChronoUnit higherOrder; + private final ChronoField[] lowerOrders; - Type(ChronoField field, ChronoField... lowerOrders) { + Type(ChronoField field, ChronoUnit higherOrder, ChronoField... lowerOrders) { this.field = field; + this.higherOrder = higherOrder; this.lowerOrders = lowerOrders; } @@ -266,17 +270,9 @@ public > T elapseUntil(T temporal, in * @return the rolled forward temporal */ public > T rollForward(T temporal) { - int current = get(temporal); - ValueRange range = temporal.range(this.field); - long amount = range.getMaximum() - current + 1; - T result = this.field.getBaseUnit().addTo(temporal, amount); - current = get(result); - range = result.range(this.field); - // adjust for daylight savings - if (current != range.getMinimum()) { - result = this.field.adjustInto(result, range.getMinimum()); - } - return result; + T result = this.higherOrder.addTo(temporal, 1); + ValueRange range = result.range(this.field); + return this.field.adjustInto(result, range.getMinimum()); } /** diff --git a/spring-context/src/test/java/org/springframework/scheduling/support/CronExpressionTests.java b/spring-context/src/test/java/org/springframework/scheduling/support/CronExpressionTests.java index 5de5362fc1dd..5dd837e0379f 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/support/CronExpressionTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/support/CronExpressionTests.java @@ -1344,6 +1344,14 @@ public void daylightSaving() { actual = cronExpression.next(last); assertThat(actual).isNotNull(); assertThat(actual).isEqualTo(expected); + + cronExpression = CronExpression.parse("0 5 0 * * *"); + + last = ZonedDateTime.parse("2019-10-27T01:05+02:00[Europe/Amsterdam]"); + expected = ZonedDateTime.parse("2019-10-28T00:05+01:00[Europe/Amsterdam]"); + actual = cronExpression.next(last); + assertThat(actual).isNotNull(); + assertThat(actual).isEqualTo(expected); } @Test From 91426e6cc40a907fb807b6f9aec2981a7ca16dca Mon Sep 17 00:00:00 2001 From: chenrl Date: Sun, 21 Mar 2021 16:46:15 +0800 Subject: [PATCH 735/735] check file with realPath is existing --- .../web/context/support/ServletContextResource.java | 9 +++++++-- .../web/context/support/ResourceTests.java | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java index bf498cda8587..8cae262fc2ef 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java @@ -139,10 +139,15 @@ public boolean isFile() { return true; } else { - return (this.servletContext.getRealPath(this.path) != null); + String realPath = this.servletContext.getRealPath(this.path); + if (realPath == null) { + return false; + } + File file = new File(realPath); + return (file.exists() && file.isFile()); } } - catch (MalformedURLException ex) { + catch (IOException ex) { return false; } } diff --git a/spring-web/src/test/java/org/springframework/web/context/support/ResourceTests.java b/spring-web/src/test/java/org/springframework/web/context/support/ResourceTests.java index 340838871814..937885e107f7 100644 --- a/spring-web/src/test/java/org/springframework/web/context/support/ResourceTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/support/ResourceTests.java @@ -36,6 +36,8 @@ public void testServletContextResource() throws IOException { MockServletContext sc = new MockServletContext(); Resource resource = new ServletContextResource(sc, "org/springframework/core/io/Resource.class"); doTestResource(resource); + Resource resourceNotExists = new ServletContextResource(sc, "org/springframework/core/io/ResourceNotExists.class"); + doTestNotExistsResource(resourceNotExists); assertThat(new ServletContextResource(sc, "org/springframework/core/../core/io/./Resource.class")).isEqualTo(resource); } @@ -48,6 +50,9 @@ public void testServletContextResourceWithRelativePath() throws IOException { } private void doTestResource(Resource resource) throws IOException { + assertThat(resource.getFile()).isNotNull(); + assertThat(resource.exists()).isTrue(); + assertThat(resource.isFile()).isTrue(); assertThat(resource.getFilename()).isEqualTo("Resource.class"); assertThat(resource.getURL().getFile().endsWith("Resource.class")).isTrue(); @@ -61,4 +66,9 @@ private void doTestResource(Resource resource) throws IOException { assertThat(relative2.getURL().getFile().endsWith("ResourcePatternResolver.class")).isTrue(); assertThat(relative2.exists()).isTrue(); } + + private void doTestNotExistsResource(Resource resource) throws IOException { + assertThat(resource.exists()).isFalse(); + assertThat(resource.isFile()).isFalse(); + } }

    Supported Exceptions

    400 (SC_BAD_REQUEST)

    MissingServletRequestPartException

    400 (SC_BAD_REQUEST)

    ServletRequestBindingException

    400 (SC_BAD_REQUEST)

    MethodArgumentNotValidException

    400 (SC_BAD_REQUEST)

    MissingServletRequestPartException

    400 (SC_BAD_REQUEST)

    BindException

    400 (SC_BAD_REQUEST)