From 1c38ab94a1d3c67c2fc47789401ee8c9d127a9ad Mon Sep 17 00:00:00 2001 From: Muhammad Abdullah Azam Khan Date: Thu, 14 Oct 2021 01:15:13 +0400 Subject: [PATCH 01/63] 415 Unsupported Media Type 1. Basic user controller added 2. POST API explains the how to support differnet content-type formats --- .../UnsupportedMediaTypeApplication.java | 13 ++++ .../baeldung/unsupportedmediatype/User.java | 61 +++++++++++++++++++ .../unsupportedmediatype/UserController.java | 29 +++++++++ 3 files changed, 103 insertions(+) create mode 100644 spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java create mode 100644 spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java create mode 100644 spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UserController.java diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java new file mode 100644 index 0000000000..ccc136ef86 --- /dev/null +++ b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.unsupportedmediatype; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UnsupportedMediaTypeApplication { + + public static void main(String[] args) { + SpringApplication.run(UnsupportedMediaTypeApplication.class, args); + } + +} diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java new file mode 100644 index 0000000000..74a6f4383b --- /dev/null +++ b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java @@ -0,0 +1,61 @@ +package com.baeldung.unsupportedmediatype; + +import javax.xml.bind.annotation.XmlRootElement; +import java.io.Serializable; + +@XmlRootElement +public class User implements Serializable { + private Integer id; + private String name; + private Integer age; + private String address; + + public User(Integer id, String name, Integer age, String address){ + this.id = id; + this.name = name; + this.age = age; + this.address = address; + } + + 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 String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + @Override + public String toString() { + return "User{" + + "id=" + id + + ", name='" + name + '\'' + + ", age=" + age + + ", address='" + address + '\'' + + '}'; + } +} diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UserController.java b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UserController.java new file mode 100644 index 0000000000..a20043619a --- /dev/null +++ b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UserController.java @@ -0,0 +1,29 @@ +package com.baeldung.unsupportedmediatype; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.Collections; +import java.util.List; + +@RestController +@RequestMapping("/user") +public class UserController { + + @GetMapping(value = "/") + List getAllUsers(){ + return Collections.singletonList(new User(1, "Andy", 28, "14th Street")); + } + + @GetMapping(value = "/{user-id}") + User getUser(@PathVariable("user-id") Integer userId){ + return new User(userId, "Andy", 28, "14th Street"); + } + + @PostMapping(value = "/", consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}) + void AddUser(@RequestBody User user){ + // Adding the User in the repository + } + + +} \ No newline at end of file From 842f27c77eb2e7e6fd6b2b920b37383ed2805d78 Mon Sep 17 00:00:00 2001 From: Muhammad Abdullah Azam Khan Date: Sun, 17 Oct 2021 00:24:08 +0400 Subject: [PATCH 02/63] Test case for unsupported media type error --- .../unsupportedmedia/ApplicationTest.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmedia/ApplicationTest.java diff --git a/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmedia/ApplicationTest.java b/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmedia/ApplicationTest.java new file mode 100644 index 0000000000..e5c56d0adc --- /dev/null +++ b/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmedia/ApplicationTest.java @@ -0,0 +1,59 @@ +package com.baeldung.unsupportedmedia; + +import com.baeldung.unsupportedmediatype.UserController; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@WebMvcTest(UserController.class) +public class ApplicationTest { + @Autowired + private MockMvc mockMvc; + + @Test + void JsonTestCase() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.post("/user/") + .contentType(MediaType.APPLICATION_JSON_VALUE) + .content("{\n" + + " \"name\": \"Andy\",\n" + + " \"age\": 1,\n" + + " \"address\": \"Hello world\"\n" + + "}")) + .andExpect(status().isOk()); + } + + @Test + void JsonFailTestCase() throws Exception {// Because no content-type added + mockMvc.perform(MockMvcRequestBuilders.post("/user/") + .content("{\n" + + " \"name\": \"Andy\",\n" + + " \"age\": 1,\n" + + " \"address\": \"Hello world\"\n" + + "}")) + .andExpect(status().isUnsupportedMediaType()); + } + + @Test + void XmlTestCase() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.post("/user/") + .contentType(MediaType.APPLICATION_XML_VALUE) + .content("Andy1
Hello world
")) + .andExpect(status().isOk()); + } + + @Test + void StringTestCase() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.post("/user/") + .contentType(MediaType.TEXT_PLAIN_VALUE) + .content("Andy1
Hello world
")) + .andExpect(status().isUnsupportedMediaType()); + } +} From 733c7e76b96ba59962dc5032ae6dd4f0de5fca1c Mon Sep 17 00:00:00 2001 From: Muhammad Abdullah Azam Khan Date: Sun, 17 Oct 2021 00:52:40 +0400 Subject: [PATCH 03/63] Resolving build failure cases --- .../com/baeldung/unsupportedmediatype/User.java | 4 ++++ .../ApplicationUnitTest.java} | 15 +++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) rename spring-boot-rest-2/src/test/java/com/baeldung/{unsupportedmedia/ApplicationTest.java => unsupportedmediatype/ApplicationUnitTest.java} (84%) diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java index 74a6f4383b..5f5f2a972c 100644 --- a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java +++ b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java @@ -10,6 +10,10 @@ public class User implements Serializable { private Integer age; private String address; + public User(){ + + } + public User(Integer id, String name, Integer age, String address){ this.id = id; this.name = name; diff --git a/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmedia/ApplicationTest.java b/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java similarity index 84% rename from spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmedia/ApplicationTest.java rename to spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java index e5c56d0adc..a84388f750 100644 --- a/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmedia/ApplicationTest.java +++ b/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java @@ -1,7 +1,6 @@ -package com.baeldung.unsupportedmedia; +package com.baeldung.unsupportedmediatype; -import com.baeldung.unsupportedmediatype.UserController; -import org.junit.jupiter.api.Test; +import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -14,12 +13,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @RunWith(SpringRunner.class) @WebMvcTest(UserController.class) -public class ApplicationTest { +public class ApplicationUnitTest { @Autowired private MockMvc mockMvc; @Test - void JsonTestCase() throws Exception { + public void JsonTestCase() throws Exception { mockMvc.perform(MockMvcRequestBuilders.post("/user/") .contentType(MediaType.APPLICATION_JSON_VALUE) .content("{\n" + @@ -31,7 +30,7 @@ public class ApplicationTest { } @Test - void JsonFailTestCase() throws Exception {// Because no content-type added + public void JsonFailTestCase() throws Exception {// Because no content-type added mockMvc.perform(MockMvcRequestBuilders.post("/user/") .content("{\n" + " \"name\": \"Andy\",\n" + @@ -42,7 +41,7 @@ public class ApplicationTest { } @Test - void XmlTestCase() throws Exception { + public void XmlTestCase() throws Exception { mockMvc.perform(MockMvcRequestBuilders.post("/user/") .contentType(MediaType.APPLICATION_XML_VALUE) .content("Andy1
Hello world
")) @@ -50,7 +49,7 @@ public class ApplicationTest { } @Test - void StringTestCase() throws Exception { + public void StringFailTestCase() throws Exception { // Because content-type is not supported mockMvc.perform(MockMvcRequestBuilders.post("/user/") .contentType(MediaType.TEXT_PLAIN_VALUE) .content("Andy1
Hello world
")) From 9d464b4f459987e0dbc548beec1dd8882dba21b6 Mon Sep 17 00:00:00 2001 From: Muhammad Abdullah Azam Khan Date: Fri, 5 Nov 2021 18:32:19 +0400 Subject: [PATCH 04/63] Refactoring for better Indentation and Formatting --- .../UnsupportedMediaTypeApplication.java | 6 ++-- .../baeldung/unsupportedmediatype/User.java | 17 +++++------ .../ApplicationUnitTest.java | 28 +++++++++---------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java index ccc136ef86..2bf6bb33cd 100644 --- a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java +++ b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java @@ -6,8 +6,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class UnsupportedMediaTypeApplication { - public static void main(String[] args) { - SpringApplication.run(UnsupportedMediaTypeApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(UnsupportedMediaTypeApplication.class, args); + } } diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java index 5f5f2a972c..f9c3d9c191 100644 --- a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java +++ b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java @@ -11,10 +11,9 @@ public class User implements Serializable { private String address; public User(){ - } - public User(Integer id, String name, Integer age, String address){ + public User(Integer id, String name, Integer age, String address) { this.id = id; this.name = name; this.age = age; @@ -55,11 +54,13 @@ public class User implements Serializable { @Override public String toString() { - return "User{" + - "id=" + id + - ", name='" + name + '\'' + - ", age=" + age + - ", address='" + address + '\'' + - '}'; + return "User{" + + "id=" + id + + ", name='" + name + '\'' + + ", age=" + age + + ", address='" + address + '\'' + + '}'; } + + } diff --git a/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java b/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java index a84388f750..95de780106 100644 --- a/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java +++ b/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java @@ -21,38 +21,38 @@ public class ApplicationUnitTest { public void JsonTestCase() throws Exception { mockMvc.perform(MockMvcRequestBuilders.post("/user/") .contentType(MediaType.APPLICATION_JSON_VALUE) - .content("{\n" + - " \"name\": \"Andy\",\n" + - " \"age\": 1,\n" + - " \"address\": \"Hello world\"\n" + - "}")) + .content( "{\n" + + " \"name\": \"Andy\",\n" + + " \"age\": 1,\n" + + " \"address\": \"Hello world\"\n" + + "}")) .andExpect(status().isOk()); } @Test public void JsonFailTestCase() throws Exception {// Because no content-type added mockMvc.perform(MockMvcRequestBuilders.post("/user/") - .content("{\n" + - " \"name\": \"Andy\",\n" + - " \"age\": 1,\n" + - " \"address\": \"Hello world\"\n" + - "}")) + .content( "{\n" + + " \"name\": \"Andy\",\n" + + " \"age\": 1,\n" + + " \"address\": \"Hello world\"\n" + + "}")) .andExpect(status().isUnsupportedMediaType()); } @Test public void XmlTestCase() throws Exception { mockMvc.perform(MockMvcRequestBuilders.post("/user/") - .contentType(MediaType.APPLICATION_XML_VALUE) - .content("Andy1
Hello world
")) + .contentType(MediaType.APPLICATION_XML_VALUE) + .content("Andy1
Hello world
")) .andExpect(status().isOk()); } @Test public void StringFailTestCase() throws Exception { // Because content-type is not supported mockMvc.perform(MockMvcRequestBuilders.post("/user/") - .contentType(MediaType.TEXT_PLAIN_VALUE) - .content("Andy1
Hello world
")) + .contentType(MediaType.TEXT_PLAIN_VALUE) + .content("Andy1
Hello world
")) .andExpect(status().isUnsupportedMediaType()); } } From 99cc4be41e5c6be9f8c50db63dd9589d4a38b74f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matea=20Pej=C4=8Dinovi=C4=87?= Date: Thu, 25 Nov 2021 20:09:04 +0100 Subject: [PATCH 05/63] BAEL-5032 Swagger to PDF --- .../spring-boot-swagger/pom.xml | 109 +++++++++++++++++- .../controller/UserController.java | 63 ++++++++++ .../baeldung/swagger2pdf/objects/User.java | 12 ++ 3 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/controller/UserController.java create mode 100644 spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/objects/User.java diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml index 87ee5f04cb..6e91189802 100644 --- a/spring-boot-modules/spring-boot-swagger/pom.xml +++ b/spring-boot-modules/spring-boot-swagger/pom.xml @@ -25,6 +25,21 @@ springfox-boot-starter ${springfox.version} + + io.springfox + springfox-swagger2 + ${springfox-swagger2.version} + + + io.swagger.core.v3 + swagger-jaxrs2 + ${swagger-jaxrs2.version} + + + javax.ws.rs + javax.ws.rs-api + ${javax.ws.rs-api.version} + @@ -33,11 +48,103 @@ org.springframework.boot spring-boot-maven-plugin + + + + com.github.kongchen + swagger-maven-plugin + 3.1.3 + + + + false + com.baeldung.swagger2pdf.controller.UserController + /api + + DEMO REST API + A simple DEMO project for REST API documentation + v1 + + ${project.build.directory}/api + true + + + + + + package + + generate + + + + + + io.github.robwin + swagger2markup-maven-plugin + 0.9.3 + + ${project.build.directory}/api + ${generated.asciidoc.directory} + asciidoc + + + + package + + process-swagger + + + + + + org.asciidoctor + asciidoctor-maven-plugin + 2.2.1 + + + + org.asciidoctor + asciidoctorj-pdf + 1.6.0 + + + + ${project.build.outputDirectory}/../asciidoc + overview.adoc + + book + left + 2 + ${generated.asciidoc.directory} + + + + + + asciidoc-to-pdf + package + + process-asciidoc + + + pdf + ${project.build.outputDirectory}/api/pdf + + + + + + 3.0.0 + ${project.build.outputDirectory}/asciidoc + 2.10.5 + 2.1.11 + 2.1 - \ No newline at end of file + diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/controller/UserController.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/controller/UserController.java new file mode 100644 index 0000000000..380bac6f8c --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/controller/UserController.java @@ -0,0 +1,63 @@ +package com.baeldung.swagger2pdf.controller; + +import com.baeldung.swagger2pdf.objects.User; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.NonNull; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.List; + +@Controller +@Api(value = "/api", description = "A controller for user management") +@RequestMapping("/user") +@ResponseStatus(HttpStatus.OK) +public class UserController { + + static List users; + + static { + users = new ArrayList<>(); + users.add(new User("Mark", "Thompson", 23)); + users.add(new User("Kate", "Jordan", 22)); + } + + @ApiOperation(value = "Retrieves all the users") + @RequestMapping(value = "/users", + method = RequestMethod.GET, + produces = MediaType.APPLICATION_JSON_VALUE) + public List getUsers() { + return users; + } + + @ApiOperation(value = "Retrieves a user based on first name") + @RequestMapping(value = "/user", + method = RequestMethod.GET, + produces = MediaType.APPLICATION_JSON_VALUE) + public User getUser(@NonNull @RequestParam String firstName) { + + if (firstName.isEmpty()) { + return null; + } + + return users.stream() + .filter(user -> user.getFirstName().equals(firstName)) + .findAny() + .orElse(null); + + } + + @ApiOperation(value = "Adds a user.") + @RequestMapping(value = "/user", + method = RequestMethod.POST, + produces = MediaType.APPLICATION_JSON_VALUE) + public List addUser(@NonNull @RequestBody User user) { + users.add(user); + return users; + } +} + diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/objects/User.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/objects/User.java new file mode 100644 index 0000000000..8c59cb246a --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/objects/User.java @@ -0,0 +1,12 @@ +package com.baeldung.swagger2pdf.objects; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class User { + private String firstName; + private String lastName; + private int age; +} From 2a3501237cb22243274fe51973fa58664baf8f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matea=20Pej=C4=8Dinovi=C4=87?= Date: Thu, 25 Nov 2021 20:16:02 +0100 Subject: [PATCH 06/63] BAEL-5032 added lombok as dependency --- spring-boot-modules/spring-boot-swagger/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml index 6e91189802..41f41a92b9 100644 --- a/spring-boot-modules/spring-boot-swagger/pom.xml +++ b/spring-boot-modules/spring-boot-swagger/pom.xml @@ -40,6 +40,11 @@ javax.ws.rs-api ${javax.ws.rs-api.version} + + org.projectlombok + lombok + ${lombok.version} + @@ -145,6 +150,7 @@ 2.10.5 2.1.11 2.1 + 1.18.22 From f9f37ac4e69a770c1217fe5c85f15693c24f4793 Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Fri, 26 Nov 2021 13:17:01 +0100 Subject: [PATCH 07/63] JAVA-8709: Extract commons-collections4.version property to the main pom.xml --- algorithms-miscellaneous-3/pom.xml | 4 +--- core-java-modules/core-java-10/pom.xml | 1 - core-java-modules/core-java-8/pom.xml | 5 ----- core-java-modules/core-java-9/pom.xml | 1 - core-java-modules/core-java-collections-2/pom.xml | 1 - core-java-modules/core-java-collections-array-list/pom.xml | 4 ---- core-java-modules/core-java-collections-list-2/pom.xml | 4 ---- core-java-modules/core-java-collections-list-3/pom.xml | 1 - core-java-modules/core-java-collections-list/pom.xml | 4 ---- core-java-modules/core-java-collections-maps-2/pom.xml | 1 - core-java-modules/core-java-collections-maps/pom.xml | 4 ---- core-java-modules/core-java-collections-set/pom.xml | 1 - core-java-modules/core-java-concurrency-advanced/pom.xml | 1 - core-java-modules/core-java-os/pom.xml | 1 - gson/pom.xml | 3 --- guava-modules/guava-collections-list/pom.xml | 3 --- guava-modules/guava-collections/pom.xml | 3 --- java-collections-conversions/pom.xml | 4 ---- java-collections-maps-3/pom.xml | 1 - json/pom.xml | 1 - libraries-6/pom.xml | 1 - libraries-apache-commons-collections/pom.xml | 3 +-- pom.xml | 1 + spring-5-reactive-client/pom.xml | 1 - spring-5-reactive-security/pom.xml | 1 - spring-5-reactive/pom.xml | 1 - spring-5/pom.xml | 1 - testing-modules/testing-assertions/pom.xml | 4 ---- video-tutorials/jackson-annotations/pom.xml | 1 - xml/pom.xml | 1 - 30 files changed, 3 insertions(+), 60 deletions(-) diff --git a/algorithms-miscellaneous-3/pom.xml b/algorithms-miscellaneous-3/pom.xml index 525a2556de..11a64eba8b 100644 --- a/algorithms-miscellaneous-3/pom.xml +++ b/algorithms-miscellaneous-3/pom.xml @@ -37,7 +37,7 @@ org.apache.commons commons-lang3 - ${commons.lang3.version} + ${commons-lang3.version} pl.pragmatists @@ -63,10 +63,8 @@ - 4.3 28.0-jre 2.6.0 - 3.8.1 1.1.0 diff --git a/core-java-modules/core-java-10/pom.xml b/core-java-modules/core-java-10/pom.xml index c3406751dc..e2ac8db919 100644 --- a/core-java-modules/core-java-10/pom.xml +++ b/core-java-modules/core-java-10/pom.xml @@ -39,7 +39,6 @@ 10 10 - 4.1 \ No newline at end of file diff --git a/core-java-modules/core-java-8/pom.xml b/core-java-modules/core-java-8/pom.xml index 85e289280b..89925bdbbb 100644 --- a/core-java-modules/core-java-8/pom.xml +++ b/core-java-modules/core-java-8/pom.xml @@ -43,9 +43,4 @@ - - - 4.1 - - \ No newline at end of file diff --git a/core-java-modules/core-java-9/pom.xml b/core-java-modules/core-java-9/pom.xml index 03a097e7a9..274d9ccb43 100644 --- a/core-java-modules/core-java-9/pom.xml +++ b/core-java-modules/core-java-9/pom.xml @@ -76,7 +76,6 @@ 1.9 1.9 25.1-jre - 4.1 \ No newline at end of file diff --git a/core-java-modules/core-java-collections-2/pom.xml b/core-java-modules/core-java-collections-2/pom.xml index 23100b1d87..e78f7b5dda 100644 --- a/core-java-modules/core-java-collections-2/pom.xml +++ b/core-java-modules/core-java-collections-2/pom.xml @@ -44,7 +44,6 @@ 7.1.0 - 4.1 1.3 diff --git a/core-java-modules/core-java-collections-array-list/pom.xml b/core-java-modules/core-java-collections-array-list/pom.xml index ca9c173947..6b040739e8 100644 --- a/core-java-modules/core-java-collections-array-list/pom.xml +++ b/core-java-modules/core-java-collections-array-list/pom.xml @@ -22,8 +22,4 @@ - - 4.1 - - \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list-2/pom.xml b/core-java-modules/core-java-collections-list-2/pom.xml index 7876b19cf9..59ab8c5f27 100644 --- a/core-java-modules/core-java-collections-list-2/pom.xml +++ b/core-java-modules/core-java-collections-list-2/pom.xml @@ -28,8 +28,4 @@ - - 4.1 - - \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list-3/pom.xml b/core-java-modules/core-java-collections-list-3/pom.xml index 9238939df7..3bb0fb4a33 100644 --- a/core-java-modules/core-java-collections-list-3/pom.xml +++ b/core-java-modules/core-java-collections-list-3/pom.xml @@ -54,7 +54,6 @@ - 4.1 3.0.2 8.1.0 1.2.0 diff --git a/core-java-modules/core-java-collections-list/pom.xml b/core-java-modules/core-java-collections-list/pom.xml index b60906d1ba..0cc8828a0d 100644 --- a/core-java-modules/core-java-collections-list/pom.xml +++ b/core-java-modules/core-java-collections-list/pom.xml @@ -27,8 +27,4 @@ - - 4.1 - - \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-2/pom.xml b/core-java-modules/core-java-collections-maps-2/pom.xml index 060796fafa..36b15c24d5 100644 --- a/core-java-modules/core-java-collections-maps-2/pom.xml +++ b/core-java-modules/core-java-collections-maps-2/pom.xml @@ -55,7 +55,6 @@ 0.6.5 - 4.1 1.7.0 8.2.0 0.7.2 diff --git a/core-java-modules/core-java-collections-maps/pom.xml b/core-java-modules/core-java-collections-maps/pom.xml index 66aca9c1b2..34b878df53 100644 --- a/core-java-modules/core-java-collections-maps/pom.xml +++ b/core-java-modules/core-java-collections-maps/pom.xml @@ -22,8 +22,4 @@ - - 4.1 - - \ No newline at end of file diff --git a/core-java-modules/core-java-collections-set/pom.xml b/core-java-modules/core-java-collections-set/pom.xml index 359c0fc86f..0b6e324c78 100644 --- a/core-java-modules/core-java-collections-set/pom.xml +++ b/core-java-modules/core-java-collections-set/pom.xml @@ -49,7 +49,6 @@ 11 11 - 4.3 2.8.5 diff --git a/core-java-modules/core-java-concurrency-advanced/pom.xml b/core-java-modules/core-java-concurrency-advanced/pom.xml index a026bdb2cd..b50a66cefc 100644 --- a/core-java-modules/core-java-concurrency-advanced/pom.xml +++ b/core-java-modules/core-java-concurrency-advanced/pom.xml @@ -56,7 +56,6 @@ 21.0 3.6.1 - 4.1 4.01 1.7.0 diff --git a/core-java-modules/core-java-os/pom.xml b/core-java-modules/core-java-os/pom.xml index 970c8a562a..c24824dfb7 100644 --- a/core-java-modules/core-java-os/pom.xml +++ b/core-java-modules/core-java-os/pom.xml @@ -69,7 +69,6 @@ - 4.1 4.01 1.8.9 1.9 diff --git a/gson/pom.xml b/gson/pom.xml index a928d87b61..082e53baf0 100644 --- a/gson/pom.xml +++ b/gson/pom.xml @@ -61,10 +61,7 @@ - 2.8.0 - - 4.1 2.9.6 diff --git a/guava-modules/guava-collections-list/pom.xml b/guava-modules/guava-collections-list/pom.xml index 1b989e79b0..6863b4011c 100644 --- a/guava-modules/guava-collections-list/pom.xml +++ b/guava-modules/guava-collections-list/pom.xml @@ -45,9 +45,6 @@ - - 4.1 - 2.0.0.0 diff --git a/guava-modules/guava-collections/pom.xml b/guava-modules/guava-collections/pom.xml index 7929283616..9283107023 100644 --- a/guava-modules/guava-collections/pom.xml +++ b/guava-modules/guava-collections/pom.xml @@ -50,10 +50,7 @@ - - 4.1 0.9.12 - 2.0.0.0 diff --git a/java-collections-conversions/pom.xml b/java-collections-conversions/pom.xml index ae800b21c1..7f5ba38e3e 100644 --- a/java-collections-conversions/pom.xml +++ b/java-collections-conversions/pom.xml @@ -38,8 +38,4 @@ - - 4.4 - - \ No newline at end of file diff --git a/java-collections-maps-3/pom.xml b/java-collections-maps-3/pom.xml index 6f724ab5ef..81466b17ba 100644 --- a/java-collections-maps-3/pom.xml +++ b/java-collections-maps-3/pom.xml @@ -30,7 +30,6 @@ - 4.1 5.2.5.RELEASE diff --git a/json/pom.xml b/json/pom.xml index 2919a3a4ee..dfe42ee4c1 100644 --- a/json/pom.xml +++ b/json/pom.xml @@ -74,7 +74,6 @@ 1.4.1 1.2.21 1.0 - 4.1 1.0.1 20171018 2.8.5 diff --git a/libraries-6/pom.xml b/libraries-6/pom.xml index accf5f3a9a..3b932f2bd2 100644 --- a/libraries-6/pom.xml +++ b/libraries-6/pom.xml @@ -146,7 +146,6 @@ 3.5-beta72 3.0 1.8.1 - 4.4 8.12.9 2.4.4 diff --git a/libraries-apache-commons-collections/pom.xml b/libraries-apache-commons-collections/pom.xml index 2cb73babe6..c1a158b16e 100644 --- a/libraries-apache-commons-collections/pom.xml +++ b/libraries-apache-commons-collections/pom.xml @@ -16,7 +16,7 @@ org.apache.commons commons-collections4 - ${commons.collections.version} + ${commons-collections4.version} org.hamcrest @@ -27,7 +27,6 @@ - 4.1 2.0.0.0 diff --git a/pom.xml b/pom.xml index 8a27d67d65..0aab7b3a02 100644 --- a/pom.xml +++ b/pom.xml @@ -1421,6 +1421,7 @@ 1.33 1.33 2.21.0 + 4.4 2.11.0 2.6 3.12.0 diff --git a/spring-5-reactive-client/pom.xml b/spring-5-reactive-client/pom.xml index 136f31b49e..4821d0fc6d 100644 --- a/spring-5-reactive-client/pom.xml +++ b/spring-5-reactive-client/pom.xml @@ -153,7 +153,6 @@ 1.1.3 1.0 1.0 - 4.1 1.1.6 4.0.1 diff --git a/spring-5-reactive-security/pom.xml b/spring-5-reactive-security/pom.xml index 267a683fa7..140c6b8296 100644 --- a/spring-5-reactive-security/pom.xml +++ b/spring-5-reactive-security/pom.xml @@ -123,7 +123,6 @@ 1.1.3 1.0 1.0 - 4.1 3.1.6.RELEASE diff --git a/spring-5-reactive/pom.xml b/spring-5-reactive/pom.xml index 408573198b..b9456c7181 100644 --- a/spring-5-reactive/pom.xml +++ b/spring-5-reactive/pom.xml @@ -153,7 +153,6 @@ 1.1.3 1.0 1.0 - 4.1 \ No newline at end of file diff --git a/spring-5/pom.xml b/spring-5/pom.xml index 5799f3bc8f..1ac696e7bd 100644 --- a/spring-5/pom.xml +++ b/spring-5/pom.xml @@ -142,7 +142,6 @@ 1.0 1.5.6 - 4.1 ${project.build.directory}/generated-snippets 4.0.3 diff --git a/testing-modules/testing-assertions/pom.xml b/testing-modules/testing-assertions/pom.xml index 689ca35733..09f4291b78 100644 --- a/testing-modules/testing-assertions/pom.xml +++ b/testing-modules/testing-assertions/pom.xml @@ -26,8 +26,4 @@ - - 4.4 - - \ No newline at end of file diff --git a/video-tutorials/jackson-annotations/pom.xml b/video-tutorials/jackson-annotations/pom.xml index 29f457964b..eaec50c1f7 100644 --- a/video-tutorials/jackson-annotations/pom.xml +++ b/video-tutorials/jackson-annotations/pom.xml @@ -116,7 +116,6 @@ 2.9.6 2.8.0 - 4.1 3.0.1 3.0.0 diff --git a/xml/pom.xml b/xml/pom.xml index 968682ee38..0764c9d145 100644 --- a/xml/pom.xml +++ b/xml/pom.xml @@ -355,7 +355,6 @@ 1.2.0 2.0.6 1.6.2 - 4.1 1.2.4.5 2.3.1 1.4.2 From 70608bb2e729a793aa24f74d9d137653b01cff8a Mon Sep 17 00:00:00 2001 From: davidmartinezbarua Date: Fri, 26 Nov 2021 10:56:17 -0300 Subject: [PATCH 08/63] Revert "Spring Webflux and @Cacheable Annotation" --- spring-5-webflux/pom.xml | 20 ---- .../com/baeldung/spring/caching/Item.java | 50 ---------- .../spring/caching/ItemRepository.java | 8 -- .../baeldung/spring/caching/ItemService.java | 42 -------- .../SpringWebfluxCachingApplication.java | 16 ---- .../resources/application-cache.properties | 2 - .../MonoFluxResultCachingLiveTest.java | 95 ------------------- 7 files changed, 233 deletions(-) delete mode 100644 spring-5-webflux/src/main/java/com/baeldung/spring/caching/Item.java delete mode 100644 spring-5-webflux/src/main/java/com/baeldung/spring/caching/ItemRepository.java delete mode 100644 spring-5-webflux/src/main/java/com/baeldung/spring/caching/ItemService.java delete mode 100644 spring-5-webflux/src/main/java/com/baeldung/spring/caching/SpringWebfluxCachingApplication.java delete mode 100644 spring-5-webflux/src/main/resources/application-cache.properties delete mode 100644 spring-5-webflux/src/test/java/com/baeldung/spring/caching/MonoFluxResultCachingLiveTest.java diff --git a/spring-5-webflux/pom.xml b/spring-5-webflux/pom.xml index d6afb686fc..69de83c227 100644 --- a/spring-5-webflux/pom.xml +++ b/spring-5-webflux/pom.xml @@ -66,31 +66,11 @@ - - io.projectreactor.addons - reactor-extra - 3.4.5 - - - com.github.ben-manes.caffeine - caffeine - 2.9.2 - - - org.springframework.boot - spring-boot-starter-data-mongodb-reactive - io.projectreactor reactor-test test - - org.testcontainers - mongodb - 1.16.2 - test - com.squareup.okhttp3 mockwebserver diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/caching/Item.java b/spring-5-webflux/src/main/java/com/baeldung/spring/caching/Item.java deleted file mode 100644 index 7b79ff7503..0000000000 --- a/spring-5-webflux/src/main/java/com/baeldung/spring/caching/Item.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.baeldung.spring.caching; - -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.mapping.Document; - -@Document -public class Item { - - @Id - private String _id; - private String name; - private double price; - - public Item(String name, double price) { - this.name = name; - this.price = price; - } - - public Item() { - } - - public String get_id() { - return _id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public double getPrice() { - return price; - } - - public void setPrice(double price) { - this.price = price; - } - - @Override - public String toString() { - return "Item{" + - "id='" + _id + '\'' + - ", name='" + name + '\'' + - ", price=" + price + - '}'; - } -} diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/caching/ItemRepository.java b/spring-5-webflux/src/main/java/com/baeldung/spring/caching/ItemRepository.java deleted file mode 100644 index 27c97de36a..0000000000 --- a/spring-5-webflux/src/main/java/com/baeldung/spring/caching/ItemRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.spring.caching; - -import org.springframework.data.mongodb.repository.ReactiveMongoRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface ItemRepository extends ReactiveMongoRepository { -} diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/caching/ItemService.java b/spring-5-webflux/src/main/java/com/baeldung/spring/caching/ItemService.java deleted file mode 100644 index b24b54521e..0000000000 --- a/spring-5-webflux/src/main/java/com/baeldung/spring/caching/ItemService.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.baeldung.spring.caching; - -import com.github.benmanes.caffeine.cache.Caffeine; -import com.github.benmanes.caffeine.cache.LoadingCache; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.stereotype.Service; -import reactor.cache.CacheMono; -import reactor.core.publisher.Mono; - -@Service -public class ItemService { - - private final ItemRepository repository; - private final LoadingCache cache; - - public ItemService(ItemRepository repository) { - this.repository = repository; - this.cache = Caffeine.newBuilder() - .build(this::getItem_withAddons); - } - - @Cacheable("items") - public Mono getItem(String id) { - return repository.findById(id); - } - - public Mono save(Item item) { - return repository.save(item); - } - - @Cacheable("items") - public Mono getItem_withCache(String id) { - return repository.findById(id).cache(); - } - - @Cacheable("items") - public Mono getItem_withAddons(String id) { - return CacheMono.lookup(cache.asMap(), id) - .onCacheMissResume(() -> repository.findById(id).cast(Object.class)).cast(Item.class); - } - -} diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/caching/SpringWebfluxCachingApplication.java b/spring-5-webflux/src/main/java/com/baeldung/spring/caching/SpringWebfluxCachingApplication.java deleted file mode 100644 index 5266e33775..0000000000 --- a/spring-5-webflux/src/main/java/com/baeldung/spring/caching/SpringWebfluxCachingApplication.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.baeldung.spring.caching; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cache.annotation.EnableCaching; -import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; - -@SpringBootApplication -@EnableMongoRepositories -@EnableCaching -public class SpringWebfluxCachingApplication { - - public static void main(String[] args) { - SpringApplication.run(SpringWebfluxCachingApplication.class, args); - } -} diff --git a/spring-5-webflux/src/main/resources/application-cache.properties b/spring-5-webflux/src/main/resources/application-cache.properties deleted file mode 100644 index 23414da2dd..0000000000 --- a/spring-5-webflux/src/main/resources/application-cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -logging.level.org.springframework.data.mongodb.core.ReactiveMongoTemplate=DEBUG -logging.level.org.springframework.cache=TRACE \ No newline at end of file diff --git a/spring-5-webflux/src/test/java/com/baeldung/spring/caching/MonoFluxResultCachingLiveTest.java b/spring-5-webflux/src/test/java/com/baeldung/spring/caching/MonoFluxResultCachingLiveTest.java deleted file mode 100644 index 322b3c5aa5..0000000000 --- a/spring-5-webflux/src/test/java/com/baeldung/spring/caching/MonoFluxResultCachingLiveTest.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.baeldung.spring.caching; - - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.MongoDBContainer; -import org.testcontainers.utility.DockerImageName; -import reactor.core.publisher.Mono; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest -@ActiveProfiles("cache") -public class MonoFluxResultCachingLiveTest { - - - @Autowired - ItemService itemService; - - final static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10")); - - @DynamicPropertySource - static void mongoDbProperties(DynamicPropertyRegistry registry) { - mongoDBContainer.start(); - registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl); - } - -@Test -public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { - Mono glass = itemService.save(new Item("glass", 1.00)); - - String id = glass.block().get_id(); - - Mono mono = itemService.getItem(id); - Item item = mono.block(); - - assertThat(item).isNotNull(); - assertThat(item.getName()).isEqualTo("glass"); - assertThat(item.getPrice()).isEqualTo(1.00); - - Mono mono2 = itemService.getItem(id); - Item item2 = mono2.block(); - - assertThat(item2).isNotNull(); - assertThat(item2.getName()).isEqualTo("glass"); - assertThat(item2.getPrice()).isEqualTo(1.00); -} - - @Test - public void givenItem_whenGetItemWithCacheIsCalled_thenMonoResultIsCached() { - Mono glass = itemService.save(new Item("glass", 1.00)); - - String id = glass.block().get_id(); - - Mono mono = itemService.getItem_withCache(id); - Item item = mono.block(); - - assertThat(item).isNotNull(); - assertThat(item.getName()).isEqualTo("glass"); - assertThat(item.getPrice()).isEqualTo(1.00); - - Mono mono2 = itemService.getItem_withCache(id); - Item item2 = mono2.block(); - - assertThat(item2).isNotNull(); - assertThat(item2.getName()).isEqualTo("glass"); - assertThat(item2.getPrice()).isEqualTo(1.00); - } - - @Test - public void givenItem_whenGetItemWithAddonsIsCalled_thenMonoResultIsCached() { - Mono glass = itemService.save(new Item("glass", 1.00)); - - String id = glass.block().get_id(); - - Mono mono = itemService.getItem_withAddons(id); - Item item = mono.block(); - - assertThat(item).isNotNull(); - assertThat(item.getName()).isEqualTo("glass"); - assertThat(item.getPrice()).isEqualTo(1.00); - - Mono mono2 = itemService.getItem_withAddons(id); - Item item2 = mono2.block(); - - assertThat(item2).isNotNull(); - assertThat(item2.getName()).isEqualTo("glass"); - assertThat(item2.getPrice()).isEqualTo(1.00); - } - -} From e931840ced257bf2a38d9ebe55e66473f05e3445 Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Fri, 26 Nov 2021 22:19:21 +0530 Subject: [PATCH 09/63] JAVA-8287: Split or move java-jpa-3 module --- persistence-modules/java-jpa-3/README.md | 1 - persistence-modules/java-mongodb/README.md | 1 + .../field}/FieldExistenceLiveTest.java | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename persistence-modules/java-mongodb/src/test/java/com/baeldung/{existence.field => existence/field}/FieldExistenceLiveTest.java (100%) diff --git a/persistence-modules/java-jpa-3/README.md b/persistence-modules/java-jpa-3/README.md index 202c97a830..aa33644b17 100644 --- a/persistence-modules/java-jpa-3/README.md +++ b/persistence-modules/java-jpa-3/README.md @@ -13,5 +13,4 @@ This module contains articles about the Java Persistence API (JPA) in Java. - [Returning an Auto-Generated Id with JPA](https://www.baeldung.com/jpa-get-auto-generated-id) - [How to Return Multiple Entities In JPA Query](https://www.baeldung.com/jpa-return-multiple-entities) - [Defining Unique Constraints in JPA](https://www.baeldung.com/jpa-unique-constraints) -- [How to Check Field Existence in MongoDB?](https://www.baeldung.com/mongodb-check-field-exists) - [Connecting to a Specific Schema in JDBC](https://www.baeldung.com/jdbc-connect-to-schema) diff --git a/persistence-modules/java-mongodb/README.md b/persistence-modules/java-mongodb/README.md index f632e7c662..34acd60c57 100644 --- a/persistence-modules/java-mongodb/README.md +++ b/persistence-modules/java-mongodb/README.md @@ -11,3 +11,4 @@ This module contains articles about MongoDB in Java. - [Introduction to Morphia – Java ODM for MongoDB](https://www.baeldung.com/mongodb-morphia) - [MongoDB Aggregations Using Java](https://www.baeldung.com/java-mongodb-aggregations) - [BSON to JSON Document Conversion in Java](https://www.baeldung.com/java-convert-bson-to-json) +- [How to Check Field Existence in MongoDB?](https://www.baeldung.com/mongodb-check-field-exists) diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/existence.field/FieldExistenceLiveTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/existence/field/FieldExistenceLiveTest.java similarity index 100% rename from persistence-modules/java-mongodb/src/test/java/com/baeldung/existence.field/FieldExistenceLiveTest.java rename to persistence-modules/java-mongodb/src/test/java/com/baeldung/existence/field/FieldExistenceLiveTest.java From 86dcb518b2d9d95321405d3099ea5ce8fe5857e7 Mon Sep 17 00:00:00 2001 From: Muhammad Abdullah Azam Khan Date: Fri, 26 Nov 2021 20:54:37 +0400 Subject: [PATCH 10/63] Indentation and Formatting Changes --- .../baeldung/unsupportedmediatype/User.java | 10 ++--- .../ApplicationUnitTest.java | 38 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java index f9c3d9c191..765149dad5 100644 --- a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java +++ b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java @@ -55,11 +55,11 @@ public class User implements Serializable { @Override public String toString() { return "User{" - + "id=" + id - + ", name='" + name + '\'' - + ", age=" + age - + ", address='" + address + '\'' - + '}'; + + "id=" + id + + ", name='" + name + '\'' + + ", age=" + age + + ", address='" + address + '\'' + + '}'; } diff --git a/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java b/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java index 95de780106..498ad9d537 100644 --- a/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java +++ b/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java @@ -20,39 +20,39 @@ public class ApplicationUnitTest { @Test public void JsonTestCase() throws Exception { mockMvc.perform(MockMvcRequestBuilders.post("/user/") - .contentType(MediaType.APPLICATION_JSON_VALUE) - .content( "{\n" - + " \"name\": \"Andy\",\n" - + " \"age\": 1,\n" - + " \"address\": \"Hello world\"\n" - + "}")) - .andExpect(status().isOk()); + .contentType(MediaType.APPLICATION_JSON_VALUE) + .content( "{\n" + + " \"name\": \"Andy\",\n" + + " \"age\": 1,\n" + + " \"address\": \"Hello world\"\n" + + "}")) + .andExpect(status().isOk()); } @Test public void JsonFailTestCase() throws Exception {// Because no content-type added mockMvc.perform(MockMvcRequestBuilders.post("/user/") - .content( "{\n" - + " \"name\": \"Andy\",\n" - + " \"age\": 1,\n" - + " \"address\": \"Hello world\"\n" - + "}")) - .andExpect(status().isUnsupportedMediaType()); + .content( "{\n" + + " \"name\": \"Andy\",\n" + + " \"age\": 1,\n" + + " \"address\": \"Hello world\"\n" + + "}")) + .andExpect(status().isUnsupportedMediaType()); } @Test public void XmlTestCase() throws Exception { mockMvc.perform(MockMvcRequestBuilders.post("/user/") - .contentType(MediaType.APPLICATION_XML_VALUE) - .content("Andy1
Hello world
")) - .andExpect(status().isOk()); + .contentType(MediaType.APPLICATION_XML_VALUE) + .content("Andy1
Hello world
")) + .andExpect(status().isOk()); } @Test public void StringFailTestCase() throws Exception { // Because content-type is not supported mockMvc.perform(MockMvcRequestBuilders.post("/user/") - .contentType(MediaType.TEXT_PLAIN_VALUE) - .content("Andy1
Hello world
")) - .andExpect(status().isUnsupportedMediaType()); + .contentType(MediaType.TEXT_PLAIN_VALUE) + .content("Andy1
Hello world
")) + .andExpect(status().isUnsupportedMediaType()); } } From 4e211b64d74bd85adadc865a70d95d33624fd89f Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Fri, 26 Nov 2021 22:15:04 +0000 Subject: [PATCH 11/63] [JAVA-8353] Wait longer for the threads to finish --- .../IllegalMonitorStateExceptionUnitTest.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/illegalmonitorstate/IllegalMonitorStateExceptionUnitTest.java b/core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/illegalmonitorstate/IllegalMonitorStateExceptionUnitTest.java index bef90e671f..857ab02c13 100644 --- a/core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/illegalmonitorstate/IllegalMonitorStateExceptionUnitTest.java +++ b/core-java-modules/core-java-exceptions-3/src/test/java/com/baeldung/exceptions/illegalmonitorstate/IllegalMonitorStateExceptionUnitTest.java @@ -1,11 +1,12 @@ package com.baeldung.exceptions.illegalmonitorstate; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + import org.junit.jupiter.api.Test; -import java.time.Duration; - -import static org.junit.jupiter.api.Assertions.*; - public class IllegalMonitorStateExceptionUnitTest { @Test @@ -20,11 +21,11 @@ public class IllegalMonitorStateExceptionUnitTest { Thread senderThread = new Thread(sender, "sender-thread"); senderThread.start(); - senderThread.join(1000); - receiverThread.join(1000); + // we need to wait for the sender and receiver threads to finish + senderThread.join(10_000); + receiverThread.join(10_000); - // we need to wait for enough time so that sender has had a chance to send the data - assertTimeout(Duration.ofSeconds(10), () -> assertEquals("test", receiver.getMessage())); + assertEquals("test", receiver.getMessage()); assertFalse(sender.hasIllegalMonitorStateExceptionOccurred()); assertFalse(receiver.hasIllegalMonitorStateExceptionOccurred()); } From 3f28be96dbc4fc2c9568e3a7e89cbbc81514fe33 Mon Sep 17 00:00:00 2001 From: ACHRAF TAITAI <43656331+achraftt@users.noreply.github.com> Date: Sat, 27 Nov 2021 17:59:29 +0100 Subject: [PATCH 12/63] BAEL-5147 : convert ByteBuffer to String (#11504) * BAEL-5147: convert ByteBuffer to String * Update README.md --- .../core-java-string-conversions-2/README.md | 1 + .../ByteArrayToStringUnitTest.java | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java diff --git a/core-java-modules/core-java-string-conversions-2/README.md b/core-java-modules/core-java-string-conversions-2/README.md index 46eb783a27..22f4cd89a1 100644 --- a/core-java-modules/core-java-string-conversions-2/README.md +++ b/core-java-modules/core-java-string-conversions-2/README.md @@ -9,4 +9,5 @@ This module contains articles about string conversions from/to another type. - [Converting String to BigDecimal in Java](https://www.baeldung.com/java-string-to-bigdecimal) - [Converting String to BigInteger in Java](https://www.baeldung.com/java-string-to-biginteger) - [Convert a String to Camel Case](https://www.baeldung.com/java-string-to-camel-case) +- [Convert a ByteBuffer to String] - More articles: [[<-- prev]](/core-java-string-conversions) diff --git a/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java b/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java new file mode 100644 index 0000000000..c498921d9a --- /dev/null +++ b/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.bytebuffertostring; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +import org.junit.Test; + +public class ByteArrayToStringUnitTest { + private static Charset charset = StandardCharsets.UTF_8; + private static final String content = "baeldung"; + + @Test + public void convertUsingNewStringFromBufferArray_thenOK() { + // Allocate a ByteBuffer + ByteBuffer byteBuffer = ByteBuffer.wrap(content.getBytes()); + if (byteBuffer.hasArray()) { + String newContent = new String(byteBuffer.array(), charset); + assertEquals(content, newContent); + } + } + + @Test + public void convertUsingNewStringFromByteBufferGetBytes_thenOK() { + // Allocate a ByteBuffer + ByteBuffer byteBuffer = ByteBuffer.wrap(content.getBytes()); + byte[] bytes = new byte[byteBuffer.remaining()]; + byteBuffer.get(bytes); + String newContent = new String(bytes, charset); + assertEquals(content, newContent); + } + + @Test + public void convertUsingCharsetDecode_thenOK() { + // Allocate a ByteBuffer + ByteBuffer byteBuffer = ByteBuffer.wrap(content.getBytes()); + String newContent = charset.decode(byteBuffer) + .toString(); + assertEquals(content, newContent); + } + +} From 7b564fe3ef4a9e309b34646215e1c086ed883537 Mon Sep 17 00:00:00 2001 From: Azhwani <13301425+azhwani@users.noreply.github.com> Date: Sun, 28 Nov 2021 16:47:49 +0100 Subject: [PATCH 13/63] init commit (#11496) --- .../baeldung/regex/matcher/MatcherUnitTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/core-java-modules/core-java-regex/src/test/java/com/baeldung/regex/matcher/MatcherUnitTest.java b/core-java-modules/core-java-regex/src/test/java/com/baeldung/regex/matcher/MatcherUnitTest.java index 304b9f2f1d..7ec4a1ae58 100644 --- a/core-java-modules/core-java-regex/src/test/java/com/baeldung/regex/matcher/MatcherUnitTest.java +++ b/core-java-modules/core-java-regex/src/test/java/com/baeldung/regex/matcher/MatcherUnitTest.java @@ -11,6 +11,9 @@ import org.junit.jupiter.api.Test; public class MatcherUnitTest { + private static final String STRING_INPUT = "test+"; + private static final String REGEX = "\\+"; + @Test public void whenFindFourDigitWorks_thenCorrect() { Pattern stringPattern = Pattern.compile("\\d\\d\\d\\d"); @@ -60,4 +63,16 @@ public class MatcherUnitTest { assertTrue(m.matches());// matches will always return the same return } + @Test + public void whenUsingMatcher_thenReturnTrue() { + Pattern pattern = Pattern.compile(REGEX); + Matcher matcher = pattern.matcher(STRING_INPUT); + assertTrue(matcher.find()); + } + + @Test + public void whenUsingMatches_thenReturnFalse() { + assertFalse(Pattern.matches(REGEX, STRING_INPUT)); + } + } From 9461caeb278d32997871fa42a80d0ce3f8201a52 Mon Sep 17 00:00:00 2001 From: wugangca Date: Sun, 28 Nov 2021 08:51:13 -0700 Subject: [PATCH 14/63] BAEL-5205 Adding a column to an Excel file using Apache POI (#11491) * BAEL-5205 Adding a column to an Excel file using Apache POI * BAEL-5205 move the test xls file into the test folder Co-authored-by: Gang Wu --- apache-poi-2/.gitignore | 3 ++ apache-poi-2/pom.xml | 24 +++++++++++ .../poi/excel/newcolumn/ExcelColumn.java | 16 +++++++ .../excel/newcolumn/ExcelColumnUnitTest.java | 40 ++++++++++++++++++ .../src/test/resources/newColumnTest.xlsx | Bin 0 -> 3375 bytes 5 files changed, 83 insertions(+) create mode 100644 apache-poi-2/.gitignore create mode 100644 apache-poi-2/pom.xml create mode 100644 apache-poi-2/src/main/java/com/baeldung/poi/excel/newcolumn/ExcelColumn.java create mode 100644 apache-poi-2/src/test/java/com/baeldung/poi/excel/newcolumn/ExcelColumnUnitTest.java create mode 100644 apache-poi-2/src/test/resources/newColumnTest.xlsx diff --git a/apache-poi-2/.gitignore b/apache-poi-2/.gitignore new file mode 100644 index 0000000000..9552c1e63d --- /dev/null +++ b/apache-poi-2/.gitignore @@ -0,0 +1,3 @@ +*.docx +temp.xls +temp.xlsx diff --git a/apache-poi-2/pom.xml b/apache-poi-2/pom.xml new file mode 100644 index 0000000000..1cb6509457 --- /dev/null +++ b/apache-poi-2/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + apache-poi + 0.0.1-SNAPSHOT + apache-poi + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + org.apache.poi + poi-ooxml + 5.0.0 + + + + \ No newline at end of file diff --git a/apache-poi-2/src/main/java/com/baeldung/poi/excel/newcolumn/ExcelColumn.java b/apache-poi-2/src/main/java/com/baeldung/poi/excel/newcolumn/ExcelColumn.java new file mode 100644 index 0000000000..00ca24f6e8 --- /dev/null +++ b/apache-poi-2/src/main/java/com/baeldung/poi/excel/newcolumn/ExcelColumn.java @@ -0,0 +1,16 @@ +package com.baeldung.poi.excel.newcolumn; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + + +public class ExcelColumn { + + public void addColumn(Sheet sheet, CellType cellType) { + for (Row currentRow : sheet) { + currentRow.createCell(currentRow.getLastCellNum(), cellType); + } + } +} diff --git a/apache-poi-2/src/test/java/com/baeldung/poi/excel/newcolumn/ExcelColumnUnitTest.java b/apache-poi-2/src/test/java/com/baeldung/poi/excel/newcolumn/ExcelColumnUnitTest.java new file mode 100644 index 0000000000..9b991719b1 --- /dev/null +++ b/apache-poi-2/src/test/java/com/baeldung/poi/excel/newcolumn/ExcelColumnUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.poi.excel.newcolumn; + +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Paths; + +import static org.junit.Assert.assertEquals; + +public class ExcelColumnUnitTest { + private static final String FILE_NAME = "newColumnTest.xlsx"; + private String fileLocation; + + @Before + public void setup() throws URISyntaxException { + fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString(); + } + + @Test + public void givenExistingRows_whenAddNewColumn_thenRowColumnNumberIncreased() throws IOException { + Workbook workbook = new XSSFWorkbook(fileLocation); + Sheet sheet = workbook.getSheetAt(0); + Row row = sheet.getRow(0); + assertEquals(5, row.getLastCellNum()); + + ExcelColumn excelColumn = new ExcelColumn(); + excelColumn.addColumn(sheet, CellType.STRING); + assertEquals(6, row.getLastCellNum()); + + workbook.close(); + } + +} \ No newline at end of file diff --git a/apache-poi-2/src/test/resources/newColumnTest.xlsx b/apache-poi-2/src/test/resources/newColumnTest.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..54e8734d58f7e14ba90c1bd65417142c460db369 GIT binary patch literal 3375 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 literal 0 HcmV?d00001 From 9ab2a1ab0f5e5845f43f76b0d6473c85fe9916a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matea=20Pej=C4=8Dinovi=C4=87?= Date: Sun, 28 Nov 2021 18:03:38 +0100 Subject: [PATCH 15/63] BAEL-5253 moving the tests to other module --- .../core-java-string-algorithms-3/pom.xml | 9 ++- .../StringFirstCharacterUppercase.java | 2 +- .../controller/UserController.java | 63 ------------------- .../baeldung/swagger2pdf/objects/User.java | 12 ---- 4 files changed, 8 insertions(+), 78 deletions(-) rename core-java-modules/{core-java-string-algorithms-2 => core-java-string-algorithms-3}/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java (100%) delete mode 100644 spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/controller/UserController.java delete mode 100644 spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/objects/User.java diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index 6700e9ba95..180d75cc61 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -24,6 +24,11 @@ commons-validator ${validator.version}
+ + com.google.guava + guava + ${guava.version} + @@ -49,8 +54,8 @@ - 28.1-jre + 31.0.1-jre 1.7 - \ No newline at end of file + diff --git a/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java similarity index 100% rename from core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java rename to core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java index 0d9d3b6431..f9edd005dc 100644 --- a/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java +++ b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java @@ -1,9 +1,9 @@ package com.baeldung.isuppercase; -import com.google.common.base.Ascii; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; +import com.google.common.base.Ascii; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.matchesPattern; diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/controller/UserController.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/controller/UserController.java deleted file mode 100644 index 380bac6f8c..0000000000 --- a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/controller/UserController.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.baeldung.swagger2pdf.controller; - -import com.baeldung.swagger2pdf.objects.User; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.NonNull; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.*; - -import java.util.ArrayList; -import java.util.List; - -@Controller -@Api(value = "/api", description = "A controller for user management") -@RequestMapping("/user") -@ResponseStatus(HttpStatus.OK) -public class UserController { - - static List users; - - static { - users = new ArrayList<>(); - users.add(new User("Mark", "Thompson", 23)); - users.add(new User("Kate", "Jordan", 22)); - } - - @ApiOperation(value = "Retrieves all the users") - @RequestMapping(value = "/users", - method = RequestMethod.GET, - produces = MediaType.APPLICATION_JSON_VALUE) - public List getUsers() { - return users; - } - - @ApiOperation(value = "Retrieves a user based on first name") - @RequestMapping(value = "/user", - method = RequestMethod.GET, - produces = MediaType.APPLICATION_JSON_VALUE) - public User getUser(@NonNull @RequestParam String firstName) { - - if (firstName.isEmpty()) { - return null; - } - - return users.stream() - .filter(user -> user.getFirstName().equals(firstName)) - .findAny() - .orElse(null); - - } - - @ApiOperation(value = "Adds a user.") - @RequestMapping(value = "/user", - method = RequestMethod.POST, - produces = MediaType.APPLICATION_JSON_VALUE) - public List addUser(@NonNull @RequestBody User user) { - users.add(user); - return users; - } -} - diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/objects/User.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/objects/User.java deleted file mode 100644 index 8c59cb246a..0000000000 --- a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2pdf/objects/User.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.swagger2pdf.objects; - -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class User { - private String firstName; - private String lastName; - private int age; -} From f5b596784f1673ce21173063b0d5dc81f759b7c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matea=20Pej=C4=8Dinovi=C4=87?= Date: Sun, 28 Nov 2021 18:14:42 +0100 Subject: [PATCH 16/63] renaming the test class --- ...ppercase.java => StringFirstCharacterUppercaseUnitTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/{StringFirstCharacterUppercase.java => StringFirstCharacterUppercaseUnitTest.java} (94%) diff --git a/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java similarity index 94% rename from core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java rename to core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java index f9edd005dc..6803285ca2 100644 --- a/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java +++ b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java @@ -9,7 +9,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.matchesPattern; @TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class StringFirstCharacterUppercase { +public class StringFirstCharacterUppercaseUnitTest { @Test public void givenString_whenCheckingWithCharacterIsUpperCase_thenStringCapitalized() { From 28b7ea96c7229147deb7cf7046a5b69e5caeb371 Mon Sep 17 00:00:00 2001 From: Bhaskara Date: Mon, 29 Nov 2021 05:02:23 +0530 Subject: [PATCH 17/63] BAEL-4648: How to debug Websockets (#11469) * BAEL-4648: How to debug Websockets * Formatted the code * Incorporated comments from Kevin --- spring-websockets/pom.xml | 4 +- .../debugwebsockets/StockTicksController.java | 39 ++++++ .../StompClientSessionHandler.java | 31 +++++ .../debugwebsockets/StompWebSocketClient.java | 24 ++++ .../debugwebsockets/WebsocketApplication.java | 13 ++ .../WebsocketConfiguration.java | 25 ++++ .../WebSocketIntegrationTest.java | 114 ++++++++++++++++++ 7 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 spring-websockets/src/main/java/com/baeldung/debugwebsockets/StockTicksController.java create mode 100644 spring-websockets/src/main/java/com/baeldung/debugwebsockets/StompClientSessionHandler.java create mode 100644 spring-websockets/src/main/java/com/baeldung/debugwebsockets/StompWebSocketClient.java create mode 100644 spring-websockets/src/main/java/com/baeldung/debugwebsockets/WebsocketApplication.java create mode 100644 spring-websockets/src/main/java/com/baeldung/debugwebsockets/WebsocketConfiguration.java create mode 100644 spring-websockets/src/test/java/com/baeldung/debugwebsockets/WebSocketIntegrationTest.java diff --git a/spring-websockets/pom.xml b/spring-websockets/pom.xml index a28ef8749a..28c875d50d 100644 --- a/spring-websockets/pom.xml +++ b/spring-websockets/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-websockets spring-websockets diff --git a/spring-websockets/src/main/java/com/baeldung/debugwebsockets/StockTicksController.java b/spring-websockets/src/main/java/com/baeldung/debugwebsockets/StockTicksController.java new file mode 100644 index 0000000000..0942657c33 --- /dev/null +++ b/spring-websockets/src/main/java/com/baeldung/debugwebsockets/StockTicksController.java @@ -0,0 +1,39 @@ +package com.baeldung.debugwebsockets; + +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Controller; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; + +@Controller +public class StockTicksController { + private final SimpMessagingTemplate simpMessagingTemplate; + + public StockTicksController(SimpMessagingTemplate simpMessagingTemplate) { + this.simpMessagingTemplate = simpMessagingTemplate; + } + + @Scheduled(fixedRate = 3000) + public void sendTicks() { + simpMessagingTemplate.convertAndSend("/topic/ticks", getStockTicks()); + } + + private Map getStockTicks() { + Map ticks = new HashMap<>(); + ticks.put("AAPL", getRandomTick()); + ticks.put("GOOGL", getRandomTick()); + ticks.put("MSFT", getRandomTick()); + ticks.put("TSLA", getRandomTick()); + ticks.put("AMZN", getRandomTick()); + ticks.put("HPE", getRandomTick()); + + return ticks; + } + + private int getRandomTick() { + return ThreadLocalRandom.current().nextInt(-100, 100 + 1); + } +} \ No newline at end of file diff --git a/spring-websockets/src/main/java/com/baeldung/debugwebsockets/StompClientSessionHandler.java b/spring-websockets/src/main/java/com/baeldung/debugwebsockets/StompClientSessionHandler.java new file mode 100644 index 0000000000..535be79cee --- /dev/null +++ b/spring-websockets/src/main/java/com/baeldung/debugwebsockets/StompClientSessionHandler.java @@ -0,0 +1,31 @@ +package com.baeldung.debugwebsockets; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.messaging.simp.stomp.StompHeaders; +import org.springframework.messaging.simp.stomp.StompSession; +import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter; + +import java.lang.reflect.Type; +import java.util.Map; + +public class StompClientSessionHandler extends StompSessionHandlerAdapter { + private static final Logger logger = LoggerFactory.getLogger("StompClientSessionHandler"); + + @Override + public void afterConnected(StompSession session, StompHeaders connectedHeaders) { + logger.info("New session established. Session Id -> {}", session.getSessionId()); + session.subscribe("/topic/ticks", this); + logger.info("Subscribed to topic: /topic/ticks"); + } + + @Override + public void handleFrame(StompHeaders headers, Object payload) { + logger.info("Payload -> {}", payload); + } + + @Override + public Type getPayloadType(StompHeaders headers) { + return Map.class; + } +} diff --git a/spring-websockets/src/main/java/com/baeldung/debugwebsockets/StompWebSocketClient.java b/spring-websockets/src/main/java/com/baeldung/debugwebsockets/StompWebSocketClient.java new file mode 100644 index 0000000000..0cbe32bf65 --- /dev/null +++ b/spring-websockets/src/main/java/com/baeldung/debugwebsockets/StompWebSocketClient.java @@ -0,0 +1,24 @@ +package com.baeldung.debugwebsockets; + +import org.springframework.messaging.converter.MappingJackson2MessageConverter; +import org.springframework.messaging.simp.stomp.StompSessionHandler; +import org.springframework.web.socket.client.WebSocketClient; +import org.springframework.web.socket.client.standard.StandardWebSocketClient; +import org.springframework.web.socket.messaging.WebSocketStompClient; + +import java.util.Scanner; + +public class StompWebSocketClient { + + private static final String URL = "ws://localhost:8080/stock-ticks/websocket"; + + public static void main(String[] args) { + WebSocketClient client = new StandardWebSocketClient(); + WebSocketStompClient stompClient = new WebSocketStompClient(client); + stompClient.setMessageConverter(new MappingJackson2MessageConverter()); + StompSessionHandler sessionHandler = new StompClientSessionHandler(); + stompClient.connect(URL, sessionHandler); + + new Scanner(System.in).nextLine(); + } +} diff --git a/spring-websockets/src/main/java/com/baeldung/debugwebsockets/WebsocketApplication.java b/spring-websockets/src/main/java/com/baeldung/debugwebsockets/WebsocketApplication.java new file mode 100644 index 0000000000..1d0d6950d3 --- /dev/null +++ b/spring-websockets/src/main/java/com/baeldung/debugwebsockets/WebsocketApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.debugwebsockets; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class WebsocketApplication { + + public static void main(String[] args) { + SpringApplication.run(WebsocketApplication.class, args); + } + +} diff --git a/spring-websockets/src/main/java/com/baeldung/debugwebsockets/WebsocketConfiguration.java b/spring-websockets/src/main/java/com/baeldung/debugwebsockets/WebsocketConfiguration.java new file mode 100644 index 0000000000..3735e7359b --- /dev/null +++ b/spring-websockets/src/main/java/com/baeldung/debugwebsockets/WebsocketConfiguration.java @@ -0,0 +1,25 @@ +package com.baeldung.debugwebsockets; + +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +@Configuration +@EnableWebSocketMessageBroker +@EnableScheduling +public class WebsocketConfiguration implements WebSocketMessageBrokerConfigurer { + @Override + public void configureMessageBroker(MessageBrokerRegistry config) { + config.enableSimpleBroker("/topic"); + config.setApplicationDestinationPrefixes("/app"); + } + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/stock-ticks").setAllowedOriginPatterns("*").withSockJS(); + } + +} diff --git a/spring-websockets/src/test/java/com/baeldung/debugwebsockets/WebSocketIntegrationTest.java b/spring-websockets/src/test/java/com/baeldung/debugwebsockets/WebSocketIntegrationTest.java new file mode 100644 index 0000000000..bdc283b9e4 --- /dev/null +++ b/spring-websockets/src/test/java/com/baeldung/debugwebsockets/WebSocketIntegrationTest.java @@ -0,0 +1,114 @@ +package com.baeldung.debugwebsockets; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.messaging.converter.MappingJackson2MessageConverter; +import org.springframework.messaging.simp.stomp.StompCommand; +import org.springframework.messaging.simp.stomp.StompFrameHandler; +import org.springframework.messaging.simp.stomp.StompHeaders; +import org.springframework.messaging.simp.stomp.StompSession; +import org.springframework.messaging.simp.stomp.StompSessionHandler; +import org.springframework.web.socket.client.WebSocketClient; +import org.springframework.web.socket.client.standard.StandardWebSocketClient; +import org.springframework.web.socket.messaging.WebSocketStompClient; + +import java.lang.reflect.Type; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +/** + * This should be part of integration test suite. + * The test starts the server and then connects to the WebSocket. Then verifies if the messages are received from the + * WebSocket. + * This test is inspired from: https://github.com/spring-guides/gs-messaging-stomp-websocket/blob/main/complete/src/test/java/com/example/messagingstompwebsocket/GreetingIntegrationTests.java + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class WebSocketIntegrationTest{ + WebSocketClient client; + WebSocketStompClient stompClient; + @LocalServerPort + private int port; + private static final Logger logger= LoggerFactory.getLogger(WebSocketIntegrationTest.class); + + @BeforeEach + public void setup() { + logger.info("Setting up the tests ..."); + client = new StandardWebSocketClient(); + stompClient = new WebSocketStompClient(client); + stompClient.setMessageConverter(new MappingJackson2MessageConverter()); + } + + @Test + void givenWebSocket_whenMessage_thenVerifyMessage() throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + final AtomicReference failure = new AtomicReference<>(); + StompSessionHandler sessionHandler = new StompSessionHandler() { + @Override + public Type getPayloadType(StompHeaders headers) { + return null; + } + + @Override + public void handleFrame(StompHeaders headers, Object payload) { + } + + @Override + public void afterConnected(StompSession session, StompHeaders connectedHeaders) { + logger.info("Connected to the WebSocket ..."); + session.subscribe("/topic/ticks", new StompFrameHandler() { + @Override + public Type getPayloadType(StompHeaders headers) { + return Map.class; + } + + @Override + public void handleFrame(StompHeaders headers, Object payload) { + try { + + assertThat(payload).isNotNull(); + assertThat(payload).isInstanceOf(Map.class); + + @SuppressWarnings("unchecked") + Map map = (Map) payload; + + assertThat(map).containsKey("HPE"); + assertThat(map.get("HPE")).isInstanceOf(Integer.class); + } catch (Throwable t) { + failure.set(t); + logger.error("There is an exception ", t); + } finally { + session.disconnect(); + latch.countDown(); + } + + } + }); + } + + @Override + public void handleException(StompSession session, StompCommand command, StompHeaders headers, byte[] payload, Throwable exception) { + } + + @Override + public void handleTransportError(StompSession session, Throwable exception) { + } + }; + stompClient.connect("ws://localhost:{port}/stock-ticks/websocket", sessionHandler, this.port); + if (latch.await(20, TimeUnit.SECONDS)) { + if (failure.get() != null) { + fail("Assertion Failed", failure.get()); + } + } else { + fail("Could not receive the message on time"); + } + } +} From 0c7a0bcb8db0e851f8ac22e7b2680d38381e54aa Mon Sep 17 00:00:00 2001 From: Teica Date: Mon, 29 Nov 2021 21:02:40 +0100 Subject: [PATCH 18/63] Update pom.xml --- .../spring-boot-swagger/pom.xml | 113 ------------------ 1 file changed, 113 deletions(-) diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml index 41f41a92b9..d6b62bce3c 100644 --- a/spring-boot-modules/spring-boot-swagger/pom.xml +++ b/spring-boot-modules/spring-boot-swagger/pom.xml @@ -25,26 +25,6 @@ springfox-boot-starter ${springfox.version} - - io.springfox - springfox-swagger2 - ${springfox-swagger2.version} - - - io.swagger.core.v3 - swagger-jaxrs2 - ${swagger-jaxrs2.version} - - - javax.ws.rs - javax.ws.rs-api - ${javax.ws.rs-api.version} - - - org.projectlombok - lombok - ${lombok.version} - @@ -53,104 +33,11 @@ org.springframework.boot spring-boot-maven-plugin - - - - com.github.kongchen - swagger-maven-plugin - 3.1.3 - - - - false - com.baeldung.swagger2pdf.controller.UserController - /api - - DEMO REST API - A simple DEMO project for REST API documentation - v1 - - ${project.build.directory}/api - true - - - - - - package - - generate - - - - - - io.github.robwin - swagger2markup-maven-plugin - 0.9.3 - - ${project.build.directory}/api - ${generated.asciidoc.directory} - asciidoc - - - - package - - process-swagger - - - - - - org.asciidoctor - asciidoctor-maven-plugin - 2.2.1 - - - - org.asciidoctor - asciidoctorj-pdf - 1.6.0 - - - - ${project.build.outputDirectory}/../asciidoc - overview.adoc - - book - left - 2 - ${generated.asciidoc.directory} - - - - - - asciidoc-to-pdf - package - - process-asciidoc - - - pdf - ${project.build.outputDirectory}/api/pdf - - - - - - 3.0.0 - ${project.build.outputDirectory}/asciidoc - 2.10.5 - 2.1.11 - 2.1 - 1.18.22 From d9b41d973700f64d3752c84393a02f211b0262b0 Mon Sep 17 00:00:00 2001 From: Teica Date: Mon, 29 Nov 2021 21:03:28 +0100 Subject: [PATCH 19/63] Update pom.xml From 3cf650f4ebeb9101b6b3085bd02beedb61ea7f7c Mon Sep 17 00:00:00 2001 From: Teica Date: Mon, 29 Nov 2021 21:04:08 +0100 Subject: [PATCH 20/63] Update pom.xml From c215f719592286fbe8ab4b702e0013dcd987a41c Mon Sep 17 00:00:00 2001 From: Teica Date: Mon, 29 Nov 2021 21:05:29 +0100 Subject: [PATCH 21/63] Delete pom.xml --- .../spring-boot-swagger/pom.xml | 43 ------------------- 1 file changed, 43 deletions(-) delete mode 100644 spring-boot-modules/spring-boot-swagger/pom.xml diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml deleted file mode 100644 index d6b62bce3c..0000000000 --- a/spring-boot-modules/spring-boot-swagger/pom.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - 4.0.0 - spring-boot-swagger - 0.1.0-SNAPSHOT - spring-boot-swagger - jar - Module For Spring Boot Swagger - - - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT - - - - - org.springframework.boot - spring-boot-starter-web - - - io.springfox - springfox-boot-starter - ${springfox.version} - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - 3.0.0 - - - From 3bcedb6eda3bf64e592d5e5a7c8762b57e72c76a Mon Sep 17 00:00:00 2001 From: Teica Date: Mon, 29 Nov 2021 21:07:36 +0100 Subject: [PATCH 22/63] Create pom.xml --- .../spring-boot-swagger/pom.xml | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 spring-boot-modules/spring-boot-swagger/pom.xml diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml new file mode 100644 index 0000000000..d6b62bce3c --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + spring-boot-swagger + 0.1.0-SNAPSHOT + spring-boot-swagger + jar + Module For Spring Boot Swagger + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + io.springfox + springfox-boot-starter + ${springfox.version} + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + 3.0.0 + + + From 719c4e4e0bd230f26e28d13e8b21c9002dc6cfe1 Mon Sep 17 00:00:00 2001 From: Teica Date: Tue, 30 Nov 2021 01:26:16 +0100 Subject: [PATCH 23/63] Feature bael 5253 (#11526) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * BAEL-5032 Swagger to PDF * BAEL-5032 added lombok as dependency * BAEL-5253 moving the tests to other module * renaming the test class * Update pom.xml * Update pom.xml * Update pom.xml * Delete pom.xml * Create pom.xml Co-authored-by: Matea Pejčinović --- core-java-modules/core-java-string-algorithms-3/pom.xml | 9 +++++++-- .../StringFirstCharacterUppercaseUnitTest.java} | 4 ++-- spring-boot-modules/spring-boot-swagger/pom.xml | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) rename core-java-modules/{core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java => core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java} (94%) diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index 6700e9ba95..180d75cc61 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -24,6 +24,11 @@ commons-validator ${validator.version} + + com.google.guava + guava + ${guava.version} + @@ -49,8 +54,8 @@ - 28.1-jre + 31.0.1-jre 1.7 - \ No newline at end of file + diff --git a/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java similarity index 94% rename from core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java rename to core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java index 0d9d3b6431..6803285ca2 100644 --- a/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java +++ b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java @@ -1,15 +1,15 @@ package com.baeldung.isuppercase; -import com.google.common.base.Ascii; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; +import com.google.common.base.Ascii; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.matchesPattern; @TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class StringFirstCharacterUppercase { +public class StringFirstCharacterUppercaseUnitTest { @Test public void givenString_whenCheckingWithCharacterIsUpperCase_thenStringCapitalized() { diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml index 87ee5f04cb..d6b62bce3c 100644 --- a/spring-boot-modules/spring-boot-swagger/pom.xml +++ b/spring-boot-modules/spring-boot-swagger/pom.xml @@ -40,4 +40,4 @@ 3.0.0 - \ No newline at end of file + From 2026f9cae7043b5e8ec1a0f88722517593851da6 Mon Sep 17 00:00:00 2001 From: vaibhav007jain <72961247+vaibhav007jain@users.noreply.github.com> Date: Tue, 30 Nov 2021 08:51:17 +0530 Subject: [PATCH 24/63] BAEL-5228: Adding code for approaches to concatenating null string in java (#11464) * commited initial code for hexagonal architecture * Deleting to check in again * Deleing to check in again * Push first code for Hexagonal Architecture * final code with UT for JSON to Java conversion * removed hexagonal-architecture code from last commit * BEL-5071 updated README * BAEL-5071: Undo README changes and added a nested object in the JSON example. * BAEL-5071: fixed whitespace/indentation in JsonToJavaClassConversion.java * BAEL-5151: Added code for getting the first of a String * BAEL-5151: Renamed Unit Test * BAEL-5151: Moved the files from core-java-string-operations to core-java-string-operations-3 * BAEL-5151: Replaced tabs with white spaces. * BAEL-5228: Adding code for approaches to concatening null string in java * BAEL-5228: Moved file to correct folder and added a UT. * BAEL-5228: corrected import statements. * BAEL-5228: corrected last commit. * BAEL-5228: removed extra import. * BAEL-5228: renamed UT Co-authored-by: Vaibhav Jain --- .../concatenation/ConcatenatingNull.java | 86 +++++++++++++++++++ .../ConcatenatingNullUnitTest.java | 59 +++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/concatenation/ConcatenatingNull.java create mode 100644 core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/concatenation/ConcatenatingNullUnitTest.java diff --git a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/concatenation/ConcatenatingNull.java b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/concatenation/ConcatenatingNull.java new file mode 100644 index 0000000000..250a0d6b25 --- /dev/null +++ b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/concatenation/ConcatenatingNull.java @@ -0,0 +1,86 @@ +package com.baeldung.concatenation; + +import java.util.StringJoiner; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class ConcatenatingNull { + + public static void main(String[] args) { + String[] values = { "Java ", null, "", "is ", "great!" }; + + concatenateUsingPlusOperator(values); + concatenateUsingHelperMethod(values); + concatenateUsingStringBuilder(values); + concatenateUsingJoin(values); + concatenateUsingStringJoiner(values); + concatenateUsingCollectorsJoining(values); + concatenateUsingStringConcat(values); + } + + public static String concatenateUsingStringConcat(String[] values) { + String result = ""; + + for (String value : values) { + result = result.concat(getNonNullString(value)); + } + + return result; + } + + public static String concatenateUsingCollectorsJoining(String[] values) { + String result = Stream.of(values).filter(value -> null != value).collect(Collectors.joining("")); + + return result; + } + + public static String concatenateUsingStringJoiner(String[] values) { + StringJoiner result = new StringJoiner(""); + + for (String value : values) { + result = result.add(getNonNullString(value)); + } + + return result.toString(); + } + + public static String concatenateUsingJoin(String[] values) { + String result = String.join("", values); + + return result; + } + + public static String concatenateUsingStringBuilder(String[] values) { + StringBuilder result = new StringBuilder(); + + for (String value : values) { + result = result.append(getNonNullString(value)); + } + + return result.toString(); + } + + public static String concatenateUsingHelperMethod(String[] values) { + String result = ""; + + for (String value : values) { + result = result + getNonNullString(value); + } + + return result; + } + + public static String concatenateUsingPlusOperator(String[] values) { + String result = ""; + + for (String value : values) { + result = result + (value == null ? "" : value); + } + + return result; + } + + private static String getNonNullString(String value) { + return value == null ? "" : value; + } +} diff --git a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/concatenation/ConcatenatingNullUnitTest.java b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/concatenation/ConcatenatingNullUnitTest.java new file mode 100644 index 0000000000..20e5f6ad7d --- /dev/null +++ b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/concatenation/ConcatenatingNullUnitTest.java @@ -0,0 +1,59 @@ +package com.baeldung.concatenation; + +import static com.baeldung.concatenation.ConcatenatingNull.concatenateUsingCollectorsJoining; +import static com.baeldung.concatenation.ConcatenatingNull.concatenateUsingHelperMethod; +import static com.baeldung.concatenation.ConcatenatingNull.concatenateUsingJoin; +import static com.baeldung.concatenation.ConcatenatingNull.concatenateUsingPlusOperator; +import static com.baeldung.concatenation.ConcatenatingNull.concatenateUsingStringBuilder; +import static com.baeldung.concatenation.ConcatenatingNull.concatenateUsingStringConcat; +import static com.baeldung.concatenation.ConcatenatingNull.concatenateUsingStringJoiner; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class ConcatenatingNullUnitTest { + + String[] values = { "Java ", null, "", "is ", "great!" }; + + @Test + public void givenStringElementsWithNull_whenConcatenatedUsingPlus_thenNullIsIgnored() { + String result = concatenateUsingPlusOperator(values); + assertEquals("Java is great!", result); + } + + @Test + public void givenStringElementsWithNull_whenConcatenatedUsingHelperMethod_thenNullIsIgnored() { + String result = concatenateUsingHelperMethod(values); + assertEquals("Java is great!", result); + } + + @Test + public void givenStringElementsWithNull_whenConcatenatedUsingStringBuilder_thenNullIsIgnored() { + String result = concatenateUsingStringBuilder(values); + assertEquals("Java is great!", result); + } + + @Test + public void givenStringElementsWithNull_whenConcatenatedUsingJoin_thenNullIsNotIgnored() { + String result = concatenateUsingJoin(values); + assertEquals("Java nullis great!", result); + } + + @Test + public void givenStringElementsWithNull_whenConcatenatedUsingStringJoiner_thenNullIsIgnored() { + String result = concatenateUsingStringJoiner(values); + assertEquals("Java is great!", result); + } + + @Test + public void givenStringElementsWithNull_whenConcatenatedUsingCollectorsJoining_thenNullIsIgnored() { + String result = concatenateUsingCollectorsJoining(values); + assertEquals("Java is great!", result); + } + + @Test + public void givenStringElementsWithNull_whenConcatenatedUsingStringConcat_thenNullIsIgnored() { + String result = concatenateUsingStringConcat(values); + assertEquals("Java is great!", result); + } +} From 318df3fb842e1089707426e5f3115f7e6d5da40e Mon Sep 17 00:00:00 2001 From: chaos2418 <> Date: Tue, 30 Nov 2021 09:06:22 +0530 Subject: [PATCH 25/63] JAVA-8735: fix logging related integration tests --- logging-modules/logback/pom.xml | 36 ++++++++++++++++++++++++++++++ spring-5-reactive-2/pom.xml | 38 +++++++++++++++++++++++++++++++- spring-5-reactive-client/pom.xml | 38 +++++++++++++++++++++++++++++++- 3 files changed, 110 insertions(+), 2 deletions(-) diff --git a/logging-modules/logback/pom.xml b/logging-modules/logback/pom.xml index 48bb37b881..b4ee42367f 100644 --- a/logging-modules/logback/pom.xml +++ b/logging-modules/logback/pom.xml @@ -74,4 +74,40 @@ 1.1.1 + + + integration-lite-first + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.basedir}/src/test/resources/logback-test.xml + + + + + + + + integration-lite-second + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.basedir}/src/test/resources/logback-test.xml + + + + + + + \ No newline at end of file diff --git a/spring-5-reactive-2/pom.xml b/spring-5-reactive-2/pom.xml index 0758365932..e48d42a863 100644 --- a/spring-5-reactive-2/pom.xml +++ b/spring-5-reactive-2/pom.xml @@ -75,9 +75,45 @@ + + + integration-lite-first + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.basedir}/src/test/resources/logback-test.xml + + + + + + + + integration-lite-second + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.basedir}/src/test/resources/logback-test.xml + + + + + + + + 1.0.1.RELEASE 2.24.0 - \ No newline at end of file diff --git a/spring-5-reactive-client/pom.xml b/spring-5-reactive-client/pom.xml index 136f31b49e..4502059ed3 100644 --- a/spring-5-reactive-client/pom.xml +++ b/spring-5-reactive-client/pom.xml @@ -148,6 +148,43 @@ + + + integration-lite-first + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.basedir}/src/test/resources/logback-test.xml + + + + + + + + integration-lite-second + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.basedir}/src/test/resources/logback-test.xml + + + + + + + + 1.0.1.RELEASE 1.1.3 @@ -157,5 +194,4 @@ 1.1.6 4.0.1 - \ No newline at end of file From 696b754971fe8d25fde5f31687e77efac873caa0 Mon Sep 17 00:00:00 2001 From: KevinGilmore Date: Mon, 29 Nov 2021 22:19:32 -0600 Subject: [PATCH 26/63] Add and update README files (#11530) --- apache-poi-2/README.md | 8 ++++++++ apache-poi/README.md | 1 + 2 files changed, 9 insertions(+) create mode 100644 apache-poi-2/README.md diff --git a/apache-poi-2/README.md b/apache-poi-2/README.md new file mode 100644 index 0000000000..69aabf4616 --- /dev/null +++ b/apache-poi-2/README.md @@ -0,0 +1,8 @@ +## Apache POI + +This module contains articles about Apache POI + +### Relevant Articles: + +- [Adding a Column to an Excel Sheet Using Apache POI](https://www.baeldung.com/java-excel-add-column) +- More articles: [[<-- prev]](/apache-poi) diff --git a/apache-poi/README.md b/apache-poi/README.md index d3d60358c5..6d5b80b03a 100644 --- a/apache-poi/README.md +++ b/apache-poi/README.md @@ -15,3 +15,4 @@ This module contains articles about Apache POI - [Multiline Text in Excel Cell Using Apache POI](https://www.baeldung.com/apache-poi-write-multiline-text) - [Set Background Color of a Cell with Apache POI](https://www.baeldung.com/apache-poi-background-color) - [Add Borders to Excel Cells With Apache POI](https://www.baeldung.com/apache-poi-add-borders) +- More articles: [[next -->]](/apache-poi-2) From 052eb565bc2cc7e0413afe60377a88db70bda085 Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Wed, 1 Dec 2021 01:17:36 +0100 Subject: [PATCH 27/63] Java Hashmap with different value types (#11495) * Java Hashmap with different value types * some fixes according to review comments * convert liveTest -> unitTest * convert liveTest -> unitTest --- .../mulipletypesinmap/DynamicTypeValue.java | 5 ++ .../mulipletypesinmap/InstantTypeValue.java | 24 ++++++ .../mulipletypesinmap/IntArrayTypeValue.java | 20 +++++ .../mulipletypesinmap/IntegerTypeValue.java | 17 +++++ .../MultipleTypesInMapUnitTest.java | 75 +++++++++++++++++++ 5 files changed, 141 insertions(+) create mode 100644 core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/DynamicTypeValue.java create mode 100644 core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/InstantTypeValue.java create mode 100644 core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/IntArrayTypeValue.java create mode 100644 core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/IntegerTypeValue.java create mode 100644 core-java-modules/core-java-collections-4/src/test/java/com/baeldung/multipletypesinmap/MultipleTypesInMapUnitTest.java diff --git a/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/DynamicTypeValue.java b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/DynamicTypeValue.java new file mode 100644 index 0000000000..4c9ed89f63 --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/DynamicTypeValue.java @@ -0,0 +1,5 @@ +package com.baeldung.collections.mulipletypesinmap; + +public interface DynamicTypeValue { + String valueDescription(); +} diff --git a/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/InstantTypeValue.java b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/InstantTypeValue.java new file mode 100644 index 0000000000..448e66d872 --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/InstantTypeValue.java @@ -0,0 +1,24 @@ +package com.baeldung.collections.mulipletypesinmap; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; + +public class InstantTypeValue implements DynamicTypeValue { + private static DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") + .withZone(ZoneId.systemDefault()); + private Instant value; + + public InstantTypeValue(Instant value) { + this.value = value; + } + + @Override + public String valueDescription() { + if (value == null) { + return "The value is null."; + } + return String.format("The value is an instant: %s", FORMATTER.format(value)); + } + +} diff --git a/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/IntArrayTypeValue.java b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/IntArrayTypeValue.java new file mode 100644 index 0000000000..290982183f --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/IntArrayTypeValue.java @@ -0,0 +1,20 @@ +package com.baeldung.collections.mulipletypesinmap; + +import java.util.Arrays; + +public class IntArrayTypeValue implements DynamicTypeValue { + private int[] value; + + public IntArrayTypeValue(int[] value) { + this.value = value; + } + + @Override + public String valueDescription() { + if (value == null) { + return "The value is null."; + } + return String.format("The value is an array of %d integers: %s", value.length, Arrays.toString(value)); + } + +} diff --git a/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/IntegerTypeValue.java b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/IntegerTypeValue.java new file mode 100644 index 0000000000..463b06f768 --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/mulipletypesinmap/IntegerTypeValue.java @@ -0,0 +1,17 @@ +package com.baeldung.collections.mulipletypesinmap; + +public class IntegerTypeValue implements DynamicTypeValue { + private Integer value; + + public IntegerTypeValue(Integer value) { + this.value = value; + } + + @Override + public String valueDescription() { + if(value == null){ + return "The value is null."; + } + return String.format("The value is a %s integer: %d", value > 0 ? "positive" : "negative", value); + } +} diff --git a/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/multipletypesinmap/MultipleTypesInMapUnitTest.java b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/multipletypesinmap/MultipleTypesInMapUnitTest.java new file mode 100644 index 0000000000..87ea310ab0 --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/multipletypesinmap/MultipleTypesInMapUnitTest.java @@ -0,0 +1,75 @@ +package com.baeldung.multipletypesinmap; + +import com.baeldung.collections.mulipletypesinmap.DynamicTypeValue; +import com.baeldung.collections.mulipletypesinmap.InstantTypeValue; +import com.baeldung.collections.mulipletypesinmap.IntArrayTypeValue; +import com.baeldung.collections.mulipletypesinmap.IntegerTypeValue; +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +class MultipleTypesInMapUnitTest { + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") + .withZone(ZoneId.systemDefault()); + + private static final Integer intValue = 777; + private static final int[] intArray = new int[]{2, 3, 5, 7, 11, 13}; + private static final Instant instant = Instant.now(); + + private static final String KEY_INT = "E1 (Integer)"; + private static final String KEY_INT_ARRAY = "E2 (IntArray)"; + private static final String KEY_INSTANT = "E3 (Instant)"; + + @Test + void givenThreeTypes_whenUsingRawMap_thenPrintDescription() { + Map rawMap = new HashMap<>(); + rawMap.put(KEY_INT, intValue); + rawMap.put(KEY_INT_ARRAY, intArray); + rawMap.put(KEY_INSTANT, instant); + + rawMap.forEach((k, v) -> { + if (v instanceof Integer) { + Integer theV = (Integer) v; + String desc = String.format("The value is a %s integer: %d", theV > 0 ? "positive" : "negative", theV); + System.out.println(k + " -> " + desc); + assertThat(k).isEqualTo(KEY_INT); + assertThat(desc).isEqualTo("The value is a positive integer: 777"); + } else if (v instanceof int[]) { + int[] theV = (int[]) v; + String desc = String.format("The value is an array of %d integers: %s", theV.length, Arrays.toString(theV)); + System.out.println(k + " -> " + desc); + assertThat(k).isEqualTo(KEY_INT_ARRAY); + assertThat(desc).isEqualTo("The value is an array of 6 integers: [2, 3, 5, 7, 11, 13]"); + } else if (v instanceof Instant) { + Instant theV = (Instant) v; + String desc = String.format("The value is an instant: %s", FORMATTER.format(theV)); + System.out.println(k + " -> " + desc); + assertThat(k).isEqualTo(KEY_INSTANT); + assertThat(desc).matches("^The value is an instant: \\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}"); + } else { + throw new IllegalStateException("Unknown Type found."); + } + }); + } + + @Test + void givenThreeTypes_whenUsingAnInterface_thenPrintDescription() { + Map theMap = new HashMap<>(); + theMap.put(KEY_INT, new IntegerTypeValue(intValue)); + theMap.put(KEY_INT_ARRAY, new IntArrayTypeValue(intArray)); + theMap.put(KEY_INSTANT, new InstantTypeValue(instant)); + + theMap.forEach((k, v) -> System.out.println(k + " -> " + v.valueDescription())); + + assertThat(theMap.get(KEY_INT).valueDescription()).isEqualTo("The value is a positive integer: 777"); + assertThat(theMap.get(KEY_INT_ARRAY).valueDescription()).isEqualTo("The value is an array of 6 integers: [2, 3, 5, 7, 11, 13]"); + assertThat(theMap.get(KEY_INSTANT).valueDescription()).matches("^The value is an instant: \\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}"); + } +} From 879e60f8c0b8e89ce260815c36d03c613ed759ea Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 1 Dec 2021 16:16:25 +0800 Subject: [PATCH 28/63] Create README.md --- quarkus-jandex/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 quarkus-jandex/README.md diff --git a/quarkus-jandex/README.md b/quarkus-jandex/README.md new file mode 100644 index 0000000000..cca5fa7714 --- /dev/null +++ b/quarkus-jandex/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Quarkus Bean Discovery With Jandex Indexing](https://www.baeldung.com/quarkus-bean-discovery-index) From eb4276fe3bc31563c789feacff291100a76cf9d3 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 1 Dec 2021 16:18:13 +0800 Subject: [PATCH 29/63] Update README.md --- jackson-modules/jackson-conversions-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/jackson-modules/jackson-conversions-2/README.md b/jackson-modules/jackson-conversions-2/README.md index bddbb60bd7..fa3568652a 100644 --- a/jackson-modules/jackson-conversions-2/README.md +++ b/jackson-modules/jackson-conversions-2/README.md @@ -11,4 +11,5 @@ This module contains articles about Jackson conversions. - [Jackson Streaming API](https://www.baeldung.com/jackson-streaming-api) - [Jackson: java.util.LinkedHashMap cannot be cast to X](https://www.baeldung.com/jackson-linkedhashmap-cannot-be-cast) - [Deserialize Snake Case to Camel Case With Jackson](https://www.baeldung.com/jackson-deserialize-snake-to-camel-case) +- [Serialize and Deserialize Booleans as Integers With Jackson](https://www.baeldung.com/jackson-booleans-as-integers) - More articles: [[<-- prev]](../jackson-conversions) From a30954150377edc3931e37a3820131ef3e3ec866 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 1 Dec 2021 16:23:15 +0800 Subject: [PATCH 30/63] Update README.md --- spring-websockets/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-websockets/README.md b/spring-websockets/README.md index 7d69c21b78..88a97850b5 100644 --- a/spring-websockets/README.md +++ b/spring-websockets/README.md @@ -7,3 +7,4 @@ This module contains articles about Spring WebSockets. - [A Quick Example of Spring Websockets’ @SendToUser Annotation](https://www.baeldung.com/spring-websockets-sendtouser) - [Scheduled WebSocket Push with Spring Boot](https://www.baeldung.com/spring-boot-scheduled-websocket) - [Test WebSocket APIs With Postman](https://www.baeldung.com/postman-websocket-apis) +- [Debugging WebSockets](https://www.baeldung.com/debug-websockets) From f579ec9ed5acd8aa3bd62c4ac814a87bc622810e Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 1 Dec 2021 16:25:31 +0800 Subject: [PATCH 31/63] Update README.md --- spring-boot-rest-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-rest-2/README.md b/spring-boot-rest-2/README.md index 41270d58ea..985aa97a86 100644 --- a/spring-boot-rest-2/README.md +++ b/spring-boot-rest-2/README.md @@ -2,3 +2,4 @@ - [Get All Endpoints in Spring Boot](https://www.baeldung.com/spring-boot-get-all-endpoints) - [HTTP PUT vs. POST in REST API](https://www.baeldung.com/rest-http-put-vs-post) +- [415 Unsupported MediaType in Spring Application](https://www.baeldung.com/spring-415-unsupported-mediatype) From d6460d88b8774ec3eda1dd5d0ab648c1e68bae46 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 1 Dec 2021 16:31:04 +0800 Subject: [PATCH 32/63] Update README.md --- core-java-modules/core-java-networking-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-networking-3/README.md b/core-java-modules/core-java-networking-3/README.md index 0dc9ad9f70..82e75820ba 100644 --- a/core-java-modules/core-java-networking-3/README.md +++ b/core-java-modules/core-java-networking-3/README.md @@ -9,4 +9,5 @@ This module contains articles about networking in Java - [Connection Timeout vs. Read Timeout for Java Sockets](https://www.baeldung.com/java-socket-connection-read-timeout) - [Find Whether an IP Address Is in the Specified Range or Not in Java](https://www.baeldung.com/java-check-ip-address-range) - [Find the IP Address of a Client Connected to a Server](https://www.baeldung.com/java-client-get-ip-address) +- [Unix Domain Socket in Java 16](https://www.baeldung.com/java-unix-domain-socket) - [[<-- Prev]](/core-java-modules/core-java-networking-2) From 689396a360df0dbb8962fae13cdf471de0c947fb Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 1 Dec 2021 16:33:28 +0800 Subject: [PATCH 33/63] Update README.md --- core-java-modules/core-java-string-operations-4/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-4/README.md b/core-java-modules/core-java-string-operations-4/README.md index be4c9ae05f..83bfeb4d05 100644 --- a/core-java-modules/core-java-string-operations-4/README.md +++ b/core-java-modules/core-java-string-operations-4/README.md @@ -2,4 +2,5 @@ - [Ignoring Commas in Quotes When Splitting a Comma-separated String](https://www.baeldung.com/java-split-string-commas) - [Compare Strings While Ignoring Whitespace in Java](https://www.baeldung.com/java-compare-string-whitespace) +- [Concatenating Null Strings in Java](https://www.baeldung.com/java-concat-null-string) From 5f78536a3a96b65564ad7aa1b8b0add55cabaf00 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Wed, 1 Dec 2021 11:39:46 +0200 Subject: [PATCH 34/63] JAVA-8748 temporarily disable test --- .../{FindFreePortUnitTest.java => FindFreePortManualTest.java} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/{FindFreePortUnitTest.java => FindFreePortManualTest.java} (98%) diff --git a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortUnitTest.java b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortManualTest.java similarity index 98% rename from core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortUnitTest.java rename to core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortManualTest.java index 95530ef292..3e533b3fc0 100644 --- a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortUnitTest.java +++ b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortManualTest.java @@ -14,7 +14,8 @@ import java.net.ServerSocket; import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.assertThat; -public class FindFreePortUnitTest { +// fixing in JAVA-8748 +public class FindFreePortManualTest { private static int FREE_PORT_NUMBER; private static int[] FREE_PORT_RANGE; From f913e0c006bafe2f9a69efb6cd3544d9898133fb Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Wed, 1 Dec 2021 10:48:53 +0100 Subject: [PATCH 35/63] JAVA-8358: Move Spring Boot Exit Codes code --- spring-boot-modules/spring-boot-basic-customization-2/README.md | 1 + .../baeldung/exitcode/event/ExitCodeEventDemoApplication.java | 0 .../exception/ExitCodeExceptionMapperDemoApplication.java | 0 .../exceptionexitgen/ExceptionExitCodeGeneratorApplication.java | 0 .../exitcode/exceptionexitgen/FailedToStartException.java | 0 .../exitcode/generator/ExitCodeGeneratorDemoApplication.java | 0 spring-boot-modules/spring-boot-basic-customization/README.md | 1 - 7 files changed, 1 insertion(+), 1 deletion(-) rename spring-boot-modules/{spring-boot-basic-customization => spring-boot-basic-customization-2}/src/main/java/com/baeldung/exitcode/event/ExitCodeEventDemoApplication.java (100%) rename spring-boot-modules/{spring-boot-basic-customization => spring-boot-basic-customization-2}/src/main/java/com/baeldung/exitcode/exception/ExitCodeExceptionMapperDemoApplication.java (100%) rename spring-boot-modules/{spring-boot-basic-customization => spring-boot-basic-customization-2}/src/main/java/com/baeldung/exitcode/exceptionexitgen/ExceptionExitCodeGeneratorApplication.java (100%) rename spring-boot-modules/{spring-boot-basic-customization => spring-boot-basic-customization-2}/src/main/java/com/baeldung/exitcode/exceptionexitgen/FailedToStartException.java (100%) rename spring-boot-modules/{spring-boot-basic-customization => spring-boot-basic-customization-2}/src/main/java/com/baeldung/exitcode/generator/ExitCodeGeneratorDemoApplication.java (100%) diff --git a/spring-boot-modules/spring-boot-basic-customization-2/README.md b/spring-boot-modules/spring-boot-basic-customization-2/README.md index 0e688bda2a..9488618ca5 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/README.md +++ b/spring-boot-modules/spring-boot-basic-customization-2/README.md @@ -7,3 +7,4 @@ This module contains articles about Spring Boot customization 2 - [DispatcherServlet and web.xml in Spring Boot](https://www.baeldung.com/spring-boot-dispatcherservlet-web-xml) - [XML Defined Beans in Spring Boot](https://www.baeldung.com/spring-boot-xml-beans) - [What Is OncePerRequestFilter?](https://www.baeldung.com/spring-onceperrequestfilter) + - [Spring Boot Exit Codes](https://www.baeldung.com/spring-boot-exit-codes) diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/exitcode/event/ExitCodeEventDemoApplication.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/exitcode/event/ExitCodeEventDemoApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/exitcode/event/ExitCodeEventDemoApplication.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/exitcode/event/ExitCodeEventDemoApplication.java diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/exitcode/exception/ExitCodeExceptionMapperDemoApplication.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/exitcode/exception/ExitCodeExceptionMapperDemoApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/exitcode/exception/ExitCodeExceptionMapperDemoApplication.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/exitcode/exception/ExitCodeExceptionMapperDemoApplication.java diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/exitcode/exceptionexitgen/ExceptionExitCodeGeneratorApplication.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/exitcode/exceptionexitgen/ExceptionExitCodeGeneratorApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/exitcode/exceptionexitgen/ExceptionExitCodeGeneratorApplication.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/exitcode/exceptionexitgen/ExceptionExitCodeGeneratorApplication.java diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/exitcode/exceptionexitgen/FailedToStartException.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/exitcode/exceptionexitgen/FailedToStartException.java similarity index 100% rename from spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/exitcode/exceptionexitgen/FailedToStartException.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/exitcode/exceptionexitgen/FailedToStartException.java diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/exitcode/generator/ExitCodeGeneratorDemoApplication.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/exitcode/generator/ExitCodeGeneratorDemoApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/exitcode/generator/ExitCodeGeneratorDemoApplication.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/exitcode/generator/ExitCodeGeneratorDemoApplication.java diff --git a/spring-boot-modules/spring-boot-basic-customization/README.md b/spring-boot-modules/spring-boot-basic-customization/README.md index 6c067fc5a1..a3d9f1b1fc 100644 --- a/spring-boot-modules/spring-boot-basic-customization/README.md +++ b/spring-boot-modules/spring-boot-basic-customization/README.md @@ -11,4 +11,3 @@ This module contains articles about Spring Boot customization - [Spring Boot: Configuring a Main Class](https://www.baeldung.com/spring-boot-main-class) - [How to Define a Spring Boot Filter?](https://www.baeldung.com/spring-boot-add-filter) - [Guide to the Favicon in Spring Boot](https://www.baeldung.com/spring-boot-favicon) - - [Spring Boot Exit Codes](https://www.baeldung.com/spring-boot-exit-codes) From cb9bfcbce8cb3e6e1d50820b8e0f261d4e889478 Mon Sep 17 00:00:00 2001 From: chaos2418 <> Date: Wed, 1 Dec 2021 20:39:43 +0530 Subject: [PATCH 36/63] JAVA-8649-1: updating spring-cloud release train version in spring-cloud-vault and removing bootstrap.yml --- spring-cloud/spring-cloud-vault/pom.xml | 2 +- .../src/main/resources/application.yml | 45 ++++++++++++++----- .../src/main/resources/bootstrap.yml | 37 --------------- 3 files changed, 35 insertions(+), 49 deletions(-) delete mode 100644 spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml diff --git a/spring-cloud/spring-cloud-vault/pom.xml b/spring-cloud/spring-cloud-vault/pom.xml index 131d58c967..3f72ac9fe2 100644 --- a/spring-cloud/spring-cloud-vault/pom.xml +++ b/spring-cloud/spring-cloud-vault/pom.xml @@ -78,7 +78,7 @@ - Greenwich.RELEASE + 2020.0.3 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-vault/src/main/resources/application.yml b/spring-cloud/spring-cloud-vault/src/main/resources/application.yml index 1c75ac21e6..cb0b2d60fd 100644 --- a/spring-cloud/spring-cloud-vault/src/main/resources/application.yml +++ b/spring-cloud/spring-cloud-vault/src/main/resources/application.yml @@ -1,11 +1,34 @@ -spring: - application: - name: fakebank - - datasource: - url: jdbc:mysql://localhost:3306/fakebank?serverTimezone=GMT-3 - hikari: connection-test-query: select 1 - idle-timeout: 5000 - max-lifetime: 120000 - maximum-pool-size: 5 - minimum-idle: 5 +spring: + application: + name: fakebank + datasource: + url: jdbc:mysql://localhost:3306/fakebank?serverTimezone=GMT-3 + hikari: + connection-test-query: select 1 + idle-timeout: 5000 + max-lifetime: 120000 + maximum-pool-size: 5 + minimum-idle: 5 + cloud: + vault: + uri: https://localhost:8200 + connection-timeout: 5000 + read-timeout: 15000 + ssl: + trust-store: classpath:/vault.jks + trust-store-password: changeit + generic: + enabled: true + application-name: fakebank + # kv: + # enabled: false + # backend: kv + # application-name: fakebank + database: + enabled: true + role: fakebank-accounts-ro + backend: database + username-property: spring.datasource.username + password-property: spring.datasource.password + config: + import: vault:// \ No newline at end of file diff --git a/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml b/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml deleted file mode 100644 index 7d38b06c0f..0000000000 --- a/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml +++ /dev/null @@ -1,37 +0,0 @@ -spring: - cloud: - vault: - uri: https://localhost:8200 - connection-timeout: 5000 - read-timeout: 15000 - - ssl: - trust-store: classpath:/vault.jks - trust-store-password: changeit - - generic: - enabled: true - application-name: fakebank - -# kv: -# enabled: false -# backend: kv -# application-name: fakebank -# - database: - enabled: true - role: fakebank-accounts-rw - backend: database - username-property: spring.datasource.username - password-property: spring.datasource.password -# -# - - - - - - - - - \ No newline at end of file From 36866c09f79be1e1bc8bb2bf2782b7eab5c9ab7c Mon Sep 17 00:00:00 2001 From: Olsi Seferi <72546616+olsiseferi@users.noreply.github.com> Date: Wed, 1 Dec 2021 19:19:19 +0100 Subject: [PATCH 37/63] ExcelUtility Jira issue BAEL-5198 (#11503) * CODE REFACTOR AND ADDED UNIT TEST * SMALL CHANGE * FIXED TESTS TIMEZONE ISSUES Co-authored-by: Olsi Seferi --- .../com/baeldung/poi/excel/ExcelUtility.java | 66 ++++++++++++++++++ .../poi/excel/ExcelUtilityUnitTest.java | 54 ++++++++++++++ apache-poi/src/test/resources/baeldung.xlsx | Bin 0 -> 16777 bytes 3 files changed, 120 insertions(+) create mode 100644 apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java create mode 100644 apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java create mode 100644 apache-poi/src/test/resources/baeldung.xlsx diff --git a/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java b/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java new file mode 100644 index 0000000000..e4a5b791c9 --- /dev/null +++ b/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java @@ -0,0 +1,66 @@ +package com.baeldung.poi.excel; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +public class ExcelUtility { + private static final String ENDLINE = System.getProperty("line.separator"); + + public static String readExcel(String filePath) throws IOException { + File file = new File(filePath); + FileInputStream inputStream = null; + StringBuilder toReturn = new StringBuilder(); + try { + inputStream = new FileInputStream(file); + Workbook baeuldungWorkBook = new XSSFWorkbook(inputStream); + for (Sheet sheet : baeuldungWorkBook) { + toReturn.append("--------------------------------------------------------------------").append(ENDLINE); + toReturn.append("Worksheet :").append(sheet.getSheetName()).append(ENDLINE); + toReturn.append("--------------------------------------------------------------------").append(ENDLINE); + int firstRow = sheet.getFirstRowNum(); + int lastRow = sheet.getLastRowNum(); + for (int index = firstRow + 1; index <= lastRow; index++) { + Row row = sheet.getRow(index); + toReturn.append("|| "); + for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) { + Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); + printCellValue(cell, toReturn); + } + toReturn.append(" ||").append(ENDLINE); + } + } + inputStream.close(); + + } catch (IOException e) { + throw e; + } + return toReturn.toString(); + } + + public static void printCellValue(Cell cell, StringBuilder toReturn) { + CellType cellType = cell.getCellType().equals(CellType.FORMULA) ? cell.getCachedFormulaResultType() + : cell.getCellType(); + if (cellType.equals(CellType.STRING)) { + toReturn.append(cell.getStringCellValue()).append(" | "); + } + if (cellType.equals(CellType.NUMERIC)) { + if (DateUtil.isCellDateFormatted(cell)) { + toReturn.append(cell.getDateCellValue()).append(" | "); + } else { + toReturn.append(cell.getNumericCellValue()).append(" | "); + } + } + if (cellType.equals(CellType.BOOLEAN)) { + toReturn.append(cell.getBooleanCellValue()).append(" | "); + } + } +} \ No newline at end of file diff --git a/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java b/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java new file mode 100644 index 0000000000..6638d77066 --- /dev/null +++ b/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.poi.excel; + +import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Paths; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import org.junit.Before; +import org.junit.Test; + +public class ExcelUtilityUnitTest { + private static final String FILE_NAME = "baeldung.xlsx"; + private String fileLocation; + private static final String ENDLINE = System.getProperty("line.separator"); + private StringBuilder output; + + @Before + public void setupUnitTest() throws IOException, URISyntaxException, ParseException { + output = new StringBuilder(); + output.append("--------------------------------------------------------------------").append(ENDLINE); + output.append("Worksheet :Sheet1").append(ENDLINE); + output.append("--------------------------------------------------------------------").append(ENDLINE); + output.append("|| Name1 | Surname1 | 3.55696564113E11 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021").toString()).append(" | ‡ | ||") + .append(ENDLINE); + output.append("|| Name2 | Surname2 | 5.646513512E9 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/12/2021").toString()).append(" | false | ||") + .append(ENDLINE); + output.append("|| Name3 | Surname3 | 3.55696564113E11 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021").toString()).append(" | 7.17039641738E11 | ||") + .append(ENDLINE); + output.append("--------------------------------------------------------------------").append(ENDLINE); + output.append("Worksheet :Sheet2").append(ENDLINE); + output.append("--------------------------------------------------------------------").append(ENDLINE); + output.append("|| Name4 | Surname4 | 3.55675623232E11 | 13/04/2021 | ||").append(ENDLINE); + + fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString(); + } + + @Test + public void givenStringPath_whenReadExcel_thenReturnStringValue() throws IOException { + assertEquals(output.toString(), ExcelUtility.readExcel(fileLocation)); + + } + + @Test + public void givenStringPath_whenReadExcel_thenThrowException() { + assertThrows(IOException.class, () -> { + ExcelUtility.readExcel("baeldung"); + }); + } + +} diff --git a/apache-poi/src/test/resources/baeldung.xlsx b/apache-poi/src/test/resources/baeldung.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a6ed6c4e6ac8b0d3bd39dd4bb114bf5e0ab56479 GIT binary patch literal 16777 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 Date: Wed, 1 Dec 2021 21:28:24 +0100 Subject: [PATCH 38/63] removed Hamcrest --- .../isuppercase/StringFirstCharacterUppercaseUnitTest.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java index 6803285ca2..ede31a3649 100644 --- a/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java +++ b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java @@ -5,9 +5,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import com.google.common.base.Ascii; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.matchesPattern; - @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class StringFirstCharacterUppercaseUnitTest { @@ -21,7 +18,7 @@ public class StringFirstCharacterUppercaseUnitTest { public void givenString_whenCheckingWithRegex_thenStringCapitalized() { String example = "Katie"; String regEx = "[A-Z]\\w*"; - assertThat(example, matchesPattern(regEx)); + Assertions.assertTrue(example.matches(regEx)); } @Test From 1ff29cf596df437780d59ec42f454e556758d402 Mon Sep 17 00:00:00 2001 From: Haroon Khan Date: Wed, 1 Dec 2021 22:40:29 +0000 Subject: [PATCH 39/63] [JAVA-8703] Fix Live test to allow isolated execution --- testing-modules/spring-testing-2/pom.xml | 2 +- .../dynamicproperties/ArticleTestFixtureLiveTest.java | 11 +++++++++-- .../dynamicproperties/PostgreSQLExtension.java | 10 +++++----- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/testing-modules/spring-testing-2/pom.xml b/testing-modules/spring-testing-2/pom.xml index 82a9ed9599..6bdec33d96 100644 --- a/testing-modules/spring-testing-2/pom.xml +++ b/testing-modules/spring-testing-2/pom.xml @@ -63,7 +63,7 @@ - 1.12.2 + 1.16.2 \ No newline at end of file diff --git a/testing-modules/spring-testing-2/src/test/java/com/baeldung/dynamicproperties/ArticleTestFixtureLiveTest.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/dynamicproperties/ArticleTestFixtureLiveTest.java index bb3ad28365..2975104c14 100644 --- a/testing-modules/spring-testing-2/src/test/java/com/baeldung/dynamicproperties/ArticleTestFixtureLiveTest.java +++ b/testing-modules/spring-testing-2/src/test/java/com/baeldung/dynamicproperties/ArticleTestFixtureLiveTest.java @@ -4,13 +4,17 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest @ActiveProfiles("pg") @ExtendWith(PostgreSQLExtension.class) +@DirtiesContext public class ArticleTestFixtureLiveTest { @Autowired @@ -23,8 +27,11 @@ public class ArticleTestFixtureLiveTest { article.setContent("Today's applications..."); articleRepository.save(article); - Article persisted = articleRepository.findAll().get(0); - assertThat(persisted.getId()).isNotNull(); + + List
allArticles = articleRepository.findAll(); + assertThat(allArticles).hasSize(1); + + Article persisted = allArticles.get(0); assertThat(persisted.getTitle()).isEqualTo("A Guide to @DynamicPropertySource in Spring"); assertThat(persisted.getContent()).isEqualTo("Today's applications..."); } diff --git a/testing-modules/spring-testing-2/src/test/java/com/baeldung/dynamicproperties/PostgreSQLExtension.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/dynamicproperties/PostgreSQLExtension.java index 8c08ad67d7..28aab34867 100644 --- a/testing-modules/spring-testing-2/src/test/java/com/baeldung/dynamicproperties/PostgreSQLExtension.java +++ b/testing-modules/spring-testing-2/src/test/java/com/baeldung/dynamicproperties/PostgreSQLExtension.java @@ -18,14 +18,14 @@ public class PostgreSQLExtension implements BeforeAllCallback, AfterAllCallback .withExposedPorts(5432); postgres.start(); - String jdbcUrl = String.format("jdbc:postgresql://localhost:%d/prop", postgres.getFirstMappedPort()); - System.setProperty("spring.datasource.url", jdbcUrl); - System.setProperty("spring.datasource.username", "postgres"); - System.setProperty("spring.datasource.password", "pass"); + + System.setProperty("spring.datasource.url", postgres.getJdbcUrl()); + System.setProperty("spring.datasource.username", postgres.getUsername()); + System.setProperty("spring.datasource.password", postgres.getPassword()); } @Override public void afterAll(ExtensionContext context) { - postgres.stop(); + // do nothing, Testcontainers handles container shutdown } } From 9d0dd5e34f41e74b6d365f6ca9ce6a13db559a8c Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Thu, 2 Dec 2021 09:33:35 +0100 Subject: [PATCH 40/63] JAVA-8748: Make each test get available port on its own --- ...ualTest.java => FindFreePortUnitTest.java} | 65 ++++++++++++------- 1 file changed, 40 insertions(+), 25 deletions(-) rename core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/{FindFreePortManualTest.java => FindFreePortUnitTest.java} (78%) diff --git a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortManualTest.java b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortUnitTest.java similarity index 78% rename from core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortManualTest.java rename to core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortUnitTest.java index 3e533b3fc0..679503cb6d 100644 --- a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortManualTest.java +++ b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortUnitTest.java @@ -4,37 +4,27 @@ import org.apache.catalina.LifecycleException; import org.apache.catalina.startup.Tomcat; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.util.SocketUtils; import java.io.IOException; import java.net.ServerSocket; +import java.util.Random; -import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; -// fixing in JAVA-8748 -public class FindFreePortManualTest { +public class FindFreePortUnitTest { - private static int FREE_PORT_NUMBER; - private static int[] FREE_PORT_RANGE; - - @BeforeAll - public static void getExplicitFreePortNumberAndRange() { - try (ServerSocket serverSocket = new ServerSocket(0)) { - FREE_PORT_NUMBER = serverSocket.getLocalPort(); - FREE_PORT_RANGE = new int[] {FREE_PORT_NUMBER, FREE_PORT_NUMBER + 1, FREE_PORT_NUMBER + 2}; - } catch (IOException e) { - fail("No free port is available"); - } - } + private static final int DEFAULT_RANDOM_PORT = 34307; @Test public void givenExplicitFreePort_whenCreatingServerSocket_thenThatPortIsAssigned() { - try (ServerSocket serverSocket = new ServerSocket(FREE_PORT_NUMBER)) { + int freePort = getFreePort(); + + try (ServerSocket serverSocket = new ServerSocket(freePort)) { assertThat(serverSocket).isNotNull(); - assertThat(serverSocket.getLocalPort()).isEqualTo(FREE_PORT_NUMBER); + assertThat(serverSocket.getLocalPort()).isEqualTo(freePort); } catch (IOException e) { fail("Port is not available"); } @@ -42,8 +32,10 @@ public class FindFreePortManualTest { @Test public void givenExplicitOccupiedPort_whenCreatingServerSocket_thenExceptionIsThrown() { - try (ServerSocket serverSocket = new ServerSocket(FREE_PORT_NUMBER)) { - new ServerSocket(FREE_PORT_NUMBER); + int freePort = getFreePort(); + + try (ServerSocket serverSocket = new ServerSocket(freePort)) { + new ServerSocket(freePort); fail("Same port cannot be used twice"); } catch (IOException e) { assertThat(e).hasMessageContaining("Address already in use"); @@ -52,7 +44,7 @@ public class FindFreePortManualTest { @Test public void givenExplicitPortRange_whenCreatingServerSocket_thenOnePortIsAssigned() { - for (int port : FREE_PORT_RANGE) { + for (int port : getFreePorts()) { try (ServerSocket serverSocket = new ServerSocket(port)) { assertThat(serverSocket).isNotNull(); assertThat(serverSocket.getLocalPort()).isEqualTo(port); @@ -105,11 +97,12 @@ public class FindFreePortManualTest { public void givenExplicitFreePort_whenCreatingJettyServer_thenThatPortIsAssigned() throws Exception { Server jettyServer = new Server(); ServerConnector serverConnector = new ServerConnector(jettyServer); - serverConnector.setPort(FREE_PORT_NUMBER); + int freePort = getFreePort(); + serverConnector.setPort(freePort); jettyServer.addConnector(serverConnector); try { jettyServer.start(); - assertThat(serverConnector.getLocalPort()).isEqualTo(FREE_PORT_NUMBER); + assertThat(serverConnector.getLocalPort()).isEqualTo(freePort); } catch (Exception e) { fail("Failed to start Jetty server"); } finally { @@ -136,10 +129,11 @@ public class FindFreePortManualTest { @Test public void givenExplicitFreePort_whenCreatingTomcatServer_thenThatPortIsAssigned() throws Exception { Tomcat tomcatServer = new Tomcat(); - tomcatServer.setPort(FREE_PORT_NUMBER); + int freePort = getFreePort(); + tomcatServer.setPort(freePort); try { tomcatServer.start(); - assertThat(tomcatServer.getConnector().getLocalPort()).isEqualTo(FREE_PORT_NUMBER); + assertThat(tomcatServer.getConnector().getLocalPort()).isEqualTo(freePort); } catch (LifecycleException e) { fail("Failed to start Tomcat server"); } finally { @@ -148,4 +142,25 @@ public class FindFreePortManualTest { } } + private int[] getFreePorts() { + int freePort = getFreePort(); + return new int[]{freePort - 1, freePort, freePort + 1}; + } + + private int getFreePort() { + return new Random() + .ints(36000, 65000) + .filter(FindFreePortUnitTest::isFree) + .findFirst() + .orElse(DEFAULT_RANDOM_PORT); + } + + private static boolean isFree(int port) { + try { + new ServerSocket(port).close(); + return true; + } catch (IOException e) { + return false; + } + } } From 4f178a1af5b0ff4fd4bd655842b3138231f3df99 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Thu, 2 Dec 2021 11:20:46 +0200 Subject: [PATCH 41/63] remove duplicate dependency --- core-java-modules/core-java-string-algorithms-3/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index 180d75cc61..ccb9457a11 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -24,11 +24,6 @@ commons-validator ${validator.version} - - com.google.guava - guava - ${guava.version} - From 205ad52ea26029318fba1fe0bcb9190149667396 Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Thu, 2 Dec 2021 12:27:52 +0100 Subject: [PATCH 42/63] JAVA-8764: Fix test/main directories structure --- .../springbootxml/SpringBootXmlApplicationIntegrationTest.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename spring-boot-modules/spring-boot-basic-customization-2/src/{main/test => test/java}/com/baeldung/springbootxml/SpringBootXmlApplicationIntegrationTest.java (100%) diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/test/com/baeldung/springbootxml/SpringBootXmlApplicationIntegrationTest.java b/spring-boot-modules/spring-boot-basic-customization-2/src/test/java/com/baeldung/springbootxml/SpringBootXmlApplicationIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot-basic-customization-2/src/main/test/com/baeldung/springbootxml/SpringBootXmlApplicationIntegrationTest.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/test/java/com/baeldung/springbootxml/SpringBootXmlApplicationIntegrationTest.java From 85faed7f391bf38baf3ca438b6f764eff7fdf1f5 Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Thu, 2 Dec 2021 12:58:13 +0100 Subject: [PATCH 43/63] JAVA-8748: Use ServerSocket(0) approach to get free port --- .../baeldung/socket/FindFreePortUnitTest.java | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortUnitTest.java b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortUnitTest.java index 679503cb6d..4dfc114438 100644 --- a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortUnitTest.java +++ b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/FindFreePortUnitTest.java @@ -9,7 +9,6 @@ import org.springframework.util.SocketUtils; import java.io.IOException; import java.net.ServerSocket; -import java.util.Random; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; @@ -148,19 +147,10 @@ public class FindFreePortUnitTest { } private int getFreePort() { - return new Random() - .ints(36000, 65000) - .filter(FindFreePortUnitTest::isFree) - .findFirst() - .orElse(DEFAULT_RANDOM_PORT); - } - - private static boolean isFree(int port) { - try { - new ServerSocket(port).close(); - return true; - } catch (IOException e) { - return false; + try(ServerSocket serverSocket = new ServerSocket(0)){ + return serverSocket.getLocalPort(); + } catch (IOException ex){ + return DEFAULT_RANDOM_PORT; } } } From 615f3ba2bc8fd93ef8d4fee954a2c4b1061b78a2 Mon Sep 17 00:00:00 2001 From: Daniel Strmecki Date: Thu, 2 Dec 2021 14:43:55 +0100 Subject: [PATCH 44/63] Feature/bael 5133 utility class constructor (#11421) * BAEL-5133: initial commit * BAEL-5133: better example * BAEL-5133: add Lombok examples * BAEL-5133: add interface and enum examples * BAEL-5133: add exception * BAEL-5133: add suppress warning * BAEL-5133: dummy Co-authored-by: ashleyfrieze --- .../core-java-lang-oop-methods/pom.xml | 5 +++- .../com/baeldung/utilities/StringUtils.java | 17 +++++++++++ .../alternatives/StringUtilsEnum.java | 13 +++++++++ .../alternatives/StringUtilsInterface.java | 13 +++++++++ .../StringUtilsWithNoArgsConstructor.java | 17 +++++++++++ .../lombok/StringUtilsWithUtilityClass.java | 16 ++++++++++ .../warning/StringUtilsSuppressWarning.java | 14 +++++++++ .../utilities/StringUtilsUnitTest.java | 28 ++++++++++++++++++ .../alternatives/StringUtilsEnumUnitTest.java | 29 +++++++++++++++++++ .../StringUtilsInterfaceUnitTest.java | 29 +++++++++++++++++++ ...ingUtilsWithNoArgsConstructorUnitTest.java | 29 +++++++++++++++++++ .../StringUtilsWithUtilityClassUnitTest.java | 29 +++++++++++++++++++ ...ilsStringUtilsSuppressWarningUnitTest.java | 29 +++++++++++++++++++ 13 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/StringUtils.java create mode 100644 core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/alternatives/StringUtilsEnum.java create mode 100644 core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/alternatives/StringUtilsInterface.java create mode 100644 core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/lombok/StringUtilsWithNoArgsConstructor.java create mode 100644 core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/lombok/StringUtilsWithUtilityClass.java create mode 100644 core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/warning/StringUtilsSuppressWarning.java create mode 100644 core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/StringUtilsUnitTest.java create mode 100644 core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/alternatives/StringUtilsEnumUnitTest.java create mode 100644 core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/alternatives/StringUtilsInterfaceUnitTest.java create mode 100644 core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/lombok/StringUtilsWithNoArgsConstructorUnitTest.java create mode 100644 core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/lombok/StringUtilsWithUtilityClassUnitTest.java create mode 100644 core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/warning/StringUtilsStringUtilsSuppressWarningUnitTest.java diff --git a/core-java-modules/core-java-lang-oop-methods/pom.xml b/core-java-modules/core-java-lang-oop-methods/pom.xml index e57b51b7bd..e41c56fc6f 100644 --- a/core-java-modules/core-java-lang-oop-methods/pom.xml +++ b/core-java-modules/core-java-lang-oop-methods/pom.xml @@ -2,6 +2,7 @@ + 4.0.0 core-java-lang-oop-methods core-java-lang-oop-methods @@ -33,7 +34,9 @@ - 1.18.12 + 1.18.22 + 2.6 + 3.10.0 3.0.3 diff --git a/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/StringUtils.java b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/StringUtils.java new file mode 100644 index 0000000000..1e94281d21 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/StringUtils.java @@ -0,0 +1,17 @@ +package com.baeldung.utilities; + +public final class StringUtils { + + private StringUtils() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } + + public static boolean isEmpty(String source) { + return source == null || source.length() == 0; + } + + public static String wrap(String source, String wrapWith) { + return isEmpty(source) ? source : wrapWith + source + wrapWith; + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/alternatives/StringUtilsEnum.java b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/alternatives/StringUtilsEnum.java new file mode 100644 index 0000000000..2fa96874c0 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/alternatives/StringUtilsEnum.java @@ -0,0 +1,13 @@ +package com.baeldung.utilities.alternatives; + +public enum StringUtilsEnum {; + + public static boolean isEmpty(String source) { + return source == null || source.length() == 0; + } + + public static String wrap(String source, String wrapWith) { + return isEmpty(source) ? source : wrapWith + source + wrapWith; + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/alternatives/StringUtilsInterface.java b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/alternatives/StringUtilsInterface.java new file mode 100644 index 0000000000..b6afdfff5d --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/alternatives/StringUtilsInterface.java @@ -0,0 +1,13 @@ +package com.baeldung.utilities.alternatives; + +public interface StringUtilsInterface { + + static boolean isEmpty(String source) { + return source == null || source.length() == 0; + } + + static String wrap(String source, String wrapWith) { + return isEmpty(source) ? source : wrapWith + source + wrapWith; + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/lombok/StringUtilsWithNoArgsConstructor.java b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/lombok/StringUtilsWithNoArgsConstructor.java new file mode 100644 index 0000000000..38e60e0216 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/lombok/StringUtilsWithNoArgsConstructor.java @@ -0,0 +1,17 @@ +package com.baeldung.utilities.lombok; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access= AccessLevel.PRIVATE) +public final class StringUtilsWithNoArgsConstructor { + + public static boolean isEmpty(String source) { + return source == null || source.length() == 0; + } + + public static String wrap(String source, String wrapWith) { + return isEmpty(source) ? source : wrapWith + source + wrapWith; + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/lombok/StringUtilsWithUtilityClass.java b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/lombok/StringUtilsWithUtilityClass.java new file mode 100644 index 0000000000..56718f8ce4 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/lombok/StringUtilsWithUtilityClass.java @@ -0,0 +1,16 @@ +package com.baeldung.utilities.lombok; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class StringUtilsWithUtilityClass { + + public static boolean isEmpty(String source) { + return source == null || source.length() == 0; + } + + public static String wrap(String source, String wrapWith) { + return isEmpty(source) ? source : wrapWith + source + wrapWith; + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/warning/StringUtilsSuppressWarning.java b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/warning/StringUtilsSuppressWarning.java new file mode 100644 index 0000000000..d8354f993d --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/utilities/warning/StringUtilsSuppressWarning.java @@ -0,0 +1,14 @@ +package com.baeldung.utilities.warning; + +@SuppressWarnings("java:S1118") +public final class StringUtilsSuppressWarning { + + public static boolean isEmpty(String source) { + return source == null || source.length() == 0; + } + + public static String wrap(String source, String wrapWith) { + return isEmpty(source) ? source : wrapWith + source + wrapWith; + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/StringUtilsUnitTest.java b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/StringUtilsUnitTest.java new file mode 100644 index 0000000000..ca8b270d8d --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/StringUtilsUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.utilities; + +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.*; + +class StringUtilsUnitTest { + + @Test + void givenAnEmptyString_whenCallingIsEmpty_thenResultIsTrue() { + assertThat(StringUtils.isEmpty("")).isTrue(); + } + + @Test + void givenNonEmptyString_whenCallingIsEmpty_thenResultIsFalse() { + assertThat(StringUtils.isEmpty("asd")).isFalse(); + } + + @Test + void givenAnEmptyString_whenCallingWrap_thenResultIsAnEmptyString() { + assertThat(StringUtils.wrap("", "wrapper")).isEmpty(); + } + + @Test + void givenNonEmptyString_whenCallingWrap_thenResultIsWrappedString() { + assertThat(StringUtils.wrap("asd", "wrapper")).isEqualTo("wrapperasdwrapper"); + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/alternatives/StringUtilsEnumUnitTest.java b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/alternatives/StringUtilsEnumUnitTest.java new file mode 100644 index 0000000000..4d948c44ae --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/alternatives/StringUtilsEnumUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.utilities.alternatives; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class StringUtilsEnumUnitTest { + + @Test + void givenAnEmptyString_whenCallingIsEmpty_thenResultIsTrue() { + assertThat(StringUtilsEnum.isEmpty("")).isTrue(); + } + + @Test + void givenNonEmptyString_whenCallingIsEmpty_thenResultIsFalse() { + assertThat(StringUtilsEnum.isEmpty("asd")).isFalse(); + } + + @Test + void givenAnEmptyString_whenCallingWrap_thenResultIsAnEmptyString() { + assertThat(StringUtilsEnum.wrap("", "wrapper")).isEmpty(); + } + + @Test + void givenNonEmptyString_whenCallingWrap_thenResultIsWrappedString() { + assertThat(StringUtilsEnum.wrap("asd", "wrapper")).isEqualTo("wrapperasdwrapper"); + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/alternatives/StringUtilsInterfaceUnitTest.java b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/alternatives/StringUtilsInterfaceUnitTest.java new file mode 100644 index 0000000000..600f6c2156 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/alternatives/StringUtilsInterfaceUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.utilities.alternatives; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class StringUtilsInterfaceUnitTest { + + @Test + void givenAnEmptyString_whenCallingIsEmpty_thenResultIsTrue() { + assertThat(StringUtilsInterface.isEmpty("")).isTrue(); + } + + @Test + void givenNonEmptyString_whenCallingIsEmpty_thenResultIsFalse() { + assertThat(StringUtilsInterface.isEmpty("asd")).isFalse(); + } + + @Test + void givenAnEmptyString_whenCallingWrap_thenResultIsAnEmptyString() { + assertThat(StringUtilsInterface.wrap("", "wrapper")).isEmpty(); + } + + @Test + void givenNonEmptyString_whenCallingWrap_thenResultIsWrappedString() { + assertThat(StringUtilsInterface.wrap("asd", "wrapper")).isEqualTo("wrapperasdwrapper"); + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/lombok/StringUtilsWithNoArgsConstructorUnitTest.java b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/lombok/StringUtilsWithNoArgsConstructorUnitTest.java new file mode 100644 index 0000000000..b110c31080 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/lombok/StringUtilsWithNoArgsConstructorUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.utilities.lombok; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class StringUtilsWithNoArgsConstructorUnitTest { + + @Test + void givenAnEmptyString_whenCallingIsEmpty_thenResultIsTrue() { + assertThat(StringUtilsWithNoArgsConstructor.isEmpty("")).isTrue(); + } + + @Test + void givenNonEmptyString_whenCallingIsEmpty_thenResultIsFalse() { + assertThat(StringUtilsWithNoArgsConstructor.isEmpty("asd")).isFalse(); + } + + @Test + void givenAnEmptyString_whenCallingWrap_thenResultIsAnEmptyString() { + assertThat(StringUtilsWithNoArgsConstructor.wrap("", "wrapper")).isEmpty(); + } + + @Test + void givenNonEmptyString_whenCallingWrap_thenResultIsWrappedString() { + assertThat(StringUtilsWithNoArgsConstructor.wrap("asd", "wrapper")).isEqualTo("wrapperasdwrapper"); + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/lombok/StringUtilsWithUtilityClassUnitTest.java b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/lombok/StringUtilsWithUtilityClassUnitTest.java new file mode 100644 index 0000000000..c2f5003ada --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/lombok/StringUtilsWithUtilityClassUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.utilities.lombok; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class StringUtilsWithUtilityClassUnitTest { + + @Test + void givenAnEmptyString_whenCallingIsEmpty_thenResultIsTrue() { + assertThat(StringUtilsWithUtilityClass.isEmpty("")).isTrue(); + } + + @Test + void givenNonEmptyString_whenCallingIsEmpty_thenResultIsFalse() { + assertThat(StringUtilsWithUtilityClass.isEmpty("asd")).isFalse(); + } + + @Test + void givenAnEmptyString_whenCallingWrap_thenResultIsAnEmptyString() { + assertThat(StringUtilsWithUtilityClass.wrap("", "wrapper")).isEmpty(); + } + + @Test + void givenNonEmptyString_whenCallingWrap_thenResultIsWrappedString() { + assertThat(StringUtilsWithUtilityClass.wrap("asd", "wrapper")).isEqualTo("wrapperasdwrapper"); + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/warning/StringUtilsStringUtilsSuppressWarningUnitTest.java b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/warning/StringUtilsStringUtilsSuppressWarningUnitTest.java new file mode 100644 index 0000000000..646da08cc4 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/utilities/warning/StringUtilsStringUtilsSuppressWarningUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.utilities.warning; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class StringUtilsStringUtilsSuppressWarningUnitTest { + + @Test + void givenAnEmptyString_whenCallingIsEmpty_thenResultIsTrue() { + assertThat(StringUtilsSuppressWarning.isEmpty("")).isTrue(); + } + + @Test + void givenNonEmptyString_whenCallingIsEmpty_thenResultIsFalse() { + assertThat(StringUtilsSuppressWarning.isEmpty("asd")).isFalse(); + } + + @Test + void givenAnEmptyString_whenCallingWrap_thenResultIsAnEmptyString() { + assertThat(StringUtilsSuppressWarning.wrap("", "wrapper")).isEmpty(); + } + + @Test + void givenNonEmptyString_whenCallingWrap_thenResultIsWrappedString() { + assertThat(StringUtilsSuppressWarning.wrap("asd", "wrapper")).isEqualTo("wrapperasdwrapper"); + } + +} From 7ce6fc4e4596ab0f1b5071c0ed1b11f343620b5c Mon Sep 17 00:00:00 2001 From: sachin <56427366+sachin071287@users.noreply.github.com> Date: Thu, 2 Dec 2021 19:18:05 +0530 Subject: [PATCH 45/63] BAEL-5203 :Add an image to an Excel file with Java (#11391) Co-authored-by: Sachin kumar Co-authored-by: ashleyfrieze --- apache-poi-2/pom.xml | 13 ++- .../addimageincell/ExcelCellImageHelper.java | 76 ++++++++++++++++++ apache-poi-2/src/main/resources/ironman.png | Bin 0 -> 47793 bytes apache-poi-2/src/main/resources/spiderman.png | Bin 0 -> 57060 bytes 4 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 apache-poi-2/src/main/java/com/baeldung/poi/excel/write/addimageincell/ExcelCellImageHelper.java create mode 100644 apache-poi-2/src/main/resources/ironman.png create mode 100644 apache-poi-2/src/main/resources/spiderman.png diff --git a/apache-poi-2/pom.xml b/apache-poi-2/pom.xml index 1cb6509457..a46365c63c 100644 --- a/apache-poi-2/pom.xml +++ b/apache-poi-2/pom.xml @@ -3,9 +3,9 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - apache-poi + apache-poi-2 0.0.1-SNAPSHOT - apache-poi + apache-poi-2 com.baeldung @@ -17,8 +17,13 @@ org.apache.poi poi-ooxml - 5.0.0 + ${poi.version} - \ No newline at end of file + + 5.0.0 + + + + diff --git a/apache-poi-2/src/main/java/com/baeldung/poi/excel/write/addimageincell/ExcelCellImageHelper.java b/apache-poi-2/src/main/java/com/baeldung/poi/excel/write/addimageincell/ExcelCellImageHelper.java new file mode 100644 index 0000000000..6bd4f9d66b --- /dev/null +++ b/apache-poi-2/src/main/java/com/baeldung/poi/excel/write/addimageincell/ExcelCellImageHelper.java @@ -0,0 +1,76 @@ +package com.baeldung.poi.excel.write.addimageincell; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +/** + * This Helper class Add an Image to a Cell of an Excel File With apache-poi api. + * + */ +public class ExcelCellImageHelper { + + public static void main(String[] args) throws IOException, InvalidFormatException { + try (final Workbook workbook = new XSSFWorkbook(); + FileOutputStream saveExcel = new FileOutputStream("target/baeldung-apachepoi.xlsx");) { + + Sheet sheet = workbook.createSheet("Avengers"); + + XSSFDrawing drawing = (XSSFDrawing) sheet.createDrawingPatriarch(); + XSSFClientAnchor ironManAnchor = new XSSFClientAnchor(); + XSSFClientAnchor spiderManAnchor = new XSSFClientAnchor(); + + // Fill row1 data + Row row1 = sheet.createRow(0); + row1.setHeight((short) 1000); + row1.createCell(0) + .setCellValue("IRON-MAN"); + updateCellWithImage(workbook, 1, drawing, ironManAnchor, "ironman.png"); + + // Fill row2 data + Row row2 = sheet.createRow(1); + row2.setHeight((short) 1000); + row2.createCell(0) + .setCellValue("SPIDER-MAN"); + updateCellWithImage(workbook, 2, drawing, spiderManAnchor, "spiderman.png"); + + // Resize all columns to fit the content size + for (int i = 0; i < 2; i++) { + sheet.autoSizeColumn(i); + } + workbook.write(saveExcel); + } + + } + + /** + * This method position the anchor for a given rowNum and add the image correctly. + * @param workbook + * @param rowNum + * @param drawing + * @param inputImageAnchor + * @throws IOException + */ + private static void updateCellWithImage(Workbook workbook, int rowNum, XSSFDrawing drawing, XSSFClientAnchor inputImageAnchor, String inputImageName) throws IOException { + InputStream inputImageStream = ExcelCellImageHelper.class.getClassLoader() + .getResourceAsStream(inputImageName); + byte[] inputImageBytes = IOUtils.toByteArray(inputImageStream); + int inputImagePictureID = workbook.addPicture(inputImageBytes, Workbook.PICTURE_TYPE_PNG); + inputImageStream.close(); + inputImageAnchor.setCol1(1); + inputImageAnchor.setRow1(rowNum - 1); + inputImageAnchor.setCol2(2); + inputImageAnchor.setRow2(rowNum); + drawing.createPicture(inputImageAnchor, inputImagePictureID); + } + +} diff --git a/apache-poi-2/src/main/resources/ironman.png b/apache-poi-2/src/main/resources/ironman.png new file mode 100644 index 0000000000000000000000000000000000000000..30096294c9b26a8dc0a20d1427e2f3fdcbf4c8a8 GIT binary patch literal 47793 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 Date: Fri, 3 Dec 2021 17:20:12 +0530 Subject: [PATCH 46/63] JAVA-8736: update JDK version for the jdk9-and-above Jenkins jobs --- core-java-modules/core-java-11-2/pom.xml | 1 + core-java-modules/core-java-11/pom.xml | 2 ++ .../core-java-time-measurements/pom.xml | 16 ++++++++-------- .../com/baeldung/time/InstantUnitTest.java | 19 +++++++------------ .../baeldung/time/LocalDateTimeUnitTest.java | 7 ------- quarkus-vs-springboot/spring-project/pom.xml | 2 +- 6 files changed, 19 insertions(+), 28 deletions(-) diff --git a/core-java-modules/core-java-11-2/pom.xml b/core-java-modules/core-java-11-2/pom.xml index 332b24ff2e..757c1c0772 100644 --- a/core-java-modules/core-java-11-2/pom.xml +++ b/core-java-modules/core-java-11-2/pom.xml @@ -12,6 +12,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../pom.xml diff --git a/core-java-modules/core-java-11/pom.xml b/core-java-modules/core-java-11/pom.xml index fc61e373ec..1fa5ae2b45 100644 --- a/core-java-modules/core-java-11/pom.xml +++ b/core-java-modules/core-java-11/pom.xml @@ -13,6 +13,8 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + + ../../pom.xml diff --git a/core-java-modules/core-java-time-measurements/pom.xml b/core-java-modules/core-java-time-measurements/pom.xml index e2924b5278..28959d0938 100644 --- a/core-java-modules/core-java-time-measurements/pom.xml +++ b/core-java-modules/core-java-time-measurements/pom.xml @@ -38,15 +38,15 @@ ${asspectj.version} - org.powermock - powermock-module-junit4 - ${powermock.version} + org.mockito + mockito-inline + ${mockito-inline.version} test - org.powermock - powermock-api-mockito2 - ${powermock.version} + org.mockito + mockito-core + ${mockito-inline.version} test @@ -82,10 +82,10 @@ 3.6.1 2.10 - 1.18.12 + 1.18.22 1.8.9 - 2.0.7 1.44 + 4.0.0 \ No newline at end of file diff --git a/core-java-modules/core-java-time-measurements/src/test/java/com/baeldung/time/InstantUnitTest.java b/core-java-modules/core-java-time-measurements/src/test/java/com/baeldung/time/InstantUnitTest.java index 608199197a..ba1821b1ce 100644 --- a/core-java-modules/core-java-time-measurements/src/test/java/com/baeldung/time/InstantUnitTest.java +++ b/core-java-modules/core-java-time-measurements/src/test/java/com/baeldung/time/InstantUnitTest.java @@ -1,20 +1,15 @@ package com.baeldung.time; import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; +import org.mockito.MockedStatic; import java.time.Clock; import java.time.Instant; import java.time.ZoneId; import static org.assertj.core.api.Assertions.assertThat; -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.when; +import static org.mockito.Mockito.mockStatic; -@RunWith(PowerMockRunner.class) -@PrepareForTest({ Instant.class }) public class InstantUnitTest { @Test @@ -22,12 +17,12 @@ public class InstantUnitTest { String instantExpected = "2014-12-22T10:15:30Z"; Clock clock = Clock.fixed(Instant.parse(instantExpected), ZoneId.of("UTC")); Instant instant = Instant.now(clock); - mockStatic(Instant.class); - when(Instant.now()).thenReturn(instant); - Instant now = Instant.now(); - - assertThat(now.toString()).isEqualTo(instantExpected); + try (MockedStatic mockedStatic = mockStatic(Instant.class)) { + mockedStatic.when(Instant::now).thenReturn(instant); + Instant now = Instant.now(); + assertThat(now.toString()).isEqualTo(instantExpected); + } } @Test diff --git a/core-java-modules/core-java-time-measurements/src/test/java/com/baeldung/time/LocalDateTimeUnitTest.java b/core-java-modules/core-java-time-measurements/src/test/java/com/baeldung/time/LocalDateTimeUnitTest.java index 52dc9ba1c6..e4401d67b7 100644 --- a/core-java-modules/core-java-time-measurements/src/test/java/com/baeldung/time/LocalDateTimeUnitTest.java +++ b/core-java-modules/core-java-time-measurements/src/test/java/com/baeldung/time/LocalDateTimeUnitTest.java @@ -1,9 +1,6 @@ package com.baeldung.time; import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; import java.time.Clock; import java.time.Instant; @@ -11,11 +8,7 @@ import java.time.LocalDateTime; import java.time.ZoneId; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; -import static org.powermock.api.mockito.PowerMockito.mockStatic; -@RunWith(PowerMockRunner.class) -@PrepareForTest({ LocalDateTime.class }) public class LocalDateTimeUnitTest { @Test diff --git a/quarkus-vs-springboot/spring-project/pom.xml b/quarkus-vs-springboot/spring-project/pom.xml index 128966c07e..ad841a4c0f 100644 --- a/quarkus-vs-springboot/spring-project/pom.xml +++ b/quarkus-vs-springboot/spring-project/pom.xml @@ -166,7 +166,7 @@ 11 - 0.10.3 + 0.10.5 \ No newline at end of file From fdadff3a517add0813b4be752b3168f2f7cc4801 Mon Sep 17 00:00:00 2001 From: chaos2418 <> Date: Sat, 4 Dec 2021 10:00:10 +0530 Subject: [PATCH 47/63] JAVA-8736: fixing plugin versions in core-java-11-2 to work with JDK 17 --- core-java-modules/core-java-11-2/pom.xml | 20 ++++--------------- .../soap/ws/client/generated/Country.java | 8 ++++---- .../ws/client/generated/CountryService.java | 18 ++++++++--------- .../generated/CountryServiceImplService.java | 16 +++++++-------- .../soap/ws/client/generated/Currency.java | 5 ++--- .../ws/client/generated/ObjectFactory.java | 2 +- .../ws/client/generated/package-info.java | 2 +- 7 files changed, 29 insertions(+), 42 deletions(-) diff --git a/core-java-modules/core-java-11-2/pom.xml b/core-java-modules/core-java-11-2/pom.xml index 757c1c0772..fac23f9bfd 100644 --- a/core-java-modules/core-java-11-2/pom.xml +++ b/core-java-modules/core-java-11-2/pom.xml @@ -36,18 +36,6 @@ jakarta.xml.ws-api ${jakarta.ws-api.version} - - com.sun.xml.ws - jaxws-rt - ${jaxws-rt.version} - runtime - - - com.sun.xml.ws - jaxws-ri - ${jaxws-ri.version} - pom - @@ -83,10 +71,10 @@ 11 29.0-jre 5.11.1 - 3.0.0 - 3.0.0 - 2.3.1 - 2.3.2 + 3.0.1 + 3.0.2 + 3.0.2 + 3.0.2 \ No newline at end of file diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Country.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Country.java index 950d588661..d39f333b41 100644 --- a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Country.java +++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Country.java @@ -1,10 +1,10 @@ package com.baeldung.soap.ws.client.generated; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlSchemaType; +import jakarta.xml.bind.annotation.XmlType; /** diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryService.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryService.java index 807d152cf1..f10dcade1b 100644 --- a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryService.java +++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryService.java @@ -1,19 +1,19 @@ package com.baeldung.soap.ws.client.generated; -import javax.jws.WebMethod; -import javax.jws.WebParam; -import javax.jws.WebResult; -import javax.jws.WebService; -import javax.jws.soap.SOAPBinding; -import javax.xml.bind.annotation.XmlSeeAlso; -import javax.xml.ws.Action; +import jakarta.jws.WebMethod; +import jakarta.jws.WebParam; +import jakarta.jws.WebResult; +import jakarta.jws.WebService; +import jakarta.jws.soap.SOAPBinding; +import jakarta.xml.bind.annotation.XmlSeeAlso; +import jakarta.xml.ws.Action; /** * This class was generated by the JAX-WS RI. - * JAX-WS RI 2.3.2 - * Generated source version: 2.2 + * JAX-WS RI 3.0.2 + * Generated source version: 3.0 * */ @WebService(name = "CountryService", targetNamespace = "http://server.ws.soap.baeldung.com/") diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java index 97d6c82145..ae7ff38f7d 100644 --- a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java +++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java @@ -4,17 +4,17 @@ package com.baeldung.soap.ws.client.generated; import java.net.MalformedURLException; import java.net.URL; import javax.xml.namespace.QName; -import javax.xml.ws.Service; -import javax.xml.ws.WebEndpoint; -import javax.xml.ws.WebServiceClient; -import javax.xml.ws.WebServiceException; -import javax.xml.ws.WebServiceFeature; +import jakarta.xml.ws.Service; +import jakarta.xml.ws.WebEndpoint; +import jakarta.xml.ws.WebServiceClient; +import jakarta.xml.ws.WebServiceException; +import jakarta.xml.ws.WebServiceFeature; /** * This class was generated by the JAX-WS RI. - * JAX-WS RI 2.3.2 - * Generated source version: 2.2 + * JAX-WS RI 3.0.2 + * Generated source version: 3.0 * */ @WebServiceClient(name = "CountryServiceImplService", targetNamespace = "http://server.ws.soap.baeldung.com/", wsdlLocation = "http://localhost:8888/ws/country?wsdl") @@ -75,7 +75,7 @@ public class CountryServiceImplService /** * * @param features - * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. + * A list of {@link jakarta.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. * @return * returns CountryService */ diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Currency.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Currency.java index c010f5533c..ad42c65461 100644 --- a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Currency.java +++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/Currency.java @@ -1,15 +1,14 @@ package com.baeldung.soap.ws.client.generated; -import javax.xml.bind.annotation.XmlEnum; -import javax.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlEnum; +import jakarta.xml.bind.annotation.XmlType; /** *

Java class for currency. * *

The following schema fragment specifies the expected content contained within this class. - *

*

  * <simpleType name="currency">
  *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/ObjectFactory.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/ObjectFactory.java
index 9ed85fe2b9..0489e49c2b 100644
--- a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/ObjectFactory.java
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/ObjectFactory.java
@@ -1,7 +1,7 @@
 
 package com.baeldung.soap.ws.client.generated;
 
-import javax.xml.bind.annotation.XmlRegistry;
+import jakarta.xml.bind.annotation.XmlRegistry;
 
 
 /**
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/package-info.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/package-info.java
index dfc556859f..6dcc08c268 100644
--- a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/package-info.java
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/soap/ws/client/generated/package-info.java
@@ -1,2 +1,2 @@
-@javax.xml.bind.annotation.XmlSchema(namespace = "http://server.ws.soap.baeldung.com/")
+@jakarta.xml.bind.annotation.XmlSchema(namespace = "http://server.ws.soap.baeldung.com/")
 package com.baeldung.soap.ws.client.generated;

From 3a001425f82a3308cd48ede405d779c01d1b6248 Mon Sep 17 00:00:00 2001
From: johnA1331 <53036378+johnA1331@users.noreply.github.com>
Date: Sat, 4 Dec 2021 16:10:21 +0800
Subject: [PATCH 48/63] Update README.md

---
 spring-5-webflux/README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/spring-5-webflux/README.md b/spring-5-webflux/README.md
index bd667468fb..889f211fc6 100644
--- a/spring-5-webflux/README.md
+++ b/spring-5-webflux/README.md
@@ -11,3 +11,4 @@ This module contains articles about Spring 5 WebFlux
 - [Spring MVC Async vs Spring WebFlux](https://www.baeldung.com/spring-mvc-async-vs-webflux)
 - [Set a Timeout in Spring 5 Webflux WebClient](https://www.baeldung.com/spring-webflux-timeout)
 - [Guide to Retry in Spring WebFlux](https://www.baeldung.com/spring-webflux-retry)
+- [Spring Webflux and @Cacheable Annotation](https://www.baeldung.com/spring-webflux-cacheable)

From 65f604e05df66f41b7b506889bb7b96e39795edf Mon Sep 17 00:00:00 2001
From: johnA1331 <53036378+johnA1331@users.noreply.github.com>
Date: Sat, 4 Dec 2021 16:14:21 +0800
Subject: [PATCH 49/63] Update README.md

---
 core-java-modules/core-java-string-algorithms-3/README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/core-java-modules/core-java-string-algorithms-3/README.md b/core-java-modules/core-java-string-algorithms-3/README.md
index 8d515b9aea..e6dbf3a489 100644
--- a/core-java-modules/core-java-string-algorithms-3/README.md
+++ b/core-java-modules/core-java-string-algorithms-3/README.md
@@ -6,3 +6,4 @@ This module contains articles about string-related algorithms.
 
 - [Check if Two Strings are Anagrams in Java](https://www.baeldung.com/java-strings-anagrams)
 - [Email Validation in Java](https://www.baeldung.com/java-email-validation-regex)
+- [Check if the First Letter of a String is Uppercase](https://www.baeldung.com/java-check-first-letter-uppercase)

From 77c7b12b20801c883b46516b75bd4dfada96a67d Mon Sep 17 00:00:00 2001
From: chaos2418 <>
Date: Sat, 4 Dec 2021 10:33:19 +0530
Subject: [PATCH 50/63] JAVA-8736: updating spring-aot-maven-plugin version in
 sprng-project to be compatible with JDK 17

---
 quarkus-vs-springboot/spring-project/pom.xml | 22 ++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/quarkus-vs-springboot/spring-project/pom.xml b/quarkus-vs-springboot/spring-project/pom.xml
index ad841a4c0f..989e30526f 100644
--- a/quarkus-vs-springboot/spring-project/pom.xml
+++ b/quarkus-vs-springboot/spring-project/pom.xml
@@ -10,7 +10,7 @@
     
         org.springframework.boot
         spring-boot-starter-parent
-        2.5.4
+        2.6.0
         
     
 
@@ -96,6 +96,15 @@
                 false
             
         
+        
+        
+            spring-milestones
+            Spring Milestones
+            https://repo.spring.io/libs-milestone-local
+            
+                false
+            
+        
     
     
         
@@ -106,6 +115,15 @@
                 false
             
         
+        
+        
+            spring-milestones
+            Spring Milestones
+            https://repo.spring.io/libs-milestone-local
+            
+                false
+            
+        
     
 
     
@@ -166,7 +184,7 @@
     
         11
         
-        0.10.5
+        0.11.0-RC1
     
 
 
\ No newline at end of file

From 6666a7574ad08be0cf9fa1479ada0b194c833902 Mon Sep 17 00:00:00 2001
From: johnA1331 <53036378+johnA1331@users.noreply.github.com>
Date: Sat, 4 Dec 2021 19:22:39 +0800
Subject: [PATCH 51/63] Update README.md

---
 persistence-modules/spring-jpa/README.md | 1 -
 1 file changed, 1 deletion(-)

diff --git a/persistence-modules/spring-jpa/README.md b/persistence-modules/spring-jpa/README.md
index 202f5b0293..aa9e833260 100644
--- a/persistence-modules/spring-jpa/README.md
+++ b/persistence-modules/spring-jpa/README.md
@@ -5,7 +5,6 @@
 - [JPA Pagination](https://www.baeldung.com/jpa-pagination)
 - [Sorting with JPA](https://www.baeldung.com/jpa-sort)
 - [Self-Contained Testing Using an In-Memory Database](https://www.baeldung.com/spring-jpa-test-in-memory-database)
-- [Obtaining Auto-generated Keys in Spring JDBC](https://www.baeldung.com/spring-jdbc-autogenerated-keys)
 - [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
 - [A Guide to Spring AbstractRoutingDatasource](https://www.baeldung.com/spring-abstract-routing-data-source)
 - More articles: [[next -->]](/spring-jpa-2)

From 42549ff9e2b87615a2b3db0fdacefb9b451104a3 Mon Sep 17 00:00:00 2001
From: johnA1331 <53036378+johnA1331@users.noreply.github.com>
Date: Sat, 4 Dec 2021 19:26:22 +0800
Subject: [PATCH 52/63] Update README.md

---
 core-java-modules/core-java-string-algorithms-2/README.md | 1 -
 1 file changed, 1 deletion(-)

diff --git a/core-java-modules/core-java-string-algorithms-2/README.md b/core-java-modules/core-java-string-algorithms-2/README.md
index aa71e5f59e..dbfbb3ef3c 100644
--- a/core-java-modules/core-java-string-algorithms-2/README.md
+++ b/core-java-modules/core-java-string-algorithms-2/README.md
@@ -13,5 +13,4 @@ This module contains articles about string-related algorithms.
 - [Remove Leading and Trailing Characters from a String](https://www.baeldung.com/java-remove-trailing-characters)
 - [Counting Words in a String with Java](https://www.baeldung.com/java-word-counting)
 - [Finding the Difference Between Two Strings in Java](https://www.baeldung.com/java-difference-between-two-strings)
-- [Check if the First Letter of a String is Uppercase](https://www.baeldung.com/java-check-first-letter-uppercase)
 - More articles: [[<-- prev]](../core-java-string-algorithms)

From 48e61e7d56464f4803b7a600fa40b1b5431348f6 Mon Sep 17 00:00:00 2001
From: johnA1331 <53036378+johnA1331@users.noreply.github.com>
Date: Sat, 4 Dec 2021 19:35:52 +0800
Subject: [PATCH 53/63] Update README.md

---
 persistence-modules/spring-boot-persistence/README.md | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/persistence-modules/spring-boot-persistence/README.md b/persistence-modules/spring-boot-persistence/README.md
index a9fe3905c2..88526cdb89 100644
--- a/persistence-modules/spring-boot-persistence/README.md
+++ b/persistence-modules/spring-boot-persistence/README.md
@@ -7,5 +7,4 @@
 - [Resolving “Failed to Configure a DataSource” Error](https://www.baeldung.com/spring-boot-failed-to-configure-data-source)
 - [Hibernate Field Naming with Spring Boot](https://www.baeldung.com/hibernate-field-naming-spring-boot)
 - [Spring Boot with Hibernate](https://www.baeldung.com/spring-boot-hibernate)
-- [A Guide to Spring AbstractRoutingDatasource](https://www.baeldung.com/spring-abstract-routing-data-source)
-- More articles: [[more -->]](../spring-boot-persistence-2)
\ No newline at end of file
+- More articles: [[more -->]](../spring-boot-persistence-2)

From 446cc2beb90ced8044fd7394b7d01f50e5dff9d1 Mon Sep 17 00:00:00 2001
From: johnA1331 <53036378+johnA1331@users.noreply.github.com>
Date: Sat, 4 Dec 2021 19:41:35 +0800
Subject: [PATCH 54/63] Delete README.md

---
 .../src/test/java/com/baeldung/hexToAscii/README.md             | 2 --
 1 file changed, 2 deletions(-)
 delete mode 100644 core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/hexToAscii/README.md

diff --git a/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/hexToAscii/README.md b/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/hexToAscii/README.md
deleted file mode 100644
index c6d5826333..0000000000
--- a/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/hexToAscii/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-### Relevant Articles:
-- [Convert Hex to ASCII in Java](http://www.baeldung.com/java-convert-hex-to-ascii)

From 0673bc708b08bbc5c47afb355ef5f5db08d7e39b Mon Sep 17 00:00:00 2001
From: johnA1331 <53036378+johnA1331@users.noreply.github.com>
Date: Sat, 4 Dec 2021 19:44:36 +0800
Subject: [PATCH 55/63] Update README.md

---
 spring-boot-modules/spring-boot-runtime/README.md | 1 -
 1 file changed, 1 deletion(-)

diff --git a/spring-boot-modules/spring-boot-runtime/README.md b/spring-boot-modules/spring-boot-runtime/README.md
index 94822af09e..6f21efe793 100644
--- a/spring-boot-modules/spring-boot-runtime/README.md
+++ b/spring-boot-modules/spring-boot-runtime/README.md
@@ -10,4 +10,3 @@ This module contains articles about administering a Spring Boot runtime
  - [Project Configuration with Spring](https://www.baeldung.com/project-configuration-with-spring)
  - [Spring – Log Incoming Requests](https://www.baeldung.com/spring-http-logging)
  - [How to Configure Spring Boot Tomcat](https://www.baeldung.com/spring-boot-configure-tomcat)
- - [Max-HTTP-Header-Size in Spring Boot 2](https://www.baeldung.com/spring-boot-max-http-header-size)

From 2c5982f9f9ddcb265674152917853a5694f091a6 Mon Sep 17 00:00:00 2001
From: polomos 
Date: Sun, 5 Dec 2021 03:40:46 +0100
Subject: [PATCH 56/63] BAEL-5060 JMX ports explained (#11505)

---
 .../main/java/com/baeldung/jmx/JMXConfiguration.java   | 10 ++++++++++
 1 file changed, 10 insertions(+)
 create mode 100644 core-java-modules/core-java-perf/src/main/java/com/baeldung/jmx/JMXConfiguration.java

diff --git a/core-java-modules/core-java-perf/src/main/java/com/baeldung/jmx/JMXConfiguration.java b/core-java-modules/core-java-perf/src/main/java/com/baeldung/jmx/JMXConfiguration.java
new file mode 100644
index 0000000000..e60ea253ed
--- /dev/null
+++ b/core-java-modules/core-java-perf/src/main/java/com/baeldung/jmx/JMXConfiguration.java
@@ -0,0 +1,10 @@
+package com.baeldung.jmx;
+
+public class JMXConfiguration {
+
+    public static void main(String[] args) {
+        while (true) {
+            // to ensure application does not terminate
+        }
+    }
+}
\ No newline at end of file

From f97df9e8285059c224d35beaaf66e11e4dc8a21e Mon Sep 17 00:00:00 2001
From: sampadawagde 
Date: Sun, 5 Dec 2021 11:58:14 +0530
Subject: [PATCH 57/63] JAVA-8354: Split or move core-java-collections-3

---
 core-java-modules/core-java-collections-3/README.md |  2 +-
 .../baeldung/collections/stack/StackUnitTest.java   |  2 +-
 core-java-modules/core-java-collections/README.md   |  3 ++-
 core-java-modules/core-java-collections/pom.xml     |  5 +++++
 .../ConvertPrimitivesArrayToList.java               |  8 +++++---
 .../ConvertPrimitivesArrayToListUnitTest.java       | 13 +++++--------
 6 files changed, 19 insertions(+), 14 deletions(-)
 rename core-java-modules/{core-java-collections-3 => core-java-collections}/src/main/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java (95%)
 rename core-java-modules/{core-java-collections-3 => core-java-collections}/src/test/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java (87%)

diff --git a/core-java-modules/core-java-collections-3/README.md b/core-java-modules/core-java-collections-3/README.md
index 6bc9139856..4249d8ad30 100644
--- a/core-java-modules/core-java-collections-3/README.md
+++ b/core-java-modules/core-java-collections-3/README.md
@@ -11,7 +11,7 @@
 - [Performance of contains() in a HashSet vs ArrayList](https://www.baeldung.com/java-hashset-arraylist-contains-performance)
 - [Fail-Safe Iterator vs Fail-Fast Iterator](https://www.baeldung.com/java-fail-safe-vs-fail-fast-iterator)
 - [Quick Guide to the Java Stack](https://www.baeldung.com/java-stack)
-- [Convert an Array of Primitives to a List](https://www.baeldung.com/java-primitive-array-to-list)
 - [A Guide to BitSet in Java](https://www.baeldung.com/java-bitset)
 - [Get the First Key and Value From a HashMap](https://www.baeldung.com/java-hashmap-get-first-entry)
 - [Performance of removeAll() in a HashSet](https://www.baeldung.com/java-hashset-removeall-performance)
+- More articles: [[<-- prev]](/core-java-modules/core-java-collections-2) [[next -->]](/core-java-modules/core-java-collections-4)
diff --git a/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/stack/StackUnitTest.java b/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/stack/StackUnitTest.java
index 6a2feff551..14eafe8924 100644
--- a/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/stack/StackUnitTest.java
+++ b/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/stack/StackUnitTest.java
@@ -1,4 +1,4 @@
-package com.baeldung.stack;
+package com.baeldung.collections.stack;
 
 import org.junit.Test;
 
diff --git a/core-java-modules/core-java-collections/README.md b/core-java-modules/core-java-collections/README.md
index 12e3c5ac17..574f61ac6a 100644
--- a/core-java-modules/core-java-collections/README.md
+++ b/core-java-modules/core-java-collections/README.md
@@ -12,4 +12,5 @@ This module contains articles about Java collections
 - [Defining a Char Stack in Java](https://www.baeldung.com/java-char-stack)
 - [Guide to the Java Queue Interface](https://www.baeldung.com/java-queue)
 - [An Introduction to Synchronized Java Collections](https://www.baeldung.com/java-synchronized-collections)
-- [[More -->]](/core-java-modules/core-java-collections-2)
+- [Convert an Array of Primitives to a List](https://www.baeldung.com/java-primitive-array-to-list)
+- More articles: [[next -->]](/core-java-modules/core-java-collections-2)
diff --git a/core-java-modules/core-java-collections/pom.xml b/core-java-modules/core-java-collections/pom.xml
index 8df0d7cdd3..eab7a35584 100644
--- a/core-java-modules/core-java-collections/pom.xml
+++ b/core-java-modules/core-java-collections/pom.xml
@@ -25,6 +25,11 @@
             jmh-generator-annprocess
             ${jmh-generator.version}
         
+        
+            org.apache.commons
+            commons-lang3
+            ${commons-lang3.version}
+        
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-collections-3/src/main/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java b/core-java-modules/core-java-collections/src/main/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java
similarity index 95%
rename from core-java-modules/core-java-collections-3/src/main/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java
rename to core-java-modules/core-java-collections/src/main/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java
index f7be99abdc..1e6efb7840 100644
--- a/core-java-modules/core-java-collections-3/src/main/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java
+++ b/core-java-modules/core-java-collections/src/main/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java
@@ -1,13 +1,15 @@
-package com.baeldung.collections.iterators;
+package com.baeldung.collections.convertarrayprimitives;
 
-import java.util.List;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-import com.google.common.primitives.Ints;
+
 import org.apache.commons.lang3.ArrayUtils;
 
+import com.google.common.primitives.Ints;
+
 public class ConvertPrimitivesArrayToList {
 
     public static void failConvert() {
diff --git a/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java b/core-java-modules/core-java-collections/src/test/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java
similarity index 87%
rename from core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java
rename to core-java-modules/core-java-collections/src/test/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java
index b773baf7d8..f9f5f8ea91 100644
--- a/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java
+++ b/core-java-modules/core-java-collections/src/test/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java
@@ -1,14 +1,11 @@
-package com.baeldung.collections.iterators;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.stream.Collectors;
-import com.google.common.primitives.Ints;
-import org.junit.Test;
+package com.baeldung.collections.convertarrayprimitives;
 
 import static org.junit.Assert.assertEquals;
 
+import java.util.Arrays;
+
+import org.junit.Test;
+
 public class ConvertPrimitivesArrayToListUnitTest {
 
     @Test

From 40669cc7c682925bba691ca820a19c0fab95a6fc Mon Sep 17 00:00:00 2001
From: ioanadinuit <83220826+ioanadinuit@users.noreply.github.com>
Date: Sun, 5 Dec 2021 10:01:04 +0200
Subject: [PATCH 58/63] Update annotation name (#11531)

---
 .../validation/{Camelcase.java => Capitalized.java}         | 6 +++---
 .../{CamelcaseValidator.java => CapitalizedValidator.java}  | 6 +++---
 .../src/main/resources/openapi/templates/api.mustache       | 2 +-
 .../src/main/resources/openapi/templates/model.mustache     | 2 +-
 .../src/main/resources/petstore.yml                         | 4 ++--
 5 files changed, 10 insertions(+), 10 deletions(-)
 rename spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/{Camelcase.java => Capitalized.java} (74%)
 rename spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/{CamelcaseValidator.java => CapitalizedValidator.java} (83%)

diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/Camelcase.java b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/Capitalized.java
similarity index 74%
rename from spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/Camelcase.java
rename to spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/Capitalized.java
index b0b0b739e2..de83297c53 100644
--- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/Camelcase.java
+++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/Capitalized.java
@@ -5,12 +5,12 @@ import javax.validation.Payload;
 import java.lang.annotation.*;
 
 @Documented
-@Constraint(validatedBy = {CamelcaseValidator.class})
+@Constraint(validatedBy = {CapitalizedValidator.class})
 @Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
 @Retention(RetentionPolicy.RUNTIME)
-public @interface Camelcase {
+public @interface Capitalized {
 
-    String message() default "Name should be uppercase.";
+    String message() default "Name should be capitalized.";
 
     boolean required() default true;
 
diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/CamelcaseValidator.java b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/CapitalizedValidator.java
similarity index 83%
rename from spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/CamelcaseValidator.java
rename to spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/CapitalizedValidator.java
index 2b08e3dd2a..969dc0c56c 100644
--- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/CamelcaseValidator.java
+++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/CapitalizedValidator.java
@@ -4,11 +4,11 @@ import javax.validation.ConstraintValidator;
 import javax.validation.ConstraintValidatorContext;
 import java.util.Objects;
 
-public class CamelcaseValidator implements ConstraintValidator {
+public class CapitalizedValidator implements ConstraintValidator {
 
-	private Camelcase uppercaseAnnotation;
+	private Capitalized uppercaseAnnotation;
 
-	public void initialize(Camelcase constraintAnnotation) {
+	public void initialize(Capitalized constraintAnnotation) {
 		this.uppercaseAnnotation = constraintAnnotation;
 	}
 
diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/api.mustache b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/api.mustache
index a7a35d43b5..34f4afac3a 100644
--- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/api.mustache
+++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/api.mustache
@@ -8,7 +8,7 @@ package {{package}};
 {{#imports}}import {{import}};
 {{/imports}}
 import io.swagger.annotations.*;
-import com.baeldung.openapi.petstore.validation.Camelcase;
+import com.baeldung.openapi.petstore.validation.Capitalized;
 {{#jdk8-no-delegate}}
 {{#virtualService}}
 import io.virtualan.annotation.ApiVirtual;
diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/model.mustache b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/model.mustache
index d9329b40d3..4546a811ef 100644
--- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/model.mustache
+++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/model.mustache
@@ -4,7 +4,7 @@ package {{package}};
 {{/imports}}
 import com.fasterxml.jackson.databind.annotation.*;
 import com.fasterxml.jackson.annotation.*;
-import com.baeldung.openapi.petstore.validation.Camelcase;
+import com.baeldung.openapi.petstore.validation.Capitalized;
 {{^supportJava6}}
 import java.util.Objects;
 import java.util.Arrays;
diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/petstore.yml b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/petstore.yml
index c9884c01e8..c5fbd830bb 100644
--- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/petstore.yml
+++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/petstore.yml
@@ -37,7 +37,7 @@ paths:
           schema:
             type: string
           description: Tags to filter by
-          x-constraints: "@Camelcase(required = true)"
+          x-constraints: "@Capitalized(required = true)"
       responses:
         '200':
           description: default response
@@ -62,4 +62,4 @@ components:
           format: int64
         name:
           type: string
-          x-constraints: "@Camelcase(required = true)"
\ No newline at end of file
+          x-constraints: "@Capitalized(required = true)"
\ No newline at end of file

From f879ab8cefc36044319874c7b9a57e6c6770c719 Mon Sep 17 00:00:00 2001
From: LiamGve 
Date: Sun, 5 Dec 2021 14:34:24 +0000
Subject: [PATCH 59/63] BAEL-5182 code for webclient status code handling
 article (#11373)

* BAEL-5182 code for webclient status code handling article

* BAEL-5182 code for webclient status code handling article

* BAEL-5182 added different exceptions to make seperate examples clearer

Co-authored-by: Liam Garvie 
---
 .../status/WebClientStatusCodeHandler.java    | 54 ++++++++++
 .../status/exception/BadRequestException.java |  7 ++
 .../exception/ServerErrorException.java       |  7 ++
 ...lientStatusCodeHandlerIntegrationTest.java | 98 +++++++++++++++++++
 4 files changed, 166 insertions(+)
 create mode 100644 spring-5-reactive-client/src/main/java/com/baeldung/webclient/status/WebClientStatusCodeHandler.java
 create mode 100644 spring-5-reactive-client/src/main/java/com/baeldung/webclient/status/exception/BadRequestException.java
 create mode 100644 spring-5-reactive-client/src/main/java/com/baeldung/webclient/status/exception/ServerErrorException.java
 create mode 100644 spring-5-reactive-client/src/test/java/com/baeldung/webclient/WebClientStatusCodeHandlerIntegrationTest.java

diff --git a/spring-5-reactive-client/src/main/java/com/baeldung/webclient/status/WebClientStatusCodeHandler.java b/spring-5-reactive-client/src/main/java/com/baeldung/webclient/status/WebClientStatusCodeHandler.java
new file mode 100644
index 0000000000..9594ca32f1
--- /dev/null
+++ b/spring-5-reactive-client/src/main/java/com/baeldung/webclient/status/WebClientStatusCodeHandler.java
@@ -0,0 +1,54 @@
+package com.baeldung.webclient.status;
+
+import com.baeldung.webclient.status.exception.BadRequestException;
+import com.baeldung.webclient.status.exception.ServerErrorException;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.reactive.function.client.ClientResponse;
+import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Mono;
+
+public class WebClientStatusCodeHandler {
+
+    public static Mono getResponseBodyUsingExchangeFilterFunction(String uri) {
+        ExchangeFilterFunction errorResponseFilter = ExchangeFilterFunction
+            .ofResponseProcessor(WebClientStatusCodeHandler::exchangeFilterResponseProcessor);
+        return WebClient
+            .builder()
+            .filter(errorResponseFilter)
+            .build()
+            .post()
+            .uri(uri)
+            .retrieve()
+            .bodyToMono(String.class);
+    }
+
+    public static Mono getResponseBodyUsingOnStatus(String uri) {
+        return WebClient
+            .builder()
+            .build()
+            .post()
+            .uri(uri)
+            .retrieve()
+            .onStatus(
+                HttpStatus.INTERNAL_SERVER_ERROR::equals,
+                response -> response.bodyToMono(String.class).map(ServerErrorException::new))
+            .onStatus(
+                HttpStatus.BAD_REQUEST::equals,
+                response -> response.bodyToMono(String.class).map(BadRequestException::new))
+            .bodyToMono(String.class);
+    }
+
+    private static Mono exchangeFilterResponseProcessor(ClientResponse response) {
+        HttpStatus status = response.statusCode();
+        if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
+            return response.bodyToMono(String.class)
+                .flatMap(body -> Mono.error(new ServerErrorException(body)));
+        }
+        if (HttpStatus.BAD_REQUEST.equals(status)) {
+            return response.bodyToMono(String.class)
+                .flatMap(body -> Mono.error(new BadRequestException(body)));
+        }
+        return Mono.just(response);
+    }
+}
diff --git a/spring-5-reactive-client/src/main/java/com/baeldung/webclient/status/exception/BadRequestException.java b/spring-5-reactive-client/src/main/java/com/baeldung/webclient/status/exception/BadRequestException.java
new file mode 100644
index 0000000000..bf5c599805
--- /dev/null
+++ b/spring-5-reactive-client/src/main/java/com/baeldung/webclient/status/exception/BadRequestException.java
@@ -0,0 +1,7 @@
+package com.baeldung.webclient.status.exception;
+
+public class BadRequestException extends Exception {
+    public BadRequestException(String message) {
+        super(message);
+    }
+}
diff --git a/spring-5-reactive-client/src/main/java/com/baeldung/webclient/status/exception/ServerErrorException.java b/spring-5-reactive-client/src/main/java/com/baeldung/webclient/status/exception/ServerErrorException.java
new file mode 100644
index 0000000000..7e97f17dff
--- /dev/null
+++ b/spring-5-reactive-client/src/main/java/com/baeldung/webclient/status/exception/ServerErrorException.java
@@ -0,0 +1,7 @@
+package com.baeldung.webclient.status.exception;
+
+public class ServerErrorException extends Exception {
+    public ServerErrorException(String message) {
+        super(message);
+    }
+}
diff --git a/spring-5-reactive-client/src/test/java/com/baeldung/webclient/WebClientStatusCodeHandlerIntegrationTest.java b/spring-5-reactive-client/src/test/java/com/baeldung/webclient/WebClientStatusCodeHandlerIntegrationTest.java
new file mode 100644
index 0000000000..e491baf97a
--- /dev/null
+++ b/spring-5-reactive-client/src/test/java/com/baeldung/webclient/WebClientStatusCodeHandlerIntegrationTest.java
@@ -0,0 +1,98 @@
+package com.baeldung.webclient;
+
+import com.baeldung.webclient.status.WebClientStatusCodeHandler;
+import com.github.tomakehurst.wiremock.WireMockServer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.junit4.SpringRunner;
+import reactor.core.publisher.Mono;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.configureFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
+import static java.lang.String.format;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+
+@RunWith(SpringRunner.class)
+public class WebClientStatusCodeHandlerIntegrationTest {
+    private String baseUrl;
+    private WireMockServer wireMockServer;
+
+    @Before
+    public void setUp() {
+        wireMockServer = new WireMockServer(wireMockConfig().dynamicPort());
+        wireMockServer.start();
+        configureFor("localhost", wireMockServer.port());
+        baseUrl = format("http://localhost:%s", wireMockServer.port());
+    }
+
+    @After
+    public void tearDown() {
+        wireMockServer.stop();
+    }
+
+    @Test
+    public void whenResponseIs2XX_thenBothStatusHandlerAndExchangeFilterReturnEqualResponses() {
+        stubPostResponse("/success", 200, "success");
+
+        Mono responseStatusHandler = WebClientStatusCodeHandler
+            .getResponseBodyUsingOnStatus(baseUrl + "/success");
+
+        Mono responseExchangeFilter = WebClientStatusCodeHandler
+           .getResponseBodyUsingExchangeFilterFunction(baseUrl + "/success");
+
+        assertThat(responseStatusHandler.block())
+            .isEqualTo(responseExchangeFilter.block())
+            .isEqualTo("success");
+    }
+
+    @Test
+    public void whenResponseIs500_thenBothStatusHandlerAndExchangeFilterReturnEqualResponses() {
+        stubPostResponse("/server-error", 500, "Internal Server Error");
+
+        Mono responseStatusHandler = WebClientStatusCodeHandler
+            .getResponseBodyUsingOnStatus(baseUrl + "/server-error");
+
+        Mono responseExchangeFilter = WebClientStatusCodeHandler
+            .getResponseBodyUsingExchangeFilterFunction(baseUrl + "/server-error");
+
+        assertThatThrownBy(responseStatusHandler::block)
+            .isInstanceOf(Exception.class)
+            .hasMessageContaining("Internal Server Error");
+
+        assertThatThrownBy(responseExchangeFilter::block)
+            .isInstanceOf(Exception.class)
+            .hasMessageContaining("Internal Server Error");
+    }
+
+    @Test
+    public void whenResponseIs400_thenBothStatusHandlerAndExchangeFilterReturnEqualResponses() {
+        stubPostResponse("/client-error", 400, "Bad Request");
+
+        Mono responseStatusHandler = WebClientStatusCodeHandler
+            .getResponseBodyUsingOnStatus(baseUrl + "/client-error");
+
+        Mono responseExchangeFilter = WebClientStatusCodeHandler
+            .getResponseBodyUsingExchangeFilterFunction(baseUrl + "/client-error");
+
+        assertThatThrownBy(responseStatusHandler::block)
+            .isInstanceOf(Exception.class)
+            .hasMessageContaining("Bad Request");
+
+        assertThatThrownBy(responseExchangeFilter::block)
+            .isInstanceOf(Exception.class)
+            .hasMessageContaining("Bad Request");
+    }
+
+    private static void stubPostResponse(String url, int statusCode, String response) {
+        stubFor(post(urlEqualTo(url)).willReturn(aResponse()
+            .withStatus(statusCode)
+            .withBody(response)));
+    }
+}
\ No newline at end of file

From 9d62c835c5034cf7e232bfeb7e4eef644178fb2c Mon Sep 17 00:00:00 2001
From: chaos2418 <>
Date: Sun, 5 Dec 2021 20:59:15 +0530
Subject: [PATCH 60/63] JAVA-8649: removing bootstrap.properties in
 spring-cloud-bus module

---
 .../src/main/resources/application.yml               | 12 +++++++++++-
 .../src/main/resources/bootstrap.properties          |  7 -------
 .../src/main/resources/application.properties        |  7 ++++++-
 .../src/main/resources/bootstrap.properties          |  4 ----
 .../client/src/main/resources/application.properties |  2 +-
 5 files changed, 18 insertions(+), 14 deletions(-)
 delete mode 100644 spring-cloud-bus/spring-cloud-config-client/src/main/resources/bootstrap.properties
 delete mode 100644 spring-cloud-bus/spring-cloud-config-server/src/main/resources/bootstrap.properties

diff --git a/spring-cloud-bus/spring-cloud-config-client/src/main/resources/application.yml b/spring-cloud-bus/spring-cloud-config-client/src/main/resources/application.yml
index fbbc6d138f..bb5c9607b8 100644
--- a/spring-cloud-bus/spring-cloud-config-client/src/main/resources/application.yml
+++ b/spring-cloud-bus/spring-cloud-config-client/src/main/resources/application.yml
@@ -1,5 +1,11 @@
 ---
 spring:
+  application:
+    name: config-client
+  profiles:
+    active: development
+  config:
+    import: configserver:http://root:s3cr3t@localhost:8888
   rabbitmq:
     host: localhost
     port: 5672
@@ -10,8 +16,12 @@ spring:
       enabled: true
       refresh:
         enabled: true
+    config:
+      fail-fast: true
 management:
   endpoints:
     web:
       exposure:
-        include: "*"
\ No newline at end of file
+        include: "*"
+  security:
+    enabled: false
\ No newline at end of file
diff --git a/spring-cloud-bus/spring-cloud-config-client/src/main/resources/bootstrap.properties b/spring-cloud-bus/spring-cloud-config-client/src/main/resources/bootstrap.properties
deleted file mode 100644
index 7b362614ba..0000000000
--- a/spring-cloud-bus/spring-cloud-config-client/src/main/resources/bootstrap.properties
+++ /dev/null
@@ -1,7 +0,0 @@
-spring.application.name=config-client
-spring.profiles.active=development
-spring.cloud.config.uri=http://localhost:8888
-spring.cloud.config.username=root
-spring.cloud.config.password=s3cr3t
-spring.cloud.config.fail-fast=true
-management.security.enabled=false
\ No newline at end of file
diff --git a/spring-cloud-bus/spring-cloud-config-server/src/main/resources/application.properties b/spring-cloud-bus/spring-cloud-config-server/src/main/resources/application.properties
index 6d7a945612..00ef9f0217 100644
--- a/spring-cloud-bus/spring-cloud-config-server/src/main/resources/application.properties
+++ b/spring-cloud-bus/spring-cloud-config-server/src/main/resources/application.properties
@@ -6,4 +6,9 @@ spring.security.user.password=s3cr3t
 spring.rabbitmq.host=localhost
 spring.rabbitmq.port=5672
 spring.rabbitmq.username=guest
-spring.rabbitmq.password=guest
\ No newline at end of file
+spring.rabbitmq.password=guest
+
+encrypt.key-store.location=classpath:/config-server.jks
+encrypt.key-store.password=my-s70r3-s3cr3t
+encrypt.key-store.alias=config-server-key
+encrypt.key-store.secret=my-k34-s3cr3t
\ No newline at end of file
diff --git a/spring-cloud-bus/spring-cloud-config-server/src/main/resources/bootstrap.properties b/spring-cloud-bus/spring-cloud-config-server/src/main/resources/bootstrap.properties
deleted file mode 100644
index b0c35c72a6..0000000000
--- a/spring-cloud-bus/spring-cloud-config-server/src/main/resources/bootstrap.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-encrypt.key-store.location=classpath:/config-server.jks
-encrypt.key-store.password=my-s70r3-s3cr3t
-encrypt.key-store.alias=config-server-key
-encrypt.key-store.secret=my-k34-s3cr3t
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-config/client/src/main/resources/application.properties b/spring-cloud/spring-cloud-config/client/src/main/resources/application.properties
index 6366bc515c..a96e6189a1 100644
--- a/spring-cloud/spring-cloud-config/client/src/main/resources/application.properties
+++ b/spring-cloud/spring-cloud-config/client/src/main/resources/application.properties
@@ -1,3 +1,3 @@
 spring.application.name=config-client
 spring.profiles.active=development
-spring.config.import=optional:configserver:http://root:s3cr3t@localhost:8888 
\ No newline at end of file
+spring.config.import=optional:configserver:http://root:s3cr3t@localhost:8888
\ No newline at end of file

From c43b11c0f5107756f6786076bfc52bd54756555b Mon Sep 17 00:00:00 2001
From: chaos2418 <>
Date: Mon, 6 Dec 2021 14:54:20 +0530
Subject: [PATCH 61/63] JAVA-8736: removing unused jaxws* properties

---
 core-java-modules/core-java-11-2/pom.xml | 2 --
 1 file changed, 2 deletions(-)

diff --git a/core-java-modules/core-java-11-2/pom.xml b/core-java-modules/core-java-11-2/pom.xml
index fac23f9bfd..b077373448 100644
--- a/core-java-modules/core-java-11-2/pom.xml
+++ b/core-java-modules/core-java-11-2/pom.xml
@@ -72,8 +72,6 @@
         29.0-jre
         5.11.1
         3.0.1
-        3.0.2
-        3.0.2
         3.0.2
     
 

From 5e02fd897aca7817f2e0087bb52ec29419dbd6ba Mon Sep 17 00:00:00 2001
From: sampadawagde 
Date: Mon, 6 Dec 2021 18:53:41 +0530
Subject: [PATCH 62/63] JAVA-8370: Split or move json module

---
 json-2/README.md                                            | 2 ++
 json-2/pom.xml                                              | 6 ++++++
 .../test/java/com/baeldung/fastjson}/FastJsonUnitTest.java  | 2 +-
 .../src/test/java/com/baeldung/fastjson}/Person.java        | 2 +-
 json/README.md                                              | 2 +-
 json/pom.xml                                                | 6 ------
 6 files changed, 11 insertions(+), 9 deletions(-)
 rename {json/src/test/java/fast_json => json-2/src/test/java/com/baeldung/fastjson}/FastJsonUnitTest.java (99%)
 rename {json/src/test/java/fast_json => json-2/src/test/java/com/baeldung/fastjson}/Person.java (97%)

diff --git a/json-2/README.md b/json-2/README.md
index aebc42c472..ed5a79dd3d 100644
--- a/json-2/README.md
+++ b/json-2/README.md
@@ -8,3 +8,5 @@ This module contains articles about JSON.
 - [Introduction to Moshi Json](https://www.baeldung.com/java-json-moshi)
 - [Hypermedia Serialization With JSON-LD](https://www.baeldung.com/json-linked-data)
 - [Generate a Java Class From JSON](https://www.baeldung.com/java-generate-class-from-json)
+- [A Guide to FastJson](https://www.baeldung.com/fastjson)
+- More Articles: [[<-- prev]](/json)
diff --git a/json-2/pom.xml b/json-2/pom.xml
index 591b7c0883..751199d394 100644
--- a/json-2/pom.xml
+++ b/json-2/pom.xml
@@ -14,6 +14,11 @@
     
 
     
+        
+            com.alibaba
+            fastjson
+            ${fastjson.version}
+        
         
             org.jsonschema2pojo
             jsonschema2pojo-core
@@ -142,6 +147,7 @@
     
         0.9.23
         1.9.2
+        1.2.21
     
 
 
\ No newline at end of file
diff --git a/json/src/test/java/fast_json/FastJsonUnitTest.java b/json-2/src/test/java/com/baeldung/fastjson/FastJsonUnitTest.java
similarity index 99%
rename from json/src/test/java/fast_json/FastJsonUnitTest.java
rename to json-2/src/test/java/com/baeldung/fastjson/FastJsonUnitTest.java
index 6fcf1e398a..eec7a1c95f 100644
--- a/json/src/test/java/fast_json/FastJsonUnitTest.java
+++ b/json-2/src/test/java/com/baeldung/fastjson/FastJsonUnitTest.java
@@ -1,4 +1,4 @@
-package fast_json;
+package com.baeldung.fastjson;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
diff --git a/json/src/test/java/fast_json/Person.java b/json-2/src/test/java/com/baeldung/fastjson/Person.java
similarity index 97%
rename from json/src/test/java/fast_json/Person.java
rename to json-2/src/test/java/com/baeldung/fastjson/Person.java
index 3d772348a4..5e142131a3 100644
--- a/json/src/test/java/fast_json/Person.java
+++ b/json-2/src/test/java/com/baeldung/fastjson/Person.java
@@ -1,4 +1,4 @@
-package fast_json;
+package com.baeldung.fastjson;
 
 import com.alibaba.fastjson.annotation.JSONField;
 
diff --git a/json/README.md b/json/README.md
index 6ad4c8a29d..0a4782cd86 100644
--- a/json/README.md
+++ b/json/README.md
@@ -4,7 +4,6 @@ This module contains articles about JSON.
 
 ### Relevant Articles:
 - [Introduction to JSON Schema in Java](https://www.baeldung.com/introduction-to-json-schema-in-java)
-- [A Guide to FastJson](https://www.baeldung.com/fastjson)
 - [Introduction to JSONForms](https://www.baeldung.com/introduction-to-jsonforms)
 - [Introduction to JsonPath](https://www.baeldung.com/guide-to-jayway-jsonpath)
 - [Introduction to JSON-Java (org.json)](https://www.baeldung.com/java-org-json)
@@ -14,3 +13,4 @@ This module contains articles about JSON.
 - [Iterating Over an Instance of org.json.JSONObject](https://www.baeldung.com/jsonobject-iteration)
 - [Escape JSON String in Java](https://www.baeldung.com/java-json-escaping)
 - [Reducing JSON Data Size](https://www.baeldung.com/json-reduce-data-size)
+- More Articles: [[next -->]](/json-2)
diff --git a/json/pom.xml b/json/pom.xml
index dfe42ee4c1..0d83f523b8 100644
--- a/json/pom.xml
+++ b/json/pom.xml
@@ -26,11 +26,6 @@
                 
             
         
-        
-            com.alibaba
-            fastjson
-            ${fastjson.version}
-        
         
             org.json
             json
@@ -72,7 +67,6 @@
 
     
         1.4.1
-        1.2.21
         1.0
         1.0.1
         20171018

From 5c9e48a10f6c3e6136906053610d695e3a4ccee9 Mon Sep 17 00:00:00 2001
From: Olsi Seferi <72546616+olsiseferi@users.noreply.github.com>
Date: Mon, 6 Dec 2021 20:05:13 +0100
Subject: [PATCH 63/63] ExcelUtility Jira issue BAEL-5198 (#11559)

* CODE REFACTOR AND ADDED UNIT TEST

* SMALL CHANGE

* FIXED TESTS TIMEZONE ISSUES

* UPDATED FORMATTING

Co-authored-by: Olsi Seferi 
---
 .../com/baeldung/poi/excel/ExcelUtility.java  | 103 +++++++-------
 .../baeldung/poi/excel/ExcelUtility.java.orig | 128 ++++++++++++++++++
 .../poi/excel/ExcelUtilityUnitTest.java       |  82 ++++++-----
 .../poi/excel/ExcelUtilityUnitTest.java.orig  | 112 +++++++++++++++
 4 files changed, 346 insertions(+), 79 deletions(-)
 create mode 100644 apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java.orig
 create mode 100644 apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java.orig

diff --git a/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java b/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java
index e4a5b791c9..50bbfbbe3c 100644
--- a/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java
+++ b/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java
@@ -13,54 +13,63 @@ import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
 public class ExcelUtility {
-	private static final String ENDLINE = System.getProperty("line.separator");
+    private static final String ENDLINE = System.getProperty("line.separator");
 
-	public static String readExcel(String filePath) throws IOException {
-		File file = new File(filePath);
-		FileInputStream inputStream = null;
-		StringBuilder toReturn = new StringBuilder();
-		try {
-			inputStream = new FileInputStream(file);
-			Workbook baeuldungWorkBook = new XSSFWorkbook(inputStream);
-			for (Sheet sheet : baeuldungWorkBook) {
-				toReturn.append("--------------------------------------------------------------------").append(ENDLINE);
-				toReturn.append("Worksheet :").append(sheet.getSheetName()).append(ENDLINE);
-				toReturn.append("--------------------------------------------------------------------").append(ENDLINE);
-				int firstRow = sheet.getFirstRowNum();
-				int lastRow = sheet.getLastRowNum();
-				for (int index = firstRow + 1; index <= lastRow; index++) {
-					Row row = sheet.getRow(index);
-					toReturn.append("|| ");
-					for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) {
-						Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
-						printCellValue(cell, toReturn);
-					}
-					toReturn.append(" ||").append(ENDLINE);
-				}
-			}
-			inputStream.close();
+    public static String readExcel(String filePath) throws IOException {
+        File file = new File(filePath);
+        FileInputStream inputStream = null;
+        StringBuilder toReturn = new StringBuilder();
+        try {
+            inputStream = new FileInputStream(file);
+            Workbook baeuldungWorkBook = new XSSFWorkbook(inputStream);
+            for (Sheet sheet : baeuldungWorkBook) {
+                toReturn.append("--------------------------------------------------------------------")
+                    .append(ENDLINE);
+                toReturn.append("Worksheet :")
+                    .append(sheet.getSheetName())
+                    .append(ENDLINE);
+                toReturn.append("--------------------------------------------------------------------")
+                    .append(ENDLINE);
+                int firstRow = sheet.getFirstRowNum();
+                int lastRow = sheet.getLastRowNum();
+                for (int index = firstRow + 1; index <= lastRow; index++) {
+                    Row row = sheet.getRow(index);
+                    toReturn.append("|| ");
+                    for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) {
+                        Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
+                        printCellValue(cell, toReturn);
+                    }
+                    toReturn.append(" ||")
+                        .append(ENDLINE);
+                }
+            }
+            inputStream.close();
 
-		} catch (IOException e) {
-			throw e;
-		}
-		return toReturn.toString();
-	}
+        } catch (IOException e) {
+            throw e;
+        }
+        return toReturn.toString();
+    }
 
-	public static void printCellValue(Cell cell, StringBuilder toReturn) {
-		CellType cellType = cell.getCellType().equals(CellType.FORMULA) ? cell.getCachedFormulaResultType()
-				: cell.getCellType();
-		if (cellType.equals(CellType.STRING)) {
-			toReturn.append(cell.getStringCellValue()).append(" | ");
-		}
-		if (cellType.equals(CellType.NUMERIC)) {
-			if (DateUtil.isCellDateFormatted(cell)) {
-				toReturn.append(cell.getDateCellValue()).append(" | ");
-			} else {
-				toReturn.append(cell.getNumericCellValue()).append(" | ");
-			}
-		}
-		if (cellType.equals(CellType.BOOLEAN)) {
-			toReturn.append(cell.getBooleanCellValue()).append(" | ");
-		}
-	}
+    public static void printCellValue(Cell cell, StringBuilder toReturn) {
+        CellType cellType = cell.getCellType()
+            .equals(CellType.FORMULA) ? cell.getCachedFormulaResultType() : cell.getCellType();
+        if (cellType.equals(CellType.STRING)) {
+            toReturn.append(cell.getStringCellValue())
+                .append(" | ");
+        }
+        if (cellType.equals(CellType.NUMERIC)) {
+            if (DateUtil.isCellDateFormatted(cell)) {
+                toReturn.append(cell.getDateCellValue())
+                    .append(" | ");
+            } else {
+                toReturn.append(cell.getNumericCellValue())
+                    .append(" | ");
+            }
+        }
+        if (cellType.equals(CellType.BOOLEAN)) {
+            toReturn.append(cell.getBooleanCellValue())
+                .append(" | ");
+        }
+    }
 }
\ No newline at end of file
diff --git a/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java.orig b/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java.orig
new file mode 100644
index 0000000000..c058f3abcf
--- /dev/null
+++ b/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java.orig
@@ -0,0 +1,128 @@
+package com.baeldung.poi.excel;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.ss.usermodel.DateUtil;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+public class ExcelUtility {
+<<<<<<< HEAD
+    private static final String ENDLINE = System.getProperty("line.separator");
+
+    public static String readExcel(String filePath) throws IOException {
+        File file = new File(filePath);
+        FileInputStream inputStream = null;
+        StringBuilder toReturn = new StringBuilder();
+        try {
+            inputStream = new FileInputStream(file);
+            Workbook baeuldungWorkBook = new XSSFWorkbook(inputStream);
+            for (Sheet sheet : baeuldungWorkBook) {
+                toReturn.append("--------------------------------------------------------------------")
+                    .append(ENDLINE);
+                toReturn.append("Worksheet :")
+                    .append(sheet.getSheetName())
+                    .append(ENDLINE);
+                toReturn.append("--------------------------------------------------------------------")
+                    .append(ENDLINE);
+                int firstRow = sheet.getFirstRowNum();
+                int lastRow = sheet.getLastRowNum();
+                for (int index = firstRow + 1; index <= lastRow; index++) {
+                    Row row = sheet.getRow(index);
+                    toReturn.append("|| ");
+                    for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) {
+                        Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
+                        printCellValue(cell, toReturn);
+                    }
+                    toReturn.append(" ||")
+                        .append(ENDLINE);
+                }
+            }
+            inputStream.close();
+
+        } catch (IOException e) {
+            throw e;
+        }
+        return toReturn.toString();
+    }
+
+    public static void printCellValue(Cell cell, StringBuilder toReturn) {
+        CellType cellType = cell.getCellType()
+            .equals(CellType.FORMULA) ? cell.getCachedFormulaResultType() : cell.getCellType();
+        if (cellType.equals(CellType.STRING)) {
+            toReturn.append(cell.getStringCellValue())
+                .append(" | ");
+        }
+        if (cellType.equals(CellType.NUMERIC)) {
+            if (DateUtil.isCellDateFormatted(cell)) {
+                toReturn.append(cell.getDateCellValue())
+                    .append(" | ");
+            } else {
+                toReturn.append(cell.getNumericCellValue())
+                    .append(" | ");
+            }
+        }
+        if (cellType.equals(CellType.BOOLEAN)) {
+            toReturn.append(cell.getBooleanCellValue())
+                .append(" | ");
+        }
+    }
+=======
+	private static final String ENDLINE = System.getProperty("line.separator");
+
+	public static String readExcel(String filePath) throws IOException {
+		File file = new File(filePath);
+		FileInputStream inputStream = null;
+		StringBuilder toReturn = new StringBuilder();
+		try {
+			inputStream = new FileInputStream(file);
+			Workbook baeuldungWorkBook = new XSSFWorkbook(inputStream);
+			for (Sheet sheet : baeuldungWorkBook) {
+				toReturn.append("--------------------------------------------------------------------").append(ENDLINE);
+				toReturn.append("Worksheet :").append(sheet.getSheetName()).append(ENDLINE);
+				toReturn.append("--------------------------------------------------------------------").append(ENDLINE);
+				int firstRow = sheet.getFirstRowNum();
+				int lastRow = sheet.getLastRowNum();
+				for (int index = firstRow + 1; index <= lastRow; index++) {
+					Row row = sheet.getRow(index);
+					toReturn.append("|| ");
+					for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) {
+						Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
+						printCellValue(cell, toReturn);
+					}
+					toReturn.append(" ||").append(ENDLINE);
+				}
+			}
+			inputStream.close();
+
+		} catch (IOException e) {
+			throw e;
+		}
+		return toReturn.toString();
+	}
+
+	public static void printCellValue(Cell cell, StringBuilder toReturn) {
+		CellType cellType = cell.getCellType().equals(CellType.FORMULA) ? cell.getCachedFormulaResultType()
+				: cell.getCellType();
+		if (cellType.equals(CellType.STRING)) {
+			toReturn.append(cell.getStringCellValue()).append(" | ");
+		}
+		if (cellType.equals(CellType.NUMERIC)) {
+			if (DateUtil.isCellDateFormatted(cell)) {
+				toReturn.append(cell.getDateCellValue()).append(" | ");
+			} else {
+				toReturn.append(cell.getNumericCellValue()).append(" | ");
+			}
+		}
+		if (cellType.equals(CellType.BOOLEAN)) {
+			toReturn.append(cell.getBooleanCellValue()).append(" | ");
+		}
+	}
+>>>>>>> master
+}
\ No newline at end of file
diff --git a/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java b/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java
index 6638d77066..b4d3fdd732 100644
--- a/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java
+++ b/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java
@@ -13,42 +13,60 @@ import org.junit.Before;
 import org.junit.Test;
 
 public class ExcelUtilityUnitTest {
-	private static final String FILE_NAME = "baeldung.xlsx";
-	private String fileLocation;
-	private static final String ENDLINE = System.getProperty("line.separator");
-	private StringBuilder output;
+    private static final String FILE_NAME = "baeldung.xlsx";
+    private String fileLocation;
+    private static final String ENDLINE = System.getProperty("line.separator");
+    private StringBuilder output;
 
-	@Before
-	public void setupUnitTest() throws IOException, URISyntaxException, ParseException {
-		output = new StringBuilder();
-		output.append("--------------------------------------------------------------------").append(ENDLINE);
-		output.append("Worksheet :Sheet1").append(ENDLINE);
-		output.append("--------------------------------------------------------------------").append(ENDLINE);
-		output.append("|| Name1 | Surname1 | 3.55696564113E11 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021").toString()).append(" | ‡ |  ||")
-				.append(ENDLINE);
-		output.append("|| Name2 | Surname2 | 5.646513512E9 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/12/2021").toString()).append(" | false |  ||")
-				.append(ENDLINE);
-		output.append("|| Name3 | Surname3 | 3.55696564113E11 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021").toString()).append(" | 7.17039641738E11 |  ||")
-				.append(ENDLINE);
-		output.append("--------------------------------------------------------------------").append(ENDLINE);
-		output.append("Worksheet :Sheet2").append(ENDLINE);
-		output.append("--------------------------------------------------------------------").append(ENDLINE);
-		output.append("|| Name4 | Surname4 | 3.55675623232E11 | 13/04/2021 |  ||").append(ENDLINE);
+    @Before
+    public void setupUnitTest() throws IOException, URISyntaxException, ParseException {
+        output = new StringBuilder();
+        output.append("--------------------------------------------------------------------")
+            .append(ENDLINE);
+        output.append("Worksheet :Sheet1")
+            .append(ENDLINE);
+        output.append("--------------------------------------------------------------------")
+            .append(ENDLINE);
+        output.append("|| Name1 | Surname1 | 3.55696564113E11 | ")
+            .append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021")
+                .toString())
+            .append(" | ‡ |  ||")
+            .append(ENDLINE);
+        output.append("|| Name2 | Surname2 | 5.646513512E9 | ")
+            .append(new SimpleDateFormat("dd/MM/yyyy").parse("4/12/2021")
+                .toString())
+            .append(" | false |  ||")
+            .append(ENDLINE);
+        output.append("|| Name3 | Surname3 | 3.55696564113E11 | ")
+            .append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021")
+                .toString())
+            .append(" | 7.17039641738E11 |  ||")
+            .append(ENDLINE);
+        output.append("--------------------------------------------------------------------")
+            .append(ENDLINE);
+        output.append("Worksheet :Sheet2")
+            .append(ENDLINE);
+        output.append("--------------------------------------------------------------------")
+            .append(ENDLINE);
+        output.append("|| Name4 | Surname4 | 3.55675623232E11 | 13/04/2021 |  ||")
+            .append(ENDLINE);
 
-		fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString();
-	}
+        fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME)
+            .toURI())
+            .toString();
+    }
 
-	@Test
-	public void givenStringPath_whenReadExcel_thenReturnStringValue() throws IOException {
-		assertEquals(output.toString(), ExcelUtility.readExcel(fileLocation));
+    @Test
+    public void givenStringPath_whenReadExcel_thenReturnStringValue() throws IOException {
+        assertEquals(output.toString(), ExcelUtility.readExcel(fileLocation));
 
-	}
+    }
 
-	@Test
-	public void givenStringPath_whenReadExcel_thenThrowException() {
-		assertThrows(IOException.class, () -> {
-			ExcelUtility.readExcel("baeldung");
-		});
-	}
+    @Test
+    public void givenStringPath_whenReadExcel_thenThrowException() {
+        assertThrows(IOException.class, () -> {
+            ExcelUtility.readExcel("baeldung");
+        });
+    }
 
 }
diff --git a/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java.orig b/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java.orig
new file mode 100644
index 0000000000..cfc3062b5a
--- /dev/null
+++ b/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java.orig
@@ -0,0 +1,112 @@
+package com.baeldung.poi.excel;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Paths;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class ExcelUtilityUnitTest {
+<<<<<<< HEAD
+    private static final String FILE_NAME = "baeldung.xlsx";
+    private String fileLocation;
+    private static final String ENDLINE = System.getProperty("line.separator");
+    private StringBuilder output;
+
+    @Before
+    public void setupUnitTest() throws IOException, URISyntaxException, ParseException {
+        output = new StringBuilder();
+        output.append("--------------------------------------------------------------------")
+            .append(ENDLINE);
+        output.append("Worksheet :Sheet1")
+            .append(ENDLINE);
+        output.append("--------------------------------------------------------------------")
+            .append(ENDLINE);
+        output.append("|| Name1 | Surname1 | 3.55696564113E11 | ")
+            .append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021")
+                .toString())
+            .append(" | ‡ |  ||")
+            .append(ENDLINE);
+        output.append("|| Name2 | Surname2 | 5.646513512E9 | ")
+            .append(new SimpleDateFormat("dd/MM/yyyy").parse("4/12/2021")
+                .toString())
+            .append(" | false |  ||")
+            .append(ENDLINE);
+        output.append("|| Name3 | Surname3 | 3.55696564113E11 | ")
+            .append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021")
+                .toString())
+            .append(" | 7.17039641738E11 |  ||")
+            .append(ENDLINE);
+        output.append("--------------------------------------------------------------------")
+            .append(ENDLINE);
+        output.append("Worksheet :Sheet2")
+            .append(ENDLINE);
+        output.append("--------------------------------------------------------------------")
+            .append(ENDLINE);
+        output.append("|| Name4 | Surname4 | 3.55675623232E11 | 13/04/2021 |  ||")
+            .append(ENDLINE);
+
+        fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME)
+            .toURI())
+            .toString();
+    }
+
+    @Test
+    public void givenStringPath_whenReadExcel_thenReturnStringValue() throws IOException {
+        assertEquals(output.toString(), ExcelUtility.readExcel(fileLocation));
+
+    }
+
+    @Test
+    public void givenStringPath_whenReadExcel_thenThrowException() {
+        assertThrows(IOException.class, () -> {
+            ExcelUtility.readExcel("baeldung");
+        });
+    }
+=======
+	private static final String FILE_NAME = "baeldung.xlsx";
+	private String fileLocation;
+	private static final String ENDLINE = System.getProperty("line.separator");
+	private StringBuilder output;
+
+	@Before
+	public void setupUnitTest() throws IOException, URISyntaxException, ParseException {
+		output = new StringBuilder();
+		output.append("--------------------------------------------------------------------").append(ENDLINE);
+		output.append("Worksheet :Sheet1").append(ENDLINE);
+		output.append("--------------------------------------------------------------------").append(ENDLINE);
+		output.append("|| Name1 | Surname1 | 3.55696564113E11 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021").toString()).append(" | ‡ |  ||")
+				.append(ENDLINE);
+		output.append("|| Name2 | Surname2 | 5.646513512E9 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/12/2021").toString()).append(" | false |  ||")
+				.append(ENDLINE);
+		output.append("|| Name3 | Surname3 | 3.55696564113E11 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021").toString()).append(" | 7.17039641738E11 |  ||")
+				.append(ENDLINE);
+		output.append("--------------------------------------------------------------------").append(ENDLINE);
+		output.append("Worksheet :Sheet2").append(ENDLINE);
+		output.append("--------------------------------------------------------------------").append(ENDLINE);
+		output.append("|| Name4 | Surname4 | 3.55675623232E11 | 13/04/2021 |  ||").append(ENDLINE);
+
+		fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString();
+	}
+
+	@Test
+	public void givenStringPath_whenReadExcel_thenReturnStringValue() throws IOException {
+		assertEquals(output.toString(), ExcelUtility.readExcel(fileLocation));
+
+	}
+
+	@Test
+	public void givenStringPath_whenReadExcel_thenThrowException() {
+		assertThrows(IOException.class, () -> {
+			ExcelUtility.readExcel("baeldung");
+		});
+	}
+>>>>>>> master
+
+}