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/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/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-2/pom.xml b/apache-poi-2/pom.xml new file mode 100644 index 0000000000..a46365c63c --- /dev/null +++ b/apache-poi-2/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + apache-poi-2 + 0.0.1-SNAPSHOT + apache-poi-2 + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + + 5.0.0 + + + + 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/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 0000000000..30096294c9 Binary files /dev/null and b/apache-poi-2/src/main/resources/ironman.png differ diff --git a/apache-poi-2/src/main/resources/spiderman.png b/apache-poi-2/src/main/resources/spiderman.png new file mode 100644 index 0000000000..32982bbe65 Binary files /dev/null and b/apache-poi-2/src/main/resources/spiderman.png differ 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 0000000000..54e8734d58 Binary files /dev/null and b/apache-poi-2/src/test/resources/newColumnTest.xlsx differ 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) 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..50bbfbbe3c --- /dev/null +++ b/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java @@ -0,0 +1,75 @@ +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/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 new file mode 100644 index 0000000000..b4d3fdd732 --- /dev/null +++ b/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java @@ -0,0 +1,72 @@ +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/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 + +} diff --git a/apache-poi/src/test/resources/baeldung.xlsx b/apache-poi/src/test/resources/baeldung.xlsx new file mode 100644 index 0000000000..a6ed6c4e6a Binary files /dev/null and b/apache-poi/src/test/resources/baeldung.xlsx differ 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-11-2/pom.xml b/core-java-modules/core-java-11-2/pom.xml index 332b24ff2e..b077373448 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 @@ -35,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 - @@ -82,10 +71,8 @@ 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 \ 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;
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-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-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-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}");
+    }
+}
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-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
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-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());
     }
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");
+    }
+
+}
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)
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 95530ef292..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
@@ -4,36 +4,26 @@ 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 static org.assertj.core.api.Assertions.*;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
 
 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");
         }
@@ -41,8 +31,10 @@ public class FindFreePortUnitTest {
 
     @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");
@@ -51,7 +43,7 @@ public class FindFreePortUnitTest {
 
     @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);
@@ -104,11 +96,12 @@ public class FindFreePortUnitTest {
     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 {
@@ -135,10 +128,11 @@ public class FindFreePortUnitTest {
     @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 {
@@ -147,4 +141,16 @@ public class FindFreePortUnitTest {
         }
     }
 
+    private int[] getFreePorts() {
+        int freePort = getFreePort();
+        return new int[]{freePort - 1, freePort, freePort + 1};
+    }
+
+    private int getFreePort() {
+        try(ServerSocket serverSocket = new ServerSocket(0)){
+            return serverSocket.getLocalPort();
+        } catch (IOException ex){
+            return DEFAULT_RANDOM_PORT;
+        }
+    }
 }
diff --git a/core-java-modules/core-java-os/pom.xml b/core-java-modules/core-java-os/pom.xml
index d2bf842897..54b86522f4 100644
--- a/core-java-modules/core-java-os/pom.xml
+++ b/core-java-modules/core-java-os/pom.xml
@@ -75,7 +75,6 @@
     
 
     
-        4.1
         4.01
         1.8.9
         1.9
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
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));
+    }
+
 }
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)
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)
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..ccb9457a11 100644
--- a/core-java-modules/core-java-string-algorithms-3/pom.xml
+++ b/core-java-modules/core-java-string-algorithms-3/pom.xml
@@ -49,8 +49,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 80%
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..524f7ca839 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,12 @@
 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 static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.matchesPattern;
+import com.google.common.base.Ascii;
 
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
-public class StringFirstCharacterUppercase {
+public class StringFirstCharacterUppercaseUnitTest {
 
     @Test
     public void givenString_whenCheckingWithCharacterIsUpperCase_thenStringCapitalized() {
@@ -21,7 +18,8 @@ public class StringFirstCharacterUppercase {
     public void givenString_whenCheckingWithRegex_thenStringCapitalized() {
         String example = "Katie";
         String regEx = "[A-Z]\\w*";
-        assertThat(example, matchesPattern(regEx));
+
+        Assertions.assertTrue(example.matches(regEx));
     }
 
     @Test
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);
+    }
+
+}
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)
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)
 
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);
+    }
+}
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/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/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)
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-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 2919a3a4ee..0d83f523b8 100644
--- a/json/pom.xml
+++ b/json/pom.xml
@@ -26,11 +26,6 @@
                 
             
         
-        
-            com.alibaba
-            fastjson
-            ${fastjson.version}
-        
         
             org.json
             json
@@ -72,9 +67,7 @@
 
     
         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/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/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
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)
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)
diff --git a/pom.xml b/pom.xml
index 780393dfab..ad002650d7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1433,6 +1433,7 @@
         1.33
         1.33
         2.21.0
+        4.4
         2.11.0
         2.6
         3.12.0
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)
diff --git a/quarkus-vs-springboot/spring-project/pom.xml b/quarkus-vs-springboot/spring-project/pom.xml
index 128966c07e..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.3
+        0.11.0-RC1
     
 
 
\ 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..f665d5c9a6 100644
--- a/spring-5-reactive-client/pom.xml
+++ b/spring-5-reactive-client/pom.xml
@@ -148,14 +148,49 @@
         
     
 
+    
+        
+            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
         1.0
         1.0
-        4.1
         1.1.6
         4.0.1
     
-
 
\ No newline at end of file
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
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-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)
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/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-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
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)
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)
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
+
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)
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..2bf6bb33cd
--- /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..765149dad5
--- /dev/null
+++ b/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java
@@ -0,0 +1,66 @@
+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(){
+    }
+
+    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
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
new file mode 100644
index 0000000000..498ad9d537
--- /dev/null
+++ b/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java
@@ -0,0 +1,58 @@
+package com.baeldung.unsupportedmediatype;
+
+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;
+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 ApplicationUnitTest {
+    @Autowired
+    private MockMvc mockMvc;
+
+    @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());
+    }
+
+    @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());
+    }
+
+    @Test
+    public void XmlTestCase() throws Exception {
+        mockMvc.perform(MockMvcRequestBuilders.post("/user/")
+          .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()); + } +} 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 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 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 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) 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"); + } + } +} 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 } } 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