diff --git a/akka-http/pom.xml b/akka-http/pom.xml index 4b73fbc960..a64d7a80f6 100644 --- a/akka-http/pom.xml +++ b/akka-http/pom.xml @@ -41,4 +41,4 @@ 2.5.11 - + \ No newline at end of file diff --git a/algorithms-genetic/pom.xml b/algorithms-genetic/pom.xml index 00c9b88dfe..c53ae0f776 100644 --- a/algorithms-genetic/pom.xml +++ b/algorithms-genetic/pom.xml @@ -35,18 +35,11 @@ jenetics ${io.jenetics.version} - - org.assertj - assertj-core - ${org.assertj.core.version} - test - 3.6.1 3.7.0 - 3.9.0 1.11 diff --git a/algorithms-miscellaneous-1/pom.xml b/algorithms-miscellaneous-1/pom.xml index dd3742d4b0..3b55d979fe 100644 --- a/algorithms-miscellaneous-1/pom.xml +++ b/algorithms-miscellaneous-1/pom.xml @@ -35,12 +35,6 @@ ${lombok.version} provided - - org.assertj - assertj-core - ${org.assertj.core.version} - test - com.github.dpaukov combinatoricslib3 @@ -70,7 +64,6 @@ 3.6.1 - 3.9.0 1.11 27.0.1-jre 3.3.0 diff --git a/algorithms-miscellaneous-2/pom.xml b/algorithms-miscellaneous-2/pom.xml index fcefc3ccba..a411cfdb71 100644 --- a/algorithms-miscellaneous-2/pom.xml +++ b/algorithms-miscellaneous-2/pom.xml @@ -45,12 +45,6 @@ tradukisto ${tradukisto.version} - - org.assertj - assertj-core - ${org.assertj.core.version} - test - @@ -78,7 +72,6 @@ 1.0.1 1.0.1 1.0.1 - 3.9.0 1.11 2.7 diff --git a/algorithms-miscellaneous-3/pom.xml b/algorithms-miscellaneous-3/pom.xml index 19eca8eca7..11a64eba8b 100644 --- a/algorithms-miscellaneous-3/pom.xml +++ b/algorithms-miscellaneous-3/pom.xml @@ -14,12 +14,6 @@ - - org.assertj - assertj-core - ${org.assertj.core.version} - test - org.apache.commons commons-collections4 @@ -43,7 +37,7 @@ org.apache.commons commons-lang3 - ${commons.lang3.version} + ${commons-lang3.version} pl.pragmatists @@ -69,11 +63,8 @@ - 3.9.0 - 4.3 28.0-jre 2.6.0 - 3.8.1 1.1.0 diff --git a/algorithms-miscellaneous-4/pom.xml b/algorithms-miscellaneous-4/pom.xml index 1eae038bc0..8417c121bf 100644 --- a/algorithms-miscellaneous-4/pom.xml +++ b/algorithms-miscellaneous-4/pom.xml @@ -25,16 +25,9 @@ ${lombok.version} provided - - org.assertj - assertj-core - ${org.assertj.core.version} - test - - 3.9.0 27.0.1-jre diff --git a/algorithms-miscellaneous-5/pom.xml b/algorithms-miscellaneous-5/pom.xml index 32ecce58a6..4a0abc5cba 100644 --- a/algorithms-miscellaneous-5/pom.xml +++ b/algorithms-miscellaneous-5/pom.xml @@ -34,22 +34,10 @@ guava ${guava.version} - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - - - org.assertj - assertj-core - ${org.assertj.core.version} - test - 1.0.1 - 3.9.0 1.11 3.6.1 28.1-jre diff --git a/algorithms-miscellaneous-6/pom.xml b/algorithms-miscellaneous-6/pom.xml index 6d5f211c8a..1984139069 100644 --- a/algorithms-miscellaneous-6/pom.xml +++ b/algorithms-miscellaneous-6/pom.xml @@ -19,17 +19,6 @@ guava ${guava.version} - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - - - org.assertj - assertj-core - ${org.assertj.core.version} - test - org.projectlombok lombok @@ -45,7 +34,6 @@ 28.1-jre - 3.9.0 3.6.1 diff --git a/algorithms-searching/pom.xml b/algorithms-searching/pom.xml index a67c062403..edb8a0c423 100644 --- a/algorithms-searching/pom.xml +++ b/algorithms-searching/pom.xml @@ -13,15 +13,6 @@ 1.0.0-SNAPSHOT - - - org.assertj - assertj-core - ${org.assertj.core.version} - test - - - algorithms-searching @@ -32,8 +23,4 @@ - - 3.9.0 - - \ No newline at end of file diff --git a/algorithms-sorting-2/pom.xml b/algorithms-sorting-2/pom.xml index b673af9d70..a8477bf624 100644 --- a/algorithms-sorting-2/pom.xml +++ b/algorithms-sorting-2/pom.xml @@ -29,23 +29,10 @@ ${lombok.version} provided - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - - - org.assertj - assertj-core - ${org.assertj.core.version} - test - 3.6.1 - 3.9.0 1.11 diff --git a/algorithms-sorting/pom.xml b/algorithms-sorting/pom.xml index b853fd80ee..383014d528 100644 --- a/algorithms-sorting/pom.xml +++ b/algorithms-sorting/pom.xml @@ -30,23 +30,10 @@ ${lombok.version} provided - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - - - org.assertj - assertj-core - ${org.assertj.core.version} - test - 3.6.1 - 3.9.0 1.11 diff --git a/apache-kafka/pom.xml b/apache-kafka/pom.xml index 8003743f95..9ff894bc55 100644 --- a/apache-kafka/pom.xml +++ b/apache-kafka/pom.xml @@ -98,12 +98,6 @@ jackson-databind ${jackson.version} - - org.assertj - assertj-core - ${assertj.version} - test - org.testcontainers kafka @@ -170,7 +164,6 @@ - 3.6.2 2.8.0 1.15.3 1.15.3 diff --git a/apache-libraries/pom.xml b/apache-libraries/pom.xml index b4cf11b07d..3d78869865 100644 --- a/apache-libraries/pom.xml +++ b/apache-libraries/pom.xml @@ -156,13 +156,6 @@ solr-solrj ${solr.solr-solrj.version} - - - org.assertj - assertj-core - ${assertj.version} - test - @@ -202,7 +195,6 @@ 1.8 1.8.2 2.19.0 - 3.9.0 1.1.2 1.1.0.Final 1.2.0 diff --git a/apache-olingo/olingo2/src/test/resources/logback-test.xml b/apache-olingo/olingo2/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/apache-olingo/olingo2/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file 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..e31c219819 --- /dev/null +++ b/apache-poi-2/README.md @@ -0,0 +1,9 @@ +## 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) +- [Add an Image to a Cell in an Excel File With Java](https://www.baeldung.com/java-add-image-excel) +- More articles: [[<-- prev]](/apache-poi) diff --git a/junit5/pom.xml b/apache-poi-2/pom.xml similarity index 50% rename from junit5/pom.xml rename to apache-poi-2/pom.xml index b9804408a2..a46365c63c 100644 --- a/junit5/pom.xml +++ b/apache-poi-2/pom.xml @@ -2,35 +2,28 @@ - 4.0.0 - junit5 - junit5 + apache-poi-2 + 0.0.1-SNAPSHOT + apache-poi-2 - parent-modules com.baeldung + parent-modules 1.0.0-SNAPSHOT - - 8 - 8 - - - org.junit.jupiter - junit-jupiter-api - 5.8.1 - test - - - org.junit.jupiter - junit-jupiter-engine - 5.8.1 - test + org.apache.poi + poi-ooxml + ${poi.version} - \ No newline at end of file + + 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 d500787536..3dc58fe1b4 100644 --- a/apache-poi/README.md +++ b/apache-poi/README.md @@ -12,3 +12,8 @@ This module contains articles about Apache POI - [Read Excel Cell Value Rather Than Formula With Apache POI](https://www.baeldung.com/apache-poi-read-cell-value-formula) - [Setting Formulas in Excel with Apache POI](https://www.baeldung.com/java-apache-poi-set-formulas) - [Insert a Row in Excel Using Apache POI](https://www.baeldung.com/apache-poi-insert-excel-row) +- [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) +- [Reading Values From Excel in Java](https://www.baeldung.com/java-read-dates-excel) +- 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/main/java/com/baeldung/poi/excel/cellstyle/CellBordersHandler.java b/apache-poi/src/main/java/com/baeldung/poi/excel/cellstyle/CellBordersHandler.java new file mode 100644 index 0000000000..1c96db0b60 --- /dev/null +++ b/apache-poi/src/main/java/com/baeldung/poi/excel/cellstyle/CellBordersHandler.java @@ -0,0 +1,37 @@ +package com.baeldung.poi.excel.cellstyle; + +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.RegionUtil; + +public class CellBordersHandler { + + public void setRegionBorder(CellRangeAddress region, Sheet sheet, BorderStyle borderStyle) { + RegionUtil.setBorderTop(borderStyle, region, sheet); + RegionUtil.setBorderBottom(borderStyle, region, sheet); + RegionUtil.setBorderLeft(borderStyle, region, sheet); + RegionUtil.setBorderRight(borderStyle, region, sheet); + } + + public void setRegionBorderWithColor(CellRangeAddress region, Sheet sheet, BorderStyle borderStyle, short color) { + RegionUtil.setTopBorderColor(color, region, sheet); + RegionUtil.setBottomBorderColor(color, region, sheet); + RegionUtil.setLeftBorderColor(color, region, sheet); + RegionUtil.setRightBorderColor(color, region, sheet); + RegionUtil.setBorderTop(borderStyle, region, sheet); + RegionUtil.setBorderBottom(borderStyle, region, sheet); + RegionUtil.setBorderLeft(borderStyle, region, sheet); + RegionUtil.setBorderRight(borderStyle, region, sheet); + } + + public void setCrazyBorder(CellRangeAddress region, Sheet sheet) { + RegionUtil.setTopBorderColor(IndexedColors.RED.index, region, sheet); + RegionUtil.setBottomBorderColor(IndexedColors.GREEN.index, region, sheet); + RegionUtil.setLeftBorderColor(IndexedColors.BLUE.index, region, sheet); + RegionUtil.setRightBorderColor(IndexedColors.VIOLET.index, region, sheet); + RegionUtil.setBorderTop(BorderStyle.DASH_DOT, region, sheet); + RegionUtil.setBorderBottom(BorderStyle.DOUBLE, region, sheet); + RegionUtil.setBorderLeft(BorderStyle.DOTTED, region, sheet); + RegionUtil.setBorderRight(BorderStyle.SLANTED_DASH_DOT, region, sheet); + } +} diff --git a/apache-poi/src/main/java/com/baeldung/poi/excel/cellstyle/CellStyleHandler.java b/apache-poi/src/main/java/com/baeldung/poi/excel/cellstyle/CellStyleHandler.java new file mode 100644 index 0000000000..4d97fe50cb --- /dev/null +++ b/apache-poi/src/main/java/com/baeldung/poi/excel/cellstyle/CellStyleHandler.java @@ -0,0 +1,30 @@ +package com.baeldung.poi.excel.cellstyle; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.IndexedColors; + +public class CellStyleHandler { + + public void changeCellBackgroundColor(Cell cell) { + CellStyle cellStyle = cell.getCellStyle(); + if(cellStyle == null) { + cellStyle = cell.getSheet().getWorkbook().createCellStyle(); + } + cellStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); + cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + cell.setCellStyle(cellStyle); + } + + public void changeCellBackgroundColorWithPattern(Cell cell) { + CellStyle cellStyle = cell.getCellStyle(); + if(cellStyle == null) { + cellStyle = cell.getSheet().getWorkbook().createCellStyle(); + } + cellStyle.setFillBackgroundColor(IndexedColors.BLACK.index); + cellStyle.setFillPattern(FillPatternType.BIG_SPOTS); + cellStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); + cell.setCellStyle(cellStyle); + } +} diff --git a/apache-poi/src/main/resources/cellstyle/CellStyleHandlerTest.xlsx b/apache-poi/src/main/resources/cellstyle/CellStyleHandlerTest.xlsx new file mode 100644 index 0000000000..29f128211b Binary files /dev/null and b/apache-poi/src/main/resources/cellstyle/CellStyleHandlerTest.xlsx differ 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/java/com/baeldung/poi/excel/cellstyle/CellBorderHandlerUnitTest.java b/apache-poi/src/test/java/com/baeldung/poi/excel/cellstyle/CellBorderHandlerUnitTest.java new file mode 100644 index 0000000000..3cabff2dff --- /dev/null +++ b/apache-poi/src/test/java/com/baeldung/poi/excel/cellstyle/CellBorderHandlerUnitTest.java @@ -0,0 +1,130 @@ +package com.baeldung.poi.excel.cellstyle; + +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.*; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Paths; + +import static org.junit.Assert.assertEquals; + +public class CellBorderHandlerUnitTest { + private static final String FILE_NAME = "cellstyle/CellStyleHandlerTest.xlsx"; + private static final int SHEET_INDEX = 0; + + private static CellBordersHandler cellBordersHandler; + private static Workbook workbook; + + @BeforeClass + public static void setup() throws URISyntaxException, IOException { + String fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString(); + cellBordersHandler = new CellBordersHandler(); + workbook = new XSSFWorkbook(fileLocation); + createRowsAndCells(workbook); + } + + private static void createRowsAndCells(Workbook workbook) { + Sheet sheet = workbook.getSheetAt(SHEET_INDEX); + for (int rowIndex = 0; rowIndex < 10; rowIndex++) { + Row row = sheet.getRow(rowIndex); + if (row == null) { + row = sheet.createRow(rowIndex); + } + for (int colIndex = 0; colIndex < 10; colIndex++) { + Cell cell = row.getCell(colIndex); + if (cell == null) { + row.createCell(colIndex); + } + } + } + } + + @Test + public void givenWorkbookCell_whenSetRegionBorder() { + Sheet sheet = workbook.getSheetAt(SHEET_INDEX); + + CellRangeAddress region = new CellRangeAddress(1, 1, 1, 1); + cellBordersHandler.setRegionBorder(region, sheet, BorderStyle.THICK); + + Row row = sheet.getRow(1); + Cell cell = row.getCell(1); + assertEquals(cell.getCellStyle().getBorderTop(), BorderStyle.THICK); + assertEquals(cell.getCellStyle().getBorderBottom(), BorderStyle.THICK); + assertEquals(cell.getCellStyle().getBorderLeft(), BorderStyle.THICK); + assertEquals(cell.getCellStyle().getBorderRight(), BorderStyle.THICK); + } + + @Test + public void givenWorkbookCell_whenSetRegionBorderWithColor() { + Sheet sheet = workbook.getSheetAt(SHEET_INDEX); + + CellRangeAddress region = new CellRangeAddress(1, 1, 3, 3); + cellBordersHandler.setRegionBorderWithColor(region, sheet, BorderStyle.THICK, IndexedColors.MAROON.index); + + Row row = sheet.getRow(1); + Cell cell = row.getCell(1 + 2); + assertEquals(cell.getCellStyle().getBorderTop(), BorderStyle.THICK); + assertEquals(cell.getCellStyle().getBorderBottom(), BorderStyle.THICK); + assertEquals(cell.getCellStyle().getBorderLeft(), BorderStyle.THICK); + assertEquals(cell.getCellStyle().getBorderRight(), BorderStyle.THICK); + assertEquals(cell.getCellStyle().getTopBorderColor(), IndexedColors.MAROON.index); + assertEquals(cell.getCellStyle().getBottomBorderColor(), IndexedColors.MAROON.index); + assertEquals(cell.getCellStyle().getLeftBorderColor(), IndexedColors.MAROON.index); + assertEquals(cell.getCellStyle().getRightBorderColor(), IndexedColors.MAROON.index); + } + + @Test + public void givenWorkbookCell_whenSetCrazyBorder() { + Sheet sheet = workbook.getSheetAt(SHEET_INDEX); + + CellRangeAddress region = new CellRangeAddress(1, 1, 5, 5); + cellBordersHandler.setCrazyBorder(region, sheet); + + Row row = sheet.getRow(1); + Cell cell = row.getCell(5); + assertEquals(cell.getCellStyle().getBorderTop(), BorderStyle.DASH_DOT); + assertEquals(cell.getCellStyle().getBorderBottom(), BorderStyle.DOUBLE); + assertEquals(cell.getCellStyle().getBorderLeft(), BorderStyle.DOTTED); + assertEquals(cell.getCellStyle().getBorderRight(), BorderStyle.SLANTED_DASH_DOT); + assertEquals(cell.getCellStyle().getTopBorderColor(), IndexedColors.RED.index); + assertEquals(cell.getCellStyle().getBottomBorderColor(), IndexedColors.GREEN.index); + assertEquals(cell.getCellStyle().getLeftBorderColor(), IndexedColors.BLUE.index); + assertEquals(cell.getCellStyle().getRightBorderColor(), IndexedColors.VIOLET.index); + } + + @Test + public void givenWorkbookRegion_whenSetRegionBorder() { + Sheet sheet = workbook.getSheetAt(SHEET_INDEX); + + CellRangeAddress region = new CellRangeAddress(3, 5, 1, 5); + cellBordersHandler.setRegionBorder(region, sheet, BorderStyle.MEDIUM); + + Row row = sheet.getRow(3); + Cell cell = row.getCell(1); + assertEquals(cell.getCellStyle().getBorderTop(), BorderStyle.MEDIUM); + assertEquals(cell.getCellStyle().getBorderLeft(), BorderStyle.MEDIUM); + } + + @Test + public void givenWorkbookRegion_whenSetRegionBorderWithColor() { + Sheet sheet = workbook.getSheetAt(SHEET_INDEX); + + CellRangeAddress region = new CellRangeAddress(7, 8, 1, 5); + cellBordersHandler.setRegionBorderWithColor(region, sheet, BorderStyle.MEDIUM, IndexedColors.ORANGE.index); + + Row row = sheet.getRow(7); + Cell cell = row.getCell(1); + assertEquals(cell.getCellStyle().getBorderTop(), BorderStyle.MEDIUM); + assertEquals(cell.getCellStyle().getBorderLeft(), BorderStyle.MEDIUM); + assertEquals(cell.getCellStyle().getTopBorderColor(), IndexedColors.ORANGE.index); + assertEquals(cell.getCellStyle().getLeftBorderColor(), IndexedColors.ORANGE.index); + } + + @AfterClass + public static void close() throws IOException { + workbook.close(); + } +} diff --git a/apache-poi/src/test/java/com/baeldung/poi/excel/cellstyle/CellStyleHandlerUnitTest.java b/apache-poi/src/test/java/com/baeldung/poi/excel/cellstyle/CellStyleHandlerUnitTest.java new file mode 100644 index 0000000000..e131db8e56 --- /dev/null +++ b/apache-poi/src/test/java/com/baeldung/poi/excel/cellstyle/CellStyleHandlerUnitTest.java @@ -0,0 +1,56 @@ +package com.baeldung.poi.excel.cellstyle; + +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.Before; +import org.junit.Test; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URISyntaxException; +import java.nio.file.Paths; + +import static org.junit.Assert.assertEquals; + +public class CellStyleHandlerUnitTest { + private static final String FILE_NAME = "cellstyle/CellStyleHandlerTest.xlsx"; + private static final int SHEET_INDEX = 0; + private static final int ROW_INDEX = 0; + private static final int CELL_INDEX = 0; + + private String fileLocation; + private CellStyleHandler cellStyleHandler; + + @Before + public void setup() throws URISyntaxException { + fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString(); + cellStyleHandler = new CellStyleHandler(); + } + + @Test + public void givenWorkbookCell_whenChangeCellBackgroundColor() throws IOException { + Workbook workbook = new XSSFWorkbook(fileLocation); + Sheet sheet = workbook.getSheetAt(SHEET_INDEX); + Row row = sheet.getRow(ROW_INDEX); + Cell cell = row.getCell(CELL_INDEX); + + cellStyleHandler.changeCellBackgroundColor(cell); + + assertEquals(IndexedColors.LIGHT_BLUE.index, cell.getCellStyle().getFillForegroundColor()); + workbook.close(); + } + + @Test + public void givenWorkbookCell_whenChangeCellBackgroundColorWithPattern() throws IOException { + Workbook workbook = new XSSFWorkbook(fileLocation); + Sheet sheet = workbook.getSheetAt(SHEET_INDEX); + Row row = sheet.getRow(ROW_INDEX); + Cell cell = row.getCell(CELL_INDEX + 1); + + cellStyleHandler.changeCellBackgroundColorWithPattern(cell); + + assertEquals(IndexedColors.LIGHT_BLUE.index, cell.getCellStyle().getFillForegroundColor()); + workbook.close(); + } +} 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/apache-shiro/src/test/resources/logback-test.xml b/apache-shiro/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/apache-shiro/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/atomikos/pom.xml b/atomikos/pom.xml index cb10168c0d..cd798825d1 100644 --- a/atomikos/pom.xml +++ b/atomikos/pom.xml @@ -71,12 +71,6 @@ derby ${derby.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - javax.transaction diff --git a/aws-lambda/lambda/pom.xml b/aws-lambda/lambda/pom.xml index dea951d1b3..8bfe7a0ade 100644 --- a/aws-lambda/lambda/pom.xml +++ b/aws-lambda/lambda/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-modules + aws-lambda 1.0.0-SNAPSHOT - ../../ @@ -63,7 +62,8 @@ json-simple ${json-simple.version} - + junit junit diff --git a/aws-lambda/pom.xml b/aws-lambda/pom.xml index 3264356977..fc655f282d 100644 --- a/aws-lambda/pom.xml +++ b/aws-lambda/pom.xml @@ -11,7 +11,6 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ diff --git a/aws/pom.xml b/aws/pom.xml index 1663266612..7c363eb400 100644 --- a/aws/pom.xml +++ b/aws/pom.xml @@ -26,12 +26,6 @@ ${mockito-core.version} test - - org.assertj - assertj-core - ${assertj-core.version} - test - com.amazonaws aws-lambda-java-core @@ -118,7 +112,6 @@ 2.8.0 1.11.290 2.21.0 - 3.8.0 1.11.86 https://s3-us-west-2.amazonaws.com/dynamodb-local/release 1.10.L001 diff --git a/blade/pom.xml b/blade/pom.xml index 8fc517e966..9c8638f0bc 100644 --- a/blade/pom.xml +++ b/blade/pom.xml @@ -36,12 +36,6 @@ provided - - org.assertj - assertj-core - ${assertj-core.version} - test - org.apache.httpcomponents httpclient @@ -119,7 +113,6 @@ 4.5.6 4.5.6 4.4.10 - 3.11.1 3.0.0-M3 0.7 3.1.0 diff --git a/cdi/pom.xml b/cdi/pom.xml index 5eb566dcfb..ee23e082c7 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -25,12 +25,6 @@ weld-se-core ${weld-se-core.version} - - org.assertj - assertj-core - ${assertj-core.version} - test - org.aspectj aspectjweaver @@ -53,7 +47,6 @@ 2.0.SP1 3.0.5.Final 1.9.2 - 3.10.0 \ No newline at end of file diff --git a/cloud-foundry-uaa/cf-uaa-oauth2-client/pom.xml b/cloud-foundry-uaa/cf-uaa-oauth2-client/pom.xml index 74603bf0fb..7fcce181a3 100644 --- a/cloud-foundry-uaa/cf-uaa-oauth2-client/pom.xml +++ b/cloud-foundry-uaa/cf-uaa-oauth2-client/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + cloud-foundry-uaa 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/cloud-foundry-uaa/cf-uaa-oauth2-resource-server/pom.xml b/cloud-foundry-uaa/cf-uaa-oauth2-resource-server/pom.xml index 276c8bbaa6..4dffd4d768 100644 --- a/cloud-foundry-uaa/cf-uaa-oauth2-resource-server/pom.xml +++ b/cloud-foundry-uaa/cf-uaa-oauth2-resource-server/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + cloud-foundry-uaa 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/cloud-foundry-uaa/pom.xml b/cloud-foundry-uaa/pom.xml index 03a5b978d4..6ae43b2c08 100644 --- a/cloud-foundry-uaa/pom.xml +++ b/cloud-foundry-uaa/pom.xml @@ -4,14 +4,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 cloud-foundry-uaa - 0.0.1-SNAPSHOT cloud-foundry-uaa pom com.baeldung - parent-modules - 1.0.0-SNAPSHOT + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 diff --git a/core-java-modules/core-java-10/pom.xml b/core-java-modules/core-java-10/pom.xml index b293110546..e2ac8db919 100644 --- a/core-java-modules/core-java-10/pom.xml +++ b/core-java-modules/core-java-10/pom.xml @@ -12,7 +12,6 @@ com.baeldung.core-java-modules core-java-modules 0.0.1-SNAPSHOT - ../ @@ -40,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 68e8b66d67..b077373448 100644 --- a/core-java-modules/core-java-11-2/pom.xml +++ b/core-java-modules/core-java-11-2/pom.xml @@ -12,7 +12,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../.. + ../../pom.xml @@ -21,35 +21,11 @@ guava ${guava.version} - - org.assertj - assertj-core - ${assertj.version} - test - org.mock-server mockserver-junit-jupiter ${mockserver.version} - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-params - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - org.apache.commons commons-lang3 @@ -60,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 - @@ -106,13 +70,9 @@ 11 11 29.0-jre - 3.17.2 5.11.1 - 3.12.0 - 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/httpsclientauthentication/SSLScocketClient.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/httpsclientauthentication/SSLScocketClient.java new file mode 100644 index 0000000000..286ecfc9df --- /dev/null +++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/httpsclientauthentication/SSLScocketClient.java @@ -0,0 +1,41 @@ +package com.baeldung.httpsclientauthentication; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.net.SocketFactory; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + +public class SSLScocketClient { + + static void startClient(String host, int port) throws IOException { + + SocketFactory factory = SSLSocketFactory.getDefault(); + + try (SSLSocket socket = (SSLSocket) factory.createSocket(host, port)) { + socket.setEnabledCipherSuites(new String[] { "TLS_AES_128_GCM_SHA256" }); + socket.setEnabledProtocols(new String[] { "TLSv1.3" }); + InputStream is = new BufferedInputStream(socket.getInputStream()); + String message = "Hello World Message"; + System.out.println("sending message: " + message); + OutputStream os = new BufferedOutputStream(socket.getOutputStream()); + os.write(message.getBytes()); + os.flush(); + byte[] data = new byte[2048]; + int len = is.read(data); + if (len <= 0) { + throw new IOException("no data received"); + } + System.out.printf("client received %d bytes: %s%n", len, new String(data, 0, len)); + } + } + + public static void main(String[] args) throws IOException { + + startClient("localhost", 8443); + } +} diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/httpsclientauthentication/SSLSocketEchoServer.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/httpsclientauthentication/SSLSocketEchoServer.java new file mode 100644 index 0000000000..66efa18fe9 --- /dev/null +++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/httpsclientauthentication/SSLSocketEchoServer.java @@ -0,0 +1,46 @@ +package com.baeldung.httpsclientauthentication; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; + +import javax.net.ServerSocketFactory; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLServerSocketFactory; + +public class SSLSocketEchoServer { + + static void startServer(int port) throws IOException { + + ServerSocketFactory factory = SSLServerSocketFactory.getDefault(); + + try (SSLServerSocket listener = (SSLServerSocket) factory.createServerSocket(port)) { + listener.setNeedClientAuth(true); + listener.setEnabledCipherSuites(new String[] { "TLS_AES_128_GCM_SHA256" }); + listener.setEnabledProtocols(new String[] { "TLSv1.3" }); + System.out.println("listening for messages..."); + try (Socket socket = listener.accept()) { + InputStream is = new BufferedInputStream(socket.getInputStream()); + OutputStream os = new BufferedOutputStream(socket.getOutputStream()); + byte[] data = new byte[2048]; + int len = is.read(data); + if (len <= 0) { + throw new IOException("no data received"); + } + String message = new String(data, 0, len); + System.out.printf("server received %d bytes: %s%n", len, message); + String response = message + " processed by server"; + os.write(response.getBytes(), 0, response.getBytes().length); + os.flush(); + } + System.out.println("message processed, exiting"); + } + } + + public static void main(String[] args) throws IOException { + startServer(8443); + } +} \ 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-2/src/test/java/com/baeldung/version/VersionUnitTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/version/VersionManualTest.java
similarity index 92%
rename from core-java-modules/core-java-11-2/src/test/java/com/baeldung/version/VersionUnitTest.java
rename to core-java-modules/core-java-11-2/src/test/java/com/baeldung/version/VersionManualTest.java
index 128c7f60f4..74035a3e2f 100644
--- a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/version/VersionUnitTest.java
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/version/VersionManualTest.java
@@ -5,7 +5,8 @@ import org.assertj.core.api.Assertions;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
-public class VersionUnitTest {
+// manual test as the runtime JDK version can be different depending on where the test is run
+public class VersionManualTest {
 
     @Test
     public void givenJava_whenUsingRuntime_thenGetVersion() {
diff --git a/core-java-modules/core-java-11/pom.xml b/core-java-modules/core-java-11/pom.xml
index def7ab43f7..1fa5ae2b45 100644
--- a/core-java-modules/core-java-11/pom.xml
+++ b/core-java-modules/core-java-11/pom.xml
@@ -13,7 +13,8 @@
         com.baeldung
         parent-modules
         1.0.0-SNAPSHOT
-        ../..
+
+        ../../pom.xml
     
 
     
@@ -22,12 +23,6 @@
             guava
             ${guava.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.openjdk.jmh
             jmh-core
@@ -104,7 +99,6 @@
         11
         11
         27.1-jre
-        3.11.1
         benchmarks
         10.0.0
         3.2.4
diff --git a/core-java-modules/core-java-12/pom.xml b/core-java-modules/core-java-12/pom.xml
index 931fce820b..9f95b1bc3f 100644
--- a/core-java-modules/core-java-12/pom.xml
+++ b/core-java-modules/core-java-12/pom.xml
@@ -13,20 +13,13 @@
         com.baeldung
         parent-modules
         1.0.0-SNAPSHOT
-        ../../
     
 
     
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             commons-io
             commons-io
-            2.11.0
+            ${commons-io.version}
         
     
 
@@ -54,7 +47,6 @@
     
         12
         12
-        3.6.1
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-13/pom.xml b/core-java-modules/core-java-13/pom.xml
index 6369976580..9e42838971 100644
--- a/core-java-modules/core-java-13/pom.xml
+++ b/core-java-modules/core-java-13/pom.xml
@@ -14,18 +14,8 @@
         com.baeldung
         parent-modules
         1.0.0-SNAPSHOT
-        ../../
     
 
-    
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-    
-
     
         
             
@@ -53,7 +43,6 @@
     
         13
         13
-        3.6.1
         3.0.0-M3
     
 
diff --git a/core-java-modules/core-java-14/pom.xml b/core-java-modules/core-java-14/pom.xml
index a03332d8bc..35ea0bd2d0 100644
--- a/core-java-modules/core-java-14/pom.xml
+++ b/core-java-modules/core-java-14/pom.xml
@@ -12,30 +12,8 @@
         com.baeldung
         parent-modules
         1.0.0-SNAPSHOT
-        ../../
     
 
-    
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-        
-            org.junit.jupiter
-            junit-jupiter-engine
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.jupiter
-            junit-jupiter-api
-            ${junit-jupiter.version}
-            test
-        
-    
-
     
         
             
@@ -62,7 +40,6 @@
 
     
         14
-        3.6.1
         3.8.1
         3.0.0-M3
     
diff --git a/core-java-modules/core-java-15/pom.xml b/core-java-modules/core-java-15/pom.xml
index 091f0568a7..8cb6c2410d 100644
--- a/core-java-modules/core-java-15/pom.xml
+++ b/core-java-modules/core-java-15/pom.xml
@@ -21,24 +21,6 @@
             commons-lang3
             ${commons-lang3.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-        
-            org.junit.jupiter
-            junit-jupiter-engine
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.jupiter
-            junit-jupiter-api
-            ${junit-jupiter.version}
-            test
-        
     
 
     
@@ -67,7 +49,6 @@
 
     
         15
-        3.17.2
         3.8.1
         3.0.0-M3
     
diff --git a/core-java-modules/core-java-16/pom.xml b/core-java-modules/core-java-16/pom.xml
index 5d10325f03..4adc3ee6d1 100644
--- a/core-java-modules/core-java-16/pom.xml
+++ b/core-java-modules/core-java-16/pom.xml
@@ -17,29 +17,11 @@
     
 
     
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.apache.commons
             commons-lang3
-            3.12.0
+            ${commons-lang3.version}
         
-		
-			org.junit.jupiter
-			junit-jupiter-engine
-			${junit-jupiter.version}
-			test
-		
-		
-			org.junit.jupiter
-			junit-jupiter-api
-			${junit-jupiter.version}
-			test
-		
     
 
     
@@ -50,37 +32,35 @@
                 ${maven-compiler-plugin.version}
                 
                     ${maven.compiler.release}
-					--enable-preview
+                    --enable-preview
                     ${maven.compiler.source.version}
                     ${maven.compiler.target.version}
                 
             
-			
-				org.apache.maven.plugins
-				maven-surefire-plugin
-				${surefire.plugin.version}
-				
-					--enable-preview
-					1
-				
-				
-					
-						org.apache.maven.surefire
-						surefire-api
-						${surefire.plugin.version}
-					
-				
-			
+            
+                org.apache.maven.plugins
+                maven-surefire-plugin
+                ${surefire.plugin.version}
+                
+                    --enable-preview
+                    1
+                
+                
+                    
+                        org.apache.maven.surefire
+                        surefire-api
+                        ${surefire.plugin.version}
+                    
+                
+            
         
     
 
     
         16
         16
-		16
-		3.8.1
-		3.0.0-M5
-		3.17.2
+        16
+        3.0.0-M5
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-17/README.md b/core-java-modules/core-java-17/README.md
index 074c5e4f86..688ef2845d 100644
--- a/core-java-modules/core-java-17/README.md
+++ b/core-java-modules/core-java-17/README.md
@@ -1,3 +1,5 @@
 ### Relevant articles:
 
 - [Pattern Matching for Switch](https://www.baeldung.com/java-switch-pattern-matching)
+- [Introduction to HexFormat in Java 17](https://www.baeldung.com/java-hexformat)
+- [New Features in Java 17](https://www.baeldung.com/java-17-new-features)
diff --git a/core-java-modules/core-java-17/pom.xml b/core-java-modules/core-java-17/pom.xml
index f9a7ec326b..2fe16cad57 100644
--- a/core-java-modules/core-java-17/pom.xml
+++ b/core-java-modules/core-java-17/pom.xml
@@ -16,27 +16,6 @@
         ../../
     
 
-    
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-		
-			org.junit.jupiter
-			junit-jupiter-engine
-			${junit-jupiter.version}
-			test
-		
-		
-			org.junit.jupiter
-			junit-jupiter-api
-			${junit-jupiter.version}
-			test
-		
-    
-
     
         
             
@@ -50,32 +29,31 @@
                     ${maven.compiler.target.version}
                 
             
-			
-				org.apache.maven.plugins
-				maven-surefire-plugin
-				${surefire.plugin.version}
-				
-					--enable-preview
-					1
-				
-				
-					
-						org.apache.maven.surefire
-						surefire-api
-						${surefire.plugin.version}
-					
-				
-			
+            
+                org.apache.maven.plugins
+                maven-surefire-plugin
+                ${surefire.plugin.version}
+                
+                    --enable-preview
+                    --enable-native-access=core.java
+                    1
+                
+                
+                    
+                        org.apache.maven.surefire
+                        surefire-api
+                        ${surefire.plugin.version}
+                    
+                
+            
         
     
 
     
         17
         17
-		17
-		3.8.1
-		3.0.0-M5
-		3.17.2
+        17
+        3.0.0-M5
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java
new file mode 100644
index 0000000000..0890b025be
--- /dev/null
+++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java
@@ -0,0 +1,20 @@
+package com.baeldung.features;
+
+import java.util.random.RandomGeneratorFactory;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+public class JEP356 {
+
+    public Stream getAllAlgorithms() {
+        return RandomGeneratorFactory.all().map(RandomGeneratorFactory::name);
+    }
+
+    public IntStream getPseudoInts(String algorithm, int streamSize) {
+        // returns an IntStream with size @streamSize of random numbers generated using the @algorithm
+        // where the lower bound is 0 and the upper is 100 (exclusive)
+        return RandomGeneratorFactory.of(algorithm)
+                .create()
+                .ints(streamSize, 0,100);
+    }
+}
diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java
new file mode 100644
index 0000000000..2bc3a664d1
--- /dev/null
+++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java
@@ -0,0 +1,28 @@
+package com.baeldung.features;
+
+import com.baeldung.features.JEP409.Circle;
+import com.baeldung.features.JEP409.Shape;
+import com.baeldung.features.JEP409.Triangle;
+
+public class JEP406 {
+
+    static record Human (String name, int age, String profession) {}
+
+    public String checkObject(Object obj) {
+        return switch (obj) {
+            case Human h -> "Name: %s, age: %s and profession: %s".formatted(h.name(), h.age(), h.profession());
+            case Circle c -> "This is a circle";
+            case Shape s -> "It is just a shape";
+            case null -> "It is null";
+            default -> "It is an object";
+        };
+    }
+
+    public String checkShape(Shape shape) {
+        return switch (shape) {
+            case Triangle t && (t.getNumberOfSides() != 3) -> "This is a weird triangle";
+            case Circle c && (c.getNumberOfSides() != 0) -> "This is a weird circle";
+            default -> "Just a normal shape";
+        };
+    }
+}
diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java
new file mode 100644
index 0000000000..0fc3d6f467
--- /dev/null
+++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java
@@ -0,0 +1,38 @@
+package com.baeldung.features;
+
+public class JEP409 {
+
+    sealed interface Shape permits Rectangle, Circle, Square, Triangle {
+        int getNumberOfSides();
+    }
+
+    static final class Rectangle implements Shape {
+        @Override
+        public int getNumberOfSides() {
+            return 4;
+        }
+    }
+
+    static final class Circle implements Shape {
+        @Override
+        public int getNumberOfSides() {
+            return 0;
+        }
+    }
+
+    static final class Square implements Shape {
+        @Override
+        public int getNumberOfSides() {
+            return 4;
+        }
+    }
+
+    static non-sealed class Triangle implements Shape {
+
+        @Override
+        public int getNumberOfSides() {
+            return 3;
+        }
+    }
+
+}
diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java
new file mode 100644
index 0000000000..8c998629c9
--- /dev/null
+++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java
@@ -0,0 +1,56 @@
+package com.baeldung.features;
+
+import jdk.incubator.foreign.CLinker;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.SymbolLookup;
+
+import java.io.IOException;
+import java.lang.invoke.MethodType;
+
+import static jdk.incubator.foreign.ResourceScope.newImplicitScope;
+
+public class JEP412 {
+
+    private static final SymbolLookup libLookup;
+
+    static {
+        var resource = JEP412.class.getResource("/compile_c.sh");
+        try {
+            var process = new ProcessBuilder("sh", resource.getPath()).start();
+            while (process.isAlive()) {}
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        }
+
+        var path = JEP412.class.getResource("/print_name.so").getPath();
+        System.load(path);
+        libLookup = SymbolLookup.loaderLookup();
+    }
+
+    public String getPrintNameFormat(String name){
+
+        var printMethod = libLookup.lookup("printName");
+
+        if (printMethod.isPresent()) {
+            var methodReference = CLinker.getInstance()
+                .downcallHandle(
+                    printMethod.get(),
+                    MethodType.methodType(MemoryAddress.class, MemoryAddress.class),
+                    FunctionDescriptor.of(CLinker.C_POINTER, CLinker.C_POINTER)
+                );
+
+            try {
+                var nativeString = CLinker.toCString(name, newImplicitScope());
+                var invokeReturn = methodReference.invoke(nativeString.address());
+                var memoryAddress = (MemoryAddress) invokeReturn;
+                return CLinker.toJavaString(memoryAddress);
+            } catch (Throwable throwable) {
+                throw new RuntimeException(throwable);
+            }
+        }
+        throw new RuntimeException("printName function not found.");
+    }
+}
+
+
diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java
new file mode 100644
index 0000000000..aaccc4a665
--- /dev/null
+++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java
@@ -0,0 +1,27 @@
+package com.baeldung.features;
+
+import jdk.incubator.vector.FloatVector;
+import jdk.incubator.vector.VectorSpecies;
+
+public class JEP414 {
+
+    private static final VectorSpecies SPECIES = FloatVector.SPECIES_PREFERRED;
+
+
+    public void newVectorComputation(float[] a, float[] b, float[] c) {
+        for (var i = 0; i < a.length; i += SPECIES.length()) {
+            var m = SPECIES.indexInRange(i, a.length);
+            var va = FloatVector.fromArray(SPECIES, a, i, m);
+            var vb = FloatVector.fromArray(SPECIES, b, i, m);
+            var vc = va.mul(vb);
+            vc.intoArray(c, i, m);
+        }
+    }
+
+    public void commonVectorComputation(float[] a, float[] b, float[] c) {
+        for (var i = 0; i < a.length; i ++) {
+            c[i] = a[i] * b[i];
+        }
+    }
+
+}
diff --git a/core-java-modules/core-java-17/src/main/java/module-info.java b/core-java-modules/core-java-17/src/main/java/module-info.java
new file mode 100644
index 0000000000..b1ce62aa68
--- /dev/null
+++ b/core-java-modules/core-java-17/src/main/java/module-info.java
@@ -0,0 +1,4 @@
+module core.java {
+    requires jdk.incubator.vector;
+    requires jdk.incubator.foreign;
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-17/src/main/resources/compile_c.sh b/core-java-modules/core-java-17/src/main/resources/compile_c.sh
new file mode 100755
index 0000000000..d2e0629cc5
--- /dev/null
+++ b/core-java-modules/core-java-17/src/main/resources/compile_c.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
+
+gcc -c -fPIC $SCRIPTPATH/print_name.c
+gcc -shared -rdynamic -o print_name.so print_name.o
+
+mv print_name.so $SCRIPTPATH/
+mv print_name.o $SCRIPTPATH/
\ No newline at end of file
diff --git a/core-java-modules/core-java-17/src/main/resources/print_name.c b/core-java-modules/core-java-17/src/main/resources/print_name.c
new file mode 100644
index 0000000000..7bda12e352
--- /dev/null
+++ b/core-java-modules/core-java-17/src/main/resources/print_name.c
@@ -0,0 +1,8 @@
+#include
+#include
+
+char* printName(char *name) {
+    char* newString = (char*)malloc((15 + sizeof(name))*sizeof(char));
+    sprintf(newString, "Your name is %s", name);
+    return newString;
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java
new file mode 100644
index 0000000000..b4f61a6f24
--- /dev/null
+++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java
@@ -0,0 +1,19 @@
+package com.baeldung.features;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class JEP356UnitTest {
+
+    @Test
+    void getPseudoInts_whenUsingAlgorithmXoroshiro128PlusPlus_shouldReturnStreamOfRandomInteger() {
+        var algorithm = "Xoshiro256PlusPlus";
+        var streamSize = 100;
+
+        JEP356 jep356 = new JEP356();
+
+        jep356.getPseudoInts(algorithm, streamSize)
+            .forEach(value -> assertThat(value).isLessThanOrEqualTo(99));
+    }
+}
diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java
new file mode 100644
index 0000000000..87e6f3bec6
--- /dev/null
+++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.features;
+
+import com.baeldung.features.JEP406.Human;
+import com.baeldung.features.JEP409.Square;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class JEP406UnitTest {
+
+    @Test
+    void checkObject_shouldMatchWithHuman() {
+        var jep406 = new JEP406();
+
+        var human = new Human("John", 31, "Developer");
+
+        var checkResult = jep406.checkObject(human);
+
+        assertEquals("Name: John, age: 31 and profession: Developer", checkResult);
+    }
+
+    @Test
+    void checkShape_shouldMatchWithShape() {
+        var jep406 = new JEP406();
+
+        var square = new Square();
+
+        var checkResult = jep406.checkShape(square);
+
+        assertEquals("Just a normal shape", checkResult);
+    }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java
new file mode 100644
index 0000000000..41380ec2bb
--- /dev/null
+++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.features;
+
+import com.baeldung.features.JEP409.*;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+class JEP409UnitTest {
+
+    static class WeirdTriangle extends Triangle {
+        @Override public int getNumberOfSides() {
+            return 40;
+        }
+    }
+
+    @Test
+    void testSealedClass_shouldInvokeRightClass() {
+
+        Shape shape = spy(new WeirdTriangle());
+
+        int numberOfSides = getNumberOfSides(shape);
+
+        assertEquals(40, numberOfSides);
+        verify(shape).getNumberOfSides();
+    }
+
+    int getNumberOfSides(Shape shape) {
+        return switch (shape) {
+            case WeirdTriangle t -> t.getNumberOfSides();
+            case Circle c -> c.getNumberOfSides();
+            case Triangle t -> t.getNumberOfSides();
+            case Rectangle r -> r.getNumberOfSides();
+            case Square s -> s.getNumberOfSides();
+        };
+    }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java
new file mode 100644
index 0000000000..66e7d952c7
--- /dev/null
+++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.features;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class JEP412UnitTest {
+
+    @Test
+    void getPrintNameFormat_whenPassingAName_shouldReceiveItFormatted() {
+        var jep412 = new JEP412();
+
+        var formattedName = jep412.getPrintNameFormat("John");
+
+        assertEquals("Your name is John", formattedName);
+    }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java
new file mode 100644
index 0000000000..459344d907
--- /dev/null
+++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java
@@ -0,0 +1,38 @@
+package com.baeldung.features;
+
+import org.junit.jupiter.api.Test;
+
+import static java.util.stream.Collectors.toList;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class JEP414UnitTest {
+
+    @Test
+    void vectorComputation_shouldMultiplyVectors() {
+        var jep414 = new JEP414();
+
+        float[] a = initArray(100);
+        float[] b = initArray(100);
+        float[] c = new float[100];
+        float[] d = new float[100];
+
+        jep414.newVectorComputation(a, b, c);
+        jep414.commonVectorComputation(a, b, d);
+
+        for (int i = 0; i < a.length; i++) {
+            assertEquals(c[i], d[i]);
+        }
+    }
+
+    private float[] initArray(int size) {
+        final var jep356 = new JEP356();
+        final var values = new float[size];
+        final var pseudoInts = jep356.getPseudoInts("Xoshiro256PlusPlus", size).mapToObj(Float::valueOf).collect(toList());
+
+        for (int i = 0; i < pseudoInts.size(); i++) {
+            values[i] = pseudoInts.get(i);
+        }
+
+        return values;
+    }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java
new file mode 100644
index 0000000000..29b6eb1bee
--- /dev/null
+++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java
@@ -0,0 +1,23 @@
+package com.baeldung.hexformat;
+
+import java.util.HexFormat;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class ByteHexadecimalConversionUnitTest {
+
+    private HexFormat hexFormat = HexFormat.of();
+
+    @Test
+    void givenInitialisedHexFormat_whenHexStringIsPassed_thenByteArrayRepresentationIsReturned() {
+        byte[] hexBytes = hexFormat.parseHex("ABCDEF0123456789");
+        assertArrayEquals(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119 }, hexBytes);
+    }
+
+    @Test
+    void givenInitialisedHexFormat_whenByteArrayIsPassed_thenHexStringRepresentationIsReturned() {
+        String bytesAsString = hexFormat.formatHex(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119});
+        assertEquals("abcdef0123456789", bytesAsString);
+    }
+}
diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java
new file mode 100644
index 0000000000..6f26a8351c
--- /dev/null
+++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.hexformat;
+
+import java.util.HexFormat;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class PrimitiveTypeHexadecimalConversionUnitTest {
+
+    private HexFormat hexFormat = HexFormat.of();
+
+    @Test
+    void givenInitialisedHexFormat_whenPrimitiveByteIsPassed_thenHexStringRepresentationIsReturned() {
+        String fromByte = hexFormat.toHexDigits((byte)64);
+        assertEquals("40", fromByte);
+    }
+
+    @Test
+    void givenInitialisedHexFormat_whenPrimitiveLongIsPassed_thenHexStringRepresentationIsReturned() {
+        String fromLong = hexFormat.toHexDigits(1234_5678_9012_3456L);
+        assertEquals("000462d53c8abac0", fromLong);
+    }
+}
diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java
new file mode 100644
index 0000000000..28189d0e8c
--- /dev/null
+++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java
@@ -0,0 +1,15 @@
+package com.baeldung.hexformat;
+
+import java.util.HexFormat;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class StringFormattingUnitTest {
+
+    private HexFormat hexFormat = HexFormat.of().withPrefix("[").withSuffix("]").withDelimiter(", ");
+
+    @Test
+    public void givenInitialisedHexFormatWithFormattedStringOptions_whenByteArrayIsPassed_thenHexStringRepresentationFormattedCorrectlyIsReturned() {
+        assertEquals("[48], [0c], [11]", hexFormat.formatHex(new byte[] {72, 12, 17}));
+    }
+}
diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java
new file mode 100644
index 0000000000..c2a33fb4b5
--- /dev/null
+++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java
@@ -0,0 +1,40 @@
+package com.baeldung.hexformat;
+
+import java.util.HexFormat;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class UppercaseLowercaseOutputUnitTest {
+
+    @Test
+    public void givenInitialisedHexFormat_whenByteArrayIsPassed_thenLowerCaseHexStringRepresentationIsReturned() {
+        HexFormat hexFormat = HexFormat.of();
+        String bytesAsString = hexFormat.formatHex(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119});
+        assertTrue(isLowerCase(bytesAsString));
+    }
+
+    @Test
+    public void givenInitialisedHexFormatWithUpperCaseOption_whenByteArrayIsPassed_thenLowerCaseHexStringRepresentationIsReturned() {
+        HexFormat hexFormat = HexFormat.of().withUpperCase();
+        String bytesAsString = hexFormat.formatHex(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119});
+        assertTrue(isUpperCase(bytesAsString));
+    }
+
+    private boolean isLowerCase(String str) {
+        char[] charArray = str.toCharArray();
+        for (int i=0; i < charArray.length; i++) {
+            if (Character.isUpperCase(charArray[i]))
+                return false;
+        }
+        return true;
+    }
+
+    private boolean isUpperCase(String str) {
+        char[] charArray = str.toCharArray();
+        for (int i=0; i < charArray.length; i++) {
+            if (Character.isLowerCase(charArray[i]))
+                return false;
+        }
+        return true;
+    }
+}
diff --git a/core-java-modules/core-java-8-2/pom.xml b/core-java-modules/core-java-8-2/pom.xml
index af26289db8..7db1e1ed4e 100644
--- a/core-java-modules/core-java-8-2/pom.xml
+++ b/core-java-modules/core-java-8-2/pom.xml
@@ -20,17 +20,10 @@
             icu4j
             ${icu.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
         64.2
-        3.12.2
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-8-datetime-2/pom.xml b/core-java-modules/core-java-8-datetime-2/pom.xml
index e662ba400c..9e54b0ee12 100644
--- a/core-java-modules/core-java-8-datetime-2/pom.xml
+++ b/core-java-modules/core-java-8-datetime-2/pom.xml
@@ -25,12 +25,6 @@
             joda-time
             ${joda-time.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             log4j
             log4j
@@ -63,8 +57,6 @@
         1.8
         1.8
         2.10
-        
-        3.6.1
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-8-datetime/pom.xml b/core-java-modules/core-java-8-datetime/pom.xml
index f58557df7f..01ec6c0b76 100644
--- a/core-java-modules/core-java-8-datetime/pom.xml
+++ b/core-java-modules/core-java-8-datetime/pom.xml
@@ -25,12 +25,6 @@
             joda-time
             ${joda-time.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             log4j
             log4j
@@ -64,8 +58,6 @@
         1.8
         1.8
         2.10
-        
-        3.6.1
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-8/pom.xml b/core-java-modules/core-java-8/pom.xml
index 987ba2e568..89925bdbbb 100644
--- a/core-java-modules/core-java-8/pom.xml
+++ b/core-java-modules/core-java-8/pom.xml
@@ -31,13 +31,6 @@
             ${lombok.version}
             provided
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -50,11 +43,4 @@
         
     
 
-    
-        
-        4.1
-        
-        3.6.1
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-9-improvements/pom.xml b/core-java-modules/core-java-9-improvements/pom.xml
index 6abdd7dab8..e6c596937b 100644
--- a/core-java-modules/core-java-9-improvements/pom.xml
+++ b/core-java-modules/core-java-9-improvements/pom.xml
@@ -21,12 +21,6 @@
             ${awaitility.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             com.google.guava
             guava
@@ -68,8 +62,6 @@
     
 
     
-        
-        3.10.0
         1.7.0
         1.9
         1.9
diff --git a/core-java-modules/core-java-9-jigsaw/src/test/java/com/baeldung/java9/modules/ModuleAPIUnitTest.java b/core-java-modules/core-java-9-jigsaw/src/test/java/com/baeldung/java9/modules/ModuleAPIUnitTest.java
index b909636b56..f6ea266676 100644
--- a/core-java-modules/core-java-9-jigsaw/src/test/java/com/baeldung/java9/modules/ModuleAPIUnitTest.java
+++ b/core-java-modules/core-java-9-jigsaw/src/test/java/com/baeldung/java9/modules/ModuleAPIUnitTest.java
@@ -16,6 +16,7 @@ import java.util.stream.Collectors;
 
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.Ignore;
 
 public class ModuleAPIUnitTest {
 
@@ -110,6 +111,7 @@ public class ModuleAPIUnitTest {
     }
 
     @Test
+    @Ignore // fixing in http://team.baeldung.com/browse/JAVA-8679
     public void givenModules_whenAccessingModuleDescriptorProvides_thenProvidesAreReturned() {
         Set javaBaseProvides = javaBaseModule.getDescriptor().provides();
         Set javaSqlProvides = javaSqlModule.getDescriptor().provides();
diff --git a/core-java-modules/core-java-9-new-features/pom.xml b/core-java-modules/core-java-9-new-features/pom.xml
index 7dca8d5f88..ce90a0f04a 100644
--- a/core-java-modules/core-java-9-new-features/pom.xml
+++ b/core-java-modules/core-java-9-new-features/pom.xml
@@ -20,12 +20,6 @@
             rxjava
             ${rxjava.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.junit.platform
             junit-platform-runner
@@ -156,8 +150,6 @@
 
     
         3.0.0
-        
-        3.10.0
         4.0.2
         1.9
         1.9
diff --git a/core-java-modules/core-java-9/pom.xml b/core-java-modules/core-java-9/pom.xml
index 1bd650f7d2..274d9ccb43 100644
--- a/core-java-modules/core-java-9/pom.xml
+++ b/core-java-modules/core-java-9/pom.xml
@@ -21,12 +21,6 @@
             ${awaitility.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             com.google.guava
             guava
@@ -78,14 +72,10 @@
     
 
     
-        
-        3.10.0
         1.7.0
         1.9
         1.9
         25.1-jre
-        4.1
-        3.2.2
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-annotations/pom.xml b/core-java-modules/core-java-annotations/pom.xml
index a87baa6204..a1f84ab563 100644
--- a/core-java-modules/core-java-annotations/pom.xml
+++ b/core-java-modules/core-java-annotations/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
     core-java-annotations
     0.1.0-SNAPSHOT
@@ -14,19 +14,6 @@
         0.0.1-SNAPSHOT
     
 
-    
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
-    
-
-    
-        3.10.0
-    
-
     
         core-java-annotations
         
@@ -37,4 +24,4 @@
         
     
 
-
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-arrays-guides/pom.xml b/core-java-modules/core-java-arrays-guides/pom.xml
index 3dba2dc05f..d22f6b4d7d 100644
--- a/core-java-modules/core-java-arrays-guides/pom.xml
+++ b/core-java-modules/core-java-arrays-guides/pom.xml
@@ -24,12 +24,6 @@
             jmh-generator-annprocess
             ${jmh-generator.version}
         
-        
-            org.assertj
-            assertj-core
-            3.19.0
-            test
-        
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-arrays-operations-advanced/pom.xml b/core-java-modules/core-java-arrays-operations-advanced/pom.xml
index 065f1930e2..cbcd6ae440 100644
--- a/core-java-modules/core-java-arrays-operations-advanced/pom.xml
+++ b/core-java-modules/core-java-arrays-operations-advanced/pom.xml
@@ -19,32 +19,18 @@
             commons-lang3
             ${commons-lang3.version}
         
-
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
-
         
             org.openjdk.jmh
             jmh-core
-            ${jmh.version}
+            ${jmh-core.version}
         
-
         
             org.openjdk.jmh
             jmh-generator-annprocess
-            ${jmh.version}
+            ${jmh-generator.version}
         
     
 
-    
-        3.10.0
-        1.33
-    
-
     
         
             
diff --git a/core-java-modules/core-java-arrays-operations-basic/pom.xml b/core-java-modules/core-java-arrays-operations-basic/pom.xml
index 382cee102d..6517b2efb9 100644
--- a/core-java-modules/core-java-arrays-operations-basic/pom.xml
+++ b/core-java-modules/core-java-arrays-operations-basic/pom.xml
@@ -30,12 +30,6 @@
             jmh-generator-annprocess
             ${jmh-generator.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
     
 
     
@@ -67,7 +61,6 @@
 
     
         3.2.0
-        3.10.0
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-arrays-sorting/pom.xml b/core-java-modules/core-java-arrays-sorting/pom.xml
index e9946d46ed..97ff95e92b 100644
--- a/core-java-modules/core-java-arrays-sorting/pom.xml
+++ b/core-java-modules/core-java-arrays-sorting/pom.xml
@@ -36,13 +36,6 @@
             jmh-generator-annprocess
             ${jmh-generator.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
     
 
     
@@ -75,7 +68,6 @@
     
         3.2.0
         28.2-jre
-        3.10.0
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-char/pom.xml b/core-java-modules/core-java-char/pom.xml
index 009197a1d0..7dc0923fb5 100644
--- a/core-java-modules/core-java-char/pom.xml
+++ b/core-java-modules/core-java-char/pom.xml
@@ -15,12 +15,6 @@
     
 
     
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.openjdk.jmh
             jmh-core
@@ -33,8 +27,4 @@
         
     
 
-    
-        3.11.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 0f1f1ee2fe..e78f7b5dda 100644
--- a/core-java-modules/core-java-collections-2/pom.xml
+++ b/core-java-modules/core-java-collections-2/pom.xml
@@ -34,12 +34,6 @@
             commons-lang3
             ${commons-lang3.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.junit.platform
             junit-platform-runner
@@ -50,8 +44,6 @@
 
     
         7.1.0
-        4.1
-        3.11.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/pom.xml b/core-java-modules/core-java-collections-3/pom.xml
index 4ca4bda1ee..6ef8e3c81a 100644
--- a/core-java-modules/core-java-collections-3/pom.xml
+++ b/core-java-modules/core-java-collections-3/pom.xml
@@ -25,12 +25,6 @@
             jmh-core
             ${jmh-core.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.apache.commons
             commons-lang3
@@ -39,7 +33,6 @@
     
 
     
-        3.11.1
         0.10
     
 
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/pom.xml b/core-java-modules/core-java-collections-4/pom.xml
index d86b04644c..2193b5118a 100644
--- a/core-java-modules/core-java-collections-4/pom.xml
+++ b/core-java-modules/core-java-collections-4/pom.xml
@@ -14,17 +14,4 @@
         0.0.1-SNAPSHOT
     
 
-    
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-    
-
-    
-        3.19.0
-    
-
 
\ No newline at end of file
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 c14e59bac0..6b040739e8 100644
--- a/core-java-modules/core-java-collections-array-list/pom.xml
+++ b/core-java-modules/core-java-collections-array-list/pom.xml
@@ -20,17 +20,6 @@
             commons-collections4
             ${commons-collections4.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
-    
-        4.1
-        3.11.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 51e66fc0c2..59ab8c5f27 100644
--- a/core-java-modules/core-java-collections-list-2/pom.xml
+++ b/core-java-modules/core-java-collections-list-2/pom.xml
@@ -20,12 +20,6 @@
             commons-collections4
             ${commons-collections4.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.projectlombok
             lombok
@@ -34,9 +28,4 @@
         
     
 
-    
-        4.1
-        3.11.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 efe79509c1..3bb0fb4a33 100644
--- a/core-java-modules/core-java-collections-list-3/pom.xml
+++ b/core-java-modules/core-java-collections-list-3/pom.xml
@@ -26,12 +26,6 @@
             ${guava.version}
             compile
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             net.sf.trove4j
             trove4j
@@ -60,8 +54,6 @@
     
 
     
-        4.1
-        3.11.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 ae1e1561c6..0cc8828a0d 100644
--- a/core-java-modules/core-java-collections-list/pom.xml
+++ b/core-java-modules/core-java-collections-list/pom.xml
@@ -25,17 +25,6 @@
             commons-lang3
             ${commons-lang3.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
-    
-        4.1
-        3.11.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 772cf30416..36b15c24d5 100644
--- a/core-java-modules/core-java-collections-maps-2/pom.xml
+++ b/core-java-modules/core-java-collections-maps-2/pom.xml
@@ -51,22 +51,14 @@
             ${avaitility.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
         0.6.5
-        4.1
         1.7.0
         8.2.0
         0.7.2
         8.1.0
-        3.11.1
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-collections-maps-4/README.md b/core-java-modules/core-java-collections-maps-4/README.md
index 54ab60da7d..795f0df702 100644
--- a/core-java-modules/core-java-collections-maps-4/README.md
+++ b/core-java-modules/core-java-collections-maps-4/README.md
@@ -4,3 +4,5 @@ This module contains articles about Map data structures in Java.
 
 ### Relevant Articles: 
 - [Using a Custom Class as a Key in a Java HashMap](https://www.baeldung.com/java-custom-class-map-key)
+- [Nested HashMaps Examples in Java](https://www.baeldung.com/java-nested-hashmaps)
+- [Java HashMap With Different Value Types](https://www.baeldung.com/java-hashmap-different-value-types)
diff --git a/core-java-modules/core-java-collections-maps-4/pom.xml b/core-java-modules/core-java-collections-maps-4/pom.xml
index 1835e3ceac..c5296e9a43 100644
--- a/core-java-modules/core-java-collections-maps-4/pom.xml
+++ b/core-java-modules/core-java-collections-maps-4/pom.xml
@@ -1,34 +1,49 @@
 
 
-    4.0.0
-    core-java-collections-maps-4
-    0.1.0-SNAPSHOT
-    core-java-collections-maps-4
-    jar
+	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
+	core-java-collections-maps-4
+	0.1.0-SNAPSHOT
+	core-java-collections-maps-4
+	jar
 
-    
-        com.baeldung.core-java-modules
-        core-java-modules
-        0.0.1-SNAPSHOT
-        ../pom.xml
-    
+	
+		com.baeldung.core-java-modules
+		core-java-modules
+		0.0.1-SNAPSHOT
+		../pom.xml
+	
+	
+	
+	    UTF-8
+		1.8
+		1.8
+	
 
-    
-        
-            
-                
-                    org.apache.maven.plugins
-                    maven-surefire-plugin
-                    3.0.0-M5
-                    
-                        
-                        !performance
-                    
-                
-            
-        
-    
+	
+		
+			junit
+			junit
+			${junit.version}
+			test
+		
+	
 
-
+	
+		
+			
+				
+					org.apache.maven.plugins
+					maven-surefire-plugin
+					3.0.0-M5
+					
+						
+						!performance
+					
+				
+			
+		
+	
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java
new file mode 100644
index 0000000000..410758405e
--- /dev/null
+++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java
@@ -0,0 +1,32 @@
+package com.baeldung.nestedhashmaps;
+
+public class Address {
+
+    private Integer addressId;
+    private String addressLocation;
+
+    public Address() {
+    }
+
+    public Address(Integer addressId, String addressLocation) {
+        this.addressId = addressId;
+        this.addressLocation = addressLocation;
+    }
+
+    public Integer getAddressId() {
+        return addressId;
+    }
+
+    public void setAddressId(Integer addressId) {
+        this.addressId = addressId;
+    }
+
+    public String getAddressLocation() {
+        return addressLocation;
+    }
+
+    public void setAddressLocation(String addressLocation) {
+        this.addressLocation = addressLocation;
+    }
+
+}
diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java
new file mode 100644
index 0000000000..2ab54ff17c
--- /dev/null
+++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java
@@ -0,0 +1,43 @@
+package com.baeldung.nestedhashmaps;
+
+public class Employee {
+
+    private Integer employeeId;
+    private Address address;
+    private String employeeName;
+
+    public Employee() {
+        super();
+    }
+
+    public Employee(Integer employeeId, Address address, String employeeName) {
+        this.employeeId = employeeId;
+        this.address = address;
+        this.employeeName = employeeName;
+    }
+
+    public Integer getEmployeeId() {
+        return employeeId;
+    }
+
+    public void setEmployeeId(Integer employeeId) {
+        this.employeeId = employeeId;
+    }
+
+    public Address getAddress() {
+        return address;
+    }
+
+    public void setAddress(Address address) {
+        this.address = address;
+    }
+
+    public String getEmployeeName() {
+        return employeeName;
+    }
+
+    public void setEmployeeName(String employeeName) {
+        this.employeeName = employeeName;
+    }
+
+}
diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java
new file mode 100644
index 0000000000..53781b0bc1
--- /dev/null
+++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java
@@ -0,0 +1,57 @@
+package com.baeldung.nestedhashmaps;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
+
+public class MapsUtil {
+
+    MapsUtil() {
+        super();
+    }
+
+    public Map buildInnerMap(List batterList) {
+        Map innerBatterMap = new HashMap();
+
+        int index = 1;
+        for (String item : batterList) {
+            innerBatterMap.put(index, item);
+            index++;
+        }
+
+        return innerBatterMap;
+    }
+
+    public Map> createNestedMapfromStream(List listEmployee) {
+        Map> employeeAddressMap = listEmployee.stream()
+                .collect(Collectors.groupingBy(e -> e.getAddress().getAddressId(),
+                        Collectors.toMap(f -> f.getAddress().getAddressLocation(), Employee::getEmployeeName)));
+        return employeeAddressMap;
+    }
+
+    public Map> createNestedObjectMap(List listEmployee) {
+        Map> employeeMap = new HashMap<>();
+
+        employeeMap = listEmployee.stream().collect(Collectors.groupingBy((Employee emp) -> emp.getEmployeeId(),
+                Collectors.toMap((Employee emp) -> emp.getAddress().getAddressId(), fEmpObj -> fEmpObj.getAddress())));
+
+        return employeeMap;
+    }
+
+    public Map flattenMap(Map source) {
+        Map converted = new HashMap<>();
+
+        for (Entry entry : source.entrySet()) {
+            if (entry.getValue() instanceof Map) {
+                flattenMap((Map) entry.getValue())
+                        .forEach((key, value) -> converted.put(entry.getKey() + "." + key, value));
+            } else {
+                converted.put(entry.getKey().toString(), entry.getValue().toString());
+            }
+        }
+        return converted;
+    }
+
+}
diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java
new file mode 100644
index 0000000000..ce63b72527
--- /dev/null
+++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java
@@ -0,0 +1,118 @@
+package com.baeldung.nestedhashmaps;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import java.util.List;
+
+public class NestedHashMapExamplesClass {
+    public static void main(String[] args) {
+
+        MapsUtil mUtil = new MapsUtil();
+
+        List batterList = new ArrayList<>();
+        Map> outerBakedGoodsMap = new HashMap<>();
+        Map> outerBakedGoodsMap2 = new HashMap<>();
+        Map> outerBakedGoodsMap3 = new HashMap<>();
+        Map> outerBakedGoodsMap4 = new HashMap<>();
+
+        batterList.add("Mulberry");
+        batterList.add("Cranberry");
+        batterList.add("Blackberry");
+        batterList.add("Mixed fruit");
+        batterList.add("Orange");
+
+        outerBakedGoodsMap.put("Cake", mUtil.buildInnerMap(batterList));
+
+        batterList.clear();
+        batterList.add("Candy");
+        batterList.add("Dark Chocolate");
+        batterList.add("Chocolate");
+        batterList.add("Jam filled");
+        batterList.add("Pineapple");
+
+        outerBakedGoodsMap.put("Donut", mUtil.buildInnerMap(batterList));
+
+        outerBakedGoodsMap2.put("Eclair", mUtil.buildInnerMap(batterList));
+        outerBakedGoodsMap2.put("Donut", mUtil.buildInnerMap(batterList));
+
+        outerBakedGoodsMap3.put("Cake", mUtil.buildInnerMap(batterList));
+        batterList.clear();
+        batterList.add("Banana");
+        batterList.add("Red Velvet");
+        batterList.add("Blackberry");
+        batterList.add("Passion fruit");
+        batterList.add("Kiwi");
+
+        outerBakedGoodsMap3.put("Donut", mUtil.buildInnerMap(batterList));
+
+        outerBakedGoodsMap4.putAll(outerBakedGoodsMap);
+
+        System.out.println(outerBakedGoodsMap.equals(outerBakedGoodsMap2));
+        System.out.println(outerBakedGoodsMap.equals(outerBakedGoodsMap3));
+        System.out.println(outerBakedGoodsMap.equals(outerBakedGoodsMap4));
+
+        outerBakedGoodsMap.get("Cake")
+            .put(6, "Cranberry");
+        System.out.println(outerBakedGoodsMap);
+
+        outerBakedGoodsMap.get("Cake")
+            .remove(5);
+        System.out.println(outerBakedGoodsMap);
+
+        outerBakedGoodsMap.put("Eclair", new HashMap() {
+            {
+                put(1, "Dark Chocolate");
+            }
+        });
+
+        System.out.println(outerBakedGoodsMap);
+        outerBakedGoodsMap.remove("Eclair");
+        System.out.println(outerBakedGoodsMap);
+        System.out.println("Baked Goods Map Flattened: " + mUtil.flattenMap(outerBakedGoodsMap));
+
+        // Employees Map
+        List listEmployee = new ArrayList();
+
+        listEmployee.add(new Employee(1, new Address(124, "Timbuktoo"), "Thorin Oakenshield"));
+        listEmployee.add(new Employee(2, new Address(100, "Misty Lanes"), "Balin"));
+        listEmployee.add(new Employee(3, new Address(156, "Bramles Lane"), "Bofur"));
+        listEmployee.add(new Employee(4, new Address(200, "Bag End"), "Bilbo Baggins"));
+        listEmployee.add(new Employee(5, new Address(23, "Rivendell"), "Elrond"));
+
+        Map> employeeAddressMap = mUtil.createNestedMapfromStream(listEmployee);
+
+        Map> employeeMap = mUtil.createNestedObjectMap(listEmployee);
+        Map> employeeMap2 = mUtil.createNestedObjectMap(listEmployee);
+
+        listEmployee.clear();
+        listEmployee.add(new Employee(1, new Address(500, "Timbuktoo"), "Thorin Oakenshield"));
+        listEmployee.add(new Employee(2, new Address(600, "Misty Lanes"), "Balin"));
+        listEmployee.add(new Employee(3, new Address(700, "Bramles Lane"), "Bofur"));
+        listEmployee.add(new Employee(4, new Address(800, "Bag End"), "Bilbo Baggins"));
+        listEmployee.add(new Employee(5, new Address(900, "Rivendell"), "Elrond"));
+
+        Map> employeeAddressMap1 = mUtil.createNestedMapfromStream(listEmployee);
+
+        Map> employeeMap1 = mUtil.createNestedObjectMap(listEmployee);
+
+        System.out.println(employeeMap.equals(employeeMap1));
+        System.out.println(employeeMap.equals(employeeMap2));
+
+        for (Map.Entry> outerBakedGoodsMapEntrySet : outerBakedGoodsMap.entrySet()) {
+            Map valueMap = outerBakedGoodsMapEntrySet.getValue();
+            System.out.println(valueMap.entrySet());
+        }
+
+        for (Map.Entry> employeeEntrySet : employeeAddressMap.entrySet()) {
+            Map valueMap = employeeEntrySet.getValue();
+            System.out.println(valueMap.entrySet());
+        }
+
+        System.out.println("Employee Address Map Flattened: " + mUtil.flattenMap(employeeAddressMap));
+
+        System.out.println(employeeAddressMap.equals(employeeAddressMap1));
+    }
+
+}
diff --git a/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java b/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java
new file mode 100644
index 0000000000..a86e329bea
--- /dev/null
+++ b/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java
@@ -0,0 +1,243 @@
+package com.baeldung.nestedhashmaps;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertThat;
+import org.hamcrest.collection.IsMapContaining;
+
+public class NestedHashMapExamplesClassUnitTest {
+    private MapsUtil mUtil = new MapsUtil();
+    private List batterList = new ArrayList<>();
+    private List listEmployee = new ArrayList();
+    private Map> actualBakedGoodsMap = new HashMap<>();
+    private Map> actualEmployeeAddressMap = new HashMap<>();
+    private Map> actualEmployeeMap = new HashMap<>();
+
+    @Test
+    public void whenCreateNestedHashMap_thenNestedMap() {
+        assertThat(mUtil.buildInnerMap(batterList), is(notNullValue()));
+        Assert.assertEquals(actualBakedGoodsMap.keySet().size(), 2);
+        Assert.assertThat(actualBakedGoodsMap, IsMapContaining.hasValue(equalTo(mUtil.buildInnerMap(batterList))));
+    }
+
+    private Map> setup() {
+        Map> expectedMap = new HashMap<>();
+        expectedMap.put(Integer.valueOf(100), new HashMap() {
+            {
+                put("Misty Lanes", "Balin");
+            }
+        });
+        expectedMap.put(Integer.valueOf(200), new HashMap() {
+            {
+                put("Bag End", "Bilbo Baggins");
+            }
+        });
+        expectedMap.put(Integer.valueOf(156), new HashMap() {
+            {
+                put("Brambles Lane", "Bofur");
+            }
+        });
+        expectedMap.put(Integer.valueOf(124), new HashMap() {
+            {
+                put("Timbuktoo", "Thorin Oakenshield");
+            }
+        });
+        expectedMap.put(Integer.valueOf(23), new HashMap() {
+            {
+                put("Rivendell", "Elrond");
+            }
+        });
+
+        return expectedMap;
+    }
+
+    @Test
+    public void whenCreateNestedHashMapwithStreams_thenNestedMap() {
+
+        Map> expectedMap = setup();
+
+        assertThat(actualEmployeeAddressMap, equalTo(expectedMap));
+    }
+
+    @Test
+    public void whenCompareTwoHashMapswithDifferenctValues_usingEquals_thenFail() {
+        Map> outerBakedGoodsMap2 = new HashMap<>();
+        outerBakedGoodsMap2.put("Eclair", mUtil.buildInnerMap(batterList));
+        outerBakedGoodsMap2.put("Donut", mUtil.buildInnerMap(batterList));
+        assertNotEquals(outerBakedGoodsMap2, actualBakedGoodsMap);
+
+        Map> outerBakedGoodsMap3 = new HashMap>();
+        outerBakedGoodsMap3.put("Cake", mUtil.buildInnerMap(batterList));
+        batterList = new ArrayList<>();
+        batterList = Arrays.asList("Banana", "Red Velvet", "Blackberry", "Passion fruit", "Kiwi");
+
+        outerBakedGoodsMap3.put("Donut", mUtil.buildInnerMap(batterList));
+
+        assertNotEquals(outerBakedGoodsMap2, actualBakedGoodsMap);
+
+        listEmployee.clear();
+        listEmployee.add(new Employee(1, new Address(500, "Timbuktoo"), "Thorin Oakenshield"));
+        listEmployee.add(new Employee(2, new Address(600, "Misty Lanes"), "Balin"));
+        listEmployee.add(new Employee(3, new Address(700, "Bramles Lane"), "Bofur"));
+        listEmployee.add(new Employee(4, new Address(800, "Bag End"), "Bilbo Baggins"));
+        listEmployee.add(new Employee(5, new Address(900, "Rivendell"), "Elrond"));
+
+        Map> employeeAddressMap1 = mUtil.createNestedMapfromStream(listEmployee);
+
+        Map> employeeMap1 = mUtil.createNestedObjectMap(listEmployee);
+
+        assertNotEquals(employeeAddressMap1, actualEmployeeAddressMap);
+
+        assertNotEquals(employeeMap1, actualEmployeeMap);
+    }
+
+    @Test
+    public void whencomparingDifferentObjectValuesUsingEquals_thenFail() {
+        listEmployee.clear();
+        listEmployee.add(new Employee(1, new Address(124, "Timbuktoo"), "Thorin Oakenshield"));
+        listEmployee.add(new Employee(2, new Address(100, "Misty Lanes"), "Balin"));
+        listEmployee.add(new Employee(3, new Address(156, "Brambles Lane"), "Bofur"));
+        listEmployee.add(new Employee(4, new Address(200, "Bag End"), "Bilbo Baggins"));
+        listEmployee.add(new Employee(5, new Address(23, "Rivendell"), "Elrond"));
+
+        Map> employeeMap1 = listEmployee.stream().collect(Collectors.groupingBy(
+                (Employee emp) -> emp.getEmployeeId(),
+                Collectors.toMap((Employee emp) -> emp.getAddress().getAddressId(), fEmpObj -> fEmpObj.getAddress())));
+
+        assertNotSame(employeeMap1, actualEmployeeMap);
+        assertNotEquals(employeeMap1, actualEmployeeMap);
+
+        Map> expectedMap = setupAddressObjectMap();
+        assertNotSame(expectedMap, actualEmployeeMap);
+        assertNotEquals(expectedMap, actualEmployeeMap);
+
+    }
+
+    @Test
+    public void whenCompareTwoHashMapsUsingEquals_thenSuccess() {
+        Map> outerBakedGoodsMap4 = new HashMap<>();
+        outerBakedGoodsMap4.putAll(actualBakedGoodsMap);
+
+        assertEquals(actualBakedGoodsMap, outerBakedGoodsMap4);
+
+        Map> employeeMap1 = new HashMap<>();
+        employeeMap1.putAll(actualEmployeeMap);
+        assertEquals(actualEmployeeMap, employeeMap1);
+    }
+
+    @Test
+    public void whenAddElementinHashMaps_thenSuccess() {
+        assertEquals(actualBakedGoodsMap.get("Cake").size(), 5);
+        actualBakedGoodsMap.get("Cake").put(6, "Cranberry");
+        assertEquals(actualBakedGoodsMap.get("Cake").size(), 6);
+    }
+
+    @Test
+    public void whenDeleteElementinHashMaps_thenSuccess() {
+        assertNotEquals(actualBakedGoodsMap.get("Cake").get(5), null);
+        actualBakedGoodsMap.get("Cake").remove(5);
+        assertEquals(actualBakedGoodsMap.get("Cake").get(5), null);
+
+        actualBakedGoodsMap.put("Eclair", new HashMap() {
+            {
+                put(1, "Dark Chocolate");
+            }
+        });
+
+        assertNotEquals(actualBakedGoodsMap.get("Eclair").get(1), null);
+        actualBakedGoodsMap.get("Eclair").remove(1);
+        assertEquals(actualBakedGoodsMap.get("Eclair").get(1), null);
+
+        actualBakedGoodsMap.put("Eclair", new HashMap() {
+            {
+                put(1, "Dark Chocolate");
+            }
+        });
+
+        assertNotEquals(actualBakedGoodsMap.get("Eclair"), null);
+        actualBakedGoodsMap.remove("Eclair");
+        assertEquals(actualBakedGoodsMap.get("Eclair"), null);
+    }
+
+    @Test
+    public void whenFlattenMap_thenRemovesNesting() {
+
+        Map flattenedBakedGoodsMap = mUtil.flattenMap(actualBakedGoodsMap);
+        assertThat(flattenedBakedGoodsMap, IsMapContaining.hasKey("Donut.2"));
+
+        Map flattenedEmployeeAddressMap = mUtil.flattenMap(actualEmployeeAddressMap);
+        assertThat(flattenedEmployeeAddressMap, IsMapContaining.hasKey("200.Bag End"));
+    }
+
+    @Before
+    public void buildMaps() {
+
+        batterList = Arrays.asList("Mulberry", "Cranberry", "Blackberry", "Mixed fruit", "Orange");
+
+        actualBakedGoodsMap.put("Cake", mUtil.buildInnerMap(batterList));
+
+        batterList = new ArrayList<>();
+        batterList = Arrays.asList("Candy", "Dark Chocolate", "Chocolate", "Jam filled", "Pineapple");
+
+        actualBakedGoodsMap.put("Donut", mUtil.buildInnerMap(batterList));
+
+        listEmployee.add(new Employee(1, new Address(124, "Timbuktoo"), "Thorin Oakenshield"));
+        listEmployee.add(new Employee(2, new Address(100, "Misty Lanes"), "Balin"));
+        listEmployee.add(new Employee(3, new Address(156, "Brambles Lane"), "Bofur"));
+        listEmployee.add(new Employee(4, new Address(200, "Bag End"), "Bilbo Baggins"));
+        listEmployee.add(new Employee(5, new Address(23, "Rivendell"), "Elrond"));
+
+        actualEmployeeAddressMap = mUtil.createNestedMapfromStream(listEmployee);
+
+        actualEmployeeMap = mUtil.createNestedObjectMap(listEmployee);
+
+    }
+
+    private Map> setupAddressObjectMap() {
+
+        Map> expectedMap = new HashMap<>();
+
+        expectedMap.put(1, new HashMap() {
+            {
+                put(124, new Address(124, "Timbuktoo"));
+            }
+        });
+        expectedMap.put(2, new HashMap() {
+            {
+                put(100, new Address(100, "Misty Lanes"));
+            }
+        });
+        expectedMap.put(3, new HashMap() {
+            {
+                put(156, new Address(156, "Brambles Lane"));
+            }
+        });
+        expectedMap.put(4, new HashMap() {
+            {
+                put(200, new Address(200, "Bag End"));
+            }
+        });
+        expectedMap.put(5, new HashMap() {
+            {
+                put(23, new Address(23, "Rivendell"));
+            }
+        });
+        return expectedMap;
+    }
+
+}
diff --git a/core-java-modules/core-java-collections-maps/pom.xml b/core-java-modules/core-java-collections-maps/pom.xml
index 245c4b04bb..34b878df53 100644
--- a/core-java-modules/core-java-collections-maps/pom.xml
+++ b/core-java-modules/core-java-collections-maps/pom.xml
@@ -20,17 +20,6 @@
             commons-collections4
             ${commons-collections4.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
-    
-        4.1
-        3.6.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 b8940f4a68..0b6e324c78 100644
--- a/core-java-modules/core-java-collections-set/pom.xml
+++ b/core-java-modules/core-java-collections-set/pom.xml
@@ -12,7 +12,6 @@
         com.baeldung.core-java-modules
         core-java-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
@@ -50,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 8fbc6e8de7..eab7a35584 100644
--- a/core-java-modules/core-java-collections/pom.xml
+++ b/core-java-modules/core-java-collections/pom.xml
@@ -15,12 +15,6 @@
     
 
     
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.openjdk.jmh
             jmh-core
@@ -31,10 +25,11 @@
             jmh-generator-annprocess
             ${jmh-generator.version}
         
+        
+            org.apache.commons
+            commons-lang3
+            ${commons-lang3.version}
+        
     
 
-    
-        3.11.1
-    
-
 
\ 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-2/pom.xml b/core-java-modules/core-java-concurrency-2/pom.xml
index b8a1d641d4..c61f28a6b3 100644
--- a/core-java-modules/core-java-concurrency-2/pom.xml
+++ b/core-java-modules/core-java-concurrency-2/pom.xml
@@ -15,11 +15,6 @@
     
 
     
-        
-            org.junit.vintage
-            junit-vintage-engine
-            test
-        
         
             com.googlecode.thread-weaver
             threadweaver
@@ -31,6 +26,12 @@
             tempus-fugit
             ${tempus-fugit.version}
             test
+            
+                
+                    junit
+                    junit
+                
+            
         
         
             com.googlecode.multithreadedtc
diff --git a/core-java-modules/core-java-concurrency-advanced-2/pom.xml b/core-java-modules/core-java-concurrency-advanced-2/pom.xml
index 93c23ccae7..1f19dc8cca 100644
--- a/core-java-modules/core-java-concurrency-advanced-2/pom.xml
+++ b/core-java-modules/core-java-concurrency-advanced-2/pom.xml
@@ -30,12 +30,6 @@
             jmh-generator-annprocess
             ${jmh-generator.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -48,8 +42,4 @@
         
     
 
-    
-        3.6.1
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-concurrency-advanced-3/pom.xml b/core-java-modules/core-java-concurrency-advanced-3/pom.xml
index 915aa8d912..591e46f505 100644
--- a/core-java-modules/core-java-concurrency-advanced-3/pom.xml
+++ b/core-java-modules/core-java-concurrency-advanced-3/pom.xml
@@ -15,12 +15,6 @@
     
 
     
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             com.jcabi
             jcabi-aspects
@@ -94,7 +88,6 @@
     
 
     
-        3.14.0
         1.8
         1.8
         0.22.6
diff --git a/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/abaproblem/Account.java b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/abaproblem/Account.java
index ee1bdcd55b..2af3113549 100644
--- a/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/abaproblem/Account.java
+++ b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/abaproblem/Account.java
@@ -3,17 +3,18 @@ package com.baeldung.abaproblem;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterruptibly;
+
 public class Account {
 
-    private AtomicInteger balance;
-    private AtomicInteger transactionCount;
-    private ThreadLocal currentThreadCASFailureCount;
+    private final AtomicInteger balance;
+    private final AtomicInteger transactionCount;
+    private final ThreadLocal currentThreadCASFailureCount;
 
     public Account() {
         this.balance = new AtomicInteger(0);
         this.transactionCount = new AtomicInteger(0);
-        this.currentThreadCASFailureCount = new ThreadLocal<>();
-        this.currentThreadCASFailureCount.set(0);
+        this.currentThreadCASFailureCount = ThreadLocal.withInitial(() -> 0);
     }
 
     public int getBalance() {
@@ -43,11 +44,7 @@ public class Account {
 
     private void maybeWait() {
         if ("thread1".equals(Thread.currentThread().getName())) {
-            try {
-                TimeUnit.SECONDS.sleep(2);
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-            }
+            sleepUninterruptibly(2, TimeUnit.SECONDS);
         }
     }
 
diff --git a/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountUnitTest.java b/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountUnitTest.java
index aa5f0f7997..3e188d682e 100644
--- a/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountUnitTest.java
+++ b/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountUnitTest.java
@@ -1,8 +1,13 @@
 package com.baeldung.abaproblem;
 
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -30,45 +35,39 @@ public class AccountUnitTest {
         assertTrue(account.deposit(moneyToDeposit));
 
         assertEquals(moneyToDeposit, account.getBalance());
+        assertEquals(1, account.getTransactionCount());
     }
 
     @Test
-    public void withdrawTest() throws InterruptedException {
+    public void withdrawTest() {
         final int defaultBalance = 50;
         final int moneyToWithdraw = 20;
 
         account.deposit(defaultBalance);
 
         assertTrue(account.withdraw(moneyToWithdraw));
-
         assertEquals(defaultBalance - moneyToWithdraw, account.getBalance());
     }
 
     @Test
-    public void abaProblemTest() throws InterruptedException {
+    public void abaProblemTest() throws Exception {
         final int defaultBalance = 50;
 
         final int amountToWithdrawByThread1 = 20;
         final int amountToWithdrawByThread2 = 10;
         final int amountToDepositByThread2 = 10;
 
-        assertEquals(0, account.getTransactionCount());
-        assertEquals(0, account.getCurrentThreadCASFailureCount());
         account.deposit(defaultBalance);
-        assertEquals(1, account.getTransactionCount());
-
-        Thread thread1 = new Thread(() -> {
 
+        Runnable thread1 = () -> {
             // this will take longer due to the name of the thread
             assertTrue(account.withdraw(amountToWithdrawByThread1));
 
             // thread 1 fails to capture ABA problem
             assertNotEquals(1, account.getCurrentThreadCASFailureCount());
+        };
 
-        }, "thread1");
-
-        Thread thread2 = new Thread(() -> {
-
+        Runnable thread2 = () -> {
             assertTrue(account.deposit(amountToDepositByThread2));
             assertEquals(defaultBalance + amountToDepositByThread2, account.getBalance());
 
@@ -79,12 +78,13 @@ public class AccountUnitTest {
             assertEquals(defaultBalance, account.getBalance());
 
             assertEquals(0, account.getCurrentThreadCASFailureCount());
-        }, "thread2");
+        };
 
-        thread1.start();
-        thread2.start();
-        thread1.join();
-        thread2.join();
+        Future future1 = getSingleThreadExecutorService("thread1").submit(thread1);
+        Future future2 = getSingleThreadExecutorService("thread2").submit(thread2);
+
+        future1.get();
+        future2.get();
 
         // compareAndSet operation succeeds for thread 1
         assertEquals(defaultBalance - amountToWithdrawByThread1, account.getBalance());
@@ -95,4 +95,10 @@ public class AccountUnitTest {
         // thread 2 did two modifications as well
         assertEquals(4, account.getTransactionCount());
     }
+
+    private static ExecutorService getSingleThreadExecutorService(String threadName) {
+        return Executors.newSingleThreadExecutor(
+          new ThreadFactoryBuilder().setNameFormat(threadName).build()
+        );
+    }
 }
diff --git a/core-java-modules/core-java-concurrency-advanced/pom.xml b/core-java-modules/core-java-concurrency-advanced/pom.xml
index 3c21b49ae5..b50a66cefc 100644
--- a/core-java-modules/core-java-concurrency-advanced/pom.xml
+++ b/core-java-modules/core-java-concurrency-advanced/pom.xml
@@ -35,12 +35,6 @@
             commons-math3
             ${commons-math3.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             com.jayway.awaitility
             awaitility
@@ -60,13 +54,9 @@
     
 
     
-        
         21.0
         3.6.1
-        4.1
         4.01
-        
-        3.6.1
         1.7.0
     
 
diff --git a/core-java-modules/core-java-concurrency-basic/pom.xml b/core-java-modules/core-java-concurrency-basic/pom.xml
index 7212a2dcb1..1e3157291a 100644
--- a/core-java-modules/core-java-concurrency-basic/pom.xml
+++ b/core-java-modules/core-java-concurrency-basic/pom.xml
@@ -20,12 +20,6 @@
             commons-lang3
             ${commons-lang3.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             com.jayway.awaitility
             awaitility
@@ -45,8 +39,6 @@
     
 
     
-        
-        3.6.1
         1.7.0
     
 
diff --git a/core-java-modules/core-java-concurrency-collections-2/pom.xml b/core-java-modules/core-java-concurrency-collections-2/pom.xml
index 8de0e1bef7..02c046b2ea 100644
--- a/core-java-modules/core-java-concurrency-collections-2/pom.xml
+++ b/core-java-modules/core-java-concurrency-collections-2/pom.xml
@@ -29,18 +29,10 @@
             jmh-generator-annprocess
             ${jmh-generator.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
         28.2-jre
-        
-        3.6.1
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-concurrency-collections/pom.xml b/core-java-modules/core-java-concurrency-collections/pom.xml
index f22da1c848..8b8d2fe03b 100644
--- a/core-java-modules/core-java-concurrency-collections/pom.xml
+++ b/core-java-modules/core-java-concurrency-collections/pom.xml
@@ -14,15 +14,6 @@
         0.0.1-SNAPSHOT
     
 
-    
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-    
-
     
         core-java-concurrency-collections
         
@@ -33,9 +24,4 @@
         
     
 
-    
-        
-        3.6.1
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-date-operations-1/pom.xml b/core-java-modules/core-java-date-operations-1/pom.xml
index 7b7c68d1b6..ea9f94fa56 100644
--- a/core-java-modules/core-java-date-operations-1/pom.xml
+++ b/core-java-modules/core-java-date-operations-1/pom.xml
@@ -12,7 +12,6 @@
         com.baeldung.core-java-modules
         core-java-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
@@ -26,16 +25,11 @@
             commons-lang3
             ${commons-lang3.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
+
         
             com.darwinsys
             hirondelle-date4j
-            RELEASE
+            ${hirondelle-date4j.version}
             test
         
     
@@ -63,8 +57,7 @@
 
     
         2.10
-        
-        3.6.1
+        RELEASE
         1.9
         1.9
     
diff --git a/core-java-modules/core-java-date-operations-2/pom.xml b/core-java-modules/core-java-date-operations-2/pom.xml
index 1d283851ca..f60c7b7fc0 100644
--- a/core-java-modules/core-java-date-operations-2/pom.xml
+++ b/core-java-modules/core-java-date-operations-2/pom.xml
@@ -30,18 +30,11 @@
             hirondelle-date4j
             ${hirondelle-date4j.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
         2.10
         1.5.1
-        3.14.0
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-datetime-conversion/pom.xml b/core-java-modules/core-java-datetime-conversion/pom.xml
index 8f082e2793..6e9aeaf5af 100644
--- a/core-java-modules/core-java-datetime-conversion/pom.xml
+++ b/core-java-modules/core-java-datetime-conversion/pom.xml
@@ -31,13 +31,6 @@
             log4j
             ${log4j.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -63,8 +56,6 @@
 
     
         2.10
-        
-        3.6.1
         1.9
         1.9
     
diff --git a/core-java-modules/core-java-datetime-string/pom.xml b/core-java-modules/core-java-datetime-string/pom.xml
index f50eb2ae5e..2b3c2edb02 100644
--- a/core-java-modules/core-java-datetime-string/pom.xml
+++ b/core-java-modules/core-java-datetime-string/pom.xml
@@ -12,7 +12,6 @@
         com.baeldung.core-java-modules
         core-java-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
@@ -32,13 +31,6 @@
             log4j
             ${log4j.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             joda-time
             joda-time
@@ -47,7 +39,7 @@
         
             com.darwinsys
             hirondelle-date4j
-            RELEASE
+            ${hirondelle-date4j.version}
             test
         
     
@@ -76,8 +68,7 @@
     
         1.6
         2.10.10
-        
-        3.6.1
+        RELEASE
         1.9
         1.9
     
diff --git a/core-java-modules/core-java-exceptions-2/pom.xml b/core-java-modules/core-java-exceptions-2/pom.xml
index af7a778b23..9103672cd4 100644
--- a/core-java-modules/core-java-exceptions-2/pom.xml
+++ b/core-java-modules/core-java-exceptions-2/pom.xml
@@ -15,24 +15,11 @@
     
 
     
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             org.apache.commons
             commons-lang3
-            ${commons.lang3.version}
+            ${commons-lang3.version}
         
     
 
-    
-        3.10
-        
-        3.10.0
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-exceptions-3/pom.xml b/core-java-modules/core-java-exceptions-3/pom.xml
index bdee998e8d..18dc52932e 100644
--- a/core-java-modules/core-java-exceptions-3/pom.xml
+++ b/core-java-modules/core-java-exceptions-3/pom.xml
@@ -19,21 +19,13 @@
         
             com.h2database
             h2
-            1.4.191
-            test
-        
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
+            ${h2.version}
             test
         
     
 
     
-        
-        3.10.0
+        1.4.191
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/SynchronizedReceiver.java b/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/SynchronizedReceiver.java
index ff6b926cdc..8b0aa95153 100644
--- a/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/SynchronizedReceiver.java
+++ b/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/SynchronizedReceiver.java
@@ -4,7 +4,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class SynchronizedReceiver implements Runnable {
-    private static Logger log = LoggerFactory.getLogger(SynchronizedReceiver.class);
+
+    private static final Logger LOG = LoggerFactory.getLogger(SynchronizedReceiver.class);
+
     private final Data data;
     private String message;
     private boolean illegalMonitorStateExceptionOccurred;
@@ -20,10 +22,10 @@ public class SynchronizedReceiver implements Runnable {
                 data.wait();
                 this.message = data.receive();
             } catch (InterruptedException e) {
-                log.error("thread was interrupted", e);
+                LOG.error("thread was interrupted", e);
                 Thread.currentThread().interrupt();
             } catch (IllegalMonitorStateException e) {
-                log.error("illegal monitor state exception occurred", e);
+                LOG.error("illegal monitor state exception occurred", e);
                 illegalMonitorStateExceptionOccurred = true;
             }
         }
diff --git a/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/SynchronizedSender.java b/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/SynchronizedSender.java
index 1618bc8efa..8317b5ade7 100644
--- a/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/SynchronizedSender.java
+++ b/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/SynchronizedSender.java
@@ -4,7 +4,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class SynchronizedSender implements Runnable {
-    private static Logger log = LoggerFactory.getLogger(SynchronizedSender.class);
+
+    private static final Logger LOG = LoggerFactory.getLogger(SynchronizedSender.class);
+
     private final Data data;
     private boolean illegalMonitorStateExceptionOccurred;
 
@@ -22,10 +24,10 @@ public class SynchronizedSender implements Runnable {
 
                 data.notifyAll();
             } catch (InterruptedException e) {
-                log.error("thread was interrupted", e);
+                LOG.error("thread was interrupted", e);
                 Thread.currentThread().interrupt();
             } catch (IllegalMonitorStateException e) {
-                log.error("illegal monitor state exception occurred", e);
+                LOG.error("illegal monitor state exception occurred", e);
                 illegalMonitorStateExceptionOccurred = true;
             }
         }
diff --git a/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/UnsynchronizedReceiver.java b/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/UnsynchronizedReceiver.java
index 3a0b72e6cd..69fb363731 100644
--- a/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/UnsynchronizedReceiver.java
+++ b/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/UnsynchronizedReceiver.java
@@ -4,7 +4,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class UnsynchronizedReceiver implements Runnable {
-    private static Logger log = LoggerFactory.getLogger(UnsynchronizedReceiver.class);
+    private static final Logger LOG = LoggerFactory.getLogger(UnsynchronizedReceiver.class);
+
     private final Data data;
     private String message;
     private boolean illegalMonitorStateExceptionOccurred;
@@ -19,10 +20,10 @@ public class UnsynchronizedReceiver implements Runnable {
             data.wait();
             this.message = data.receive();
         } catch (InterruptedException e) {
-            log.error("thread was interrupted", e);
+            LOG.error("thread was interrupted", e);
             Thread.currentThread().interrupt();
         } catch (IllegalMonitorStateException e) {
-            log.error("illegal monitor state exception occurred", e);
+            LOG.error("illegal monitor state exception occurred", e);
             illegalMonitorStateExceptionOccurred = true;
         }
     }
diff --git a/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/UnsynchronizedSender.java b/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/UnsynchronizedSender.java
index 7f15418bfa..b97453f655 100644
--- a/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/UnsynchronizedSender.java
+++ b/core-java-modules/core-java-exceptions-3/src/main/java/com/baeldung/exceptions/illegalmonitorstate/UnsynchronizedSender.java
@@ -4,7 +4,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class UnsynchronizedSender implements Runnable {
-    private static Logger log = LoggerFactory.getLogger(UnsynchronizedSender.class);
+    private static final Logger LOG = LoggerFactory.getLogger(UnsynchronizedSender.class);
+
     private final Data data;
     private boolean illegalMonitorStateExceptionOccurred;
 
@@ -21,10 +22,10 @@ public class UnsynchronizedSender implements Runnable {
 
             data.notifyAll();
         } catch (InterruptedException e) {
-            log.error("thread was interrupted", e);
+            LOG.error("thread was interrupted", e);
             Thread.currentThread().interrupt();
         } catch (IllegalMonitorStateException e) {
-            log.error("illegal monitor state exception occurred", e);
+            LOG.error("illegal monitor state exception occurred", e);
             illegalMonitorStateExceptionOccurred = true;
         }
     }
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 82c00bc72f..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,8 +1,11 @@
 package com.baeldung.exceptions.illegalmonitorstate;
 
-import org.junit.jupiter.api.Test;
+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 static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.Test;
 
 public class IllegalMonitorStateExceptionUnitTest {
 
@@ -18,10 +21,9 @@ public class IllegalMonitorStateExceptionUnitTest {
         Thread senderThread = new Thread(sender, "sender-thread");
         senderThread.start();
 
-        senderThread.join(1000);
-        receiverThread.join(1000);
-        
-        Thread.sleep(2000);
+        // we need to wait for the sender and receiver threads to finish
+        senderThread.join(10_000);
+        receiverThread.join(10_000);
 
         assertEquals("test", receiver.getMessage());
         assertFalse(sender.hasIllegalMonitorStateExceptionOccurred());
diff --git a/core-java-modules/core-java-exceptions/pom.xml b/core-java-modules/core-java-exceptions/pom.xml
index 1f15dabe36..f1f60120a5 100644
--- a/core-java-modules/core-java-exceptions/pom.xml
+++ b/core-java-modules/core-java-exceptions/pom.xml
@@ -30,22 +30,12 @@
         
             org.apache.commons
             commons-lang3
-            ${commons.lang3.version}
-        
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
+            ${commons-lang3.version}
         
     
 
     
         1.5.0-b01
-        3.10
-        
-        3.10.0
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-function/pom.xml b/core-java-modules/core-java-function/pom.xml
index cc44ba5a7c..a3add5a686 100644
--- a/core-java-modules/core-java-function/pom.xml
+++ b/core-java-modules/core-java-function/pom.xml
@@ -14,16 +14,6 @@
         0.0.1-SNAPSHOT
     
 
-    
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-    
-
     
         core-java-function
         
@@ -34,9 +24,4 @@
         
     
 
-    
-        
-        3.6.1
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-io-2/pom.xml b/core-java-modules/core-java-io-2/pom.xml
index 924248f4f9..800756767c 100644
--- a/core-java-modules/core-java-io-2/pom.xml
+++ b/core-java-modules/core-java-io-2/pom.xml
@@ -38,13 +38,6 @@
             log4j-over-slf4j
             ${org.slf4j.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
         
             com.github.tomakehurst
@@ -76,7 +69,6 @@
     
 
     
-        3.6.1
         3.0.0-M1
         2.26.3
     
diff --git a/core-java-modules/core-java-io-3/pom.xml b/core-java-modules/core-java-io-3/pom.xml
index 017b56f03f..7af90dbab9 100644
--- a/core-java-modules/core-java-io-3/pom.xml
+++ b/core-java-modules/core-java-io-3/pom.xml
@@ -38,17 +38,6 @@
             log4j-over-slf4j
             ${org.slf4j.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
-    
-        3.6.1
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-io-4/pom.xml b/core-java-modules/core-java-io-4/pom.xml
index 0501bb4a66..9fc00ff586 100644
--- a/core-java-modules/core-java-io-4/pom.xml
+++ b/core-java-modules/core-java-io-4/pom.xml
@@ -32,17 +32,6 @@
             log4j-over-slf4j
             ${org.slf4j.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
-    
-        3.6.1
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-io-apis/pom.xml b/core-java-modules/core-java-io-apis/pom.xml
index f2a574ed89..fab2bff959 100644
--- a/core-java-modules/core-java-io-apis/pom.xml
+++ b/core-java-modules/core-java-io-apis/pom.xml
@@ -32,13 +32,6 @@
             ${lombok.version}
             provided
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -51,8 +44,4 @@
         
     
 
-    
-        3.6.1
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-io-conversions-2/README.md b/core-java-modules/core-java-io-conversions-2/README.md
index b2153b3669..9abb539066 100644
--- a/core-java-modules/core-java-io-conversions-2/README.md
+++ b/core-java-modules/core-java-io-conversions-2/README.md
@@ -4,6 +4,7 @@ This module contains articles about core Java input/output(IO) conversions.
 
 ### Relevant Articles:
 - [Java InputStream to String](https://www.baeldung.com/convert-input-stream-to-string)
+- [Java String to InputStream](https://www.baeldung.com/convert-string-to-input-stream)
 - [Java – Write an InputStream to a File](https://www.baeldung.com/convert-input-stream-to-a-file)
 - [Converting a BufferedReader to a JSONObject](https://www.baeldung.com/java-bufferedreader-to-jsonobject)
 - [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array)
diff --git a/core-java-modules/core-java-io-conversions-2/pom.xml b/core-java-modules/core-java-io-conversions-2/pom.xml
index dcb9d494dc..24708ad967 100644
--- a/core-java-modules/core-java-io-conversions-2/pom.xml
+++ b/core-java-modules/core-java-io-conversions-2/pom.xml
@@ -12,7 +12,6 @@
         com.baeldung.core-java-modules
         core-java-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
diff --git a/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/stringtoinputstream/JavaXToInputStreamUnitTest.java b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/stringtoinputstream/JavaXToInputStreamUnitTest.java
new file mode 100644
index 0000000000..7e7c79f764
--- /dev/null
+++ b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/stringtoinputstream/JavaXToInputStreamUnitTest.java
@@ -0,0 +1,44 @@
+package com.baeldung.stringtoinputstream;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.io.CharSource;
+
+public class JavaXToInputStreamUnitTest {
+    protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+    // tests - String - InputStream
+
+    @Test
+    public final void givenUsingPlainJava_whenConvertingStringToInputStream_thenCorrect() throws IOException {
+        final String initialString = "text";
+        final InputStream targetStream = new ByteArrayInputStream(initialString.getBytes());
+
+        IOUtils.closeQuietly(targetStream);
+    }
+
+    @Test
+    public final void givenUsingGuava_whenConvertingStringToInputStream_thenCorrect() throws IOException {
+        final String initialString = "text";
+        final InputStream targetStream = CharSource.wrap(initialString).asByteSource(StandardCharsets.UTF_8).openStream();
+
+        IOUtils.closeQuietly(targetStream);
+    }
+
+    @Test
+    public final void givenUsingCommonsIO_whenConvertingStringToInputStream_thenCorrect() throws IOException {
+        final String initialString = "text";
+        final InputStream targetStream = IOUtils.toInputStream(initialString);
+
+        IOUtils.closeQuietly(targetStream);
+    }
+
+}
diff --git a/core-java-modules/core-java-io-conversions/README.md b/core-java-modules/core-java-io-conversions/README.md
index 52f5222040..1f12c87241 100644
--- a/core-java-modules/core-java-io-conversions/README.md
+++ b/core-java-modules/core-java-io-conversions/README.md
@@ -13,5 +13,4 @@ This module contains articles about core Java input/output(IO) conversions.
 - [Java – Write a Reader to File](https://www.baeldung.com/java-write-reader-to-file)
 - [Java – Reader to Byte Array](https://www.baeldung.com/java-convert-reader-to-byte-array)
 - [Java – Reader to InputStream](https://www.baeldung.com/java-convert-reader-to-inputstream)
-- [Java String to InputStream](https://www.baeldung.com/convert-string-to-input-stream)
 - More articles: [[next -->]](/core-java-modules/core-java-io-conversions-2)
diff --git a/core-java-modules/core-java-io-conversions/src/test/java/com/baeldung/filetoinputstream/JavaXToInputStreamUnitTest.java b/core-java-modules/core-java-io-conversions/src/test/java/com/baeldung/filetoinputstream/JavaXToInputStreamUnitTest.java
index c20752639f..9d061307ce 100644
--- a/core-java-modules/core-java-io-conversions/src/test/java/com/baeldung/filetoinputstream/JavaXToInputStreamUnitTest.java
+++ b/core-java-modules/core-java-io-conversions/src/test/java/com/baeldung/filetoinputstream/JavaXToInputStreamUnitTest.java
@@ -1,46 +1,25 @@
 package com.baeldung.filetoinputstream;
 
-import com.google.common.io.ByteSource;
-import com.google.common.io.CharSource;
-import com.google.common.io.Files;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.SequenceInputStream;
+
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.*;
-import java.nio.charset.StandardCharsets;
+import com.google.common.io.ByteSource;
+import com.google.common.io.Files;
 
 public class JavaXToInputStreamUnitTest {
     protected final Logger logger = LoggerFactory.getLogger(getClass());
 
-    // tests - String - InputStream
-
-    @Test
-    public final void givenUsingPlainJava_whenConvertingStringToInputStream_thenCorrect() throws IOException {
-        final String initialString = "text";
-        final InputStream targetStream = new ByteArrayInputStream(initialString.getBytes());
-
-        IOUtils.closeQuietly(targetStream);
-    }
-
-    @Test
-    public final void givenUsingGuava_whenConvertingStringToInputStream_thenCorrect() throws IOException {
-        final String initialString = "text";
-        final InputStream targetStream = CharSource.wrap(initialString).asByteSource(StandardCharsets.UTF_8).openStream();
-
-        IOUtils.closeQuietly(targetStream);
-    }
-
-    @Test
-    public final void givenUsingCommonsIO_whenConvertingStringToInputStream_thenCorrect() throws IOException {
-        final String initialString = "text";
-        final InputStream targetStream = IOUtils.toInputStream(initialString);
-
-        IOUtils.closeQuietly(targetStream);
-    }
-
     // byte array - InputStream
 
     @Test
diff --git a/core-java-modules/core-java-io-conversions/src/test/java/com/baeldung/readertox/JavaReaderToXUnitTest.java b/core-java-modules/core-java-io-conversions/src/test/java/com/baeldung/readertox/JavaReaderToXUnitTest.java
index 72813df9b1..fa3c34d479 100644
--- a/core-java-modules/core-java-io-conversions/src/test/java/com/baeldung/readertox/JavaReaderToXUnitTest.java
+++ b/core-java-modules/core-java-io-conversions/src/test/java/com/baeldung/readertox/JavaReaderToXUnitTest.java
@@ -1,7 +1,7 @@
 package com.baeldung.readertox;
 
 import static org.hamcrest.CoreMatchers.equalTo;
-import static org.junit.Assert.assertThat;
+import static org.hamcrest.MatcherAssert.assertThat;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -17,6 +17,7 @@ import java.nio.charset.StandardCharsets;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.input.CharSequenceReader;
+import org.apache.commons.io.input.ReaderInputStream;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -181,7 +182,7 @@ public class JavaReaderToXUnitTest {
     }
 
     @Test
-    public void givenUsingCommonsIO_whenConvertingReaderIntoInputStream() throws IOException {
+    public void givenUsingCommonsIOUtils_whenConvertingReaderIntoInputStream() throws IOException {
         final Reader initialReader = new StringReader("With Commons IO");
 
         final InputStream targetStream = IOUtils.toInputStream(IOUtils.toString(initialReader));
@@ -191,7 +192,7 @@ public class JavaReaderToXUnitTest {
     }
 
     @Test
-    public void givenUsingCommonsIO_whenConvertingReaderIntoInputStream_thenCorrect() throws IOException {
+    public void givenUsingCommonsIOUtils_whenConvertingReaderIntoInputStream_thenCorrect() throws IOException {
         String initialString = "With Commons IO";
         final Reader initialReader = new StringReader(initialString);
 
@@ -204,6 +205,30 @@ public class JavaReaderToXUnitTest {
         targetStream.close();
     }
 
+    @Test
+    public void givenUsingCommonsIOReaderInputStream_whenConvertingReaderIntoInputStream() throws IOException {
+        final Reader initialReader = new StringReader("With Commons IO");
+
+        final InputStream targetStream = new ReaderInputStream(initialReader);
+
+        initialReader.close();
+        targetStream.close();
+    }
+
+    @Test
+    public void givenUsingCommonsIOReaderInputStream_whenConvertingReaderIntoInputStream_thenCorrect() throws IOException {
+        String initialString = "With Commons IO";
+        final Reader initialReader = new StringReader(initialString);
+
+        final InputStream targetStream = new ReaderInputStream(initialReader);
+
+        final String finalString = IOUtils.toString(targetStream);
+        assertThat(finalString, equalTo(initialString));
+
+        initialReader.close();
+        targetStream.close();
+    }
+
     // tests - Reader to InputStream with encoding
 
     @Test
@@ -233,7 +258,7 @@ public class JavaReaderToXUnitTest {
     }
 
     @Test
-    public void givenUsingCommonsIO_whenConvertingReaderIntoInputStreamWithEncoding() throws IOException {
+    public void givenUsingCommonsIOUtils_whenConvertingReaderIntoInputStreamWithEncoding() throws IOException {
         final Reader initialReader = new StringReader("With Commons IO");
 
         final InputStream targetStream = IOUtils.toInputStream(IOUtils.toString(initialReader), Charsets.UTF_8);
@@ -243,7 +268,7 @@ public class JavaReaderToXUnitTest {
     }
 
     @Test
-    public void givenUsingCommonsIO_whenConvertingReaderIntoInputStreamWithEncoding_thenCorrect() throws IOException {
+    public void givenUsingCommonsIOUtils_whenConvertingReaderIntoInputStreamWithEncoding_thenCorrect() throws IOException {
         String initialString = "With Commons IO";
         final Reader initialReader = new StringReader(initialString);
         final InputStream targetStream = IOUtils.toInputStream(IOUtils.toString(initialReader), Charsets.UTF_8);
@@ -255,4 +280,27 @@ public class JavaReaderToXUnitTest {
         targetStream.close();
     }
 
+    @Test
+    public void givenUsingCommonsIOReaderInputStream_whenConvertingReaderIntoInputStreamWithEncoding() throws IOException {
+        final Reader initialReader = new StringReader("With Commons IO");
+
+        final InputStream targetStream = new ReaderInputStream(initialReader, Charsets.UTF_8);
+
+        initialReader.close();
+        targetStream.close();
+    }
+
+    @Test
+    public void givenUsingCommonsIOReaderInputStream_whenConvertingReaderIntoInputStreamWithEncoding_thenCorrect() throws IOException {
+        String initialString = "With Commons IO";
+        final Reader initialReader = new StringReader(initialString);
+
+        final InputStream targetStream = new ReaderInputStream(initialReader, Charsets.UTF_8);
+
+        String finalString = IOUtils.toString(targetStream, Charsets.UTF_8);
+        assertThat(finalString, equalTo(initialString));
+
+        initialReader.close();
+        targetStream.close();
+    }
 }
diff --git a/core-java-modules/core-java-io/pom.xml b/core-java-modules/core-java-io/pom.xml
index 0cf6d6767e..7de29ac23c 100644
--- a/core-java-modules/core-java-io/pom.xml
+++ b/core-java-modules/core-java-io/pom.xml
@@ -12,17 +12,9 @@
         com.baeldung.core-java-modules
         core-java-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.hsqldb
             hsqldb
@@ -133,8 +125,6 @@
     
 
     
-        
-        3.6.1
         
         3.0.0-M1
         2.4.0
diff --git a/core-java-modules/core-java-jar/pom.xml b/core-java-modules/core-java-jar/pom.xml
index 3c5a1b35bf..da107c745f 100644
--- a/core-java-modules/core-java-jar/pom.xml
+++ b/core-java-modules/core-java-jar/pom.xml
@@ -49,13 +49,6 @@
             ${lombok.version}
             provided
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             org.javamoney
             moneta
@@ -376,8 +369,6 @@
         
         0.4
         1.8.7
-        
-        3.10.0
         
         1.1
         3.0.0-M1
diff --git a/core-java-modules/core-java-jndi/README.md b/core-java-modules/core-java-jndi/README.md
index d9fb324c9a..b0b23fc0d0 100644
--- a/core-java-modules/core-java-jndi/README.md
+++ b/core-java-modules/core-java-jndi/README.md
@@ -2,3 +2,4 @@
 ### Relevant Articles:
 
 - [Java Naming and Directory Interface Overview](https://www.baeldung.com/jndi)
+- [LDAP Authentication Using Pure Java](https://www.baeldung.com/java-ldap-auth)
diff --git a/core-java-modules/core-java-jndi/pom.xml b/core-java-modules/core-java-jndi/pom.xml
index f1b374b2b5..68b7f9361f 100644
--- a/core-java-modules/core-java-jndi/pom.xml
+++ b/core-java-modules/core-java-jndi/pom.xml
@@ -15,23 +15,6 @@
     
 
     
-        
-            org.junit.jupiter
-            junit-jupiter
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.jupiter
-            junit-jupiter-api
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.jupiter
-            junit-jupiter-engine
-            ${junit-jupiter.version}
-        
         
             org.springframework
             spring-core
@@ -58,6 +41,12 @@
             h2
             ${h2.version}
         
+        
+            org.apache.directory.server
+            apacheds-test-framework
+            ${apacheds.version}
+            test
+        
     
 
     
@@ -76,6 +65,7 @@
     
         5.0.9.RELEASE
         1.4.199
+        2.0.0.AM26
         1.8
         1.8
     
diff --git a/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java
new file mode 100644
index 0000000000..5a675c62c9
--- /dev/null
+++ b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java
@@ -0,0 +1,165 @@
+package com.baeldung.jndi.ldap.auth;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+import java.util.Hashtable;
+
+import javax.naming.AuthenticationException;
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.annotations.ApplyLdifFiles;
+import org.apache.directory.server.core.annotations.CreateDS;
+import org.apache.directory.server.core.annotations.CreatePartition;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(FrameworkRunner.class)
+@CreateLdapServer(transports = { @CreateTransport(protocol = "LDAP", address = "localhost", port = 10390)})
+@CreateDS(
+  allowAnonAccess = false, partitions = {@CreatePartition(name = "TestPartition", suffix = "dc=baeldung,dc=com")})
+@ApplyLdifFiles({"users.ldif"})
+// class marked as manual test, as it has to run independently from the other unit tests in the module
+public class JndiLdapAuthManualTest extends AbstractLdapTestUnit {
+    
+    private static void authenticateUser(Hashtable environment) throws Exception {
+        DirContext context = new InitialDirContext(environment);   
+        context.close();       
+    }
+
+    @Test
+    public void givenPreloadedLDAPUserJoe_whenAuthUserWithCorrectPW_thenAuthSucceeds() throws Exception {
+        
+        Hashtable environment = new Hashtable();
+        environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+        environment.put(Context.PROVIDER_URL, "ldap://localhost:10390");
+        environment.put(Context.SECURITY_AUTHENTICATION, "simple");
+        
+        environment.put(Context.SECURITY_PRINCIPAL, "cn=Joe Simms,ou=Users,dc=baeldung,dc=com");
+        environment.put(Context.SECURITY_CREDENTIALS, "12345");
+        
+        assertThatCode(() -> authenticateUser(environment)).doesNotThrowAnyException();
+    }
+    
+    @Test
+    public void givenPreloadedLDAPUserJoe_whenAuthUserWithWrongPW_thenAuthFails() throws Exception {
+        
+        Hashtable environment = new Hashtable();
+        environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+        environment.put(Context.PROVIDER_URL, "ldap://localhost:10390");
+        environment.put(Context.SECURITY_AUTHENTICATION, "simple");
+        
+        environment.put(Context.SECURITY_PRINCIPAL, "cn=Joe Simms,ou=Users,dc=baeldung,dc=com");
+        environment.put(Context.SECURITY_CREDENTIALS, "wronguserpw");
+        
+        assertThatExceptionOfType(AuthenticationException.class).isThrownBy(() -> authenticateUser(environment));
+    }
+    
+    @Test
+    public void givenPreloadedLDAPUserJoe_whenSearchAndAuthUserWithCorrectPW_thenAuthSucceeds() throws Exception {
+        
+        // first authenticate against LDAP as admin to search up DN of user : Joe Simms
+        
+        Hashtable environment = new Hashtable();
+        environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+        environment.put(Context.PROVIDER_URL, "ldap://localhost:10390");
+        environment.put(Context.SECURITY_AUTHENTICATION, "simple");        
+        environment.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
+        environment.put(Context.SECURITY_CREDENTIALS, "secret");
+        
+        DirContext adminContext = new InitialDirContext(environment);
+        
+        // define the search filter to find the person with CN : Joe Simms
+        String filter = "(&(objectClass=person)(cn=Joe Simms))";
+
+        // declare the attributes we want returned for the object being searched
+        String[] attrIDs = { "cn" };
+
+        // define the search controls
+        SearchControls searchControls = new SearchControls();
+        searchControls.setReturningAttributes(attrIDs);
+        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+        
+        // search for User with filter cn=Joe Simms
+        NamingEnumeration searchResults = adminContext.search("dc=baeldung,dc=com", filter, searchControls);
+        if (searchResults.hasMore()) {
+            
+            SearchResult result = (SearchResult) searchResults.next();
+            Attributes attrs = result.getAttributes();
+            
+            String distinguishedName = result.getNameInNamespace();
+            assertThat(distinguishedName).isEqualTo("cn=Joe Simms,ou=Users,dc=baeldung,dc=com");
+            
+            String commonName = attrs.get("cn").toString();
+            assertThat(commonName).isEqualTo("cn: Joe Simms");
+            
+            // authenticate new context with DN for user Joe Simms, using correct password
+        
+            environment.put(Context.SECURITY_PRINCIPAL, distinguishedName);
+            environment.put(Context.SECURITY_CREDENTIALS, "12345");
+            
+            assertThatCode(() -> authenticateUser(environment)).doesNotThrowAnyException();
+        }
+        
+        adminContext.close();               
+    }    
+    
+    @Test
+    public void givenPreloadedLDAPUserJoe_whenSearchAndAuthUserWithWrongPW_thenAuthFails() throws Exception {
+        
+        // first authenticate against LDAP as admin to search up DN of user : Joe Simms
+        
+        Hashtable environment = new Hashtable();
+        environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+        environment.put(Context.PROVIDER_URL, "ldap://localhost:10390");
+        environment.put(Context.SECURITY_AUTHENTICATION, "simple");
+        environment.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
+        environment.put(Context.SECURITY_CREDENTIALS, "secret");
+        DirContext adminContext = new InitialDirContext(environment);
+        
+        // define the search filter to find the person with CN : Joe Simms
+        String filter = "(&(objectClass=person)(cn=Joe Simms))";
+
+        // declare the attributes we want returned for the object being searched
+        String[] attrIDs = { "cn" };
+
+        // define the search controls
+        SearchControls searchControls = new SearchControls();
+        searchControls.setReturningAttributes(attrIDs);
+        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+        
+        // search for User with filter cn=Joe Simms
+        NamingEnumeration searchResults = adminContext.search("dc=baeldung,dc=com", filter, searchControls);
+        if (searchResults.hasMore()) {
+            
+            SearchResult result = (SearchResult) searchResults.next();
+            Attributes attrs = result.getAttributes();
+            
+            String distinguishedName = result.getNameInNamespace();
+            assertThat(distinguishedName).isEqualTo("cn=Joe Simms,ou=Users,dc=baeldung,dc=com");
+
+            String commonName = attrs.get("cn").toString();
+            assertThat(commonName).isEqualTo("cn: Joe Simms");
+            
+            // authenticate new context with DN for user Joe Simms, using wrong password
+        
+            environment.put(Context.SECURITY_PRINCIPAL, distinguishedName);
+            environment.put(Context.SECURITY_CREDENTIALS, "wronguserpassword");
+            
+            assertThatExceptionOfType(AuthenticationException.class).isThrownBy(() -> authenticateUser(environment));
+        }
+        
+        adminContext.close();               
+    }
+}
diff --git a/core-java-modules/core-java-jndi/src/test/resources/logback.xml b/core-java-modules/core-java-jndi/src/test/resources/logback.xml
index 7d900d8ea8..eaad569e43 100644
--- a/core-java-modules/core-java-jndi/src/test/resources/logback.xml
+++ b/core-java-modules/core-java-jndi/src/test/resources/logback.xml
@@ -7,7 +7,7 @@
         
     
 
-    
+    
         
     
-
\ No newline at end of file
+
diff --git a/core-java-modules/core-java-jndi/src/test/resources/users.ldif b/core-java-modules/core-java-jndi/src/test/resources/users.ldif
new file mode 100644
index 0000000000..c1996586d5
--- /dev/null
+++ b/core-java-modules/core-java-jndi/src/test/resources/users.ldif
@@ -0,0 +1,20 @@
+version: 1
+dn: dc=baeldung,dc=com
+objectClass: domain
+objectClass: top
+dc: baeldung
+
+dn: ou=Users,dc=baeldung,dc=com
+objectClass: organizationalUnit
+objectClass: top
+ou: Users
+
+dn: cn=Joe Simms,ou=Users,dc=baeldung,dc=com
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: person
+objectClass: top
+cn: Joe Simms
+sn: Simms
+uid: user1
+userPassword: 12345
diff --git a/core-java-modules/core-java-jpms/pom.xml b/core-java-modules/core-java-jpms/pom.xml
index 65f5afad47..62aa49f299 100644
--- a/core-java-modules/core-java-jpms/pom.xml
+++ b/core-java-modules/core-java-jpms/pom.xml
@@ -25,7 +25,7 @@
                 
                     org.apache.maven.plugins
                     maven-compiler-plugin
-                    ${compiler.plugin.version}
+                    ${maven-compiler-plugin.version}
                     
                         ${source.version}
                         ${target.version}
@@ -36,7 +36,6 @@
     
 
     
-        3.8.0
         11
         11
     
diff --git a/core-java-modules/core-java-jvm-2/README.md b/core-java-modules/core-java-jvm-2/README.md
index ccca3a11ac..94ebe262c8 100644
--- a/core-java-modules/core-java-jvm-2/README.md
+++ b/core-java-modules/core-java-jvm-2/README.md
@@ -12,4 +12,5 @@ This module contains articles about working with the Java Virtual Machine (JVM).
 - [Memory Address of Objects in Java](https://www.baeldung.com/java-object-memory-address)
 - [List All Classes Loaded in a Specific Class Loader](https://www.baeldung.com/java-list-classes-class-loader)
 - [An Introduction to the Constant Pool in the JVM](https://www.baeldung.com/jvm-constant-pool)
+- [List All the Classes Loaded in the JVM](https://www.baeldung.com/jvm-list-all-classes-loaded)
 - More articles: [[<-- prev]](/core-java-modules/core-java-jvm)
diff --git a/core-java-modules/core-java-jvm-2/pom.xml b/core-java-modules/core-java-jvm-2/pom.xml
index 173cf27955..60a2795116 100644
--- a/core-java-modules/core-java-jvm-2/pom.xml
+++ b/core-java-modules/core-java-jvm-2/pom.xml
@@ -15,27 +15,27 @@
     
 
     
-        
-            org.junit.vintage
-            junit-vintage-engine
-            test
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.openjdk.jol
             jol-core
             ${jol-core.version}
         
+        
+            org.reflections
+            reflections
+            ${reflections.version}
+        
+        
+            com.google.guava
+            guava
+            ${guava.version}
+        
     
 
     
-        3.6.1
         0.10
+        0.10.2
+        31.0.1-jre
     
 
-
\ No newline at end of file
+
diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ListLoadedClass.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ListLoadedClass.java
new file mode 100644
index 0000000000..b4a290e70d
--- /dev/null
+++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ListLoadedClass.java
@@ -0,0 +1,35 @@
+package com.baeldung.loadedclasslisting;
+
+import java.io.IOException;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.reflections.Reflections;
+import org.reflections.scanners.SubTypesScanner;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.reflect.ClassPath;
+import com.google.common.reflect.ClassPath.ClassInfo;
+
+public class ListLoadedClass {
+
+    public ImmutableSet listClassLoaded() throws IOException {
+        return ClassPath.from(ListLoadedClass.class.getClassLoader())
+                .getAllClasses();
+    }
+
+    public Set listClassLoaded(String packageName) throws IOException {
+        return ClassPath.from(ClassLoader.getSystemClassLoader()).getAllClasses().stream()
+                .filter(clazz -> clazz.getPackageName().equals(packageName))
+                .map(ClassInfo::load)
+                .collect(Collectors.toSet());
+    }
+
+    public Set findAllClassesUsingReflectionsLibrary(String packageName) {
+        Reflections reflections = new Reflections(packageName, new SubTypesScanner(false));
+        return reflections.getSubTypesOf(Object.class)
+               .stream()
+               .collect(Collectors.toSet());
+    }
+    
+}
diff --git a/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/loadedclasslisting/ListLoadedClassUnitTest.java b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/loadedclasslisting/ListLoadedClassUnitTest.java
new file mode 100644
index 0000000000..c3e29b27b6
--- /dev/null
+++ b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/loadedclasslisting/ListLoadedClassUnitTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.loadedclasslisting;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+
+import com.baeldung.loadedclasslisting.ListLoadedClass;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.reflect.ClassPath;
+import com.google.common.reflect.ClassPath.ClassInfo;
+
+public class ListLoadedClassUnitTest {
+
+    private static final String PACKAGE_NAME = "com.baeldung.loadedclasslisting";
+
+    @Test
+    public void when_findAllClassesUsingReflectionsLibrary_thenSuccess() {
+        ListLoadedClass instance = new ListLoadedClass();
+        Set classes = instance.findAllClassesUsingReflectionsLibrary(PACKAGE_NAME);
+
+        Assertions.assertEquals(4, classes.size());
+    }
+
+    @Test
+    public void when_findAllClassesUsingGuavaLibrary_InPackage_thenSuccess() throws IOException {
+        ListLoadedClass instance = new ListLoadedClass();
+        Set classes = instance.listClassLoaded(PACKAGE_NAME);
+
+        Assertions.assertEquals(4, classes.size());
+    }
+
+    @Test
+    public void when_findAllClassesUsingGuavaLibrary_thenSuccess() throws IOException {
+        ListLoadedClass instance = new ListLoadedClass();
+        Set classes = instance.listClassLoaded();
+
+        Assertions.assertTrue(4com.baeldung.core-java-modules
         core-java-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
-        
-            org.junit.vintage
-            junit-vintage-engine
-            test
-        
         
             org.apache.commons
             commons-lang3
             ${commons-lang3.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.javassist
             javassist
@@ -72,8 +60,6 @@
     
 
     
-        3.6.1
-        
         3.27.0-GA
         1.8.0
         0.10
diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappers.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappers.java
index 64532c8b6f..db710589e7 100644
--- a/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappers.java
+++ b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappers.java
@@ -1,15 +1,20 @@
 package com.baeldung.java8.lambda.exceptions;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.util.function.Consumer;
 
 public class LambdaExceptionWrappers {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(LambdaExceptionWrappers.class);
+
     public static Consumer lambdaWrapper(Consumer consumer) {
         return i -> {
             try {
                 consumer.accept(i);
             } catch (ArithmeticException e) {
-                System.err.println("Arithmetic Exception occured : " + e.getMessage());
+                LOGGER.error("Arithmetic Exception occurred.", e);
             }
         };
     }
@@ -21,7 +26,7 @@ public class LambdaExceptionWrappers {
             } catch (Exception ex) {
                 try {
                     E exCast = clazz.cast(ex);
-                    System.err.println("Exception occured : " + exCast.getMessage());
+                    LOGGER.error("Exception occurred.", exCast);
                 } catch (ClassCastException ccEx) {
                     throw ex;
                 }
@@ -46,7 +51,7 @@ public class LambdaExceptionWrappers {
             } catch (Exception ex) {
                 try {
                     E exCast = exceptionClass.cast(ex);
-                    System.err.println("Exception occured : " + exCast.getMessage());
+                    LOGGER.error("Exception occurred.", exCast);
                 } catch (ClassCastException ccEx) {
                     throw new RuntimeException(ex);
                 }
diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/methodreference/MethodReferenceUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/methodreference/MethodReferenceUnitTest.java
index 957294153b..87c01c3ded 100644
--- a/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/methodreference/MethodReferenceUnitTest.java
+++ b/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/methodreference/MethodReferenceUnitTest.java
@@ -7,14 +7,16 @@ import java.util.function.BiFunction;
 
 import org.apache.commons.lang3.StringUtils;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class MethodReferenceUnitTest {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(MethodReferenceUnitTest.class);
+
     private static  void doNothingAtAll(Object... o) {
     }
 
-    ;
-    
     @Test
     public void referenceToStaticMethod() {
         List messages = Arrays.asList("Hello", "Baeldung", "readers!");
@@ -61,7 +63,7 @@ public class MethodReferenceUnitTest {
 
     @Test
     public void limitationsAndAdditionalExamples() {
-        createBicyclesList().forEach(b -> System.out.printf("Bike brand is '%s' and frame size is '%d'%n", b.getBrand(), b.getFrameSize()));
+        createBicyclesList().forEach(b -> LOGGER.debug("Bike brand is '{}' and frame size is '{}'", b.getBrand(), b.getFrameSize()));
         createBicyclesList().forEach((o) -> MethodReferenceUnitTest.doNothingAtAll(o));
     }
 
diff --git a/core-java-modules/core-java-lang-2/pom.xml b/core-java-modules/core-java-lang-2/pom.xml
index d1a8d68075..f155f2abaf 100644
--- a/core-java-modules/core-java-lang-2/pom.xml
+++ b/core-java-modules/core-java-lang-2/pom.xml
@@ -45,12 +45,6 @@
             jmh-core
             ${jmh-core.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -64,7 +58,6 @@
     
 
     
-        3.12.2
         1.9.4
         29.0-jre
     
diff --git a/core-java-modules/core-java-lang-3/pom.xml b/core-java-modules/core-java-lang-3/pom.xml
index 0eda5dd16b..92c724826c 100644
--- a/core-java-modules/core-java-lang-3/pom.xml
+++ b/core-java-modules/core-java-lang-3/pom.xml
@@ -15,12 +15,6 @@
     
 
     
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             com.google.guava
             guava
@@ -45,8 +39,4 @@
         
     
 
-    
-        3.12.2
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-4/README.md b/core-java-modules/core-java-lang-4/README.md
index 4546a00fe6..e2a74b36af 100644
--- a/core-java-modules/core-java-lang-4/README.md
+++ b/core-java-modules/core-java-lang-4/README.md
@@ -9,3 +9,4 @@ This module contains articles about core features in the Java language
 - [Referencing a Method in Javadoc Comments](https://www.baeldung.com/java-method-in-javadoc)
 - [Tiered Compilation in JVM](https://www.baeldung.com/jvm-tiered-compilation)
 - [Fixing the “Declared package does not match the expected package” Error](https://www.baeldung.com/java-declared-expected-package-error)
+- [Chaining Constructors in Java](https://www.baeldung.com/java-chain-constructors)
diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java
new file mode 100644
index 0000000000..62dbdef297
--- /dev/null
+++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java
@@ -0,0 +1,34 @@
+package com.baeldung.constructorchaining;
+
+import java.util.Objects;
+
+public class Customer extends Person {
+    private final String loyaltyCardId;
+
+    public Customer(String firstName, String lastName, int age, String loyaltyCardId) {
+        this(firstName, null, lastName, age, loyaltyCardId);
+    }
+
+    public Customer(String firstName, String middleName, String lastName, int age, String loyaltyCardId) {
+        super(firstName, middleName, lastName, age);
+        this.loyaltyCardId = loyaltyCardId;
+    }
+
+    public String getLoyaltyCardId() {
+        return loyaltyCardId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+        Customer customer = (Customer) o;
+        return Objects.equals(loyaltyCardId, customer.loyaltyCardId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), loyaltyCardId);
+    }
+}
diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java
new file mode 100644
index 0000000000..02ce2220ba
--- /dev/null
+++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java
@@ -0,0 +1,51 @@
+package com.baeldung.constructorchaining;
+
+import java.util.Objects;
+
+public class Person {
+    private final String firstName;
+    private final String middleName;
+    private final String lastName;
+    private final int age;
+
+    public Person(String firstName, String lastName, int age) {
+        this(firstName, null, lastName, age);
+    }
+
+
+    public Person(String firstName, String middleName, String lastName, int age) {
+        this.firstName = firstName;
+        this.middleName = middleName;
+        this.lastName = lastName;
+        this.age = age;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public int getAge() {
+        return age;
+    }
+
+    public String getMiddleName() {
+        return middleName;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Person person = (Person) o;
+        return age == person.age && Objects.equals(firstName, person.firstName) && Objects.equals(middleName, person.middleName) && Objects.equals(lastName, person.lastName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(firstName, middleName, lastName, age);
+    }
+}
diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java
new file mode 100644
index 0000000000..ad00ea65b8
--- /dev/null
+++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java
@@ -0,0 +1,31 @@
+package com.baeldung.constructorchaining;
+
+import org.junit.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+public class CustomerUnitTest {
+
+    @Test
+    public void givenNameLastNameAndAge_whenUsingDedicatedConstructor_shouldInitializeFieldsAndNullifyMiddleName() {
+        Customer mark = new Customer("Mark", "Johnson", 23, "abcd1234");
+
+        assertEquals(23, mark.getAge());
+        assertEquals("Mark", mark.getFirstName());
+        assertEquals("Johnson", mark.getLastName());
+        assertEquals("abcd1234", mark.getLoyaltyCardId());
+        assertNull(mark.getMiddleName());
+    }
+
+    @Test
+    public void givenAllFieldsRequired_whenUsingDedicatedConstructor_shouldInitializeAllFields() {
+        Customer mark = new Customer("Mark", "Andrew", "Johnson", 23, "abcd1234");
+
+        assertEquals(23, mark.getAge());
+        assertEquals("Mark", mark.getFirstName());
+        assertEquals("Andrew", mark.getMiddleName());
+        assertEquals("Johnson", mark.getLastName());
+        assertEquals("abcd1234", mark.getLoyaltyCardId());
+    }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java
new file mode 100644
index 0000000000..8322917951
--- /dev/null
+++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java
@@ -0,0 +1,29 @@
+package com.baeldung.constructorchaining;
+
+import org.junit.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+public class PersonUnitTest {
+
+    @Test
+    public void givenNameLastNameAndAge_whenUsingDedicatedConstructor_shouldInitializeFieldsAndNullifyMiddleName() {
+        Person mark = new Person("Mark", "Johnson", 23);
+
+        assertEquals(23, mark.getAge());
+        assertEquals("Mark", mark.getFirstName());
+        assertEquals("Johnson", mark.getLastName());
+        assertNull(mark.getMiddleName());
+    }
+
+    @Test
+    public void givenAllFieldsRequired_whenUsingDedicatedConstructor_shouldInitializeAllFields() {
+        Person mark = new Person("Mark", "Andrew", "Johnson", 23);
+
+        assertEquals(23, mark.getAge());
+        assertEquals("Mark", mark.getFirstName());
+        assertEquals("Andrew", mark.getMiddleName());
+        assertEquals("Johnson", mark.getLastName());
+    }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/pom.xml b/core-java-modules/core-java-lang-math-2/pom.xml
index 4411d313db..4057429896 100644
--- a/core-java-modules/core-java-lang-math-2/pom.xml
+++ b/core-java-modules/core-java-lang-math-2/pom.xml
@@ -44,12 +44,6 @@
             guava
             ${guava.version}
         
-        
-            org.assertj
-            assertj-core
-            ${org.assertj.core.version}
-            test
-        
         
             com.github.dpaukov
             combinatoricslib3
@@ -65,7 +59,6 @@
 
     
         3.6.1
-        3.9.0
         27.0.1-jre
         3.3.0
         0.38
diff --git a/core-java-modules/core-java-lang-math/pom.xml b/core-java-modules/core-java-lang-math/pom.xml
index 2cc9b90fa4..37550b67d8 100644
--- a/core-java-modules/core-java-lang-math/pom.xml
+++ b/core-java-modules/core-java-lang-math/pom.xml
@@ -14,16 +14,6 @@
         0.0.1-SNAPSHOT
     
 
-    
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-    
-
     
         core-java-lang-math
         
@@ -34,9 +24,4 @@
         
     
 
-    
-        
-        3.6.1
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-oop-constructors/README.md b/core-java-modules/core-java-lang-oop-constructors/README.md
index 69ade3e25a..d3d05d31bf 100644
--- a/core-java-modules/core-java-lang-oop-constructors/README.md
+++ b/core-java-modules/core-java-lang-oop-constructors/README.md
@@ -8,3 +8,4 @@ This module contains article about constructors in Java
 - [Cannot Reference “X” Before Supertype Constructor Has Been Called](https://www.baeldung.com/java-cannot-reference-x-before-supertype-constructor-error)
 - [Private Constructors in Java](https://www.baeldung.com/java-private-constructors)
 - [Throwing Exceptions in Constructors](https://www.baeldung.com/java-constructors-exceptions)
+- [Constructors in Java Abstract Classes](https://www.baeldung.com/java-abstract-classes-constructors)
diff --git a/core-java-modules/core-java-lang-oop-constructors/pom.xml b/core-java-modules/core-java-lang-oop-constructors/pom.xml
index 5635059fa9..061b3c08de 100644
--- a/core-java-modules/core-java-lang-oop-constructors/pom.xml
+++ b/core-java-modules/core-java-lang-oop-constructors/pom.xml
@@ -13,17 +13,4 @@
         0.0.1-SNAPSHOT
     
 
-    
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
-    
-
-    
-        3.10.0
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/defaultconstructor/AbstractClass.java b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/defaultconstructor/AbstractClass.java
new file mode 100644
index 0000000000..7599529014
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/defaultconstructor/AbstractClass.java
@@ -0,0 +1,5 @@
+package com.baeldung.abstractconstructors.defaultconstructor;
+
+public abstract class AbstractClass {
+    // compiler creates a default constructor
+}
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/defaultconstructor/ConcreteClass.java b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/defaultconstructor/ConcreteClass.java
new file mode 100644
index 0000000000..71c418735d
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/defaultconstructor/ConcreteClass.java
@@ -0,0 +1,8 @@
+package com.baeldung.abstractconstructors.defaultconstructor;
+
+public class ConcreteClass extends AbstractClass {
+
+    public ConcreteClass() {
+        super();
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/AbstractClass.java b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/AbstractClass.java
new file mode 100644
index 0000000000..bdd554b2d9
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/AbstractClass.java
@@ -0,0 +1,8 @@
+package com.baeldung.abstractconstructors.noargs;
+
+public abstract class AbstractClass {
+
+    public AbstractClass() {
+        System.out.println("Initializing AbstractClass");
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/ConcreteClassA.java b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/ConcreteClassA.java
new file mode 100644
index 0000000000..8339098127
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/ConcreteClassA.java
@@ -0,0 +1,4 @@
+package com.baeldung.abstractconstructors.noargs;
+
+public class ConcreteClassA extends AbstractClass {
+}
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/ConcreteClassB.java b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/ConcreteClassB.java
new file mode 100644
index 0000000000..cad20d2ec0
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/ConcreteClassB.java
@@ -0,0 +1,8 @@
+package com.baeldung.abstractconstructors.noargs;
+
+public class ConcreteClassB extends AbstractClass {
+
+    public ConcreteClassB() {
+        System.out.println("Initializing ConcreteClassB");
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/Counter.java b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/Counter.java
new file mode 100644
index 0000000000..a0471ad777
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/Counter.java
@@ -0,0 +1,18 @@
+package com.baeldung.abstractconstructors.noargs;
+
+public abstract class Counter {
+
+    int value;
+
+    private Counter() {
+        this.value = 0;
+        System.out.println("Counter No-Arguments constructor");
+    }
+
+    public Counter(int value) {
+        this.value = value;
+        System.out.println("Parametrized Counter constructor");
+    }
+
+    abstract int increment();
+}
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/SimpleCounter.java b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/SimpleCounter.java
new file mode 100644
index 0000000000..93add905df
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/noargs/SimpleCounter.java
@@ -0,0 +1,13 @@
+package com.baeldung.abstractconstructors.noargs;
+
+public class SimpleCounter extends Counter {
+
+    public SimpleCounter(int value) {
+        super(value);
+    }
+
+    @Override
+    int increment() {
+        return ++value;
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/parametrized/Car.java b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/parametrized/Car.java
new file mode 100644
index 0000000000..8919636b7e
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/parametrized/Car.java
@@ -0,0 +1,28 @@
+package com.baeldung.abstractconstructors.parametrized;
+
+public abstract class Car {
+
+    private int distance;
+
+    private Car(int distance) {
+        this.distance = distance;
+    }
+
+    public Car() {
+        this(0);
+        System.out.println("Car default constructor");
+    }
+
+    abstract String getInformation();
+
+    protected void display() {
+        String info = new StringBuilder(getInformation())
+          .append("\nDistance: " + getDistance())
+          .toString();
+        System.out.println(info);
+    }
+
+    public int getDistance() {
+        return distance;
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/parametrized/ElectricCar.java b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/parametrized/ElectricCar.java
new file mode 100644
index 0000000000..e17ea6d9c5
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/parametrized/ElectricCar.java
@@ -0,0 +1,17 @@
+package com.baeldung.abstractconstructors.parametrized;
+
+public class ElectricCar extends Car {
+
+    int chargingTime;
+
+    public ElectricCar(int chargingTime) {
+        this.chargingTime = chargingTime;
+    }
+
+    @Override
+    String getInformation() {
+        return new StringBuilder("Electric Car")
+          .append("\nCharging Time: " + chargingTime)
+          .toString();
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/parametrized/FuelCar.java b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/parametrized/FuelCar.java
new file mode 100644
index 0000000000..c18c3a26ef
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/abstractconstructors/parametrized/FuelCar.java
@@ -0,0 +1,17 @@
+package com.baeldung.abstractconstructors.parametrized;
+
+public class FuelCar extends Car {
+
+    String fuel;
+
+    public FuelCar(String fuel) {
+        this.fuel = fuel;
+    }
+
+    @Override
+    String getInformation() {
+        return new StringBuilder("Fuel Car")
+          .append("\nFuel type: " + fuel)
+          .toString();
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/test/java/com/baeldung/abstractconstructors/noargs/AbstractClassUnitTest.java b/core-java-modules/core-java-lang-oop-constructors/src/test/java/com/baeldung/abstractconstructors/noargs/AbstractClassUnitTest.java
new file mode 100644
index 0000000000..c72d3b0f3f
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/test/java/com/baeldung/abstractconstructors/noargs/AbstractClassUnitTest.java
@@ -0,0 +1,18 @@
+package com.baeldung.abstractconstructors.noargs;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class AbstractClassUnitTest {
+
+    @Test
+    void givenNoArgsAbstractConstructor_whenNewSubclassA_thenCalled() {
+        assertNotNull(new ConcreteClassA());
+    }
+
+    @Test
+    void givenNoArgsAbstractConstructor_whenNewSubclassB_thenCalled() {
+        assertNotNull(new ConcreteClassB());
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/test/java/com/baeldung/abstractconstructors/noargs/CounterUnitTest.java b/core-java-modules/core-java-lang-oop-constructors/src/test/java/com/baeldung/abstractconstructors/noargs/CounterUnitTest.java
new file mode 100644
index 0000000000..774136c5b6
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/test/java/com/baeldung/abstractconstructors/noargs/CounterUnitTest.java
@@ -0,0 +1,16 @@
+package com.baeldung.abstractconstructors.noargs;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class CounterUnitTest {
+
+    @Test
+    void givenNoArgAbstractConstructor_whenSubclassCreation_thenCalled() {
+        Counter counter = new SimpleCounter(1);
+        assertNotNull(counter);
+        assertEquals(1, counter.value);
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-constructors/src/test/java/com/baeldung/abstractconstructors/parametrized/CarUnitTest.java b/core-java-modules/core-java-lang-oop-constructors/src/test/java/com/baeldung/abstractconstructors/parametrized/CarUnitTest.java
new file mode 100644
index 0000000000..6d17861355
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-constructors/src/test/java/com/baeldung/abstractconstructors/parametrized/CarUnitTest.java
@@ -0,0 +1,20 @@
+package com.baeldung.abstractconstructors.parametrized;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class CarUnitTest {
+    @Test
+    void givenParametrizedConstructor_whenConcreteCreation_thenCall() {
+        ElectricCar electricCar = new ElectricCar(8);
+        assertNotNull(electricCar);
+        electricCar.display();
+
+        System.out.println();
+
+        FuelCar fuelCar = new FuelCar("Gasoline");
+        assertNotNull(fuelCar);
+        fuelCar.display();
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-inheritance/pom.xml b/core-java-modules/core-java-lang-oop-inheritance/pom.xml
index e0272fb94e..4fc7e14d84 100644
--- a/core-java-modules/core-java-lang-oop-inheritance/pom.xml
+++ b/core-java-modules/core-java-lang-oop-inheritance/pom.xml
@@ -13,17 +13,4 @@
         0.0.1-SNAPSHOT
     
 
-    
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
-    
-
-    
-        3.10.0
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-oop-methods/README.md b/core-java-modules/core-java-lang-oop-methods/README.md
index 43eab24003..f34606f26a 100644
--- a/core-java-modules/core-java-lang-oop-methods/README.md
+++ b/core-java-modules/core-java-lang-oop-methods/README.md
@@ -10,3 +10,4 @@ This module contains articles about methods in Java
 - [Guide to hashCode() in Java](https://www.baeldung.com/java-hashcode)
 - [The Covariant Return Type in Java](https://www.baeldung.com/java-covariant-return-type)
 - [Does a Method’s Signature Include the Return Type in Java?](https://www.baeldung.com/java-method-signature-return-type)
+- [Solving the Hide Utility Class Public Constructor Sonar Warning](https://www.baeldung.com/java-sonar-hide-implicit-constructor)
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 e493f716ec..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
@@ -24,12 +25,6 @@
             commons-lang
             ${commons-lang.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             nl.jqno.equalsverifier
             equalsverifier
@@ -39,7 +34,7 @@
     
 
     
-        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-lang-oop-modifiers/pom.xml b/core-java-modules/core-java-lang-oop-modifiers/pom.xml
index 70c70608eb..14ba397b4a 100644
--- a/core-java-modules/core-java-lang-oop-modifiers/pom.xml
+++ b/core-java-modules/core-java-lang-oop-modifiers/pom.xml
@@ -14,12 +14,6 @@
     
 
     
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             com.h2database
             h2
@@ -29,7 +23,6 @@
     
 
     
-        3.10.0
+        1.4.197 
     
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-oop-patterns/pom.xml b/core-java-modules/core-java-lang-oop-patterns/pom.xml
index 8b8b4a7b46..4b89584def 100644
--- a/core-java-modules/core-java-lang-oop-patterns/pom.xml
+++ b/core-java-modules/core-java-lang-oop-patterns/pom.xml
@@ -29,17 +29,10 @@
             gson
             ${gson.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
     
 
     
         2.8.2
-        3.10.0
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-oop-types-2/README.md b/core-java-modules/core-java-lang-oop-types-2/README.md
index a4e7b101c3..e1ce057035 100644
--- a/core-java-modules/core-java-lang-oop-types-2/README.md
+++ b/core-java-modules/core-java-lang-oop-types-2/README.md
@@ -5,3 +5,4 @@ This module contains articles about types in Java
 ### Relevant Articles: 
 
 - [Convert an Array of Primitives to an Array of Objects](https://www.baeldung.com/java-primitive-array-to-object-array)
+- [Check if an Enum Value Exists in Java](https://www.baeldung.com/java-find-enum-by-criteria)
diff --git a/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/Direction.java b/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/Direction.java
new file mode 100644
index 0000000000..935aca4d65
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/Direction.java
@@ -0,0 +1,26 @@
+package com.baeldung.enums;
+
+/**
+ * Represents directions.
+ */
+public enum Direction {
+    EAST, WEST, SOUTH, NORTH;
+
+    /**
+     * Finds direction by name.
+     *
+     * @param name the name
+     * @return the direction if found else null
+     */
+    public static Direction findByName(String name) {
+        Direction result = null;
+        for (Direction direction : values()) {
+            if (direction.name().equalsIgnoreCase(name)) {
+                result = direction;
+                break;
+            }
+        }
+        return result;
+    }
+
+}
diff --git a/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/EnumSearcher.java b/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/EnumSearcher.java
new file mode 100644
index 0000000000..fa85cff38b
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/EnumSearcher.java
@@ -0,0 +1,19 @@
+package com.baeldung.enums;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EnumSearcher {
+    private static final Logger LOG = LoggerFactory.getLogger(EnumSearcher.class);
+
+    public static void main(String[] args) {
+        EnumSearcher enumSearcher = new EnumSearcher();
+        enumSearcher.printWeekdays();
+    }
+
+    private void printWeekdays() {
+        for (Weekday day: Weekday.values()) {
+            LOG.info("Name {}, Value {}, Stringified {}", day.name(), day.getValue(), day);
+        }
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/Month.java b/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/Month.java
new file mode 100644
index 0000000000..f674a4be0a
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/Month.java
@@ -0,0 +1,116 @@
+package com.baeldung.enums;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+/**
+ * Represents months in a year.
+ */
+public enum Month {
+    /**
+     * January.
+     */
+    JANUARY("January", 1),
+    /**
+     * February.
+     */
+    FEBRUARY("February", 2),
+    /**
+     * March.
+     */
+    MARCH("March", 3),
+    /**
+     * April.
+     */
+    APRIL("April", 4),
+    /**
+     * May.
+     */
+    MAY("May", 5),
+    /**
+     * June.
+     */
+    JUNE("June", 6),
+    /**
+     * July.
+     */
+    JULY("July", 7),
+    /**
+     * August.
+     */
+    AUGUST("August", 8),
+    /**
+     * September.
+     */
+    SEPTEMBER("September", 9),
+    /**
+     * October.
+     */
+    OCTOBER("October", 10),
+    /**
+     * November.
+     */
+    NOVEMBER("November", 11),
+    /**
+     * December.
+     */
+    DECEMBER("December", 12),
+    ;
+
+    private final String value;
+    private final int code;
+
+    Month(String value, int code) {
+        this.value = value;
+        this.code = code;
+    }
+
+    /**
+     * Gets value.
+     *
+     * @return the value
+     */
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * Gets code.
+     *
+     * @return the code
+     */
+    public int getCode() {
+        return code;
+    }
+
+    /**
+     * Find by name.
+     *
+     * @param name the name
+     * @return the month if found else Optional.empty()
+     */
+    public static Optional findByName(String name) {
+        return Arrays.stream(values()).filter(month -> month.name().equalsIgnoreCase(name)).findFirst();
+    }
+
+    /**
+     * Find by code.
+     *
+     * @param code the code
+     * @return the month if found else Optional.empty()
+     */
+    public static Optional findByCode(int code) {
+        return Arrays.stream(values()).filter(month -> month.getCode() == code).findFirst();
+    }
+
+    /**
+     * Finds month by value.
+     *
+     * @param value value
+     * @return month if value is valid
+     * @throws IllegalArgumentException if month not found for given value
+     */
+    public static Month findByValue(String value) {
+        return Arrays.stream(values()).filter(month -> month.getValue().equalsIgnoreCase(value)).findFirst().orElseThrow(IllegalArgumentException::new);
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/Weekday.java b/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/Weekday.java
new file mode 100644
index 0000000000..3c1031cde7
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/Weekday.java
@@ -0,0 +1,85 @@
+package com.baeldung.enums;
+
+/**
+ * Represents day in a week.
+ */
+public enum Weekday {
+    /**
+     * Monday.
+     */
+    MONDAY("Monday"),
+    /**
+     * Tuesday.
+     */
+    TUESDAY("Tuesday"),
+    /**
+     * Wednesday.
+     */
+    WEDNESDAY("Wednesday"),
+    /**
+     * Thursday.
+     */
+    THURSDAY("Thursday"),
+    /**
+     * Friday.
+     */
+    FRIDAY("Friday"),
+    /**
+     * Saturday.
+     */
+    SATURDAY("Saturday"),
+    /**
+     * Sunday.
+     */
+    SUNDAY("Sunday"),
+    ;
+
+    private final String value;
+
+    Weekday(String value) {
+        this.value = value;
+    }
+
+    /**
+     * Gets value.
+     *
+     * @return the value
+     */
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * Find by name.
+     *
+     * @param name the name
+     * @return the weekday if found else null
+     */
+    public static Weekday findByName(String name) {
+        Weekday result = null;
+        for (Weekday day : values()) {
+            if (day.name().equalsIgnoreCase(name)) {
+                result = day;
+                break;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Find by value.
+     *
+     * @param value the value
+     * @return the weekday if found else null
+     */
+    public static Weekday findByValue(String value) {
+        Weekday result = null;
+        for (Weekday day : values()) {
+            if (day.getValue().equalsIgnoreCase(value)) {
+                result = day;
+                break;
+            }
+        }
+        return result;
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/EnumSearcherUnitTest.java b/core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/EnumSearcherUnitTest.java
new file mode 100644
index 0000000000..2c96837809
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/EnumSearcherUnitTest.java
@@ -0,0 +1,89 @@
+package com.baeldung.enums;
+
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+
+import java.util.Optional;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+
+public class EnumSearcherUnitTest {
+
+    @Test
+    public void givenWeekdays_whenValidDirectionNameProvided_directionIsFound() {
+        Direction result = Direction.findByName("EAST");
+        Assertions.assertThat(result).isEqualTo(Direction.EAST);
+    }
+
+    @Test
+    public void givenWeekdays_whenValidDirectionNameLowerCaseProvided_directionIsFound() {
+        Direction result = Direction.findByName("east");
+        Assertions.assertThat(result).isEqualTo(Direction.EAST);
+    }
+
+    @Test
+    public void givenWeekdays_whenInvalidDirectionNameProvided_nullIsReturned() {
+        Direction result = Direction.findByName("E");
+        Assertions.assertThat(result).isNull();
+    }
+
+    @Test
+    public void givenWeekdays_whenValidWeekdayNameProvided_weekdayIsFound() {
+        Weekday result = Weekday.findByName("MONDAY");
+        Assertions.assertThat(result).isEqualTo(Weekday.MONDAY);
+    }
+
+    @Test
+    public void givenWeekdays_whenInvalidWeekdayNameProvided_nullIsReturned() {
+        Weekday result = Weekday.findByName("MON");
+        Assertions.assertThat(result).isNull();
+    }
+
+    @Test
+    public void givenWeekdays_whenValidWeekdayValueProvided_weekdayIsFound() {
+        Weekday result = Weekday.findByValue("Monday");
+        Assertions.assertThat(result).isEqualTo(Weekday.MONDAY);
+    }
+
+    @Test
+    public void givenWeekdays_whenInvalidWeekdayValueProvided_nullIsReturned() {
+        Weekday result = Weekday.findByValue("mon");
+        Assertions.assertThat(result).isNull();
+    }
+
+    @Test
+    public void givenMonths_whenValidMonthNameProvided_optionalMonthIsReturned() {
+        Optional result = Month.findByName("JANUARY");
+        Assertions.assertThat(result).isEqualTo(Optional.of(Month.JANUARY));
+    }
+
+    @Test
+    public void givenMonths_whenInvalidMonthNameProvided_optionalEmptyIsReturned() {
+        Optional result = Month.findByName("JAN");
+        Assertions.assertThat(result).isEmpty();
+    }
+
+    @Test
+    public void givenMonths_whenValidMonthCodeProvided_optionalMonthIsReturned() {
+        Optional result = Month.findByCode(1);
+        Assertions.assertThat(result).isEqualTo(Optional.of(Month.JANUARY));
+    }
+
+    @Test
+    public void givenMonths_whenInvalidMonthCodeProvided_optionalEmptyIsReturned() {
+        Optional result = Month.findByCode(0);
+        Assertions.assertThat(result).isEmpty();
+    }
+
+    @Test
+    public void givenMonths_whenValidMonthValueProvided_monthIsReturned() {
+        Month result = Month.findByValue("January");
+        Assertions.assertThat(result).isEqualTo(Month.JANUARY);
+    }
+
+    @Test
+    public void givenMonths_whenInvalidMonthValueProvided_illegalArgExIsThrown() {
+        assertThatIllegalArgumentException().isThrownBy(() -> Month.findByValue("Jan"));
+    }
+}
diff --git a/core-java-modules/core-java-lang-operators-2/README.md b/core-java-modules/core-java-lang-operators-2/README.md
index bc1809a4a7..480021108d 100644
--- a/core-java-modules/core-java-lang-operators-2/README.md
+++ b/core-java-modules/core-java-lang-operators-2/README.md
@@ -6,3 +6,4 @@ This module contains articles about Java operators
 
 - [Logical vs Bitwise OR Operator](https://www.baeldung.com/java-logical-vs-bitwise-or-operator)
 - [Bitmasking in Java with Bitwise Operators](https://www.baeldung.com/java-bitmasking)
+- [Getting a Bit at a Certain Position from Integral Values](https://www.baeldung.com/java-get-bit-at-position)
diff --git a/core-java-modules/core-java-lang-operators-2/pom.xml b/core-java-modules/core-java-lang-operators-2/pom.xml
index 1779b7384c..724dad95ee 100644
--- a/core-java-modules/core-java-lang-operators-2/pom.xml
+++ b/core-java-modules/core-java-lang-operators-2/pom.xml
@@ -21,13 +21,6 @@
             ${lombok.version}
             provided
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
     
 
     
@@ -40,9 +33,4 @@
         
     
 
-    
-        
-        3.10.0
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-operators/pom.xml b/core-java-modules/core-java-lang-operators/pom.xml
index 63f42917b8..c61fb81354 100644
--- a/core-java-modules/core-java-lang-operators/pom.xml
+++ b/core-java-modules/core-java-lang-operators/pom.xml
@@ -21,13 +21,6 @@
             ${lombok.version}
             provided
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
     
 
     
@@ -40,9 +33,4 @@
         
     
 
-    
-        
-        3.10.0
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-syntax/pom.xml b/core-java-modules/core-java-lang-syntax/pom.xml
index da7d56de7b..7cdbc40fbc 100644
--- a/core-java-modules/core-java-lang-syntax/pom.xml
+++ b/core-java-modules/core-java-lang-syntax/pom.xml
@@ -26,13 +26,6 @@
             log4j-over-slf4j
             ${org.slf4j.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
     
 
     
@@ -45,9 +38,4 @@
         
     
 
-    
-        
-        3.10.0
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/generics/Building.java b/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/generics/Building.java
index a34dcd3c7e..875b1d0f6d 100644
--- a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/generics/Building.java
+++ b/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/generics/Building.java
@@ -7,6 +7,6 @@ public class Building {
     private static final Logger LOGGER = LoggerFactory.getLogger(Building.class);
 
     public void paint() {
-        LOGGER.info("Painting Building");
+        LOGGER.debug("Painting Building");
     }
 }
diff --git a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/generics/House.java b/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/generics/House.java
index 88e7d2710a..c1bc6483c4 100644
--- a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/generics/House.java
+++ b/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/generics/House.java
@@ -7,6 +7,6 @@ public class House extends Building {
     private static final Logger LOGGER = LoggerFactory.getLogger(House.class);
 
     public void paint() {
-        LOGGER.info("Painting House");
+        LOGGER.debug("Painting House");
     }
 }
diff --git a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/initializationguide/User.java b/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/initializationguide/User.java
index 1d9a872d69..1604f27368 100644
--- a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/initializationguide/User.java
+++ b/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/initializationguide/User.java
@@ -1,8 +1,13 @@
 package com.baeldung.initializationguide;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.io.Serializable;
 
 public class User implements Serializable, Cloneable {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(User.class);
     private static final long serialVersionUID = 1L;
     static String forum;
     private String name;
@@ -10,12 +15,12 @@ public class User implements Serializable, Cloneable {
 
     {
         id = 0;
-        System.out.println("Instance Initializer");
+        LOGGER.debug("Instance Initializer");
     }
 
     static {
-    	forum = "Java";
-        System.out.println("Static Initializer");
+        forum = "Java";
+        LOGGER.debug("Static Initializer");
     }
 
     public User(String name, int id) {
@@ -25,7 +30,7 @@ public class User implements Serializable, Cloneable {
     }
 
     public User() {
-        System.out.println("Constructor");
+        LOGGER.debug("Constructor");
     }
 
     public String getName() {
diff --git a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/loops/LoopsInJava.java b/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/loops/LoopsInJava.java
index 1b2e621b52..cdbcd9e341 100644
--- a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/loops/LoopsInJava.java
+++ b/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/loops/LoopsInJava.java
@@ -1,12 +1,17 @@
 package com.baeldung.loops;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 public class LoopsInJava {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(LoopsInJava.class);
+    
     public int[] simple_for_loop() {
         int[] arr = new int[5];
         for (int i = 0; i < 5; i++) {
             arr[i] = i;
-            System.out.println("Simple for loop: i - " + i);
+            LOGGER.debug("Simple for loop: i - " + i);
         }
         return arr;
     }
@@ -16,7 +21,7 @@ public class LoopsInJava {
         int[] arr = new int[5];
         for (int num : intArr) {
             arr[num] = num;
-            System.out.println("Enhanced for-each loop: i - " + num);
+            LOGGER.debug("Enhanced for-each loop: i - " + num);
         }
         return arr;
     }
@@ -26,7 +31,7 @@ public class LoopsInJava {
         int[] arr = new int[5];
         while (i < 5) {
             arr[i] = i;
-            System.out.println("While loop: i - " + i++);
+            LOGGER.debug("While loop: i - " + i++);
         }
         return arr;
     }
@@ -36,7 +41,7 @@ public class LoopsInJava {
         int[] arr = new int[5];
         do {
             arr[i] = i;
-            System.out.println("Do-While loop: i - " + i++);
+            LOGGER.debug("Do-While loop: i - " + i++);
         } while (i < 5);
         return arr;
     }
diff --git a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/switchstatement/SwitchStatement.java b/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/switchstatement/SwitchStatement.java
index 69e151bfcb..55b3cbfaaf 100644
--- a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/switchstatement/SwitchStatement.java
+++ b/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/switchstatement/SwitchStatement.java
@@ -1,7 +1,13 @@
 package com.baeldung.switchstatement;
 
+import com.baeldung.loops.LoopsInJava;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 public class SwitchStatement {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(SwitchStatement.class);
+
     public String exampleOfIF(String animal) {
 
         String result;
@@ -42,11 +48,11 @@ public class SwitchStatement {
         switch (animal) {
 
         case "DOG":
-            System.out.println("domestic animal");
+            LOGGER.debug("domestic animal");
             result = "domestic animal";
 
         default:
-            System.out.println("unknown animal");
+            LOGGER.debug("unknown animal");
             result = "unknown animal";
 
         }
diff --git a/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/loops/LoopsUnitTest.java b/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/loops/LoopsUnitTest.java
index 5a8b116a2c..354a408af6 100644
--- a/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/loops/LoopsUnitTest.java
+++ b/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/loops/LoopsUnitTest.java
@@ -8,12 +8,16 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
+import com.baeldung.initializationguide.User;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class LoopsUnitTest {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(LoopsUnitTest.class);
     private LoopsInJava loops = new LoopsInJava();
     private static List list = new ArrayList<>();
     private static Set set = new HashSet<>();
@@ -65,41 +69,44 @@ public class LoopsUnitTest {
     @Test
     public void whenUsingSimpleFor_shouldIterateList() {
         for (int i = 0; i < list.size(); i++) {
-            System.out.println(list.get(i));
+            LOGGER.debug(list.get(i));
         }
     }
 
     @Test
     public void whenUsingEnhancedFor_shouldIterateList() {
         for (String item : list) {
-            System.out.println(item);
+            LOGGER.debug(item);
         }
     }
 
     @Test
     public void whenUsingEnhancedFor_shouldIterateSet() {
         for (String item : set) {
-            System.out.println(item);
+            LOGGER.debug(item);
         }
     }
 
     @Test
     public void whenUsingEnhancedFor_shouldIterateMap() {
         for (Entry entry : map.entrySet()) {
-            System.out.println("Key: " + entry.getKey() + " - " + "Value: " + entry.getValue());
+            LOGGER.debug("Key: " + entry.getKey() + " - " + "Value: " + entry.getValue());
         }
     }
 
     @Test
     public void whenUsingSimpleFor_shouldRunLabelledLoop() {
-        aa: for (int i = 1; i <= 3; i++) {
-            if (i == 1)
+        aa:
+        for (int i = 1; i <= 3; i++) {
+            if (i == 1) {
                 continue;
-            bb: for (int j = 1; j <= 3; j++) {
+            }
+            bb:
+            for (int j = 1; j <= 3; j++) {
                 if (i == 2 && j == 2) {
                     break aa;
                 }
-                System.out.println(i + " " + j);
+                LOGGER.debug(i + " " + j);
             }
         }
     }
diff --git a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/EmailService.java b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/EmailService.java
index bd2024fdfa..3d1e25e7a4 100644
--- a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/EmailService.java
+++ b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/EmailService.java
@@ -1,40 +1,55 @@
 package com.baeldung.mail;
 
-import javax.mail.*;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.Multipart;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMultipart;
 import java.io.File;
+import java.net.URI;
 import java.util.Properties;
 
 public class EmailService {
 
-    private String host = "";
-    private int port = 0;
-    private String username = "";
-    private String password = "";
+    private String username;
+    private String password;
 
+    private final Properties prop;
 
     public EmailService(String host, int port, String username, String password) {
-
-        this.host = host;
-        this.port = port;
-        this.username = username;
-        this.password = password;
-
-        sendMail();
-    }
-
-    private void sendMail() {
-
-        Properties prop = new Properties();
+        prop = new Properties();
         prop.put("mail.smtp.auth", true);
         prop.put("mail.smtp.starttls.enable", "true");
         prop.put("mail.smtp.host", host);
         prop.put("mail.smtp.port", port);
         prop.put("mail.smtp.ssl.trust", host);
 
+        this.username = username;
+        this.password = password;
+    }
+
+    public EmailService(String host, int port) {
+        prop = new Properties();
+        prop.put("mail.smtp.host", host);
+        prop.put("mail.smtp.port", port);
+    }
+
+    public static void main(String... args) {
+        try {
+            new EmailService("smtp.mailtrap.io", 25, "87ba3d9555fae8", "91cb4379af43ed")
+              .sendMail();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void sendMail() throws Exception {
+
         Session session = Session.getInstance(prop, new Authenticator() {
             @Override
             protected PasswordAuthentication getPasswordAuthentication() {
@@ -42,36 +57,35 @@ public class EmailService {
             }
         });
 
-        try {
+        Message message = new MimeMessage(session);
+        message.setFrom(new InternetAddress("from@gmail.com"));
+        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("to@gmail.com"));
+        message.setSubject("Mail Subject");
 
-                Message message = new MimeMessage(session);
-                message.setFrom(new InternetAddress("from@gmail.com"));
-                message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("to@gmail.com"));
-                message.setSubject("Mail Subject");
+        String msg = "This is my first email using JavaMailer";
 
-                String msg = "This is my first email using JavaMailer";
+        MimeBodyPart mimeBodyPart = new MimeBodyPart();
+        mimeBodyPart.setContent(msg, "text/html; charset=utf-8");
 
-                MimeBodyPart mimeBodyPart = new MimeBodyPart();
-                mimeBodyPart.setContent(msg, "text/html");
+        MimeBodyPart attachmentBodyPart = new MimeBodyPart();
 
-                MimeBodyPart attachmentBodyPart = new MimeBodyPart();
-                attachmentBodyPart.attachFile(new File("pom.xml"));
+        attachmentBodyPart.attachFile(getFile());
 
-                Multipart multipart = new MimeMultipart();
-                multipart.addBodyPart(mimeBodyPart);
-                multipart.addBodyPart(attachmentBodyPart);
+        Multipart multipart = new MimeMultipart();
+        multipart.addBodyPart(mimeBodyPart);
+        multipart.addBodyPart(attachmentBodyPart);
 
-                message.setContent(multipart);
+        message.setContent(multipart);
 
-                Transport.send(message);
-
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+        Transport.send(message);
     }
 
-    public static void main(String ... args) {
-        new EmailService("smtp.mailtrap.io", 25, "87ba3d9555fae8", "91cb4379af43ed");
+    private File getFile() throws Exception {
+        URI uri = this.getClass()
+          .getClassLoader()
+          .getResource("attachment.txt")
+          .toURI();
+        return new File(uri);
     }
 
 }
diff --git a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentService.java b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentService.java
index 7d4dc57f10..fbe8a54bbe 100644
--- a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentService.java
+++ b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentService.java
@@ -1,8 +1,5 @@
 package com.baeldung.mail.mailwithattachment;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.Properties;
 import javax.mail.BodyPart;
 import javax.mail.Message;
 import javax.mail.MessagingException;
@@ -10,23 +7,23 @@ import javax.mail.Multipart;
 import javax.mail.PasswordAuthentication;
 import javax.mail.Session;
 import javax.mail.Transport;
-import javax.mail.internet.AddressException;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMultipart;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Properties;
 
 public class MailWithAttachmentService {
 
-    private String username = "";
-    private String password = "";
-    private String host = "";
-    private String port = "";
+    private final String username;
+    private final String password;
+    private final String host;
+    private final int port;
 
-    MailWithAttachmentService() {
-    }
-
-    MailWithAttachmentService(String username, String password, String host, String port) {
+    MailWithAttachmentService(String username, String password, String host, int port) {
         this.username = username;
         this.password = password;
         this.host = host;
@@ -40,15 +37,14 @@ public class MailWithAttachmentService {
         props.put("mail.smtp.host", this.host);
         props.put("mail.smtp.port", this.port);
 
-        Session session = Session.getInstance(props, new javax.mail.Authenticator() {
+        return Session.getInstance(props, new javax.mail.Authenticator() {
             protected PasswordAuthentication getPasswordAuthentication() {
                 return new PasswordAuthentication(username, password);
             }
         });
-        return session;
     }
 
-    public Message createMail(Session session) throws AddressException, MessagingException, IOException {
+    public void sendMail(Session session) throws MessagingException, IOException {
         Message message = new MimeMessage(session);
         message.setFrom(new InternetAddress("mail@gmail.com"));
         message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("mail@gmail.com"));
@@ -61,23 +57,27 @@ public class MailWithAttachmentService {
         multipart.addBodyPart(messageBodyPart);
 
         MimeBodyPart attachmentPart = new MimeBodyPart();
-        MimeBodyPart attachmentPart2 = new MimeBodyPart();
-
-        attachmentPart.attachFile(new File("C:\\Document1.txt"));
-        attachmentPart2.attachFile(new File("C:\\Document2.txt"));
-
+        attachmentPart.attachFile(getFile("attachment.txt"));
         multipart.addBodyPart(attachmentPart);
+
+        MimeBodyPart attachmentPart2 = new MimeBodyPart();
+        attachmentPart2.attachFile(getFile("attachment2.txt"));
         multipart.addBodyPart(attachmentPart2);
 
         message.setContent(multipart);
-
-        return message;
-    }
-
-    public void sendMail(Session session) throws MessagingException, IOException {
-
-        Message message = createMail(session);
         Transport.send(message);
     }
 
-}
\ No newline at end of file
+    private File getFile(String filename) {
+        try {
+            URI uri = this.getClass()
+              .getClassLoader()
+              .getResource(filename)
+              .toURI();
+            return new File(uri);
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Unable to find file from resources: " + filename);
+        }
+    }
+
+}
diff --git a/core-java-modules/core-java-networking-2/src/main/resources/attachment.txt b/core-java-modules/core-java-networking-2/src/main/resources/attachment.txt
new file mode 100644
index 0000000000..a726ded018
--- /dev/null
+++ b/core-java-modules/core-java-networking-2/src/main/resources/attachment.txt
@@ -0,0 +1 @@
+sample attachment content
\ No newline at end of file
diff --git a/core-java-modules/core-java-networking-2/src/main/resources/attachment2.txt b/core-java-modules/core-java-networking-2/src/main/resources/attachment2.txt
new file mode 100644
index 0000000000..14c8ea9ff9
--- /dev/null
+++ b/core-java-modules/core-java-networking-2/src/main/resources/attachment2.txt
@@ -0,0 +1 @@
+sample attachment content 2
\ No newline at end of file
diff --git a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/EmailServiceLiveTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/EmailServiceLiveTest.java
new file mode 100644
index 0000000000..7f543bc612
--- /dev/null
+++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/EmailServiceLiveTest.java
@@ -0,0 +1,60 @@
+package com.baeldung.mail;
+
+import com.icegreen.greenmail.junit.GreenMailRule;
+import com.icegreen.greenmail.util.ServerSetupTest;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+public class EmailServiceLiveTest {
+
+    @Rule
+    public final GreenMailRule greenMail = new GreenMailRule(ServerSetupTest.SMTP);
+
+    private EmailService emailService;
+
+    @Before
+    public void setup() {
+        emailService = new EmailService("localhost", greenMail.getSmtp().getPort());
+    }
+
+    @Test
+    public void givenEmailMessageWithAttachment_whenEmailIsSent_MessageIsReceived() throws Exception {
+
+        emailService.sendMail();
+
+        MimeMessage[] receivedMessages = greenMail.getReceivedMessages();
+        assertEquals(1, receivedMessages.length);
+
+        MimeMessage receivedMessage = receivedMessages[0];
+        assertEquals("Mail Subject", subjectFromMessage(receivedMessage));
+        assertEquals("This is my first email using JavaMailer", emailTextFrom(receivedMessage));
+        assertEquals("sample attachment content", attachmentContentsFrom(receivedMessage));
+    }
+
+    private static String subjectFromMessage(MimeMessage receivedMessage) throws MessagingException {
+        return receivedMessage.getSubject();
+    }
+
+    private static String emailTextFrom(MimeMessage receivedMessage) throws IOException, MessagingException {
+        return ((MimeMultipart) receivedMessage.getContent())
+          .getBodyPart(0)
+          .getContent()
+          .toString();
+    }
+
+    private static String attachmentContentsFrom(MimeMessage receivedMessage) throws Exception {
+        return ((MimeMultipart) receivedMessage.getContent())
+          .getBodyPart(1)
+          .getContent()
+          .toString();
+    }
+
+}
diff --git a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentServiceLiveTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentServiceLiveTest.java
index ef82657ab5..04ad47875f 100644
--- a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentServiceLiveTest.java
+++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentServiceLiveTest.java
@@ -1,48 +1,77 @@
 package com.baeldung.mail.mailwithattachment;
 
-import static org.junit.Assert.*;
-import javax.annotation.Resource;
-import javax.mail.Session;
-
-import org.junit.After;
+import com.icegreen.greenmail.configuration.GreenMailConfiguration;
+import com.icegreen.greenmail.junit.GreenMailRule;
+import com.icegreen.greenmail.util.GreenMailUtil;
+import com.icegreen.greenmail.util.ServerSetupTest;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 
-import com.baeldung.mail.mailwithattachment.MailWithAttachmentService;
-import com.icegreen.greenmail.util.GreenMail;
-import com.icegreen.greenmail.util.ServerSetupTest;
+import javax.annotation.Resource;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import static org.junit.Assert.assertEquals;
 
 public class MailWithAttachmentServiceLiveTest {
 
+    private static final String USERNAME = "testUser";
+    private static final String PASSWORD = "password";
+    private static final String HOSTNAME = "localhost";
+
+    @Rule
+    public final GreenMailRule greenMail = new GreenMailRule(ServerSetupTest.SMTP)
+      .withConfiguration(
+        GreenMailConfiguration.aConfig()
+          .withUser(USERNAME, PASSWORD)
+      );
+
     @Resource
     private MailWithAttachmentService emailService;
-    private GreenMail greenMail;
 
     @Before
-    public void startMailServer() {
-        emailService = new MailWithAttachmentService();
-        greenMail = new GreenMail(ServerSetupTest.SMTP);
-        greenMail.start();
-    }
-
-    @After
-    public void stopMailServer() {
-        greenMail.stop();
-        emailService = null;
+    public void setup() {
+        emailService = new MailWithAttachmentService(
+          USERNAME, PASSWORD, HOSTNAME, greenMail.getSmtp().getPort()
+        );
     }
 
     @Test
-    public void canSendMail() {
-        try {
-            Session testSession = greenMail.getSmtp()
-                .createSession();
-            emailService.sendMail(testSession);
-            assertEquals(1, greenMail.getReceivedMessages().length);
-            
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+    public void givenEmailService_whenMessageSentWithAttachments_thenMessageIsReceived() throws Exception {
 
+        Session tlsSession = emailService.getSession();
+        emailService.sendMail(tlsSession);
+
+        MimeMessage[] receivedMessages = greenMail.getReceivedMessages();
+        assertEquals(1, receivedMessages.length);
+
+        MimeMessage receivedMessage = receivedMessages[0];
+        assertEquals("Testing Subject", subjectFrom(receivedMessage));
+        assertEquals("This is message body", emailTextFrom(receivedMessage));
+        assertEquals("sample attachment content", attachment1ContentsFrom(receivedMessage));
+        assertEquals("sample attachment content 2", attachment2ContentsFrom(receivedMessage));
+    }
+
+    private static String subjectFrom(MimeMessage receivedMessage) throws MessagingException {
+        return receivedMessage.getSubject();
+    }
+
+    private static String emailTextFrom(MimeMessage receivedMessage) throws Exception {
+        return GreenMailUtil.getBody(((MimeMultipart) receivedMessage.getContent())
+          .getBodyPart(0));
+    }
+
+    private static String attachment1ContentsFrom(MimeMessage receivedMessage) throws Exception {
+        return GreenMailUtil.getBody(((MimeMultipart) receivedMessage.getContent())
+          .getBodyPart(1));
+    }
+
+    private static String attachment2ContentsFrom(MimeMessage receivedMessage) throws Exception {
+        return GreenMailUtil.getBody(((MimeMultipart) receivedMessage.getContent())
+          .getBodyPart(2));
     }
 
 }
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/pom.xml b/core-java-modules/core-java-networking-3/pom.xml
index 4a05af8b25..297d665544 100644
--- a/core-java-modules/core-java-networking-3/pom.xml
+++ b/core-java-modules/core-java-networking-3/pom.xml
@@ -29,21 +29,10 @@
             tomcat-embed-core
             ${tomcat.embeded.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-        
-            org.junit.vintage
-            junit-vintage-engine
-            test
-        
         
             com.sun.mail
             javax.mail
-            1.6.2
+            ${javax.mail.version}
         
         
         
@@ -75,16 +64,26 @@
                 
             
         
+        
+            
+                org.apache.maven.plugins
+                maven-compiler-plugin
+                
+                    16
+                    16
+                
+            
+        
     
 
     
         5.2.8.RELEASE
         9.4.31.v20200723
         10.0.0-M7
-        3.11.1
         5.3.3
         1.32
         0.17
+        1.6.2
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/socket/UnixDomainSocketClient.java b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/socket/UnixDomainSocketClient.java
new file mode 100644
index 0000000000..2a8ae05628
--- /dev/null
+++ b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/socket/UnixDomainSocketClient.java
@@ -0,0 +1,49 @@
+package com.baeldung.socket;
+
+import java.io.IOException;
+import java.net.StandardProtocolFamily;
+import java.net.UnixDomainSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.nio.file.Path;
+
+class UnixDomainSocketClient {
+
+    public static void main(String[] args) throws Exception {
+        new UnixDomainSocketClient().runClient();
+    }
+
+    void runClient() throws IOException {
+        Path socketPath = Path.of(System.getProperty("user.home"))
+          .resolve("baeldung.socket");
+        UnixDomainSocketAddress socketAddress = getAddress(socketPath);
+
+        SocketChannel channel = openSocketChannel(socketAddress);
+
+        String message = "Hello from Baeldung Unix domain socket article";
+        writeMessage(channel, message);
+    }
+
+    UnixDomainSocketAddress getAddress(Path socketPath) {
+        return UnixDomainSocketAddress.of(socketPath);
+    }
+
+    SocketChannel openSocketChannel(UnixDomainSocketAddress socketAddress) throws IOException {
+        SocketChannel channel = SocketChannel
+          .open(StandardProtocolFamily.UNIX);
+        channel.connect(socketAddress);
+        return channel;
+    }
+
+    void writeMessage(SocketChannel socketChannel, String message) throws IOException {
+        ByteBuffer buffer = ByteBuffer.allocate(1024);
+        buffer.clear();
+        buffer.put(message.getBytes());
+        buffer.flip();
+
+        while (buffer.hasRemaining()) {
+            socketChannel.write(buffer);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/socket/UnixDomainSocketServer.java b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/socket/UnixDomainSocketServer.java
new file mode 100644
index 0000000000..c3093ae00c
--- /dev/null
+++ b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/socket/UnixDomainSocketServer.java
@@ -0,0 +1,57 @@
+package com.baeldung.socket;
+
+import java.io.IOException;
+import java.net.StandardProtocolFamily;
+import java.net.UnixDomainSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Optional;
+
+class UnixDomainSocketServer {
+
+    public static void main(String[] args) throws IOException, InterruptedException {
+        new UnixDomainSocketServer().runServer();
+    }
+
+    void runServer() throws IOException, InterruptedException {
+        Path socketPath = Path.of(System.getProperty("user.home"))
+          .resolve("baeldung.socket");
+        Files.deleteIfExists(socketPath);
+        UnixDomainSocketAddress socketAddress = getAddress(socketPath);
+
+        ServerSocketChannel serverChannel = createServerSocketChannel(socketAddress);
+
+        SocketChannel channel = serverChannel.accept();
+
+        while (true) {
+            readSocketMessage(channel)
+              .ifPresent(message -> System.out.printf("[Client message] %s%n", message));
+            Thread.sleep(100);
+        }
+    }
+
+    UnixDomainSocketAddress getAddress(Path socketPath) {
+        return UnixDomainSocketAddress.of(socketPath);
+    }
+
+    ServerSocketChannel createServerSocketChannel(UnixDomainSocketAddress socketAddress) throws IOException {
+        ServerSocketChannel serverChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
+        serverChannel.bind(socketAddress);
+        return serverChannel;
+    }
+
+    Optional readSocketMessage(SocketChannel channel) throws IOException {
+        ByteBuffer buffer = ByteBuffer.allocate(1024);
+        int bytesRead = channel.read(buffer);
+        if (bytesRead < 0) return Optional.empty();
+        byte[] bytes = new byte[bytesRead];
+        buffer.flip();
+        buffer.get(bytes);
+        String message = new String(bytes);
+        return Optional.of(message);
+    }
+
+}
\ No newline at end of file
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-networking-3/src/test/java/com/baeldung/socket/UnixDomainSocketClientUnitTest.java b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/UnixDomainSocketClientUnitTest.java
new file mode 100644
index 0000000000..8cd2ee94d4
--- /dev/null
+++ b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/UnixDomainSocketClientUnitTest.java
@@ -0,0 +1,82 @@
+package com.baeldung.socket;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.stubbing.Answer;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.StandardProtocolFamily;
+import java.net.UnixDomainSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.file.Path;
+import java.util.UUID;
+
+import static java.nio.file.Files.deleteIfExists;
+import static org.assertj.core.util.Files.newTemporaryFile;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class UnixDomainSocketClientUnitTest {
+
+    @Test
+    public void givenSocketPath_shouldCreateUnixDomainSocketAddress() {
+        // given
+        File tempFile = newTemporaryFile();
+        Path socketPath = tempFile.toPath();
+
+        // when
+        UnixDomainSocketAddress address = new UnixDomainSocketClient().getAddress(socketPath);
+
+        // then
+        assertEquals(address.getPath(), socketPath);
+
+        // cleanup
+        tempFile.delete();
+    }
+
+    @Test
+    public void givenUnixDomainSocketAddress_shouldOpenSocketChannel() throws IOException {
+        // given
+        File tempFile = newTemporaryFile();
+        Path socketPath = tempFile.toPath();
+        deleteIfExists(socketPath);
+        UnixDomainSocketAddress address = UnixDomainSocketAddress.of(socketPath);
+
+        // bind address as a unix domain socket
+        ServerSocketChannel serverChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
+        serverChannel.bind(address);
+
+        // when
+        SocketChannel socketChannel = new UnixDomainSocketClient().openSocketChannel(address);
+
+        // then
+        assertTrue(socketChannel.isOpen());
+        assertEquals(socketChannel.getRemoteAddress(), address);
+
+        // cleanup
+        tempFile.delete();
+    }
+
+    @Test
+    public void givenSocketChannelAndMessage_shouldWriteMessage() throws IOException {
+        // given
+        SocketChannel socketChannel = Mockito.mock(SocketChannel.class);
+        String message = UUID.randomUUID().toString();
+        Mockito.when(socketChannel.write(Mockito.any(ByteBuffer.class)))
+          .thenAnswer(
+            (Answer) invocationOnMock -> {
+              ((ByteBuffer) invocationOnMock.getArguments()[0]).position(message.getBytes().length);
+              return -1;
+            }
+          );
+
+        // when
+        new UnixDomainSocketClient().writeMessage(socketChannel, message);
+
+        // then
+        Mockito.verify(socketChannel, Mockito.times(1)).write(Mockito.any(ByteBuffer.class));
+    }
+}
diff --git a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/UnixDomainSocketServerUnitTest.java b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/UnixDomainSocketServerUnitTest.java
new file mode 100644
index 0000000000..1d0a68ac2f
--- /dev/null
+++ b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/socket/UnixDomainSocketServerUnitTest.java
@@ -0,0 +1,50 @@
+package com.baeldung.socket;
+
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.UnixDomainSocketAddress;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.file.Path;
+
+import static java.nio.file.Files.deleteIfExists;
+import static org.assertj.core.util.Files.newTemporaryFile;
+import static org.junit.Assert.assertEquals;
+
+public class UnixDomainSocketServerUnitTest {
+
+    @Test
+    public void givenSocketPath_shouldCreateUnixDomainSocketAddress() {
+        // given
+        File tempFile = newTemporaryFile();
+        Path socketPath = tempFile.toPath();
+
+        // when
+        UnixDomainSocketAddress address = new UnixDomainSocketServer().getAddress(socketPath);
+
+        // then
+        assertEquals(address.getPath(), socketPath);
+
+        // cleanup
+        tempFile.delete();
+    }
+
+    @Test
+    public void givenUnixDomainSocketAddress_shouldCreateServerSocketChannel() throws IOException {
+        // given
+        File tempFile = newTemporaryFile();
+        Path socketPath = tempFile.toPath();
+        deleteIfExists(socketPath);
+        UnixDomainSocketAddress address = UnixDomainSocketAddress.of(socketPath);
+
+        // when
+        ServerSocketChannel serverSocketChannel = new UnixDomainSocketServer().createServerSocketChannel(address);
+
+        // then
+        assertEquals(serverSocketChannel.getLocalAddress(), address);
+
+        // cleanup
+        tempFile.delete();
+    }
+}
diff --git a/core-java-modules/core-java-nio-2/pom.xml b/core-java-modules/core-java-nio-2/pom.xml
index f9cf1f3060..eb56c2bf68 100644
--- a/core-java-modules/core-java-nio-2/pom.xml
+++ b/core-java-modules/core-java-nio-2/pom.xml
@@ -14,13 +14,4 @@
         0.0.1-SNAPSHOT
     
 
-    
-        
-            org.assertj
-            assertj-core
-            3.6.1
-            test
-        
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-optional/pom.xml b/core-java-modules/core-java-optional/pom.xml
index dd5217df74..d04763598d 100644
--- a/core-java-modules/core-java-optional/pom.xml
+++ b/core-java-modules/core-java-optional/pom.xml
@@ -56,18 +56,11 @@
             ${rest-assured.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
         5.4.0.Final
         27.1-jre
-        3.10.0
         3.1.1
     
 
diff --git a/core-java-modules/core-java-os/pom.xml b/core-java-modules/core-java-os/pom.xml
index b279e3d6cb..54b86522f4 100644
--- a/core-java-modules/core-java-os/pom.xml
+++ b/core-java-modules/core-java-os/pom.xml
@@ -1,27 +1,20 @@
 
 
-	4.0.0
-	core-java-os
-	0.1.0-SNAPSHOT
-	core-java-os
-	jar
+    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
+    core-java-os
+    0.1.0-SNAPSHOT
+    core-java-os
+    jar
 
-	
-		com.baeldung.core-java-modules
-		core-java-modules
-		0.0.1-SNAPSHOT
-		../
-	
+    
+        com.baeldung.core-java-modules
+        core-java-modules
+        0.0.1-SNAPSHOT
+    
 
 	
-	    
-		    org.junit.jupiter
-			junit-jupiter-engine
-            ${junit-jupiter.version}
-			test
-		
 		
 			org.apache.commons
 			commons-collections4
@@ -42,13 +35,6 @@
 			log4j
 			${log4j.version}
 		
-		
-		
-			org.assertj
-			assertj-core
-			${assertj.version}
-			test
-		
 		
 			org.unix4j
 			unix4j-command
@@ -59,41 +45,44 @@
 			grep4j
 			${grep4j.version}
 		
+        
+            org.projectlombok
+            lombok
+            ${lombok.version}
+            provided
+        
 	
 
-	
-		core-java-os
-		
-			
-				src/main/resources
-				true
-			
-		
-		
-			
-				org.apache.maven.plugins
-				maven-compiler-plugin
-				${maven-compiler-plugin.version}
-				
-					${maven.compiler.source}
-					${maven.compiler.target}
-				
-			
-		
-	
+    
+        core-java-os
+        
+            
+                src/main/resources
+                true
+            
+        
+        
+            
+                org.apache.maven.plugins
+                maven-compiler-plugin
+                ${maven-compiler-plugin.version}
+                
+                    ${maven.compiler.source}
+                    ${maven.compiler.target}
+                
+            
+        
+    
 
-	
-		
-		4.1
-		4.01
-		
-		3.6.1
-		1.8.9
-		1.9
-		1.9
-		25.1-jre
-		0.4
-		1.8.7
-	
+    
+        4.01
+        1.8.9
+        1.9
+        1.9
+        25.1-jre
+        0.4
+        1.8.7
+        1.18.22
+    
 
-
\ No newline at end of file
+
diff --git a/core-java-modules/core-java-os/src/test/java/com/baeldung/shell/JavaProcessUnitIntegrationTest.java b/core-java-modules/core-java-os/src/test/java/com/baeldung/shell/JavaProcessUnitIntegrationTest.java
index 53e9364207..9d24dd1578 100644
--- a/core-java-modules/core-java-os/src/test/java/com/baeldung/shell/JavaProcessUnitIntegrationTest.java
+++ b/core-java-modules/core-java-os/src/test/java/com/baeldung/shell/JavaProcessUnitIntegrationTest.java
@@ -1,12 +1,23 @@
-package com.baeldung.java.shell;
+package com.baeldung.shell;
 
+import org.junit.After;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
 
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
 public class JavaProcessUnitIntegrationTest {
     private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().startsWith("windows");
 
@@ -29,6 +40,18 @@ public class JavaProcessUnitIntegrationTest {
 
     private String homeDirectory = System.getProperty("user.home");
 
+    private ExecutorService executorService;
+
+    @Before
+    public void setUp() {
+        executorService = Executors.newSingleThreadExecutor();
+    }
+
+    @After
+    public void tearDown() {
+        executorService.shutdown();
+    }
+
     @Test
     public void givenProcess_whenCreatingViaRuntime_shouldSucceed() throws Exception {
         Process process;
@@ -38,9 +61,13 @@ public class JavaProcessUnitIntegrationTest {
             process = Runtime.getRuntime().exec(String.format("sh -c ls %s", homeDirectory));
         }
         StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), consumer);
-        Executors.newSingleThreadExecutor().submit(streamGobbler);
+
+        Future future = executorService.submit(streamGobbler);
         int exitCode = process.waitFor();
-        Assert.assertEquals(0, exitCode);
+
+        // verify the stream output from the process
+        assertDoesNotThrow(() -> future.get(10, TimeUnit.SECONDS));
+        assertEquals(0, exitCode);
     }
 
     @Test
@@ -54,8 +81,12 @@ public class JavaProcessUnitIntegrationTest {
         builder.directory(new File(homeDirectory));
         Process process = builder.start();
         StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), consumer);
-        Executors.newSingleThreadExecutor().submit(streamGobbler);
+
+        Future future = executorService.submit(streamGobbler);
         int exitCode = process.waitFor();
-        Assert.assertEquals(0, exitCode);
+
+        // verify the stream output from the process
+        assertDoesNotThrow(() -> future.get(10, TimeUnit.SECONDS));
+        assertEquals(0, exitCode);
     }
 }
diff --git a/core-java-modules/core-java-perf/README.md b/core-java-modules/core-java-perf/README.md
index d52fd2d733..e09f8bb6fc 100644
--- a/core-java-modules/core-java-perf/README.md
+++ b/core-java-modules/core-java-perf/README.md
@@ -11,3 +11,4 @@ This module contains articles about performance of Java applications
 - [Monitoring Java Applications with Flight Recorder](https://www.baeldung.com/java-flight-recorder-monitoring)
 - [Branch Prediction in Java](https://www.baeldung.com/java-branch-prediction)
 - [Capturing a Java Thread Dump](https://www.baeldung.com/java-thread-dump)
+- [JMX Ports](https://www.baeldung.com/jmx-ports)
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-reflection-2/README.md b/core-java-modules/core-java-reflection-2/README.md
index 4c888bdf58..c1966dd63d 100644
--- a/core-java-modules/core-java-reflection-2/README.md
+++ b/core-java-modules/core-java-reflection-2/README.md
@@ -6,3 +6,4 @@
 - [Checking if a Java Class is ‘abstract’ Using Reflection](https://www.baeldung.com/java-reflection-is-class-abstract)
 - [Invoking a Private Method in Java](https://www.baeldung.com/java-call-private-method)
 - [Finding All Classes in a Java Package](https://www.baeldung.com/java-find-all-classes-in-package)
+- [Invoke a Static Method Using Java Reflection API](https://www.baeldung.com/java-invoke-static-method-reflection)
diff --git a/core-java-modules/core-java-reflection-2/pom.xml b/core-java-modules/core-java-reflection-2/pom.xml
index 75168936a7..06ac745f17 100644
--- a/core-java-modules/core-java-reflection-2/pom.xml
+++ b/core-java-modules/core-java-reflection-2/pom.xml
@@ -24,12 +24,12 @@
         
             org.reflections
             reflections
-            0.9.12
+            ${reflections.version}
         
         
             com.google.guava
             guava
-            30.1.1-jre
+            ${guava.version}
         
     
 
@@ -56,7 +56,8 @@
     
 
     
-        3.8.0
+        0.9.12
+        30.1.1-jre
         1.8
         1.8
         5.3.4
diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/access/staticmethods/GreetingAndBye.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/access/staticmethods/GreetingAndBye.java
new file mode 100644
index 0000000000..471ed1ee5b
--- /dev/null
+++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/access/staticmethods/GreetingAndBye.java
@@ -0,0 +1,12 @@
+package com.baeldung.reflection.access.staticmethods;
+
+public class GreetingAndBye {
+
+    public static String greeting(String name) {
+        return String.format("Hey %s, nice to meet you!", name);
+    }
+
+    private static String goodBye(String name) {
+        return String.format("Bye %s, see you next time.", name);
+    }
+}
diff --git a/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/check/abstractclass/GreetingAndByeClassUnitTest.java b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/check/abstractclass/GreetingAndByeClassUnitTest.java
new file mode 100644
index 0000000000..da82d2370c
--- /dev/null
+++ b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/check/abstractclass/GreetingAndByeClassUnitTest.java
@@ -0,0 +1,28 @@
+package com.baeldung.reflection.check.abstractclass;
+
+import com.baeldung.reflection.access.staticmethods.GreetingAndBye;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+class GreetingAndByeUnitTest {
+
+    @Test
+    void givenPublicStaticMethod_whenCallWithReflection_thenReturnExpectedResult() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class clazz = GreetingAndBye.class;
+        Method method = clazz.getMethod("greeting", String.class);
+        Object result = method.invoke(null, "Eric");
+        Assertions.assertEquals("Hey Eric, nice to meet you!", result);
+    }
+
+    @Test
+    void givenPrivateStaticMethod_whenCallWithReflection_thenReturnExpectedResult() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class clazz = GreetingAndBye.class;
+        Method method = clazz.getDeclaredMethod("goodBye", String.class);
+        method.setAccessible(true);
+        Object result = method.invoke(null, "Eric");
+        Assertions.assertEquals("Bye Eric, see you next time.", result);
+    }
+}
diff --git a/core-java-modules/core-java-reflection/pom.xml b/core-java-modules/core-java-reflection/pom.xml
index b28ecccb80..1706bf3c45 100644
--- a/core-java-modules/core-java-reflection/pom.xml
+++ b/core-java-modules/core-java-reflection/pom.xml
@@ -14,14 +14,6 @@
         0.0.1-SNAPSHOT
     
 
-    
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-        
-    
-
     
         core-java-reflection
         
@@ -45,8 +37,6 @@
     
 
     
-        3.8.0
-        3.10.0
         1.8
         1.8
     
diff --git a/core-java-modules/core-java-regex-2/README.md b/core-java-modules/core-java-regex-2/README.md
index 25656c3cb1..6dafc74d41 100644
--- a/core-java-modules/core-java-regex-2/README.md
+++ b/core-java-modules/core-java-regex-2/README.md
@@ -3,3 +3,5 @@
 - [Non-Capturing Regex Groups in Java](https://www.baeldung.com/java-regex-non-capturing-groups)
 - [Lookahead and Lookbehind in Java Regex](https://www.baeldung.com/java-regex-lookahead-lookbehind)
 - [Converting Camel Case and Title Case to Words in Java](https://www.baeldung.com/java-camel-case-title-case-to-words)
+- [How to Use Regular Expressions to Replace Tokens in Strings in Java](https://www.baeldung.com/java-regex-token-replacement)
+- More articles: [[<-- prev]](/core-java-modules/core-java-regex)
\ No newline at end of file
diff --git a/core-java-modules/core-java-regex-2/pom.xml b/core-java-modules/core-java-regex-2/pom.xml
index a47c0ff357..ae9385e63c 100644
--- a/core-java-modules/core-java-regex-2/pom.xml
+++ b/core-java-modules/core-java-regex-2/pom.xml
@@ -14,17 +14,4 @@
         0.0.1-SNAPSHOT
     
 
-    
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
-    
-
-    
-        3.15.0
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-regex/src/main/java/com/baeldung/replacetokens/ReplacingTokens.java b/core-java-modules/core-java-regex-2/src/main/java/com/baeldung/replacetokens/ReplacingTokens.java
similarity index 100%
rename from core-java-modules/core-java-regex/src/main/java/com/baeldung/replacetokens/ReplacingTokens.java
rename to core-java-modules/core-java-regex-2/src/main/java/com/baeldung/replacetokens/ReplacingTokens.java
diff --git a/core-java-modules/core-java-regex/src/test/java/com/baeldung/replacetokens/ReplacingTokensUnitTest.java b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/replacetokens/ReplacingTokensUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-regex/src/test/java/com/baeldung/replacetokens/ReplacingTokensUnitTest.java
rename to core-java-modules/core-java-regex-2/src/test/java/com/baeldung/replacetokens/ReplacingTokensUnitTest.java
diff --git a/core-java-modules/core-java-regex/README.md b/core-java-modules/core-java-regex/README.md
index 4c78f64d75..51c04af6ba 100644
--- a/core-java-modules/core-java-regex/README.md
+++ b/core-java-modules/core-java-regex/README.md
@@ -9,9 +9,9 @@
 - [Guide to Escaping Characters in Java RegExps](http://www.baeldung.com/java-regexp-escape-char)
 - [Pre-compile Regex Patterns Into Pattern Objects](https://www.baeldung.com/java-regex-pre-compile)
 - [Difference Between Java Matcher find() and matches()](https://www.baeldung.com/java-matcher-find-vs-matches)
-- [How to Use Regular Expressions to Replace Tokens in Strings in Java](https://www.baeldung.com/java-regex-token-replacement)
 - [Regular Expressions \s and \s+ in Java](https://www.baeldung.com/java-regex-s-splus)
 - [Validate Phone Numbers With Java Regex](https://www.baeldung.com/java-regex-validate-phone-numbers)
 - [How to Count the Number of Matches for a Regex?](https://www.baeldung.com/java-count-regex-matches)
 - [Find All Numbers in a String in Java](https://www.baeldung.com/java-find-numbers-in-string)
 - [Understanding the Pattern.quote Method](https://www.baeldung.com/java-pattern-quote)
+- More articles: [[next -->]](/core-java-modules/core-java-regex-2)
diff --git a/core-java-modules/core-java-regex/pom.xml b/core-java-modules/core-java-regex/pom.xml
index 3fb63fb42a..93f3ae3cdb 100644
--- a/core-java-modules/core-java-regex/pom.xml
+++ b/core-java-modules/core-java-regex/pom.xml
@@ -25,12 +25,6 @@
             jmh-generator-annprocess
             ${jmh-core.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
     
 
     
@@ -43,8 +37,4 @@
         
     
 
-    
-        3.15.0
-    
-
 
\ 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-security-2/README.md b/core-java-modules/core-java-security-2/README.md
index 680a7de925..31404d24a5 100644
--- a/core-java-modules/core-java-security-2/README.md
+++ b/core-java-modules/core-java-security-2/README.md
@@ -10,12 +10,7 @@ This module contains articles about core Java Security
 - [SHA-256 and SHA3-256 Hashing in Java](https://www.baeldung.com/sha-256-hashing-java)
 - [Checksums in Java](https://www.baeldung.com/java-checksums)
 - [How to Read PEM File to Get Public and Private Keys](https://www.baeldung.com/java-read-pem-file-keys)
-- [Listing the Available Cipher Algorithms](https://www.baeldung.com/java-list-cipher-algorithms)
 - [Get a List of Trusted Certificates in Java](https://www.baeldung.com/java-list-trusted-certificates)
 - [Security Context Basics: User, Subject and Principal](https://www.baeldung.com/security-context-basics)
-- [Java AES Encryption and Decryption](https://www.baeldung.com/java-aes-encryption-decryption)
-- [InvalidAlgorithmParameterException: Wrong IV Length](https://www.baeldung.com/java-invalidalgorithmparameter-exception)
 - [The java.security.egd JVM Option](https://www.baeldung.com/java-security-egd)
-- [RSA in Java](https://www.baeldung.com/java-rsa)
-- [3DES in Java](https://www.baeldung.com/java-3des)
 - More articles: [[<-- prev]](/core-java-modules/core-java-security)
diff --git a/core-java-modules/core-java-security-2/pom.xml b/core-java-modules/core-java-security-2/pom.xml
index 8de12c0c46..7a354ee9e2 100644
--- a/core-java-modules/core-java-security-2/pom.xml
+++ b/core-java-modules/core-java-security-2/pom.xml
@@ -25,13 +25,6 @@
             bcprov-jdk15on
             ${bouncycastle.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
         
             javax.xml.bind
@@ -41,11 +34,8 @@
     
 
     
-        
         1.60
         1.11
-        
-        3.18.0
         2.3.1
     
 
diff --git a/core-java-modules/core-java-security-3/README.md b/core-java-modules/core-java-security-3/README.md
index a37719964b..30cfd8a947 100644
--- a/core-java-modules/core-java-security-3/README.md
+++ b/core-java-modules/core-java-security-3/README.md
@@ -6,4 +6,6 @@ This module contains articles about core Java Security
 
 - [Secret Key and String Conversion in Java](https://www.baeldung.com/java-secret-key-to-string)
 - [Enabling Unlimited Strength Cryptography in Java](https://www.baeldung.com/jce-enable-unlimited-strength)
+- [Initialization Vector for Encryption](https://www.baeldung.com/java-encryption-iv)
+- [HMAC in Java](https://www.baeldung.com/java-hmac)
 - More articles: [[<-- prev]](/core-java-modules/core-java-security-2)
diff --git a/core-java-modules/core-java-security-3/pom.xml b/core-java-modules/core-java-security-3/pom.xml
index 69d0ffb917..3cd546e697 100644
--- a/core-java-modules/core-java-security-3/pom.xml
+++ b/core-java-modules/core-java-security-3/pom.xml
@@ -12,7 +12,6 @@
         com.baeldung.core-java-modules
         core-java-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
@@ -26,13 +25,6 @@
             bcprov-jdk15on
             ${bouncycastle.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
         
             javax.xml.bind
@@ -42,11 +34,8 @@
     
 
     
-        
         1.60
         1.11
-        
-        3.18.0
         2.3.1
     
 
diff --git a/core-java-modules/core-java-security-3/src/main/java/com/baeldung/crypto/CryptoDriver.java b/core-java-modules/core-java-security-3/src/main/java/com/baeldung/crypto/CryptoDriver.java
new file mode 100644
index 0000000000..552bd5d474
--- /dev/null
+++ b/core-java-modules/core-java-security-3/src/main/java/com/baeldung/crypto/CryptoDriver.java
@@ -0,0 +1,86 @@
+package com.baeldung.crypto;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.IvParameterSpec;
+import java.security.GeneralSecurityException;
+
+import com.baeldung.crypto.utils.CryptoUtils;
+
+public class CryptoDriver {
+
+    public byte[] ecbEncrypt(SecretKey key, byte[] data) throws GeneralSecurityException {
+        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+        cipher.init(Cipher.ENCRYPT_MODE, key);
+        return cipher.doFinal(data);
+    }
+
+    public byte[] ecbDecrypt(SecretKey key, byte[] cipherText) throws GeneralSecurityException {
+        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+        cipher.init(Cipher.DECRYPT_MODE, key);
+        return cipher.doFinal(cipherText);
+    }
+
+    public byte[] cbcEncrypt(SecretKey key, IvParameterSpec iv, byte[] data) throws GeneralSecurityException {
+        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
+        return cipher.doFinal(data);
+    }
+
+    public byte[] cbcDecrypt(SecretKey key, IvParameterSpec iv, byte[] cipherText) throws GeneralSecurityException {
+        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+        cipher.init(Cipher.DECRYPT_MODE, key, iv);
+        return cipher.doFinal(cipherText);
+    }
+
+    public byte[] cfbEncrypt(SecretKey key, IvParameterSpec iv, byte[] data) throws GeneralSecurityException {
+        Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
+        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
+        return cipher.doFinal(data);
+    }
+
+    public byte[] cfbDecrypt(SecretKey key, IvParameterSpec iv, byte[] cipherText) throws GeneralSecurityException {
+        Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
+        cipher.init(Cipher.DECRYPT_MODE, key, iv);
+        return cipher.doFinal(cipherText);
+    }
+
+    public byte[] ofbEncrypt(SecretKey key, IvParameterSpec iv, byte[] data) throws GeneralSecurityException {
+        Cipher cipher = Cipher.getInstance("AES/OFB32/PKCS5Padding");
+        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
+        return cipher.doFinal(data);
+    }
+
+    public byte[] ofbDecrypt(SecretKey key, IvParameterSpec iv, byte[] cipherText) throws GeneralSecurityException {
+        Cipher cipher = Cipher.getInstance("AES/OFB32/PKCS5Padding");
+        cipher.init(Cipher.DECRYPT_MODE, key, iv);
+        return cipher.doFinal(cipherText);
+    }
+
+    public byte[][] ctrEncrypt(SecretKey key, IvParameterSpec iv, byte[] data) throws GeneralSecurityException {
+        Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
+        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
+        return new byte[][] { cipher.getIV(), cipher.doFinal(data) };
+    }
+
+    public byte[] ctrDecrypt(SecretKey key, byte[] iv, byte[] cipherText) throws GeneralSecurityException {
+        Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
+        cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
+        return cipher.doFinal(cipherText);
+    }
+
+    public byte[][] gcmEncrypt(SecretKey key, byte[] iv, byte[] data) throws GeneralSecurityException {
+        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+        cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, iv));
+        byte[] ciphertext = cipher.doFinal(data);
+        return new byte[][] { iv, ciphertext };
+    }
+
+    public byte[] gcmDecrypt(SecretKey key, byte[] iv, byte[] ciphertext) throws GeneralSecurityException {
+        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+        cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));
+        byte[] plaintext = cipher.doFinal(ciphertext);
+        return plaintext;
+    }
+}
diff --git a/core-java-modules/core-java-security-3/src/main/java/com/baeldung/crypto/utils/CryptoUtils.java b/core-java-modules/core-java-security-3/src/main/java/com/baeldung/crypto/utils/CryptoUtils.java
new file mode 100644
index 0000000000..2d3df231ff
--- /dev/null
+++ b/core-java-modules/core-java-security-3/src/main/java/com/baeldung/crypto/utils/CryptoUtils.java
@@ -0,0 +1,53 @@
+package com.baeldung.crypto.utils;
+
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidParameterSpecException;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+
+public class CryptoUtils {
+
+    public static SecretKey generateKey() throws GeneralSecurityException {
+        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
+        keyGenerator.init(256);
+        return keyGenerator.generateKey();
+    }
+
+    public static IvParameterSpec getIV() {
+        SecureRandom secureRandom = new SecureRandom();
+        byte[] iv = new byte[128 / 8];
+        byte[] nonce = new byte[96 / 8];
+        secureRandom.nextBytes(nonce);
+        System.arraycopy(nonce, 0, iv, 0, nonce.length);
+        return new IvParameterSpec(nonce);
+    }
+
+    public static IvParameterSpec getIVSecureRandom(String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException {
+        SecureRandom random = SecureRandom.getInstanceStrong();
+        byte[] iv = new byte[Cipher.getInstance(algorithm)
+            .getBlockSize()];
+        random.nextBytes(iv);
+        return new IvParameterSpec(iv);
+    }
+
+    public static IvParameterSpec getIVInternal(Cipher cipher) throws InvalidParameterSpecException {
+        AlgorithmParameters params = cipher.getParameters();
+        byte[] iv = params.getParameterSpec(IvParameterSpec.class)
+            .getIV();
+        return new IvParameterSpec(iv);
+    }
+
+    public static byte[] getRandomIVWithSize(int size) {
+        byte[] nonce = new byte[size];
+        new SecureRandom().nextBytes(nonce);
+        return nonce;
+    }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-security-3/src/main/java/com/baeldung/hmac/HMACUtil.java b/core-java-modules/core-java-security-3/src/main/java/com/baeldung/hmac/HMACUtil.java
new file mode 100644
index 0000000000..3b504d9338
--- /dev/null
+++ b/core-java-modules/core-java-security-3/src/main/java/com/baeldung/hmac/HMACUtil.java
@@ -0,0 +1,68 @@
+package com.baeldung.hmac;
+
+import org.apache.commons.codec.digest.HmacUtils;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.digests.MD5Digest;
+import org.bouncycastle.crypto.digests.SHA256Digest;
+import org.bouncycastle.crypto.digests.SHA384Digest;
+import org.bouncycastle.crypto.digests.SHA512Digest;
+import org.bouncycastle.crypto.macs.HMac;
+import org.bouncycastle.crypto.params.KeyParameter;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+
+public class HMACUtil {
+
+    public static String hmacWithJava(String algorithm, String data, String key)
+        throws NoSuchAlgorithmException, InvalidKeyException {
+        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm);
+        Mac mac = Mac.getInstance(algorithm);
+        mac.init(secretKeySpec);
+        return bytesToHex(mac.doFinal(data.getBytes()));
+    }
+
+    public static String hmacWithApacheCommons(String algorithm, String data, String key) {
+        String hmac = new HmacUtils(algorithm, key).hmacHex(data);
+        return hmac;
+    }
+
+    public static String hmacWithBouncyCastle(String algorithm, String data, String key) {
+        Digest digest = getHashDigest(algorithm);
+        HMac hMac = new HMac(digest);
+        hMac.init(new KeyParameter(key.getBytes()));
+        byte[] hmacIn = data.getBytes();
+        hMac.update(hmacIn, 0, hmacIn.length);
+        byte[] hmacOut = new byte[hMac.getMacSize()];
+        hMac.doFinal(hmacOut, 0);
+        return bytesToHex(hmacOut);
+    }
+
+    private static Digest getHashDigest(String algorithm) {
+        switch (algorithm) {
+          case "HmacMD5":
+            return new MD5Digest();
+          case "HmacSHA256":
+            return new SHA256Digest();
+          case "HmacSHA384":
+            return new SHA384Digest();
+          case "HmacSHA512":
+            return new SHA512Digest();
+        }
+        return new SHA256Digest();
+    }
+
+    public static String bytesToHex(byte[] hash) {
+        StringBuilder hexString = new StringBuilder(2 * hash.length);
+        for (byte h : hash) {
+          String hex = Integer.toHexString(0xff & h);
+          if (hex.length() == 1)
+            hexString.append('0');
+          hexString.append(hex);
+        }
+        return hexString.toString();
+    }
+}
diff --git a/core-java-modules/core-java-security-3/src/test/java/com/baeldung/crypto/CryptoDriverIVUnitTest.java b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/crypto/CryptoDriverIVUnitTest.java
new file mode 100644
index 0000000000..f3bed310dd
--- /dev/null
+++ b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/crypto/CryptoDriverIVUnitTest.java
@@ -0,0 +1,86 @@
+package com.baeldung.crypto;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import java.security.GeneralSecurityException;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import com.baeldung.crypto.utils.CryptoUtils;
+
+public class CryptoDriverIVUnitTest{
+    private CryptoDriver driver = new CryptoDriver();
+    private String TEST_DATA = "Encrypt this for testing";
+
+    @Test
+    public void givenString_whenAesEcb_thenSuccess() throws GeneralSecurityException {
+        SecretKey key = CryptoUtils.generateKey();
+        byte[] plaintext = TEST_DATA.getBytes();
+
+        byte[] ciphertext = driver.ecbEncrypt(key, plaintext);
+        byte[] decryptedtext = driver.ecbDecrypt(key, ciphertext);
+
+        Assertions.assertEquals(new String(decryptedtext), TEST_DATA);
+    }
+
+    @Test
+    public void givenString_whenAesCbc_thenSuccess() throws GeneralSecurityException {
+        SecretKey key = CryptoUtils.generateKey();
+        IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES");
+        byte[] plaintext = TEST_DATA.getBytes();
+
+        byte[] ciphertext = driver.cbcEncrypt(key, iv, plaintext);
+        byte[] decryptedtext = driver.cbcDecrypt(key, iv, ciphertext);
+
+        Assertions.assertEquals(new String(decryptedtext), TEST_DATA);
+    }
+
+    @Test
+    public void givenString_whenAesCfb_thenSuccess() throws GeneralSecurityException {
+        SecretKey key = CryptoUtils.generateKey();
+        IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES/CFB/NoPadding");
+        byte[] plaintext = TEST_DATA.getBytes();
+
+        byte[] ciphertext = driver.cfbEncrypt(key, iv, plaintext);
+        byte[] decryptedtext = driver.cfbDecrypt(key, iv, ciphertext);
+
+        Assertions.assertEquals(new String(decryptedtext), TEST_DATA);
+    }
+
+    @Test
+    public void givenString_whenAesOfb_thenSuccess() throws GeneralSecurityException {
+        SecretKey key = CryptoUtils.generateKey();
+        IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES/OFB32/PKCS5Padding");
+        byte[] plaintext = TEST_DATA.getBytes();
+
+        byte[] ciphertext = driver.ofbEncrypt(key, iv, plaintext);
+        byte[] decryptedtext = driver.ofbDecrypt(key, iv, ciphertext);
+
+        Assertions.assertEquals(new String(decryptedtext), TEST_DATA);
+    }
+
+    @Test
+    public void givenString_whenAesCtr_thenSuccess() throws GeneralSecurityException {
+        SecretKey key = CryptoUtils.generateKey();
+        IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES/CTR/NoPadding");
+        byte[] plaintext = TEST_DATA.getBytes();
+
+        byte[][] ciphertext = driver.ctrEncrypt(key, iv, plaintext);
+        byte[] decryptedtext = driver.ctrDecrypt(key, ciphertext[0], ciphertext[1]);
+
+        Assertions.assertEquals(new String(decryptedtext), TEST_DATA);
+    }
+
+    @Test
+    void givenString_whenAesGcm_thenSuccess() throws GeneralSecurityException {
+        SecretKey key = CryptoUtils.generateKey();
+        byte[] iv = CryptoUtils.getRandomIVWithSize(12);
+        byte[] plaintext = (TEST_DATA).getBytes();
+
+        byte[][] ciphertext = driver.gcmEncrypt(key, iv, plaintext);
+        byte[] decryptedtext = driver.gcmDecrypt(key, ciphertext[0], ciphertext[1]);
+
+        Assertions.assertEquals(new String(decryptedtext), TEST_DATA);
+    }
+}
diff --git a/core-java-modules/core-java-security-3/src/test/java/com/baeldung/hmac/HMACUtilUnitTest.java b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/hmac/HMACUtilUnitTest.java
new file mode 100644
index 0000000000..0d7f97a094
--- /dev/null
+++ b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/hmac/HMACUtilUnitTest.java
@@ -0,0 +1,61 @@
+package com.baeldung.hmac;
+
+import org.junit.Test;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static org.junit.Assert.assertEquals;
+
+public class HMACUtilUnitTest {
+
+    @Test
+    public void givenDataAndKeyAndAlgorithm_whenHmacWithJava_thenSuccess()
+        throws NoSuchAlgorithmException, InvalidKeyException {
+
+        //given
+        String hmacSHA256Value = "5b50d80c7dc7ae8bb1b1433cc0b99ecd2ac8397a555c6f75cb8a619ae35a0c35";
+        String hmacSHA256Algorithm = "HmacSHA256";
+        String data = "baeldung";
+        String key = "123456";
+
+        //when
+        String result = HMACUtil.hmacWithJava(hmacSHA256Algorithm, data, key);
+
+        //then
+        assertEquals(hmacSHA256Value, result);
+    }
+
+    @Test
+    public void givenDataAndKeyAndAlgorithm_whenHmacWithApacheCommons_thenSuccess() {
+
+        //given
+        String hmacMD5Value = "621dc816b3bf670212e0c261dc9bcdb6";
+        String hmacMD5Algorithm = "HmacMD5";
+        String data = "baeldung";
+        String key = "123456";
+
+        //when
+        String result = HMACUtil.hmacWithApacheCommons(hmacMD5Algorithm, data, key);
+
+        //then
+        assertEquals(hmacMD5Value, result);
+    }
+
+    @Test
+    public void givenDataAndKeyAndAlgorithm_whenHmacWithBouncyCastle_thenSuccess() {
+
+        //given
+        String hmacSHA512Value = "b313a21908df55c9e322e3c65a4b0b7561ab1594ca806b3affbc0d769a1" +
+          "290c1922aa6622587bea3c0c4d871470a6d06f54dbd20dbda84250e2741eb01f08e33";
+        String hmacSHA512Algorithm = "HmacSHA512";
+        String data = "baeldung";
+        String key = "123456";
+
+        //when
+        String result = HMACUtil.hmacWithBouncyCastle(hmacSHA512Algorithm, data, key);
+
+        //then
+        assertEquals(hmacSHA512Value, result);
+    }
+}
diff --git a/core-java-modules/core-java-security-algorithms/README.md b/core-java-modules/core-java-security-algorithms/README.md
new file mode 100644
index 0000000000..a1ce244ab8
--- /dev/null
+++ b/core-java-modules/core-java-security-algorithms/README.md
@@ -0,0 +1,11 @@
+## Core Java Security Algorithms
+
+This module contains articles about core Java Security Algorithms such as AES, DES, RSA, etc
+
+### Relevant Articles:
+
+- [Listing the Available Cipher Algorithms](https://www.baeldung.com/java-list-cipher-algorithms)
+- [Java AES Encryption and Decryption](https://www.baeldung.com/java-aes-encryption-decryption)
+- [InvalidAlgorithmParameterException: Wrong IV Length](https://www.baeldung.com/java-invalidalgorithmparameter-exception)
+- [RSA in Java](https://www.baeldung.com/java-rsa)
+- [3DES in Java](https://www.baeldung.com/java-3des)
diff --git a/core-java-modules/core-java-security-algorithms/pom.xml b/core-java-modules/core-java-security-algorithms/pom.xml
new file mode 100644
index 0000000000..967ddc103e
--- /dev/null
+++ b/core-java-modules/core-java-security-algorithms/pom.xml
@@ -0,0 +1,42 @@
+
+
+    4.0.0
+    core-java-security-algorithms
+    0.1.0-SNAPSHOT
+    core-java-security-algorithms
+    jar
+
+    
+        com.baeldung.core-java-modules
+        core-java-modules
+        0.0.1-SNAPSHOT
+    
+
+    
+        
+            commons-codec
+            commons-codec
+            ${commons-codec.version}
+        
+        
+            org.bouncycastle
+            bcprov-jdk15on
+            ${bouncycastle.version}
+        
+        
+        
+            javax.xml.bind
+            jaxb-api
+            ${jaxb-api.version}
+        
+    
+
+    
+        1.60
+        1.11
+        2.3.1
+    
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-security-2/src/main/java/com/baeldung/aes/AESUtil.java b/core-java-modules/core-java-security-algorithms/src/main/java/com/baeldung/aes/AESUtil.java
similarity index 100%
rename from core-java-modules/core-java-security-2/src/main/java/com/baeldung/aes/AESUtil.java
rename to core-java-modules/core-java-security-algorithms/src/main/java/com/baeldung/aes/AESUtil.java
diff --git a/core-java-modules/core-java-security-2/src/main/java/com/baeldung/aes/Student.java b/core-java-modules/core-java-security-algorithms/src/main/java/com/baeldung/aes/Student.java
similarity index 100%
rename from core-java-modules/core-java-security-2/src/main/java/com/baeldung/aes/Student.java
rename to core-java-modules/core-java-security-algorithms/src/main/java/com/baeldung/aes/Student.java
diff --git a/core-java-modules/core-java-security-2/src/test/java/com/baeldung/aes/AESUtilUnitTest.java b/core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/aes/AESUtilUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-security-2/src/test/java/com/baeldung/aes/AESUtilUnitTest.java
rename to core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/aes/AESUtilUnitTest.java
diff --git a/core-java-modules/core-java-security-2/src/test/java/com/baeldung/cipher/AvailableCiphersUnitTest.java b/core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/cipher/AvailableCiphersUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-security-2/src/test/java/com/baeldung/cipher/AvailableCiphersUnitTest.java
rename to core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/cipher/AvailableCiphersUnitTest.java
diff --git a/core-java-modules/core-java-security-2/src/test/java/com/baeldung/des/TripleDESUnitTest.java b/core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/des/TripleDESUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-security-2/src/test/java/com/baeldung/des/TripleDESUnitTest.java
rename to core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/des/TripleDESUnitTest.java
diff --git a/core-java-modules/core-java-security-2/src/test/java/com/baeldung/rsa/RsaUnitTest.java b/core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/rsa/RsaUnitTest.java
similarity index 99%
rename from core-java-modules/core-java-security-2/src/test/java/com/baeldung/rsa/RsaUnitTest.java
rename to core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/rsa/RsaUnitTest.java
index ac93f71125..9659fd8871 100644
--- a/core-java-modules/core-java-security-2/src/test/java/com/baeldung/rsa/RsaUnitTest.java
+++ b/core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/rsa/RsaUnitTest.java
@@ -1,4 +1,4 @@
-package com.baeldung.cipher;
+package com.baeldung.rsa;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
diff --git a/core-java-modules/core-java-security-2/src/test/resources/baeldung.txt b/core-java-modules/core-java-security-algorithms/src/test/resources/baeldung.txt
similarity index 100%
rename from core-java-modules/core-java-security-2/src/test/resources/baeldung.txt
rename to core-java-modules/core-java-security-algorithms/src/test/resources/baeldung.txt
diff --git a/core-java-modules/core-java-security/pom.xml b/core-java-modules/core-java-security/pom.xml
index daba990776..b36de5ac4c 100644
--- a/core-java-modules/core-java-security/pom.xml
+++ b/core-java-modules/core-java-security/pom.xml
@@ -14,19 +14,4 @@
         0.0.1-SNAPSHOT
     
 
-    
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
-    
-
-    
-        
-        3.10.0
-    
-
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-serialization/README.md b/core-java-modules/core-java-serialization/README.md
new file mode 100644
index 0000000000..fc6cfcf134
--- /dev/null
+++ b/core-java-modules/core-java-serialization/README.md
@@ -0,0 +1,9 @@
+## Core Java Serialization
+
+### Relevant Articles: 
+  
+- [Guide to the Externalizable Interface in Java](http://www.baeldung.com/java-externalizable)
+- [Introduction to Java Serialization](http://www.baeldung.com/java-serialization)
+- [Deserialization Vulnerabilities in Java](https://www.baeldung.com/java-deserialization-vulnerabilities)
+- [Serialization Validation in Java](https://www.baeldung.com/java-validate-serializable)
+- [What is the serialVersionUID?](http://www.baeldung.com/java-serial-version-uid)
diff --git a/core-java-modules/core-java-serialization/pom.xml b/core-java-modules/core-java-serialization/pom.xml
new file mode 100644
index 0000000000..0ce5785fd9
--- /dev/null
+++ b/core-java-modules/core-java-serialization/pom.xml
@@ -0,0 +1,180 @@
+
+
+    4.0.0
+    core-java-serialization
+    0.1.0-SNAPSHOT
+    core-java-serialization
+    jar
+
+    
+        com.baeldung.core-java-modules
+        core-java-modules
+        0.0.1-SNAPSHOT
+    
+
+    
+        
+            org.unix4j
+            unix4j-command
+            ${unix4j.version}
+        
+        
+            com.googlecode.grep4j
+            grep4j
+            ${grep4j.version}
+        
+        
+        
+        
+            com.fasterxml.jackson.core
+            jackson-databind
+            ${jackson.version}
+        
+        
+        
+            log4j
+            log4j
+            ${log4j.version}
+        
+         
+            org.slf4j
+            log4j-over-slf4j
+            ${org.slf4j.version}
+        
+        
+            org.springframework
+            spring-core
+            ${spring.core.version}
+        
+        
+            org.springframework
+            spring-core
+            ${spring.core.version}
+            test
+        
+    
+
+    
+        core-java
+        
+            
+                src/main/resources
+                true
+            
+        
+
+        
+            
+                org.apache.maven.plugins
+                maven-dependency-plugin
+                
+                    
+                        copy-dependencies
+                        prepare-package
+                        
+                            copy-dependencies
+                        
+                        
+                            ${project.build.directory}/libs
+                        
+                    
+                
+            
+            
+                org.codehaus.mojo
+                exec-maven-plugin
+                
+                    java
+                    com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed
+                    
+                        -Xmx300m
+                        -XX:+UseParallelGC
+                        -classpath
+                        
+                        com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed
+                    
+                
+            
+            
+                org.apache.maven.plugins
+                maven-javadoc-plugin
+                ${maven-javadoc-plugin.version}
+                
+                    ${source.version}
+                    ${target.version}
+                
+            
+        
+    
+
+    
+        
+            integration
+            
+                
+                    
+                        org.apache.maven.plugins
+                        maven-surefire-plugin
+                        
+                            
+                                integration-test
+                                
+                                    test
+                                
+                                
+                                    
+                                        **/*ManualTest.java
+                                    
+                                    
+                                        **/*IntegrationTest.java
+                                        **/*IntTest.java
+                                    
+                                
+                            
+                        
+                        
+                            
+                                json
+                            
+                        
+                    
+                    
+                        org.codehaus.mojo
+                        exec-maven-plugin
+                        
+                            
+                                run-benchmarks
+                                
+                                none
+                                
+                                    exec
+                                
+                                
+                                    test
+                                    java
+                                    
+                                        -classpath
+                                        
+                                        org.openjdk.jmh.Main
+                                        .*
+                                    
+                                
+                            
+                        
+                    
+                
+            
+        
+    
+
+    
+        0.4
+        1.8.7
+        1.1
+        3.0.0-M1
+        4.3.20.RELEASE
+    
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/AppleProduct.java b/core-java-modules/core-java-serialization/src/main/java/com/baeldung/deserialization/AppleProduct.java
similarity index 100%
rename from core-java-modules/core-java/src/main/java/com/baeldung/deserialization/AppleProduct.java
rename to core-java-modules/core-java-serialization/src/main/java/com/baeldung/deserialization/AppleProduct.java
diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/DefaultSerial.java b/core-java-modules/core-java-serialization/src/main/java/com/baeldung/deserialization/DefaultSerial.java
similarity index 100%
rename from core-java-modules/core-java/src/main/java/com/baeldung/deserialization/DefaultSerial.java
rename to core-java-modules/core-java-serialization/src/main/java/com/baeldung/deserialization/DefaultSerial.java
diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/DeserializationUtility.java b/core-java-modules/core-java-serialization/src/main/java/com/baeldung/deserialization/DeserializationUtility.java
similarity index 100%
rename from core-java-modules/core-java/src/main/java/com/baeldung/deserialization/DeserializationUtility.java
rename to core-java-modules/core-java-serialization/src/main/java/com/baeldung/deserialization/DeserializationUtility.java
diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/SerializationUtility.java b/core-java-modules/core-java-serialization/src/main/java/com/baeldung/deserialization/SerializationUtility.java
similarity index 100%
rename from core-java-modules/core-java/src/main/java/com/baeldung/deserialization/SerializationUtility.java
rename to core-java-modules/core-java-serialization/src/main/java/com/baeldung/deserialization/SerializationUtility.java
diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/externalizable/Community.java b/core-java-modules/core-java-serialization/src/main/java/com/baeldung/externalizable/Community.java
similarity index 100%
rename from core-java-modules/core-java/src/main/java/com/baeldung/externalizable/Community.java
rename to core-java-modules/core-java-serialization/src/main/java/com/baeldung/externalizable/Community.java
diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/externalizable/Country.java b/core-java-modules/core-java-serialization/src/main/java/com/baeldung/externalizable/Country.java
similarity index 100%
rename from core-java-modules/core-java/src/main/java/com/baeldung/externalizable/Country.java
rename to core-java-modules/core-java-serialization/src/main/java/com/baeldung/externalizable/Country.java
diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/externalizable/Region.java b/core-java-modules/core-java-serialization/src/main/java/com/baeldung/externalizable/Region.java
similarity index 100%
rename from core-java-modules/core-java/src/main/java/com/baeldung/externalizable/Region.java
rename to core-java-modules/core-java-serialization/src/main/java/com/baeldung/externalizable/Region.java
diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/serialization/Address.java b/core-java-modules/core-java-serialization/src/main/java/com/baeldung/serialization/Address.java
similarity index 100%
rename from core-java-modules/core-java/src/main/java/com/baeldung/serialization/Address.java
rename to core-java-modules/core-java-serialization/src/main/java/com/baeldung/serialization/Address.java
diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/serialization/Employee.java b/core-java-modules/core-java-serialization/src/main/java/com/baeldung/serialization/Employee.java
similarity index 100%
rename from core-java-modules/core-java/src/main/java/com/baeldung/serialization/Employee.java
rename to core-java-modules/core-java-serialization/src/main/java/com/baeldung/serialization/Employee.java
diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/serialization/Person.java b/core-java-modules/core-java-serialization/src/main/java/com/baeldung/serialization/Person.java
similarity index 100%
rename from core-java-modules/core-java/src/main/java/com/baeldung/serialization/Person.java
rename to core-java-modules/core-java-serialization/src/main/java/com/baeldung/serialization/Person.java
diff --git a/core-java-modules/core-java-serialization/src/main/java/com/baeldung/util/MySerializationUtils.java b/core-java-modules/core-java-serialization/src/main/java/com/baeldung/util/MySerializationUtils.java
new file mode 100644
index 0000000000..bfaa91313c
--- /dev/null
+++ b/core-java-modules/core-java-serialization/src/main/java/com/baeldung/util/MySerializationUtils.java
@@ -0,0 +1,44 @@
+package com.baeldung.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+public class MySerializationUtils {
+
+    public static  byte[] serialize(T obj) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(obj);
+        oos.close();
+        return baos.toByteArray();
+    }
+
+    public static  T deserialize(byte[] b, Class cl) throws IOException, ClassNotFoundException {
+        ByteArrayInputStream bais = new ByteArrayInputStream(b);
+        ObjectInputStream ois = new ObjectInputStream(bais);
+        Object o = ois.readObject();
+        return cl.cast(o);
+    }
+
+    public static boolean isSerializable(Class it) {
+        boolean serializable = it.isPrimitive() || it.isInterface() || Serializable.class.isAssignableFrom(it);
+        if (!serializable) {
+            return serializable;
+        }
+        Field[] declaredFields = it.getDeclaredFields();
+        for (Field field : declaredFields) {
+            if (Modifier.isVolatile(field.getModifiers()) || Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) {
+                continue;
+            }
+            Class fieldType = field.getType();
+            return isSerializable(fieldType);
+        }
+        return serializable;
+    }
+}
diff --git a/core-java-modules/core-java-serialization/src/main/resources/log4j.properties b/core-java-modules/core-java-serialization/src/main/resources/log4j.properties
new file mode 100644
index 0000000000..621cf01735
--- /dev/null
+++ b/core-java-modules/core-java-serialization/src/main/resources/log4j.properties
@@ -0,0 +1,6 @@
+log4j.rootLogger=DEBUG, A1
+
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
\ No newline at end of file
diff --git a/core-java-modules/core-java-serialization/src/main/resources/log4j2.xml b/core-java-modules/core-java-serialization/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000..a824bef9b0
--- /dev/null
+++ b/core-java-modules/core-java-serialization/src/main/resources/log4j2.xml
@@ -0,0 +1,13 @@
+
+
+    
+        
+            
+        
+    
+    
+        
+            
+        
+    
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-serialization/src/main/resources/log4jstructuraldp.properties b/core-java-modules/core-java-serialization/src/main/resources/log4jstructuraldp.properties
new file mode 100644
index 0000000000..5bc2bfe4b9
--- /dev/null
+++ b/core-java-modules/core-java-serialization/src/main/resources/log4jstructuraldp.properties
@@ -0,0 +1,9 @@
+
+# Root logger 
+log4j.rootLogger=INFO, file, stdout
+
+# Write to console
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
\ No newline at end of file
diff --git a/core-java-modules/core-java-serialization/src/main/resources/logback.xml b/core-java-modules/core-java-serialization/src/main/resources/logback.xml
new file mode 100644
index 0000000000..56af2d397e
--- /dev/null
+++ b/core-java-modules/core-java-serialization/src/main/resources/logback.xml
@@ -0,0 +1,19 @@
+
+
+    
+        
+            %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+            
+        
+    
+
+    
+    
+
+    
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/deserialization/DeserializationUnitTest.java b/core-java-modules/core-java-serialization/src/test/java/com/baeldung/deserialization/DeserializationUnitTest.java
similarity index 99%
rename from core-java-modules/core-java/src/test/java/com/baeldung/deserialization/DeserializationUnitTest.java
rename to core-java-modules/core-java-serialization/src/test/java/com/baeldung/deserialization/DeserializationUnitTest.java
index d7c1ee17d4..89a603a298 100644
--- a/core-java-modules/core-java/src/test/java/com/baeldung/deserialization/DeserializationUnitTest.java
+++ b/core-java-modules/core-java-serialization/src/test/java/com/baeldung/deserialization/DeserializationUnitTest.java
@@ -7,6 +7,7 @@ import static org.junit.Assert.assertTrue;
 import java.io.IOException;
 import java.io.InvalidClassException;
 
+import org.junit.Assert;
 import org.junit.Ignore;
 import org.junit.Test;
 
diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/externalizable/ExternalizableUnitTest.java b/core-java-modules/core-java-serialization/src/test/java/com/baeldung/externalizable/ExternalizableUnitTest.java
similarity index 100%
rename from core-java-modules/core-java/src/test/java/com/baeldung/externalizable/ExternalizableUnitTest.java
rename to core-java-modules/core-java-serialization/src/test/java/com/baeldung/externalizable/ExternalizableUnitTest.java
diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/PersonUnitTest.java b/core-java-modules/core-java-serialization/src/test/java/com/baeldung/serialization/PersonUnitTest.java
similarity index 100%
rename from core-java-modules/core-java/src/test/java/com/baeldung/serialization/PersonUnitTest.java
rename to core-java-modules/core-java-serialization/src/test/java/com/baeldung/serialization/PersonUnitTest.java
diff --git a/core-java-modules/core-java-serialization/src/test/java/com/baeldung/serialization/SerializationUnitTest.java b/core-java-modules/core-java-serialization/src/test/java/com/baeldung/serialization/SerializationUnitTest.java
new file mode 100644
index 0000000000..a8c4009386
--- /dev/null
+++ b/core-java-modules/core-java-serialization/src/test/java/com/baeldung/serialization/SerializationUnitTest.java
@@ -0,0 +1,111 @@
+package com.baeldung.serialization;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import org.apache.commons.lang3.SerializationUtils;
+import org.junit.Test;
+
+import com.baeldung.util.MySerializationUtils;
+
+public class SerializationUnitTest {
+
+    @Test(expected = NotSerializableException.class)
+    public void whenSerializing_ThenThrowsError() throws IOException {
+        Address address = new Address();
+        address.setHouseNumber(10);
+        FileOutputStream fileOutputStream = new FileOutputStream("yofile.txt");
+        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) {
+            objectOutputStream.writeObject(address);
+        }
+    }
+
+    @Test
+    public void whenSerializingAndDeserializing_ThenObjectIsTheSame() throws IOException, ClassNotFoundException {
+        Person p = new Person();
+        p.setAge(20);
+        p.setName("Joe");
+
+        FileOutputStream fileOutputStream = new FileOutputStream("yofile.txt");
+        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) {
+            objectOutputStream.writeObject(p);
+        }
+
+        FileInputStream fileInputStream = new FileInputStream("yofile.txt");
+        try (ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) {
+            Person p2 = (Person) objectInputStream.readObject();
+            assertEquals(p2.getAge(), p.getAge());
+            assertEquals(p2.getName(), p.getName());
+        }
+    }
+
+    @Test(expected = ClassCastException.class)
+    public void whenSerializingUsingApacheCommons_ThenThrowsError() {
+        Address address = new Address();
+        address.setHouseNumber(10);
+        SerializationUtils.serialize((Serializable) address);
+    }
+
+    @Test
+    public void whenSerializingAndDeserializingUsingApacheCommons_ThenObjectIsTheSame() {
+        Person p = new Person();
+        p.setAge(20);
+        p.setName("Joe");
+        byte[] serialize = SerializationUtils.serialize(p);
+        Person p2 = (Person) SerializationUtils.deserialize(serialize);
+        assertEquals(p2.getAge(), p.getAge());
+        assertEquals(p2.getName(), p.getName());
+    }
+
+    @Test(expected = ClassCastException.class)
+    public void whenSerializingUsingSpringSerializationUtils_ThenThrowsError() {
+        Address address = new Address();
+        address.setHouseNumber(10);
+        org.springframework.util.SerializationUtils.serialize((Serializable) address);
+    }
+
+    @Test
+    public void whenSerializingAndDeserializingUsingSpringSerializationUtils_ThenObjectIsTheSame() {
+        Person p = new Person();
+        p.setAge(20);
+        p.setName("Joe");
+        byte[] serialize = org.springframework.util.SerializationUtils.serialize(p);
+        Person p2 = (Person) org.springframework.util.SerializationUtils.deserialize(serialize);
+        assertEquals(p2.getAge(), p.getAge());
+        assertEquals(p2.getName(), p.getName());
+    }
+
+    @Test(expected = ClassCastException.class)
+    public void whenSerializingUsingCustomSerializationUtils_ThenThrowsError() throws IOException {
+        Address address = new Address();
+        address.setHouseNumber(10);
+        MySerializationUtils.serialize((Serializable) address);
+    }
+
+    @Test
+    public void whenSerializingAndDeserializingUsingCustomSerializationUtils_ThenObjectIsTheSame() throws IOException, ClassNotFoundException {
+        Person p = new Person();
+        p.setAge(20);
+        p.setName("Joe");
+        byte[] serialize = MySerializationUtils.serialize(p);
+        Person p2 = MySerializationUtils.deserialize(serialize, Person.class);
+        assertEquals(p2.getAge(), p.getAge());
+        assertEquals(p2.getName(), p.getName());
+    }
+
+    @Test
+    public void whenSerializingUsingCustomSerializationUtils_ThanOk() {
+        assertFalse(MySerializationUtils.isSerializable(Address.class));
+        assertTrue(MySerializationUtils.isSerializable(Person.class));
+        assertTrue(MySerializationUtils.isSerializable(Integer.class));
+    }
+}
diff --git a/core-java-modules/core-java-serialization/src/test/resources/log4j.properties b/core-java-modules/core-java-serialization/src/test/resources/log4j.properties
new file mode 100644
index 0000000000..621cf01735
--- /dev/null
+++ b/core-java-modules/core-java-serialization/src/test/resources/log4j.properties
@@ -0,0 +1,6 @@
+log4j.rootLogger=DEBUG, A1
+
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
\ No newline at end of file
diff --git a/core-java-modules/core-java-serialization/src/test/resources/log4j2.xml b/core-java-modules/core-java-serialization/src/test/resources/log4j2.xml
new file mode 100644
index 0000000000..a824bef9b0
--- /dev/null
+++ b/core-java-modules/core-java-serialization/src/test/resources/log4j2.xml
@@ -0,0 +1,13 @@
+
+
+    
+        
+            
+        
+    
+    
+        
+            
+        
+    
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-serialization/src/test/resources/log4jstructuraldp.properties b/core-java-modules/core-java-serialization/src/test/resources/log4jstructuraldp.properties
new file mode 100644
index 0000000000..5bc2bfe4b9
--- /dev/null
+++ b/core-java-modules/core-java-serialization/src/test/resources/log4jstructuraldp.properties
@@ -0,0 +1,9 @@
+
+# Root logger 
+log4j.rootLogger=INFO, file, stdout
+
+# Write to console
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
\ No newline at end of file
diff --git a/core-java-modules/core-java-serialization/src/test/resources/logback.xml b/core-java-modules/core-java-serialization/src/test/resources/logback.xml
new file mode 100644
index 0000000000..56af2d397e
--- /dev/null
+++ b/core-java-modules/core-java-serialization/src/test/resources/logback.xml
@@ -0,0 +1,19 @@
+
+
+    
+        
+            %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+            
+        
+    
+
+    
+    
+
+    
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-streams-2/pom.xml b/core-java-modules/core-java-streams-2/pom.xml
index 087a8378b1..c8fa83c55a 100644
--- a/core-java-modules/core-java-streams-2/pom.xml
+++ b/core-java-modules/core-java-streams-2/pom.xml
@@ -30,23 +30,11 @@
             log4j
             ${log4j.version}
         
-        
-            org.junit.vintage
-            junit-vintage-engine
-            test
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
         1.9
         1.9
-        3.11.1
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-streams-3/pom.xml b/core-java-modules/core-java-streams-3/pom.xml
index b384ef7e0e..c2dfdc392b 100644
--- a/core-java-modules/core-java-streams-3/pom.xml
+++ b/core-java-modules/core-java-streams-3/pom.xml
@@ -29,19 +29,12 @@
         
             org.openjdk.jmh
             jmh-core
-            ${jmh.version}
+            ${jmh-core.version}
         
         
             org.openjdk.jmh
             jmh-generator-annprocess
-            ${jmh.version}
-            test
-        
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
+            ${jmh-generator.version}
             test
         
     
@@ -65,7 +58,7 @@
                         
                             org.openjdk.jmh
                             jmh-generator-annprocess
-                            ${jmh.version}
+                            ${jmh-generator.version}
                         
                     
                 
@@ -75,9 +68,6 @@
 
     
         1.18.20
-        
-        3.6.1
-        1.29
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-streams/pom.xml b/core-java-modules/core-java-streams/pom.xml
index 4862672c8a..a6bb827e77 100644
--- a/core-java-modules/core-java-streams/pom.xml
+++ b/core-java-modules/core-java-streams/pom.xml
@@ -43,13 +43,6 @@
             ${lombok.version}
             provided
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             com.codepoetics
             protonpack
@@ -105,14 +98,11 @@
     
 
     
-        
         0.9.0
         1.15
         0.6.5
         2.10
         1.3
-        
-        3.11.1
         1.8.9
         3.1
         1.8
diff --git a/core-java-modules/core-java-string-algorithms-2/pom.xml b/core-java-modules/core-java-string-algorithms-2/pom.xml
index 4b0d55508f..9fbe10865d 100644
--- a/core-java-modules/core-java-string-algorithms-2/pom.xml
+++ b/core-java-modules/core-java-string-algorithms-2/pom.xml
@@ -35,12 +35,6 @@
             jmh-generator-annprocess
             ${jmh-generator.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.bitbucket.cowwoc
             diff-match-patch
@@ -60,7 +54,6 @@
     
 
     
-        3.6.1
         1.2
     
 
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 6376bfa677..ccb9457a11 100644
--- a/core-java-modules/core-java-string-algorithms-3/pom.xml
+++ b/core-java-modules/core-java-string-algorithms-3/pom.xml
@@ -4,8 +4,8 @@
     4.0.0
     core-java-string-algorithms-3
     0.1.0-SNAPSHOT
-    jar
     core-java-string-algorithms-3
+    jar
 
     
         com.baeldung.core-java-modules
@@ -14,23 +14,11 @@
     
 
     
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             com.google.guava
             guava
             ${guava.version}
         
-        
-            org.junit.jupiter
-            junit-jupiter
-            test
-        
         
             commons-validator
             commons-validator
@@ -61,8 +49,7 @@
     
 
     
-        3.6.1
-        28.1-jre
+        31.0.1-jre
         1.7
     
 
diff --git a/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java
new file mode 100644
index 0000000000..524f7ca839
--- /dev/null
+++ b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercaseUnitTest.java
@@ -0,0 +1,30 @@
+package com.baeldung.isuppercase;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import com.google.common.base.Ascii;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+public class StringFirstCharacterUppercaseUnitTest {
+
+    @Test
+    public void givenString_whenCheckingWithCharacterIsUpperCase_thenStringCapitalized() {
+        String example = "Katie";
+        Assertions.assertTrue(Character.isUpperCase(example.charAt(0)));
+    }
+
+    @Test
+    public void givenString_whenCheckingWithRegex_thenStringCapitalized() {
+        String example = "Katie";
+        String regEx = "[A-Z]\\w*";
+
+        Assertions.assertTrue(example.matches(regEx));
+    }
+
+    @Test
+    public void givenString_whenCheckingWithGuava_thenStringCapitalized() {
+        String example = "Katie";
+        Assertions.assertTrue(Ascii.isUpperCase(example.charAt(0)));
+    }
+}
diff --git a/core-java-modules/core-java-string-algorithms/pom.xml b/core-java-modules/core-java-string-algorithms/pom.xml
index 9fea569b29..07018c7694 100644
--- a/core-java-modules/core-java-string-algorithms/pom.xml
+++ b/core-java-modules/core-java-string-algorithms/pom.xml
@@ -45,12 +45,6 @@
             emoji-java
             ${emoji-java.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -66,7 +60,6 @@
     
         27.0.1-jre
         0.4.0
-        3.6.1
         4.0.0
     
 
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..9cbece4ec3 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 in Java](https://www.baeldung.com/java-bytebuffer-to-string)
 - More articles: [[<-- prev]](/core-java-string-conversions)
diff --git a/core-java-modules/core-java-string-conversions-2/pom.xml b/core-java-modules/core-java-string-conversions-2/pom.xml
index ff4955726b..45eb0dc2e2 100644
--- a/core-java-modules/core-java-string-conversions-2/pom.xml
+++ b/core-java-modules/core-java-string-conversions-2/pom.xml
@@ -20,17 +20,6 @@
             guava
             ${guava.version}
         
-        
-            org.junit.vintage
-            junit-vintage-engine
-            test
-        
-        
-            org.hamcrest
-            hamcrest
-            ${hamcrest.version}
-            test
-        
         
             com.ibm.icu
             icu4j
@@ -46,21 +35,8 @@
             commons-text
             ${commons-text.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
-    
-        64.2
-        3.12.2
-        1.9
-        30.1.1-jre
-    
-
     
         core-java-string-conversions-2
         
@@ -70,5 +46,11 @@
             
         
     
+    
+    
+        64.2
+        1.9
+        30.1.1-jre
+    
 
 
\ No newline at end of file
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-conversions/pom.xml b/core-java-modules/core-java-string-conversions/pom.xml
index 1047e3e7c3..8ed3e1d628 100644
--- a/core-java-modules/core-java-string-conversions/pom.xml
+++ b/core-java-modules/core-java-string-conversions/pom.xml
@@ -35,19 +35,6 @@
             guava
             ${guava.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-        
-            org.hamcrest
-            hamcrest
-            ${hamcrest.version}
-            test
-        
     
 
     
@@ -62,7 +49,6 @@
 
     
         61.1
-        3.6.1
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-string-operations-2/README.md b/core-java-modules/core-java-string-operations-2/README.md
index d66515d372..f95b002906 100644
--- a/core-java-modules/core-java-string-operations-2/README.md
+++ b/core-java-modules/core-java-string-operations-2/README.md
@@ -12,5 +12,5 @@ This module contains articles about string operations.
 - [L-Trim and R-Trim Alternatives in Java](https://www.baeldung.com/java-trim-alternatives)
 - [Encode a String to UTF-8 in Java](https://www.baeldung.com/java-string-encode-utf-8)
 - [Guide to Character Encoding](https://www.baeldung.com/java-char-encoding)
-- [Convert Hex to ASCII in Java](https://www.baeldung.com/java-convert-hex-to-ascii) #remove additional readme file
+- [Convert Hex to ASCII in Java](https://www.baeldung.com/java-convert-hex-to-ascii)
 - More articles: [[<-- prev]](../core-java-string-operations)
diff --git a/core-java-modules/core-java-string-operations-2/pom.xml b/core-java-modules/core-java-string-operations-2/pom.xml
index db8f78da70..848a358aa2 100644
--- a/core-java-modules/core-java-string-operations-2/pom.xml
+++ b/core-java-modules/core-java-string-operations-2/pom.xml
@@ -45,12 +45,6 @@
             javax.el
             ${javax.el.version}
         
-        
-            org.hamcrest
-            hamcrest
-            ${hamcrest.version}
-            test
-        
         
             org.openjdk.jmh
             jmh-core
@@ -66,12 +60,6 @@
             commons-codec
             ${commons-codec.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -108,7 +96,6 @@
     
 
     
-        3.6.1
         2.0.0.Final
         28.2-jre
         6.0.2.Final
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-3/README.md b/core-java-modules/core-java-string-operations-3/README.md
index 1a131c57ac..b22cf56e3a 100644
--- a/core-java-modules/core-java-string-operations-3/README.md
+++ b/core-java-modules/core-java-string-operations-3/README.md
@@ -7,3 +7,6 @@
 - [Validate String as Filename in Java](https://www.baeldung.com/java-validate-filename)
 - [Count Spaces in a Java String](https://www.baeldung.com/java-string-count-spaces)
 - [Remove Accents and Diacritics From a String in Java](https://www.baeldung.com/java-remove-accents-from-text)
+- [Remove Beginning and Ending Double Quotes from a String](https://www.baeldung.com/java-remove-start-end-double-quote)
+- [Splitting a Java String by Multiple Delimiters](https://www.baeldung.com/java-string-split-multiple-delimiters)
+- [Split a String Only on the First Occurrence of Delimiter](https://www.baeldung.com/java-split-string-first-delimiter)
diff --git a/core-java-modules/core-java-string-operations-3/pom.xml b/core-java-modules/core-java-string-operations-3/pom.xml
index 20e9bcb39a..1b1237a8c3 100644
--- a/core-java-modules/core-java-string-operations-3/pom.xml
+++ b/core-java-modules/core-java-string-operations-3/pom.xml
@@ -26,12 +26,6 @@
             commons-lang3
             ${apache-commons-lang3.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.apache.maven
             maven-artifact
@@ -82,7 +76,6 @@
     
         11
         11
-        3.6.1
         5.3.9
         3.12.0
         31.0.1-jre
@@ -92,4 +85,4 @@
         3.1.0
     
 
-
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/firstword/FirstWordGetter.java b/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/firstword/FirstWordGetter.java
new file mode 100644
index 0000000000..03c134752a
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/firstword/FirstWordGetter.java
@@ -0,0 +1,20 @@
+package com.baeldung.firstword;
+
+public class FirstWordGetter {
+
+    public static void main(String[] args) {
+        String input = "Roberto \"I wish you a bug-free day\"";
+        System.out.println("Using split: " + getFirstWordUsingSplit(input));
+        System.out.println("Using subString: " + getFirstWordUsingSubString(input));
+    }
+
+    public static String getFirstWordUsingSubString(String input) {
+        int index = input.contains(" ") ? input.indexOf(" ") : 0;
+        return input.substring(0, index);
+    }
+
+    public static String getFirstWordUsingSplit(String input) {
+        String[] tokens = input.split(" ", 2);
+        return tokens[0];
+    }
+}
diff --git a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/firstword/FirstWordGetterUnitTest.java b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/firstword/FirstWordGetterUnitTest.java
new file mode 100644
index 0000000000..bdaa25180e
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/firstword/FirstWordGetterUnitTest.java
@@ -0,0 +1,30 @@
+package com.baeldung.firstword;
+
+import static com.baeldung.firstword.FirstWordGetter.getFirstWordUsingSplit;
+import static com.baeldung.firstword.FirstWordGetter.getFirstWordUsingSubString;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class FirstWordGetterUnitTest {
+
+    @Test
+    public void givenString_whenSplit_thenFirstWordIsReturned() {
+        assertEquals("Roberto", getFirstWordUsingSplit("Roberto \"I wish you a bug-free day\""));
+    }
+
+    @Test
+    public void givenStringWithNoSpace_whenSplit_thenFirstWordIsReturned() {
+        assertEquals("StringWithNoSpace", getFirstWordUsingSplit("StringWithNoSpace"));
+    }
+
+    @Test
+    public void givenString_whenPassedToSubstring_thenFirstWordIsReturned() {
+        assertEquals("Roberto", getFirstWordUsingSubString("Roberto \"I wish you a bug-free day\""));
+    }
+
+    @Test
+    public void givenStringWithNoSpace_whenPassedToSubstring_thenFirstWordIsReturned() {
+        assertEquals("", getFirstWordUsingSubString("StringWithNoSpace"));
+    }
+}
diff --git a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java
index c8f8fc2d98..2da8955645 100644
--- a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java
+++ b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java
@@ -17,7 +17,7 @@ public class MultipleDelimitersSplitUnitTest {
     @Test
     public void givenString_whenSplittingByMultipleDelimitersWithRegEx_thenStringSplit() {
         String example = "Mary;Thomas:Jane-Kate";
-        String[] names = example.split(";|:|-");
+        String[] names = example.split("[;:-]");
         String[] expectedNames = new String[]{"Mary", "Thomas", "Jane", "Kate"};
         Assertions.assertEquals(4, names.length);
         Assertions.assertArrayEquals(expectedNames, names);
@@ -38,7 +38,7 @@ public class MultipleDelimitersSplitUnitTest {
         String example = "Mary;Thomas:Jane-Kate";
         String[] expectedArray = new String[]{"Mary", "Thomas", "Jane", "Kate"};
         Iterable expected = Arrays.asList(expectedArray);
-        Iterable names = Splitter.on(Pattern.compile(";|:|-")).split(example);
+        Iterable names = Splitter.on(Pattern.compile("[;:-]")).split(example);
         Assertions.assertEquals(4, Iterators.size(names.iterator()));
         Assertions.assertIterableEquals(expected, names);
     }
@@ -48,7 +48,7 @@ public class MultipleDelimitersSplitUnitTest {
         String example = "Mary;Thomas:Jane-Kate";
         String[] expectedArray = new String[]{"Mary", "Thomas", "Jane", "Kate"};
         Iterable expected = Arrays.asList(expectedArray);
-        Iterable names = Splitter.onPattern(";|:|-").split(example);
+        Iterable names = Splitter.onPattern("[;:-]").split(example);
         Assertions.assertEquals(4, Iterators.size(names.iterator()));
         Assertions.assertIterableEquals(expected, names);
     }
diff --git a/core-java-modules/core-java-string-operations-4/README.md b/core-java-modules/core-java-string-operations-4/README.md
new file mode 100644
index 0000000000..83bfeb4d05
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-4/README.md
@@ -0,0 +1,6 @@
+### Relevant Articles:
+
+- [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/pom.xml b/core-java-modules/core-java-string-operations-4/pom.xml
new file mode 100644
index 0000000000..da1180b176
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-4/pom.xml
@@ -0,0 +1,63 @@
+
+
+    4.0.0
+    core-java-string-operations-4
+    0.1.0-SNAPSHOT
+    core-java-string-operations-4
+    jar
+
+    
+        com.baeldung.core-java-modules
+        core-java-modules
+        0.0.1-SNAPSHOT
+        ../
+    
+
+    
+        
+            com.google.guava
+            guava
+            ${guava.version}
+        
+        
+            com.opencsv
+            opencsv
+            ${opencsv.version}
+        
+        
+            org.springframework
+            spring-core
+            ${spring-core.version}
+        
+        
+            org.apache.commons
+            commons-lang3
+            ${apache-commons-lang3.version}
+        
+    
+
+    
+        
+            
+                org.apache.maven.plugins
+                maven-compiler-plugin
+                
+                    ${maven.compiler.source}
+                    ${maven.compiler.target}
+                
+            
+        
+    
+
+    
+        11
+        11
+        31.0.1-jre
+        4.1
+        5.3.13
+        3.12.0
+    
+
+
diff --git a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedString.java b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedString.java
new file mode 100644
index 0000000000..c3bbdb4dfb
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedString.java
@@ -0,0 +1,66 @@
+package com.baeldung.commaseparatedstring;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import com.google.common.base.Splitter;
+import com.opencsv.CSVParser;
+import com.opencsv.CSVParserBuilder;
+import com.opencsv.CSVReader;
+import com.opencsv.CSVReaderBuilder;
+
+public class SplitCommaSeparatedString {
+
+    public static List splitWithParser(String input) {
+
+        List tokens = new ArrayList();
+        int startPosition = 0;
+        boolean isInQuotes = false;
+        for (int currentPosition = 0; currentPosition < input.length(); currentPosition++) {
+            if (input.charAt(currentPosition) == '\"') {
+                isInQuotes = !isInQuotes;
+            } else if (input.charAt(currentPosition) == ',' && !isInQuotes) {
+                tokens.add(input.substring(startPosition, currentPosition));
+                startPosition = currentPosition + 1;
+            }
+        }
+
+        String lastToken = input.substring(startPosition);
+        if (lastToken.equals(",")) {
+            tokens.add("");
+        } else {
+            tokens.add(lastToken);
+        }
+
+        return tokens;
+    }
+
+    public static List splitWithRegex(String input) {
+        String[] tokens = input.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
+        return Arrays.asList(tokens);
+    }
+
+    public static List splitWithGuava(String input) {
+        Pattern pattern = Pattern.compile(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
+        Splitter splitter = Splitter.on(pattern);
+        return splitter.splitToList(input);
+    }
+
+    public static List splitMultiLineWithOpenCSV(String input) throws IOException {
+        CSVParser parser = new CSVParserBuilder().withSeparator(',')
+            .build();
+
+        CSVReader reader = new CSVReaderBuilder(new StringReader(input)).withCSVParser(parser)
+            .build();
+
+        List list = new ArrayList<>();
+        list = reader.readAll();
+        reader.close();
+
+        return list;
+    }
+}
\ No newline at end of file
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/commaseparatedstring/SplitCommaSeparatedStringUnitTest.java b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedStringUnitTest.java
new file mode 100644
index 0000000000..ca34430099
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedStringUnitTest.java
@@ -0,0 +1,44 @@
+package com.baeldung.commaseparatedstring;
+
+import static com.baeldung.commaseparatedstring.SplitCommaSeparatedString.splitMultiLineWithOpenCSV;
+import static com.baeldung.commaseparatedstring.SplitCommaSeparatedString.splitWithGuava;
+import static com.baeldung.commaseparatedstring.SplitCommaSeparatedString.splitWithParser;
+import static com.baeldung.commaseparatedstring.SplitCommaSeparatedString.splitWithRegex;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.Assert.assertArrayEquals;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.junit.Test;
+
+public class SplitCommaSeparatedStringUnitTest {
+    
+    @Test
+    public void givenSingleLineInput_whenParsing_shouldIgnoreCommasInsideDoubleQuotes() {
+        String input = "baeldung,tutorial,splitting,text,\"ignoring this comma,\"";
+
+        var matcher = contains("baeldung", "tutorial", "splitting", "text", "\"ignoring this comma,\"");
+        assertThat(splitWithParser(input), matcher);
+        assertThat(splitWithRegex(input), matcher);
+        assertThat(splitWithGuava(input), matcher);
+    }
+    
+    @Test
+    public void givenMultiLineInput_whenParsing_shouldIgnoreCommasInsideDoubleQuotes() throws IOException {
+        String input = "baeldung,tutorial,splitting,text,\"ignoring this comma,\"" + System.lineSeparator()
+        + "splitting,a,regular,line,no double quotes";
+
+        String[] firstLine = new String[]{"baeldung", "tutorial", "splitting", "text", "ignoring this comma,"};
+        String[] secondLine = new String[]{"splitting", "a", "regular", "line", "no double quotes"};
+        
+        List result = splitMultiLineWithOpenCSV(input);
+        
+        assertThat(result, hasSize(2));
+        assertArrayEquals(firstLine, result.get(0));
+        assertArrayEquals(secondLine, result.get(1));
+    }
+
+}
diff --git a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/comparestrings/CompareIgnoreSpacesUnitTest.java b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/comparestrings/CompareIgnoreSpacesUnitTest.java
new file mode 100644
index 0000000000..570ceb1598
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/comparestrings/CompareIgnoreSpacesUnitTest.java
@@ -0,0 +1,28 @@
+package com.baeldung.comparestrings;
+
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class CompareIgnoreSpacesUnitTest {
+
+    private static String normalString = "ABCDEF";
+    private static String stringWithSpaces = " AB  CD EF ";
+
+    @Test
+    public void givenTwoStrings_thenCompareWithReplaceAllMethod() {
+        assertEquals(normalString.replaceAll("\\s+",""), stringWithSpaces.replaceAll("\\s+",""));
+    }
+
+    @Test
+    public void givenTwoStrings_thenCompareWithApacheStringUtils() {
+        assertEquals(StringUtils.deleteWhitespace(normalString), StringUtils.deleteWhitespace(stringWithSpaces));
+    }
+
+    @Test
+    public void givenTwoStrings_thenCompareWithSpringStringUtils() {
+        assertEquals(org.springframework.util.StringUtils.trimAllWhitespace(normalString), org.springframework.util.StringUtils.trimAllWhitespace(stringWithSpaces));
+    }
+
+}
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-string-operations/pom.xml b/core-java-modules/core-java-string-operations/pom.xml
index 67ce43277e..20e4df3ba3 100644
--- a/core-java-modules/core-java-string-operations/pom.xml
+++ b/core-java-modules/core-java-string-operations/pom.xml
@@ -40,12 +40,6 @@
             commons-codec
             ${commons-codec.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -59,7 +53,6 @@
     
 
     
-        3.6.1
         1.15
     
 
diff --git a/core-java-modules/core-java-strings/pom.xml b/core-java-modules/core-java-strings/pom.xml
index aca0bb3346..d78cb7b92d 100644
--- a/core-java-modules/core-java-strings/pom.xml
+++ b/core-java-modules/core-java-strings/pom.xml
@@ -36,12 +36,6 @@
             icu4j
             ${icu4j.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -55,7 +49,6 @@
     
 
     
-        3.6.1
         61.1
         15
     
diff --git a/core-java-modules/core-java-sun/pom.xml b/core-java-modules/core-java-sun/pom.xml
index 347020a736..e959932235 100644
--- a/core-java-modules/core-java-sun/pom.xml
+++ b/core-java-modules/core-java-sun/pom.xml
@@ -12,17 +12,9 @@
         com.baeldung.core-java-modules
         core-java-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             com.sun
             tools
@@ -94,10 +86,7 @@
     
 
     
-        
-        3.6.1
         1.7.0
-        
         1.8.0
     
 
diff --git a/core-java-modules/core-java-time-measurements/pom.xml b/core-java-modules/core-java-time-measurements/pom.xml
index 663cf6708b..28959d0938 100644
--- a/core-java-modules/core-java-time-measurements/pom.xml
+++ b/core-java-modules/core-java-time-measurements/pom.xml
@@ -13,7 +13,6 @@
         com.baeldung.core-java-modules
         core-java-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
@@ -28,13 +27,6 @@
             ${lombok.version}
             provided
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             joda-time
             joda-time
@@ -46,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
         
         
@@ -75,8 +67,8 @@
         
         
             
+                org.apache.maven.plugins
                 maven-surefire-plugin
-                ${maven-surefire-plugin.version}
                 
                     
                         -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar
@@ -88,17 +80,12 @@
     
 
     
-        
         3.6.1
         2.10
-        1.18.12
-        
-        3.6.1
+        1.18.22
         1.8.9
-        2.0.7
         1.44
-        
-        2.22.1
+        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/core-java-modules/core-java-uuid/README.md b/core-java-modules/core-java-uuid/README.md
new file mode 100644
index 0000000000..836552d798
--- /dev/null
+++ b/core-java-modules/core-java-uuid/README.md
@@ -0,0 +1,5 @@
+## Core Java UUID
+
+### Relevant Articles: 
+- [Generating Alphanumeric UUID String in Java](https://www.baeldung.com/java-generate-alphanumeric-uuid)
+- [Guide to UUID in Java](http://www.baeldung.com/java-uuid)
diff --git a/core-java-modules/core-java-uuid/pom.xml b/core-java-modules/core-java-uuid/pom.xml
new file mode 100644
index 0000000000..983d0f2ba3
--- /dev/null
+++ b/core-java-modules/core-java-uuid/pom.xml
@@ -0,0 +1,147 @@
+
+
+    4.0.0
+    core-java-uuid
+    0.1.0-SNAPSHOT
+    core-java-uuid
+    jar
+
+    
+        com.baeldung.core-java-modules
+        core-java-modules
+        0.0.1-SNAPSHOT
+    
+
+    
+        
+            log4j
+            log4j
+            ${log4j.version}
+        
+         
+            org.slf4j
+            log4j-over-slf4j
+            ${org.slf4j.version}
+        
+    
+
+    
+        core-java-uuid
+        
+            
+                src/main/resources
+                true
+            
+        
+
+        
+            
+                org.apache.maven.plugins
+                maven-dependency-plugin
+                
+                    
+                        copy-dependencies
+                        prepare-package
+                        
+                            copy-dependencies
+                        
+                        
+                            ${project.build.directory}/libs
+                        
+                    
+                
+            
+            
+                org.codehaus.mojo
+                exec-maven-plugin
+                
+                    java
+                    com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed
+                    
+                        -Xmx300m
+                        -XX:+UseParallelGC
+                        -classpath
+                        
+                        com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed
+                    
+                
+            
+            
+                org.apache.maven.plugins
+                maven-javadoc-plugin
+                ${maven-javadoc-plugin.version}
+                
+                    ${source.version}
+                    ${target.version}
+                
+            
+        
+    
+
+    
+        
+            integration
+            
+                
+                    
+                        org.apache.maven.plugins
+                        maven-surefire-plugin
+                        
+                            
+                                integration-test
+                                
+                                    test
+                                
+                                
+                                    
+                                        **/*ManualTest.java
+                                    
+                                    
+                                        **/*IntegrationTest.java
+                                        **/*IntTest.java
+                                    
+                                
+                            
+                        
+                        
+                            
+                                json
+                            
+                        
+                    
+                    
+                        org.codehaus.mojo
+                        exec-maven-plugin
+                        
+                            
+                                run-benchmarks
+                                
+                                none
+                                
+                                    exec
+                                
+                                
+                                    test
+                                    java
+                                    
+                                        -classpath
+                                        
+                                        org.openjdk.jmh.Main
+                                        .*
+                                    
+                                
+                            
+                        
+                    
+                
+            
+        
+    
+
+    
+        3.0.0-M1
+    
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/uuid/UUIDGenerator.java b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/uuid/UUIDGenerator.java
similarity index 100%
rename from core-java-modules/core-java/src/main/java/com/baeldung/uuid/UUIDGenerator.java
rename to core-java-modules/core-java-uuid/src/main/java/com/baeldung/uuid/UUIDGenerator.java
diff --git a/core-java-modules/core-java-uuid/src/main/resources/log4j.properties b/core-java-modules/core-java-uuid/src/main/resources/log4j.properties
new file mode 100644
index 0000000000..621cf01735
--- /dev/null
+++ b/core-java-modules/core-java-uuid/src/main/resources/log4j.properties
@@ -0,0 +1,6 @@
+log4j.rootLogger=DEBUG, A1
+
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
\ No newline at end of file
diff --git a/core-java-modules/core-java-uuid/src/main/resources/log4j2.xml b/core-java-modules/core-java-uuid/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000..a824bef9b0
--- /dev/null
+++ b/core-java-modules/core-java-uuid/src/main/resources/log4j2.xml
@@ -0,0 +1,13 @@
+
+
+    
+        
+            
+        
+    
+    
+        
+            
+        
+    
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-uuid/src/main/resources/log4jstructuraldp.properties b/core-java-modules/core-java-uuid/src/main/resources/log4jstructuraldp.properties
new file mode 100644
index 0000000000..5bc2bfe4b9
--- /dev/null
+++ b/core-java-modules/core-java-uuid/src/main/resources/log4jstructuraldp.properties
@@ -0,0 +1,9 @@
+
+# Root logger 
+log4j.rootLogger=INFO, file, stdout
+
+# Write to console
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
\ No newline at end of file
diff --git a/core-java-modules/core-java-uuid/src/main/resources/logback.xml b/core-java-modules/core-java-uuid/src/main/resources/logback.xml
new file mode 100644
index 0000000000..56af2d397e
--- /dev/null
+++ b/core-java-modules/core-java-uuid/src/main/resources/logback.xml
@@ -0,0 +1,19 @@
+
+
+    
+        
+            %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+            
+        
+    
+
+    
+    
+
+    
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/uuid/UUIDGeneratorUnitTest.java b/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDGeneratorUnitTest.java
similarity index 100%
rename from core-java-modules/core-java/src/test/java/com/baeldung/uuid/UUIDGeneratorUnitTest.java
rename to core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDGeneratorUnitTest.java
diff --git a/core-java-modules/core-java-uuid/src/test/resources/log4j.properties b/core-java-modules/core-java-uuid/src/test/resources/log4j.properties
new file mode 100644
index 0000000000..621cf01735
--- /dev/null
+++ b/core-java-modules/core-java-uuid/src/test/resources/log4j.properties
@@ -0,0 +1,6 @@
+log4j.rootLogger=DEBUG, A1
+
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
\ No newline at end of file
diff --git a/core-java-modules/core-java-uuid/src/test/resources/log4j2.xml b/core-java-modules/core-java-uuid/src/test/resources/log4j2.xml
new file mode 100644
index 0000000000..a824bef9b0
--- /dev/null
+++ b/core-java-modules/core-java-uuid/src/test/resources/log4j2.xml
@@ -0,0 +1,13 @@
+
+
+    
+        
+            
+        
+    
+    
+        
+            
+        
+    
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-uuid/src/test/resources/log4jstructuraldp.properties b/core-java-modules/core-java-uuid/src/test/resources/log4jstructuraldp.properties
new file mode 100644
index 0000000000..5bc2bfe4b9
--- /dev/null
+++ b/core-java-modules/core-java-uuid/src/test/resources/log4jstructuraldp.properties
@@ -0,0 +1,9 @@
+
+# Root logger 
+log4j.rootLogger=INFO, file, stdout
+
+# Write to console
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
\ No newline at end of file
diff --git a/core-java-modules/core-java-uuid/src/test/resources/logback.xml b/core-java-modules/core-java-uuid/src/test/resources/logback.xml
new file mode 100644
index 0000000000..56af2d397e
--- /dev/null
+++ b/core-java-modules/core-java-uuid/src/test/resources/logback.xml
@@ -0,0 +1,19 @@
+
+
+    
+        
+            %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+            
+        
+    
+
+    
+    
+
+    
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/core-java-modules/core-java/README.md b/core-java-modules/core-java/README.md
index f1cf2d8c09..a75805e0c2 100644
--- a/core-java-modules/core-java/README.md
+++ b/core-java-modules/core-java/README.md
@@ -3,13 +3,7 @@
 ### Relevant Articles: 
 - [Getting Started with Java Properties](http://www.baeldung.com/java-properties)
 - [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency)
-- [Introduction to Java Serialization](http://www.baeldung.com/java-serialization)
-- [Guide to UUID in Java](http://www.baeldung.com/java-uuid)
 - [Compiling Java *.class Files with javac](http://www.baeldung.com/javac)
 - [Introduction to Javadoc](http://www.baeldung.com/javadoc)
-- [Guide to the Externalizable Interface in Java](http://www.baeldung.com/java-externalizable)
-- [What is the serialVersionUID?](http://www.baeldung.com/java-serial-version-uid)
 - [A Guide to the ResourceBundle](http://www.baeldung.com/java-resourcebundle)
 - [Merging java.util.Properties Objects](https://www.baeldung.com/java-merging-properties)
-- [Deserialization Vulnerabilities in Java](https://www.baeldung.com/java-deserialization-vulnerabilities)
-- [Generating Alphanumeric UUID String in Java](https://www.baeldung.com/java-generate-alphanumeric-uuid)
diff --git a/core-java-modules/core-java/pom.xml b/core-java-modules/core-java/pom.xml
index db2b1edc70..8d6921b493 100644
--- a/core-java-modules/core-java/pom.xml
+++ b/core-java-modules/core-java/pom.xml
@@ -49,18 +49,16 @@
             ${lombok.version}
             provided
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             org.javamoney
             moneta
             ${javamoney.moneta.version}
         
+        
+		    org.springframework
+		    spring-core
+		    ${spring.core.version}
+        
     
 
     
@@ -180,13 +178,12 @@
         
         0.4
         1.8.7
-        
-        3.10.0
         
         1.1
         3.0.0-M1
         1.8
         1.8
+        4.3.20.RELEASE
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/multimodulemavenproject/pom.xml b/core-java-modules/multimodulemavenproject/pom.xml
index 79d884cd86..fbafa7ebff 100644
--- a/core-java-modules/multimodulemavenproject/pom.xml
+++ b/core-java-modules/multimodulemavenproject/pom.xml
@@ -23,17 +23,6 @@
         mainappmodule
     
 
-    
-        
-            
-                org.assertj
-                assertj-core
-                ${assertj-core.version}
-                test
-            
-        
-    
-
     
         
             
@@ -54,7 +43,6 @@
         3.8.0
         1.9
         1.9
-        3.12.2
     
 
 
\ No newline at end of file
diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml
index 9f184310e9..d9da5a845b 100644
--- a/core-java-modules/pom.xml
+++ b/core-java-modules/pom.xml
@@ -90,7 +90,6 @@
         core-java-lang-syntax-2
         core-java-networking
         core-java-networking-2
-        core-java-networking-3
         core-java-nio
         core-java-nio-2
         core-java-optional
@@ -99,6 +98,9 @@
         core-java-reflection-2
         core-java-security
         core-java-security-2
+        core-java-security-3
+        core-java-serialization
+        core-java-security-algorithms
         core-java-streams
         core-java-streams-2
         core-java-streams-3
@@ -114,6 +116,7 @@
         core-java-sun
         core-java-regex
         core-java-regex-2
+        core-java-uuid
         pre-jpms
     
 
@@ -134,8 +137,4 @@
         
     
 
-    
-        2.22.2
-    
-
 
diff --git a/ddd-modules/pom.xml b/ddd-modules/pom.xml
index fe3aaf1160..134a9d0566 100644
--- a/ddd-modules/pom.xml
+++ b/ddd-modules/pom.xml
@@ -39,12 +39,6 @@
                 ${junit-jupiter.version}
                 test
             
-            
-                org.assertj
-                assertj-core
-                ${assertj-core.version}
-                test
-            
         
     
 
@@ -80,8 +74,6 @@
         3.8.1
 
         1.0
-
-        3.12.2
     
 
 
diff --git a/docker/README.md b/docker/README.md
index 8aca8e4293..0de3694215 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -5,3 +5,4 @@
 - [Running Spring Boot with PostgreSQL in Docker Compose](https://www.baeldung.com/spring-boot-postgresql-docker)
 - [How To Configure Java Heap Size Inside a Docker Container](https://www.baeldung.com/ops/docker-jvm-heap-size)
 - [Dockerfile Strategies for Git](https://www.baeldung.com/ops/dockerfile-git-strategies)
+- [How to Get Docker-Compose to Always Use the Latest Image](https://www.baeldung.com/ops/docker-compose-latest-image)
diff --git a/docker/docker-sample-app/Dockerfile b/docker/docker-sample-app/Dockerfile
new file mode 100644
index 0000000000..71fc1a29d9
--- /dev/null
+++ b/docker/docker-sample-app/Dockerfile
@@ -0,0 +1,3 @@
+FROM openjdk:11
+COPY target/docker-sample-app-0.0.1.jar app.jar
+ENTRYPOINT ["java","-jar","/app.jar"]
diff --git a/docker/docker-sample-app/README.md b/docker/docker-sample-app/README.md
new file mode 100644
index 0000000000..6aeaa1d2a3
--- /dev/null
+++ b/docker/docker-sample-app/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- How to Get Docker-Compose to Always Use the Latest Image
diff --git a/docker/docker-sample-app/docker-compose-build-image.yaml b/docker/docker-sample-app/docker-compose-build-image.yaml
new file mode 100644
index 0000000000..27c1d8ee44
--- /dev/null
+++ b/docker/docker-sample-app/docker-compose-build-image.yaml
@@ -0,0 +1,8 @@
+version: '2.4'
+services:
+  db:
+    image: postgres
+  my_app:
+    build: .
+    ports:
+      - "8080:8080"
diff --git a/docker/docker-sample-app/docker-compose-with-image.yaml b/docker/docker-sample-app/docker-compose-with-image.yaml
new file mode 100644
index 0000000000..9a8822f762
--- /dev/null
+++ b/docker/docker-sample-app/docker-compose-with-image.yaml
@@ -0,0 +1,9 @@
+version: '2.4'
+services:
+  db:
+    image: postgres
+  my_app:
+    image: "eugen/test-app:latest"
+    ports:
+      - "8080:8080"
+
diff --git a/docker/docker-sample-app/pom.xml b/docker/docker-sample-app/pom.xml
new file mode 100644
index 0000000000..6841fabcee
--- /dev/null
+++ b/docker/docker-sample-app/pom.xml
@@ -0,0 +1,45 @@
+
+
+    4.0.0
+    
+        com.baeldung.docker
+        docker
+        0.0.1
+    
+
+    docker-sample-app
+    docker-sample-app
+    Demo project for Spring Boot and Docker
+
+    
+        11
+    
+
+    
+        
+            org.springframework.boot
+            spring-boot-starter
+        
+        
+            org.springframework.boot
+            spring-boot-starter-web
+        
+
+        
+            org.springframework.boot
+            spring-boot-starter-test
+            test
+        
+    
+
+    
+        
+            
+                org.springframework.boot
+                spring-boot-maven-plugin
+            
+        
+    
+
+
diff --git a/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/DockAppApplication.java b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/DockAppApplication.java
new file mode 100644
index 0000000000..e7ff52015c
--- /dev/null
+++ b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/DockAppApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.docker.app;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class DockAppApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(DockAppApplication.class, args);
+    }
+
+}
diff --git a/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/endpoint/MyController.java b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/endpoint/MyController.java
new file mode 100644
index 0000000000..d46c57e606
--- /dev/null
+++ b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/endpoint/MyController.java
@@ -0,0 +1,13 @@
+package com.baeldung.docker.app.endpoint;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class MyController {
+
+    @GetMapping
+    public String version() {
+        return "1.7";
+    }
+}
diff --git a/docker/docker-sample-app/src/main/resources/application.properties b/docker/docker-sample-app/src/main/resources/application.properties
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/docker/docker-sample-app/src/main/resources/application.properties
@@ -0,0 +1 @@
+
diff --git a/docker/docker-sample-app/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java b/docker/docker-sample-app/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java
new file mode 100644
index 0000000000..7220766988
--- /dev/null
+++ b/docker/docker-sample-app/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java
@@ -0,0 +1,13 @@
+package com.baeldung.docker.app;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class DockAppApplicationUnitTest {
+
+    @Test
+    void contextLoads() {
+    }
+
+}
diff --git a/docker/pom.xml b/docker/pom.xml
index 3fcc9ca94f..f481f1b8b7 100644
--- a/docker/pom.xml
+++ b/docker/pom.xml
@@ -25,6 +25,7 @@
     
         docker-internal-dto
         docker-spring-boot
+        docker-sample-app
     
 
 
diff --git a/drools/pom.xml b/drools/pom.xml
index cc96d9d032..daaf1fa8a7 100644
--- a/drools/pom.xml
+++ b/drools/pom.xml
@@ -19,7 +19,6 @@
             httpcore
             ${http-component-version}
         
-        
         
             org.kie
             kie-ci
diff --git a/ethereum/pom.xml b/ethereum/pom.xml
index 7fc4057341..d2b05222c3 100644
--- a/ethereum/pom.xml
+++ b/ethereum/pom.xml
@@ -144,24 +144,6 @@
             
             test
         
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-            
-                
-                    org.hamcrest
-                    hamcrest-core
-                
-            
-        
-        
-            org.hamcrest
-            hamcrest
-            ${hamcrest.version}
-            test
-        
         
             com.jayway.jsonpath
             json-path
diff --git a/feign/pom.xml b/feign/pom.xml
index 56059d2a77..cf28890868 100644
--- a/feign/pom.xml
+++ b/feign/pom.xml
@@ -11,7 +11,6 @@
         com.baeldung
         parent-modules
         1.0.0-SNAPSHOT
-        ..
     
 
     
diff --git a/flyway-cdi-extension/pom.xml b/flyway-cdi-extension/pom.xml
index dbd21374e2..3d52ff0e36 100644
--- a/flyway-cdi-extension/pom.xml
+++ b/flyway-cdi-extension/pom.xml
@@ -11,7 +11,6 @@
         com.baeldung
         parent-modules
         1.0.0-SNAPSHOT
-        ..
     
 
     
diff --git a/google-web-toolkit/pom.xml b/google-web-toolkit/pom.xml
index 1a49ced021..bcccc136a4 100644
--- a/google-web-toolkit/pom.xml
+++ b/google-web-toolkit/pom.xml
@@ -44,12 +44,6 @@
             gwt-dev
             provided
         
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
     
 
     
diff --git a/grpc/pom.xml b/grpc/pom.xml
index f034b2b517..6f0c3b5c91 100644
--- a/grpc/pom.xml
+++ b/grpc/pom.xml
@@ -37,12 +37,6 @@
 			${io.grpc.version}
 			test
 		
-		
-			org.junit.vintage
-			junit-vintage-engine
-			${junit-jupiter.version}
-			test
-		
 		
 			javax.annotation
 			javax.annotation-api
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-18/pom.xml b/guava-modules/guava-18/pom.xml
index ed295db2f4..8f5108bff1 100644
--- a/guava-modules/guava-18/pom.xml
+++ b/guava-modules/guava-18/pom.xml
@@ -11,7 +11,6 @@
         com.baeldung
         guava-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
diff --git a/guava-modules/guava-19/pom.xml b/guava-modules/guava-19/pom.xml
index 3c29a2a59c..ba85fe0ae8 100644
--- a/guava-modules/guava-19/pom.xml
+++ b/guava-modules/guava-19/pom.xml
@@ -11,7 +11,6 @@
         com.baeldung
         guava-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
diff --git a/guava-modules/guava-21/pom.xml b/guava-modules/guava-21/pom.xml
index 8b7c3cdcfd..9e791bfe23 100644
--- a/guava-modules/guava-21/pom.xml
+++ b/guava-modules/guava-21/pom.xml
@@ -11,7 +11,6 @@
         com.baeldung
         guava-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
diff --git a/guava-modules/guava-collections-list/pom.xml b/guava-modules/guava-collections-list/pom.xml
index e57198ec40..6863b4011c 100644
--- a/guava-modules/guava-collections-list/pom.xml
+++ b/guava-modules/guava-collections-list/pom.xml
@@ -11,7 +11,6 @@
         com.baeldung
         guava-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
@@ -27,25 +26,6 @@
             ${commons-lang3.version}
         
         
-        
-            org.junit.jupiter
-            junit-jupiter
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-        
         
             org.hamcrest
             java-hamcrest
@@ -65,10 +45,6 @@
     
 
     
-        
-        4.1
-        
-        3.6.1
         2.0.0.0
     
 
diff --git a/guava-modules/guava-collections-map/pom.xml b/guava-modules/guava-collections-map/pom.xml
index 7f3e470fc3..04beaa13a1 100644
--- a/guava-modules/guava-collections-map/pom.xml
+++ b/guava-modules/guava-collections-map/pom.xml
@@ -12,24 +12,8 @@
         com.baeldung
         guava-modules
         0.0.1-SNAPSHOT
-        ../
     
 
-    
-        
-            org.junit.jupiter
-            junit-jupiter
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
-    
-
     
         guava-collections-map
         
diff --git a/guava-modules/guava-collections-set/pom.xml b/guava-modules/guava-collections-set/pom.xml
index 09e3f42e83..49bfc46ee2 100644
--- a/guava-modules/guava-collections-set/pom.xml
+++ b/guava-modules/guava-collections-set/pom.xml
@@ -11,38 +11,10 @@
         com.baeldung
         guava-modules
         0.0.1-SNAPSHOT
-        ../
     
 
-    
-        
-        
-            org.junit.jupiter
-            junit-jupiter
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-    
-
     
         guava-collections-set
     
 
-    
-        
-        3.6.1
-    
-
 
\ No newline at end of file
diff --git a/guava-modules/guava-collections/pom.xml b/guava-modules/guava-collections/pom.xml
index 6dc7510a1e..9283107023 100644
--- a/guava-modules/guava-collections/pom.xml
+++ b/guava-modules/guava-collections/pom.xml
@@ -11,7 +11,6 @@
         com.baeldung
         guava-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
@@ -32,25 +31,6 @@
             ${jool.version}
         
         
-        
-            org.junit.jupiter
-            junit-jupiter
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-        
         
             org.hamcrest
             java-hamcrest
@@ -70,11 +50,7 @@
     
 
     
-        
-        4.1
         0.9.12
-        
-        3.6.1
         2.0.0.0
     
 
diff --git a/guava-modules/guava-core/pom.xml b/guava-modules/guava-core/pom.xml
index a15dfb5178..dd68fef43a 100644
--- a/guava-modules/guava-core/pom.xml
+++ b/guava-modules/guava-core/pom.xml
@@ -11,7 +11,6 @@
         com.baeldung
         guava-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
@@ -20,13 +19,6 @@
             commons-lang3
             ${commons-lang3.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -39,9 +31,4 @@
         
     
 
-    
-        
-        3.6.1
-    
-
 
\ No newline at end of file
diff --git a/guava-modules/guava-io/pom.xml b/guava-modules/guava-io/pom.xml
index 11a5d4ada6..2ea91c5e4f 100644
--- a/guava-modules/guava-io/pom.xml
+++ b/guava-modules/guava-io/pom.xml
@@ -11,24 +11,8 @@
         com.baeldung
         guava-modules
         0.0.1-SNAPSHOT
-        ../
     
 
-    
-        
-            org.junit.jupiter
-            junit-jupiter
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
-    
-
     
         guava-io
         
diff --git a/guava-modules/guava-utilities/pom.xml b/guava-modules/guava-utilities/pom.xml
index 6049a62e85..ab849072a5 100644
--- a/guava-modules/guava-utilities/pom.xml
+++ b/guava-modules/guava-utilities/pom.xml
@@ -11,7 +11,6 @@
         com.baeldung
         guava-modules
         0.0.1-SNAPSHOT
-        ../
     
 
     
@@ -20,25 +19,6 @@
             commons-lang3
             ${commons-lang3.version}
         
-        
-        
-            org.junit.jupiter
-            junit-jupiter
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -51,9 +31,4 @@
         
     
 
-    
-        
-        3.6.1
-    
-
 
\ No newline at end of file
diff --git a/guava-modules/pom.xml b/guava-modules/pom.xml
index cbfb47fa0f..019776ad3d 100644
--- a/guava-modules/pom.xml
+++ b/guava-modules/pom.xml
@@ -34,22 +34,9 @@
             guava
             ${guava.version}
         
-        
-            org.junit.jupiter
-            junit-jupiter
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
     
 
     
-        2.22.2
         29.0-jre
     
 
diff --git a/guest/core-java/pom.xml b/guest/core-java/pom.xml
index aaf67fd27e..2ab067ad40 100644
--- a/guest/core-java/pom.xml
+++ b/guest/core-java/pom.xml
@@ -20,17 +20,10 @@
             log4j-core
             ${log4j2.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
         2.8.2
-        3.6.1
     
 
 
\ No newline at end of file
diff --git a/guest/core-kotlin/README.md b/guest/core-kotlin/README.md
deleted file mode 100644
index fad62ebea6..0000000000
--- a/guest/core-kotlin/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### Relevant Articles:
-
-- [Kotlin vs Java](https://www.baeldung.com/kotlin/vs-java)
diff --git a/guest/junit5-example/pom.xml b/guest/junit5-example/pom.xml
index a88f739891..cc52b0e3d7 100644
--- a/guest/junit5-example/pom.xml
+++ b/guest/junit5-example/pom.xml
@@ -40,15 +40,8 @@
     
         
             
+                org.apache.maven.plugins
                 maven-surefire-plugin
-                ${maven-surefire-plugin.version}
-                
-                    
-                        org.junit.platform
-                        junit-platform-surefire-provider
-                        ${junit-platform-surefire-provider.version}
-                    
-                
                 
                     
                         math
diff --git a/immutables/pom.xml b/immutables/pom.xml
index 648166fd74..7704cddbb6 100644
--- a/immutables/pom.xml
+++ b/immutables/pom.xml
@@ -18,12 +18,6 @@
             value
             ${immutables.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.mutabilitydetector
             MutabilityDetector
@@ -34,7 +28,6 @@
 
     
         2.5.6
-        3.6.1
         0.9.6
     
 
diff --git a/jackson-modules/jackson-annotations/pom.xml b/jackson-modules/jackson-annotations/pom.xml
index bdc131c867..56fd6cf2fa 100644
--- a/jackson-modules/jackson-annotations/pom.xml
+++ b/jackson-modules/jackson-annotations/pom.xml
@@ -25,12 +25,6 @@
             ${rest-assured.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -44,7 +38,6 @@
     
 
     
-        3.11.0
         3.1.1
     
 
diff --git a/jackson-modules/jackson-conversions-2/README.md b/jackson-modules/jackson-conversions-2/README.md
index 9986fe75b5..fa3568652a 100644
--- a/jackson-modules/jackson-conversions-2/README.md
+++ b/jackson-modules/jackson-conversions-2/README.md
@@ -10,4 +10,6 @@ This module contains articles about Jackson conversions.
 - [How to Process YAML with Jackson](https://www.baeldung.com/jackson-yaml)
 - [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/jackson-modules/jackson-conversions-2/pom.xml b/jackson-modules/jackson-conversions-2/pom.xml
index a498c8b4f8..7e994fb52b 100644
--- a/jackson-modules/jackson-conversions-2/pom.xml
+++ b/jackson-modules/jackson-conversions-2/pom.xml
@@ -32,12 +32,6 @@
             jackson-dataformat-csv
             ${jackson.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -50,8 +44,4 @@
         
     
 
-    
-        3.11.0
-    
-
 
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/Game.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/Game.java
new file mode 100644
index 0000000000..0ad77640d4
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/Game.java
@@ -0,0 +1,49 @@
+package com.baeldung.jackson.booleanAsInt;
+
+public class Game {
+
+    private Long id;
+    private String name;
+    private Boolean paused;
+    private Boolean over;
+
+    public Game() {
+    }
+
+    public Game(Long id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public Long getId() {
+        return this.id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Boolean isPaused() {
+        return paused;
+    }
+
+    public void setPaused(Boolean paused) {
+        this.paused = paused;
+    }
+
+    public Boolean isOver() {
+        return over;
+    }
+
+    public void setOver(Boolean over) {
+        this.over = over;
+    }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/GameAnnotatedByJsonFormat.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/GameAnnotatedByJsonFormat.java
new file mode 100644
index 0000000000..b97625fa6b
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/GameAnnotatedByJsonFormat.java
@@ -0,0 +1,56 @@
+package com.baeldung.jackson.booleanAsInt;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonFormat.Shape;
+
+public class GameAnnotatedByJsonFormat {
+
+    private Long id;
+    private String name;
+
+    @JsonFormat(shape = Shape.NUMBER)
+    private boolean paused;
+
+    @JsonFormat(shape = Shape.NUMBER)
+    private boolean over;
+
+    public GameAnnotatedByJsonFormat() {
+    }
+
+    public GameAnnotatedByJsonFormat(Long id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public Long getId() {
+        return this.id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public boolean isPaused() {
+        return paused;
+    }
+
+    public void setPaused(boolean paused) {
+        this.paused = paused;
+    }
+
+    public boolean isOver() {
+        return over;
+    }
+
+    public void setOver(boolean over) {
+        this.over = over;
+    }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/GameAnnotatedByJsonSerializeDeserialize.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/GameAnnotatedByJsonSerializeDeserialize.java
new file mode 100644
index 0000000000..50c6d96009
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/GameAnnotatedByJsonSerializeDeserialize.java
@@ -0,0 +1,58 @@
+package com.baeldung.jackson.booleanAsInt;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+public class GameAnnotatedByJsonSerializeDeserialize {
+
+    private Long id;
+    private String name;
+
+    @JsonSerialize(using = NumericBooleanSerializer.class)
+    @JsonDeserialize(using = NumericBooleanDeserializer.class)
+    private Boolean paused;
+
+    @JsonSerialize(using = NumericBooleanSerializer.class)
+    @JsonDeserialize(using = NumericBooleanDeserializer.class)
+    private Boolean over;
+
+    public GameAnnotatedByJsonSerializeDeserialize() {
+    }
+
+    public GameAnnotatedByJsonSerializeDeserialize(Long id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public Long getId() {
+        return this.id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Boolean isPaused() {
+        return paused;
+    }
+
+    public void setPaused(Boolean paused) {
+        this.paused = paused;
+    }
+
+    public Boolean isOver() {
+        return over;
+    }
+
+    public void setOver(Boolean over) {
+        this.over = over;
+    }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/NumericBooleanDeserializer.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/NumericBooleanDeserializer.java
new file mode 100644
index 0000000000..e9cb41e91d
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/NumericBooleanDeserializer.java
@@ -0,0 +1,23 @@
+package com.baeldung.jackson.booleanAsInt;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import java.io.IOException;
+
+public class NumericBooleanDeserializer extends JsonDeserializer {
+
+    @Override
+    public Boolean deserialize(JsonParser p, DeserializationContext ctxt)
+      throws IOException {
+        if ("1".equals(p.getText())) {
+            return Boolean.TRUE;
+        }
+        if ("0".equals(p.getText())) {
+            return Boolean.FALSE;
+        }
+        // for other than "1" or "0" throw exception by using Jackson internals
+        throw ctxt.weirdStringException(p.getText(), Boolean.class, "only \"1\" or \"0\" recognized");
+    }
+
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/NumericBooleanSerializer.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/NumericBooleanSerializer.java
new file mode 100644
index 0000000000..e9f7112b53
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/booleanAsInt/NumericBooleanSerializer.java
@@ -0,0 +1,15 @@
+package com.baeldung.jackson.booleanAsInt;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import java.io.IOException;
+
+public class NumericBooleanSerializer extends JsonSerializer {
+
+    @Override
+    public void serialize(Boolean value, JsonGenerator gen, SerializerProvider serializers)
+      throws IOException {
+        gen.writeString(value ? "1" : "0");
+    }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/User.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/User.java
new file mode 100644
index 0000000000..17bf6f898b
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/User.java
@@ -0,0 +1,22 @@
+package com.baeldung.jackson.snakecase;
+
+public class User {
+    private String firstName;
+    private String lastName;
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/UserWithPropertyNames.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/UserWithPropertyNames.java
new file mode 100644
index 0000000000..f9f36243ad
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/UserWithPropertyNames.java
@@ -0,0 +1,26 @@
+package com.baeldung.jackson.snakecase;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class UserWithPropertyNames {
+    @JsonProperty("first_name")
+    private String firstName;
+    @JsonProperty("last_name")
+    private String lastName;
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/UserWithSnakeStrategy.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/UserWithSnakeStrategy.java
new file mode 100644
index 0000000000..ffec940ed8
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/UserWithSnakeStrategy.java
@@ -0,0 +1,26 @@
+package com.baeldung.jackson.snakecase;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategy;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+
+@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
+public class UserWithSnakeStrategy {
+    private String firstName;
+    private String lastName;
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/booleanAsInt/BooleanAsIntegerUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/booleanAsInt/BooleanAsIntegerUnitTest.java
new file mode 100644
index 0000000000..976f3f4915
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/booleanAsInt/BooleanAsIntegerUnitTest.java
@@ -0,0 +1,132 @@
+package com.baeldung.jackson.booleanAsInt;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonFormat.Shape;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.exc.InvalidFormatException;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class BooleanAsIntegerUnitTest {
+
+    private ObjectMapper mapper;
+
+    @BeforeEach
+    public void setup() {
+        mapper = new ObjectMapper();
+    }
+
+    @Test
+    public void givenBoolean_serializedAsInteger() throws Exception {
+        GameAnnotatedByJsonFormat
+          game = new GameAnnotatedByJsonFormat(1L, "My Game");
+        game.setPaused(true);
+        game.setOver(false);
+        String json = mapper.writeValueAsString(game);
+
+        assertThat(json)
+          .isEqualTo("{\"id\":1,\"name\":\"My Game\",\"paused\":1,\"over\":0}");
+    }
+
+    @Test
+    public void givenInteger_deserializedAsBooleanByDefault() throws Exception {
+        // Integer "1" and "0" values deserialized correctly out of the box.
+        // No configuration or @JsonFormat annotation needed.
+        String json = "{\"id\":1,\"name\":\"My Game\",\"paused\":1,\"over\":0}";
+        Game game = mapper.readValue(json, Game.class);
+
+        assertThat(game.isPaused()).isEqualTo(true);
+        assertThat(game.isOver()).isEqualTo(false);
+    }
+
+    @Test
+    public void givenBoolean_serializedAsIntegerGlobally() throws Exception {
+        // global configuration override for the type Boolean
+        mapper.configOverride(Boolean.class)
+          .setFormat(JsonFormat.Value.forShape(Shape.NUMBER));
+
+        Game game = new Game(1L, "My Game");
+        game.setPaused(true);
+        game.setOver(false);
+        String json = mapper.writeValueAsString(game);
+
+        assertThat(json)
+          .isEqualTo("{\"id\":1,\"name\":\"My Game\",\"paused\":1,\"over\":0}");
+    }
+
+    @Test
+    public void givenBooleanWithCustomSerializer_serializedAsNumericString() throws Exception {
+        GameAnnotatedByJsonSerializeDeserialize
+          game = new GameAnnotatedByJsonSerializeDeserialize(1L, "My Game");
+        game.setPaused(true);
+        game.setOver(false);
+        String json = mapper.writeValueAsString(game);
+
+        assertThat(json)
+          .isEqualTo("{\"id\":1,\"name\":\"My Game\",\"paused\":\"1\",\"over\":\"0\"}");
+    }
+
+    @Test
+    public void givenNumericStringWithCustomDeserializer_deserializedAsBoolean() throws Exception {
+        String json = "{\"id\":1,\"name\":\"My Game\",\"paused\":\"1\",\"over\":\"0\"}";
+        GameAnnotatedByJsonSerializeDeserialize
+          game = mapper.readValue(json, GameAnnotatedByJsonSerializeDeserialize.class);
+
+        assertThat(game.isPaused()).isEqualTo(true);
+        assertThat(game.isOver()).isEqualTo(false);
+    }
+
+    @Test
+    public void givenBooleanWithCustomSerializer_serializedAsNumericStringGlobally() throws Exception {
+        // setting serializers globally
+        SimpleModule module = new SimpleModule();
+        module.addSerializer(Boolean.class, new NumericBooleanSerializer());
+        mapper.registerModule(module);
+
+        Game game = new Game(1L, "My Game");
+        game.setPaused(true);
+        game.setOver(false);
+        String json = mapper.writeValueAsString(game);
+
+        assertThat(json)
+          .isEqualTo("{\"id\":1,\"name\":\"My Game\",\"paused\":\"1\",\"over\":\"0\"}");
+    }
+
+    @Test
+    public void givenNumericStringWithCustomDeserializer_deserializedAsBooleanGlobally() throws Exception {
+        // setting deserializers globally
+        SimpleModule module = new SimpleModule();
+        module.addDeserializer(Boolean.class, new NumericBooleanDeserializer());
+        mapper.registerModule(module);
+
+        String json = "{\"id\":1,\"name\":\"My Game\",\"paused\":\"1\",\"over\":\"0\"}";
+        Game game = mapper.readValue(json, Game.class);
+
+        assertThat(game.isPaused()).isEqualTo(true);
+        assertThat(game.isOver()).isEqualTo(false);
+    }
+
+    @Test
+    public void givenInvalidStringWithCustomDeserializer_throwsInvalidFormatException() {
+        // another number other than "1" or "0"
+        String json = "{\"id\":1,\"name\":\"My Game\",\"paused\":\"5\"}";
+        InvalidFormatException e = Assertions.assertThrows(
+          InvalidFormatException.class, () -> mapper.readValue(json, GameAnnotatedByJsonSerializeDeserialize.class)
+        );
+
+        assertThat(e.getValue()).isEqualTo("5");
+
+        // non-numeric string
+        String json2 = "{\"id\":1,\"name\":\"My Game\",\"paused\":\"xxx\"}";
+        InvalidFormatException e2 = Assertions.assertThrows(
+          InvalidFormatException.class, () -> mapper.readValue(json2, GameAnnotatedByJsonSerializeDeserialize.class)
+        );
+
+        assertThat(e2.getValue()).isEqualTo("xxx");
+    }
+
+}
diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/snakecase/SnakeCaseUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/snakecase/SnakeCaseUnitTest.java
new file mode 100644
index 0000000000..c72908ccce
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/snakecase/SnakeCaseUnitTest.java
@@ -0,0 +1,44 @@
+package com.baeldung.jackson.snakecase;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.PropertyNamingStrategy;
+import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class SnakeCaseUnitTest {
+
+    private static final String JSON = "{\"first_name\": \"Jackie\", \"last_name\": \"Chan\"}";
+
+    @Test(expected = UnrecognizedPropertyException.class)
+    public void whenExceptionThrown_thenExpectationSatisfied() throws Exception {
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.readValue(JSON, User.class);
+    }
+
+    @Test
+    public void givenSnakeCaseJson_whenParseWithJsonPropertyAnnotation_thenGetExpectedObject() throws Exception {
+        ObjectMapper objectMapper = new ObjectMapper();
+        UserWithPropertyNames user = objectMapper.readValue(JSON, UserWithPropertyNames.class);
+        assertEquals("Jackie", user.getFirstName());
+        assertEquals("Chan", user.getLastName());
+    }
+
+    @Test
+    public void givenSnakeCaseJson_whenParseWithJsonNamingAnnotation_thenGetExpectedObject() throws Exception {
+        ObjectMapper objectMapper = new ObjectMapper();
+        UserWithSnakeStrategy user = objectMapper.readValue(JSON, UserWithSnakeStrategy.class);
+        assertEquals("Jackie", user.getFirstName());
+        assertEquals("Chan", user.getLastName());
+    }
+
+    @Test
+    public void givenSnakeCaseJson_whenParseWithCustomMapper_thenGetExpectedObject() throws Exception {
+        ObjectMapper objectMapper = new ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
+        User user = objectMapper.readValue(JSON, User.class);
+        assertEquals("Jackie", user.getFirstName());
+        assertEquals("Chan", user.getLastName());
+    }
+
+}
diff --git a/jackson-modules/jackson/README.md b/jackson-modules/jackson/README.md
index 50e13a5b75..0aa3dc5aef 100644
--- a/jackson-modules/jackson/README.md
+++ b/jackson-modules/jackson/README.md
@@ -6,9 +6,11 @@ This module contains articles about Jackson.
 
 The "REST With Spring" Classes: http://bit.ly/restwithspring
 
-### Relevant Articles: 
+### Relevant Articles:
+
 - [Using Optional with Jackson](https://www.baeldung.com/jackson-optional)
 - [Compare Two JSON Objects with Jackson](https://www.baeldung.com/jackson-compare-two-json-objects)
 - [Jackson vs Gson](https://www.baeldung.com/jackson-vs-gson)
 - [Inheritance with Jackson](https://www.baeldung.com/jackson-inheritance)
 - [Working with Tree Model Nodes in Jackson](https://www.baeldung.com/jackson-json-node-tree-model)
+- [Get all the Keys in a JSON String Using JsonNode](https://www.baeldung.com/java-jsonnode-get-keys)
diff --git a/jackson-modules/jackson/pom.xml b/jackson-modules/jackson/pom.xml
index a4aecfa3de..9df0f40874 100644
--- a/jackson-modules/jackson/pom.xml
+++ b/jackson-modules/jackson/pom.xml
@@ -48,12 +48,6 @@
             ${rest-assured.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -69,7 +63,6 @@
     
         
         3.1.1
-        3.11.0
     
 
 
\ No newline at end of file
diff --git a/jackson-modules/jackson/src/main/java/com/baeldung/jackson/jsonnode/GetAllKeysFromJSON.java b/jackson-modules/jackson/src/main/java/com/baeldung/jackson/jsonnode/GetAllKeysFromJSON.java
new file mode 100644
index 0000000000..bb8e9a8646
--- /dev/null
+++ b/jackson-modules/jackson/src/main/java/com/baeldung/jackson/jsonnode/GetAllKeysFromJSON.java
@@ -0,0 +1,135 @@
+package com.baeldung.jackson.jsonnode;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+
+public class GetAllKeysFromJSON {
+
+    public List getKeysInJsonUsingMaps(String json, ObjectMapper mapper) throws JsonMappingException, JsonProcessingException {
+        List keys = new ArrayList<>();
+        Map jsonElements = mapper.readValue(json, new TypeReference>() {
+        });
+        getAllKeys(jsonElements, keys);
+        return keys;
+    }
+
+    private void getAllKeys(Map jsonElements, List keys) {
+
+        jsonElements.entrySet()
+            .forEach(entry -> {
+                keys.add(entry.getKey());
+                if (entry.getValue() instanceof Map) {
+                    Map map = (Map) entry.getValue();
+                    getAllKeys(map, keys);
+                } else if (entry.getValue() instanceof List) {
+                    List list = (List) entry.getValue();
+                    list.forEach(listEntry -> {
+                        if (listEntry instanceof Map) {
+                            Map map = (Map) listEntry;
+                            getAllKeys(map, keys);
+                        }
+                    });
+                }
+            });
+    }
+
+    public List getKeysInJsonUsingJsonNodeFieldNames(String json, ObjectMapper mapper) throws JsonMappingException, JsonProcessingException {
+
+        List keys = new ArrayList<>();
+        JsonNode jsonNode = mapper.readTree(json);
+        Iterator iterator = jsonNode.fieldNames();
+        iterator.forEachRemaining(e -> keys.add(e));
+        return keys;
+    }
+
+    public List getAllKeysInJsonUsingJsonNodeFieldNames(String json, ObjectMapper mapper) throws JsonMappingException, JsonProcessingException {
+
+        List keys = new ArrayList<>();
+        JsonNode jsonNode = mapper.readTree(json);
+        getAllKeysUsingJsonNodeFieldNames(jsonNode, keys);
+        return keys;
+    }
+
+    public List getAllKeysInJsonUsingJsonNodeFields(String json, ObjectMapper mapper) throws JsonMappingException, JsonProcessingException {
+
+        List keys = new ArrayList<>();
+        JsonNode jsonNode = mapper.readTree(json);
+        getAllKeysUsingJsonNodeFields(jsonNode, keys);
+        return keys;
+    }
+
+    private void getAllKeysUsingJsonNodeFields(JsonNode jsonNode, List keys) {
+
+        if (jsonNode.isObject()) {
+            Iterator> fields = jsonNode.fields();
+            fields.forEachRemaining(field -> {
+                keys.add(field.getKey());
+                getAllKeysUsingJsonNodeFieldNames((JsonNode) field.getValue(), keys);
+            });
+        } else if (jsonNode.isArray()) {
+            ArrayNode arrayField = (ArrayNode) jsonNode;
+            arrayField.forEach(node -> {
+                getAllKeysUsingJsonNodeFieldNames(node, keys);
+            });
+        }
+
+    }
+
+    private void getAllKeysUsingJsonNodeFieldNames(JsonNode jsonNode, List keys) {
+
+        if (jsonNode.isObject()) {
+            Iterator fieldNames = jsonNode.fieldNames();
+            fieldNames.forEachRemaining(fieldName -> {
+                keys.add(fieldName);
+                getAllKeysUsingJsonNodeFieldNames(jsonNode.get(fieldName), keys);
+            });
+        } else if (jsonNode.isArray()) {
+            ArrayNode arrayField = (ArrayNode) jsonNode;
+            arrayField.forEach(node -> {
+                getAllKeysUsingJsonNodeFieldNames(node, keys);
+            });
+        }
+
+    }
+
+    public List getKeysInJsonUsingJsonParser(String json, ObjectMapper mapper) throws IOException {
+
+        List keys = new ArrayList<>();
+        JsonNode jsonNode = mapper.readTree(json);
+        JsonParser jsonParser = jsonNode.traverse();
+        while (!jsonParser.isClosed()) {
+            if (jsonParser.nextToken() == JsonToken.FIELD_NAME) {
+                keys.add((jsonParser.getCurrentName()));
+            }
+        }
+        return keys;
+    }
+
+    public List getKeysInJsonUsingJsonParser(String json) throws JsonParseException, IOException {
+
+        List keys = new ArrayList<>();
+        JsonFactory factory = new JsonFactory();
+        JsonParser jsonParser = factory.createParser(json);
+        while (!jsonParser.isClosed()) {
+            if (jsonParser.nextToken() == JsonToken.FIELD_NAME) {
+                keys.add((jsonParser.getCurrentName()));
+            }
+        }
+        return keys;
+    }
+}
diff --git a/jackson-modules/jackson/src/test/java/com/baeldung/jackson/jsonnode/GetAllKeysFromJSONUnitTest.java b/jackson-modules/jackson/src/test/java/com/baeldung/jackson/jsonnode/GetAllKeysFromJSONUnitTest.java
new file mode 100644
index 0000000000..5d0558ca63
--- /dev/null
+++ b/jackson-modules/jackson/src/test/java/com/baeldung/jackson/jsonnode/GetAllKeysFromJSONUnitTest.java
@@ -0,0 +1,85 @@
+package com.baeldung.jackson.jsonnode;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class GetAllKeysFromJSONUnitTest {
+
+    private static String json = "{\r\n" + "   \"Name\":\"Craig\",\r\n" + "   \"Age\":10,\r\n" + "   \"BookInterests\":[\r\n" + "      {\r\n" + "         \"Book\":\"The Kite Runner\",\r\n" + "         \"Author\":\"Khaled Hosseini\"\r\n" + "      },\r\n"
+        + "      {\r\n" + "         \"Book\":\"Harry Potter\",\r\n" + "         \"Author\":\"J. K. Rowling\"\r\n" + "      }\r\n" + "   ],\r\n" + "   \"FoodInterests\":{\r\n" + "      \"Breakfast\":[\r\n" + "         {\r\n"
+        + "            \"Bread\":\"Whole wheat\",\r\n" + "            \"Beverage\":\"Fruit juice\"\r\n" + "         },\r\n" + "         {\r\n" + "            \"Sandwich\":\"Vegetable Sandwich\",\r\n" + "            \"Beverage\":\"Coffee\"\r\n"
+        + "         }\r\n" + "      ]\r\n" + "   }\r\n" + "}";
+
+    private static ObjectMapper mapper = new ObjectMapper();
+    private static GetAllKeysFromJSON getAllKeysFromJSONUtil = new GetAllKeysFromJSON();
+
+    // Top level keys : [Name, Age, BookInterests, FoodInterests]
+    // All keys: [Name, Age, BookInterests, Book, Author, Book, Author, FoodInterests, Breakfast, Bread, Beverage, Sandwich, Beverage]
+
+    @Test
+    public void givenAJsonNode_whenUsingFieldNamesMethod_thenWeGetTopFieldNames() {
+        List keys;
+        try {
+            keys = getAllKeysFromJSONUtil.getKeysInJsonUsingJsonNodeFieldNames(json, mapper);
+            assertEquals(4, keys.size());
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void givenAJsonNode_whenUsingFieldNamesMethodForAllNodes_thenWeGetAllFieldNames() {
+        List keys;
+        try {
+            keys = getAllKeysFromJSONUtil.getAllKeysInJsonUsingJsonNodeFieldNames(json, mapper);
+            assertEquals(13, keys.size());
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void givenAJsonNode_whenUsingFieldsMethod_thenWeGetAllFieldNames() {
+        List keys;
+        try {
+            keys = getAllKeysFromJSONUtil.getAllKeysInJsonUsingJsonNodeFields(json, mapper);
+            assertEquals(13, keys.size());
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void givenAJsonNode_whenUsingJsonParserMethod_thenWeGetAllFieldNames() {
+        List keys;
+        try {
+            keys = getAllKeysFromJSONUtil.getKeysInJsonUsingJsonParser(json, mapper);
+            assertEquals(13, keys.size());
+
+            keys = getAllKeysFromJSONUtil.getKeysInJsonUsingJsonParser(json);
+            assertEquals(13, keys.size());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    @Test
+    public void givenAJsonNode_whenUsingMaps_thenWeGetAllFieldNames() {
+        List keys;
+        try {
+            keys = getAllKeysFromJSONUtil.getKeysInJsonUsingMaps(json, mapper);
+            assertEquals(13, keys.size());
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+    }
+
+}
diff --git a/jackson-modules/pom.xml b/jackson-modules/pom.xml
index 1bb684af0a..14e34a41bf 100644
--- a/jackson-modules/pom.xml
+++ b/jackson-modules/pom.xml
@@ -35,18 +35,6 @@
             jackson-dataformat-xml
             ${jackson.version}
         
-        
-            org.junit.jupiter
-            junit-jupiter
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
     
 
 
\ No newline at end of file
diff --git a/jackson-simple/pom.xml b/jackson-simple/pom.xml
index 72e31ee5e3..f71cb1ffbf 100644
--- a/jackson-simple/pom.xml
+++ b/jackson-simple/pom.xml
@@ -21,25 +21,6 @@
             jackson-dataformat-xml
             ${jackson.version}
         
-        
-        
-            org.junit.jupiter
-            junit-jupiter
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -52,9 +33,4 @@
         
     
 
-    
-        
-        3.11.0
-    
-
 
\ No newline at end of file
diff --git a/java-collections-conversions-2/pom.xml b/java-collections-conversions-2/pom.xml
index 55dc6e30b6..9f8ef7addc 100644
--- a/java-collections-conversions-2/pom.xml
+++ b/java-collections-conversions-2/pom.xml
@@ -16,12 +16,6 @@
     
 
     
-        
-            org.assertj
-            assertj-core
-            3.17.2
-            test
-        
         
             org.apache.commons
             commons-lang3
@@ -32,18 +26,6 @@
             modelmapper
             ${modelmapper.version}
         
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.hamcrest
-            hamcrest
-            ${hamcrest.version}
-            test
-        
         
             io.vavr
             vavr
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 0cdf24e31b..81466b17ba 100644
--- a/java-collections-maps-3/pom.xml
+++ b/java-collections-maps-3/pom.xml
@@ -22,12 +22,6 @@
             ${spring.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.apache.commons
             commons-collections4
@@ -36,8 +30,6 @@
     
 
     
-        4.1
-        3.6.1
         5.2.5.RELEASE
     
 
diff --git a/java-numbers-3/pom.xml b/java-numbers-3/pom.xml
index e8e080c4c0..68c2ac98de 100644
--- a/java-numbers-3/pom.xml
+++ b/java-numbers-3/pom.xml
@@ -30,12 +30,6 @@
             ${commons-lang3.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -51,7 +45,6 @@
     
         2.6.0
         0.10.2
-        3.6.1
     
 
 
\ No newline at end of file
diff --git a/java-numbers-4/pom.xml b/java-numbers-4/pom.xml
index dbd6ac456a..9b2e799840 100644
--- a/java-numbers-4/pom.xml
+++ b/java-numbers-4/pom.xml
@@ -25,12 +25,6 @@
             ${commons-lang3.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -45,7 +39,6 @@
 
     
         0.10.2
-        3.6.1
     
 
 
\ No newline at end of file
diff --git a/java-numbers/pom.xml b/java-numbers/pom.xml
index 8bab655f73..c06bc48c5d 100644
--- a/java-numbers/pom.xml
+++ b/java-numbers/pom.xml
@@ -31,12 +31,6 @@
             decimal4j
             ${decimal4j.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -51,7 +45,6 @@
 
     
         1.0.3
-        3.6.1
     
 
 
\ No newline at end of file
diff --git a/javax-servlets/pom.xml b/javax-servlets/pom.xml
index f1677050cf..1dc58aa917 100644
--- a/javax-servlets/pom.xml
+++ b/javax-servlets/pom.xml
@@ -16,12 +16,6 @@
     
 
     
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
         
             commons-fileupload
@@ -56,7 +50,6 @@
     
         4.5.3
         2.8.2
-        3.9.1
         4.0.1
     
 
diff --git a/javaxval/pom.xml b/javaxval/pom.xml
index f0093e0aa4..57369c6f52 100644
--- a/javaxval/pom.xml
+++ b/javaxval/pom.xml
@@ -34,19 +34,12 @@
             spring-test
             ${org.springframework.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
         6.0.13.Final
         3.0.0
         5.0.2.RELEASE
-        3.11.1
     
 
 
\ No newline at end of file
diff --git a/jhipster-5/bookstore-monolith/pom.xml b/jhipster-5/bookstore-monolith/pom.xml
index 8403c2d1d4..411de0e712 100644
--- a/jhipster-5/bookstore-monolith/pom.xml
+++ b/jhipster-5/bookstore-monolith/pom.xml
@@ -1136,7 +1136,7 @@
         3.0.0-M2
         2.2.1
         3.1.0
-        2.22.1
+        2.22.2
         3.2.2
         0.9.11
         1.6
diff --git a/jhipster/jhipster-uaa/gateway/pom.xml b/jhipster/jhipster-uaa/gateway/pom.xml
index bc3c9bdef2..536b847237 100644
--- a/jhipster/jhipster-uaa/gateway/pom.xml
+++ b/jhipster/jhipster-uaa/gateway/pom.xml
@@ -1054,7 +1054,6 @@
         2.10
         3.0.0-M2
         3.1.0
-        2.22.0
         3.2.2
         0.9.11
         1.6
diff --git a/jhipster/jhipster-uaa/quotes/pom.xml b/jhipster/jhipster-uaa/quotes/pom.xml
index 7e4252b309..d922be10c2 100644
--- a/jhipster/jhipster-uaa/quotes/pom.xml
+++ b/jhipster/jhipster-uaa/quotes/pom.xml
@@ -874,7 +874,6 @@
         2.10
         3.0.0-M2
         3.1.0
-        2.22.0
         3.2.2
         0.9.11
         0.8.2
diff --git a/jhipster/jhipster-uaa/uaa/pom.xml b/jhipster/jhipster-uaa/uaa/pom.xml
index ec4dc1b484..a43da9c366 100644
--- a/jhipster/jhipster-uaa/uaa/pom.xml
+++ b/jhipster/jhipster-uaa/uaa/pom.xml
@@ -875,7 +875,6 @@
         2.10
         3.0.0-M2
         3.1.0
-        2.22.0
         3.2.2
         0.9.11
         0.8.2
diff --git a/jjwt/pom.xml b/jjwt/pom.xml
index 4c194f9285..cc169ba9fc 100644
--- a/jjwt/pom.xml
+++ b/jjwt/pom.xml
@@ -38,11 +38,6 @@
             jjwt
             ${jjwt.version}
         
-        
-            org.assertj
-            assertj-core
-            test
-        
     
 
     
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 53d67320ba..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
@@ -24,18 +29,6 @@
             jsoniter
             ${jsoniter.version}
         
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             com.squareup.moshi
             moshi
@@ -153,8 +146,8 @@
 
     
         0.9.23
-        3.11.1
         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 260b2d1ad9..0d83f523b8 100644
--- a/json/pom.xml
+++ b/json/pom.xml
@@ -26,11 +26,6 @@
                 
             
         
-        
-            com.alibaba
-            fastjson
-            ${fastjson.version}
-        
         
             org.json
             json
@@ -68,24 +63,15 @@
             ${commons-collections4.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
     
 
     
         1.4.1
-        1.2.21
         1.0
-        4.1
         1.0.1
         20171018
         2.8.5
         1.1.2
-        3.11.1
     
 
 
\ No newline at end of file
diff --git a/jta/src/test/resources/logback-test.xml b/jta/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/jta/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/junit5/README.md b/junit5/README.md
deleted file mode 100644
index ad16ad164d..0000000000
--- a/junit5/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-## JUnit5
-
-This module contains articles about the JUnit 5
-
-### Relevant Articles:
-
diff --git a/junit5/src/test/java/com/baeldung/junit5/A_UnitTest.java b/junit5/src/test/java/com/baeldung/junit5/A_UnitTest.java
deleted file mode 100644
index e4ba59b22d..0000000000
--- a/junit5/src/test/java/com/baeldung/junit5/A_UnitTest.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.baeldung.junit5;
-
-import org.junit.jupiter.api.Test;
-
-public class A_UnitTest {
-
-    @Test
-    public void first() throws Exception{
-        System.out.println("Test A first() start => " + Thread.currentThread().getName());
-        Thread.sleep(500);
-        System.out.println("Test A first() end => " + Thread.currentThread().getName());
-    }
-
-    @Test
-    public void second() throws Exception{
-        System.out.println("Test A second() start => " + Thread.currentThread().getName());
-        Thread.sleep(500);
-        System.out.println("Test A second() end => " + Thread.currentThread().getName());
-    }
-
-}
diff --git a/junit5/src/test/java/com/baeldung/junit5/B_UnitTest.java b/junit5/src/test/java/com/baeldung/junit5/B_UnitTest.java
deleted file mode 100644
index 2b195d2551..0000000000
--- a/junit5/src/test/java/com/baeldung/junit5/B_UnitTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.baeldung.junit5;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.parallel.Execution;
-import org.junit.jupiter.api.parallel.ExecutionMode;
-
-public class B_UnitTest {
-
-    @Test
-    public void first() throws Exception{
-        System.out.println("Test B first() start => " + Thread.currentThread().getName());
-        Thread.sleep(500);
-        System.out.println("Test B first() end => " + Thread.currentThread().getName());
-    }
-
-    @Test
-    public void second() throws Exception{
-        System.out.println("Test B second() start => " + Thread.currentThread().getName());
-        Thread.sleep(500);
-        System.out.println("Test B second() end => " + Thread.currentThread().getName());
-    }
-
-}
diff --git a/junit5/src/test/java/com/baeldung/junit5/C_UnitTest.java b/junit5/src/test/java/com/baeldung/junit5/C_UnitTest.java
deleted file mode 100644
index ce545f6bee..0000000000
--- a/junit5/src/test/java/com/baeldung/junit5/C_UnitTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.baeldung.junit5;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.parallel.ResourceLock;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class C_UnitTest {
-
-    private List resources;
-
-    @BeforeEach
-    void before() {
-        resources = new ArrayList<>();
-        resources.add("test");
-    }
-
-    @AfterEach
-    void after() {
-        resources.clear();
-    }
-
-    @Test
-    @ResourceLock(value = "resources")
-    public void first() throws Exception {
-        System.out.println("Test C first() start => " + Thread.currentThread().getName());
-        resources.add("first");
-        System.out.println(resources);
-        Thread.sleep(500);
-        System.out.println("Test C first() end => " + Thread.currentThread().getName());
-    }
-
-    @Test
-    @ResourceLock(value = "resources")
-    public void second() throws Exception {
-        System.out.println("Test C second() start => " + Thread.currentThread().getName());
-        resources.add("second");
-        System.out.println(resources);
-        Thread.sleep(500);
-        System.out.println("Test C second() end => " + Thread.currentThread().getName());
-    }
-}
diff --git a/junit5/src/test/resources/junit-platform.properties b/junit5/src/test/resources/junit-platform.properties
deleted file mode 100644
index 42100f85da..0000000000
--- a/junit5/src/test/resources/junit-platform.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-junit.jupiter.execution.parallel.enabled = true
-junit.jupiter.execution.parallel.config.strategy=dynamic
-junit.jupiter.execution.parallel.mode.default = concurrent
-junit.jupiter.execution.parallel.mode.classes.default = concurrent
diff --git a/ksqldb/pom.xml b/ksqldb/pom.xml
index 2f92419d6e..ee4906090f 100644
--- a/ksqldb/pom.xml
+++ b/ksqldb/pom.xml
@@ -39,12 +39,6 @@
             ${awaitility.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
         
             org.testcontainers
             testcontainers
@@ -61,7 +55,6 @@
 
     
         6.2.0
-        3.20.2
         4.1.0
         1.15.3
     
diff --git a/kubernetes/k8s-admission-controller/src/test/resources/logback-test.xml b/kubernetes/k8s-admission-controller/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/kubernetes/k8s-admission-controller/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/language-interop/pom.xml b/language-interop/pom.xml
index f2b0a08969..57dd8bdd9a 100644
--- a/language-interop/pom.xml
+++ b/language-interop/pom.xml
@@ -24,12 +24,6 @@
             commons-exec
             ${commons-exec.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -49,7 +43,6 @@
     
         2.7.2
         1.3
-        3.6.1
     
 
 
\ No newline at end of file
diff --git a/libraries-2/pom.xml b/libraries-2/pom.xml
index 700a0a02d4..409363111a 100644
--- a/libraries-2/pom.xml
+++ b/libraries-2/pom.xml
@@ -39,11 +39,6 @@
             parallel-collectors
             ${parallel-collectors.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-        
         
             io.github.classgraph
             classgraph
@@ -54,7 +49,8 @@
             jbpm-test
             ${jbpm.version}
             
-                
+                
                 
                     junit
                     junit
@@ -127,7 +123,6 @@
 
     
         3.0.7
-        3.6.2
         4.8.28
         6.0.0.Final
         3.9.6
diff --git a/libraries-3/src/test/resources/logback-test.xml b/libraries-3/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/libraries-3/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/libraries-4/pom.xml b/libraries-4/pom.xml
index b16d1f216f..7d19f6d504 100644
--- a/libraries-4/pom.xml
+++ b/libraries-4/pom.xml
@@ -73,11 +73,6 @@
             vavr
             ${vavr.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-        
         
             org.pcollections
             pcollections
@@ -117,7 +112,6 @@
         2.5
         3.2.0-m7
         0.9.0
-        3.6.2
         2.1.2
         3.0.0
         0.6.5
diff --git a/libraries-5/pom.xml b/libraries-5/pom.xml
index a3ca204995..63d1924852 100644
--- a/libraries-5/pom.xml
+++ b/libraries-5/pom.xml
@@ -17,11 +17,6 @@
             spring-web
             ${spring.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-        
         
             org.jooq
             jool
@@ -119,7 +114,6 @@
         3.5.0
         0.9.12
         4.3.8.RELEASE
-        3.6.2
         2.11
         2.5.11
         0.6.5
diff --git a/libraries-6/pom.xml b/libraries-6/pom.xml
index cecc9ca476..3b932f2bd2 100644
--- a/libraries-6/pom.xml
+++ b/libraries-6/pom.xml
@@ -74,11 +74,6 @@
             commons-net
             ${commons-net.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-        
         
             commons-io
             commons-io
@@ -148,13 +143,11 @@
         0.12.1
         1.15
         3.6
-        3.6.2
         3.5-beta72
         3.0
         1.8.1
-        4.4
         8.12.9
         2.4.4
     
 
-
+
\ No newline at end of file
diff --git a/libraries-apache-commons-collections/pom.xml b/libraries-apache-commons-collections/pom.xml
index e2805552e3..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
@@ -24,17 +24,9 @@
             ${org.hamcrest.java-hamcrest.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
-        4.1
-        3.6.2
         2.0.0.0
     
 
diff --git a/libraries-apache-commons/pom.xml b/libraries-apache-commons/pom.xml
index 8fa55c1b0e..9bf6c40e19 100644
--- a/libraries-apache-commons/pom.xml
+++ b/libraries-apache-commons/pom.xml
@@ -13,11 +13,6 @@
     
 
     
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-        
         
             commons-beanutils
             commons-beanutils
@@ -69,7 +64,6 @@
         1.1
         1.9.3
         1.2
-        3.6.2
         1.6
         3.5.2
         3.6.1
diff --git a/libraries-data-2/pom.xml b/libraries-data-2/pom.xml
index 75b2cc962d..b69d9808c4 100644
--- a/libraries-data-2/pom.xml
+++ b/libraries-data-2/pom.xml
@@ -96,11 +96,6 @@
             derive4j
             ${derive4j.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-        
         
             org.slf4j
             slf4j-api
@@ -160,7 +155,6 @@
         4.3.8.RELEASE
         4.0.0
         1.1.0
-        3.6.2
         3.0.0
         2.8.4
         29.0-jre
diff --git a/libraries-data-db/pom.xml b/libraries-data-db/pom.xml
index 20119da8a2..c0f2848705 100644
--- a/libraries-data-db/pom.xml
+++ b/libraries-data-db/pom.xml
@@ -63,7 +63,6 @@
         
             com.h2database
             h2
-            ${h2.version}
         
         
         
diff --git a/libraries-data-io/pom.xml b/libraries-data-io/pom.xml
index 1335ba54d1..713c4342d1 100644
--- a/libraries-data-io/pom.xml
+++ b/libraries-data-io/pom.xml
@@ -95,12 +95,6 @@
             protobuf-java
             ${google-protobuf.version}
         
-        
-            org.assertj
-            assertj-core
-            ${org.assertj.core.version}
-            test
-        
     
 
     
@@ -110,7 +104,6 @@
         4.1
         1.23.0
         v4-rev493-1.21.0
-        3.9.0
         3.3.5
         2.1
         2.8.7
diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml
index 3db34709e7..dd48453a8c 100644
--- a/libraries-data/pom.xml
+++ b/libraries-data/pom.xml
@@ -14,12 +14,6 @@
     
 
     
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
         
             org.apache.kafka
             kafka-streams
@@ -92,6 +86,10 @@
                     commons-codec
                     commons-codec
                 
+                
+                    junit
+                    junit
+                
             
         
         
@@ -104,6 +102,12 @@
             flink-test-utils_2.11
             ${flink.version}
             test
+            
+                
+                    junit
+                    junit
+                
+            
         
         
             org.slf4j
diff --git a/libraries-http/pom.xml b/libraries-http/pom.xml
index a00bb4bd39..0ee5f4b290 100644
--- a/libraries-http/pom.xml
+++ b/libraries-http/pom.xml
@@ -13,11 +13,6 @@
     
 
     
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-        
         
         
             com.squareup.okhttp3
@@ -116,7 +111,6 @@
         2.8.5
         4.5.3
         
-        3.6.2
         4.9.1
         1.23.0
         2.2.0
diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml
index 001ecc54a0..6d3bbcd26c 100644
--- a/libraries-security/pom.xml
+++ b/libraries-security/pom.xml
@@ -48,11 +48,6 @@
             bcpkix-jdk15on
             ${bouncycastle.version}
         
-        
-            org.junit.vintage
-            junit-vintage-engine
-            test
-        
         
             org.passay
             passay
diff --git a/libraries-security/src/test/resources/logback-test.xml b/libraries-security/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/libraries-security/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/libraries-server/pom.xml b/libraries-server/pom.xml
index a9c340b319..66d6295f7c 100644
--- a/libraries-server/pom.xml
+++ b/libraries-server/pom.xml
@@ -19,12 +19,6 @@
             org.eclipse.paho.client.mqttv3
             ${eclipse.paho.client.mqttv3.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-        
         
             org.eclipse.jetty
             jetty-server
@@ -61,12 +55,6 @@
             netty-all
             ${netty.version}
         
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
         
         
             org.apache.tomcat
@@ -102,7 +90,6 @@
     
 
     
-        3.6.2
         4.5.3
         9.4.27.v20200227
         4.1.20.Final
diff --git a/libraries-testing/pom.xml b/libraries-testing/pom.xml
index d7b4a88369..4bc6eba7fc 100644
--- a/libraries-testing/pom.xml
+++ b/libraries-testing/pom.xml
@@ -118,12 +118,6 @@
             ${spring-mock-mvc.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-        
-        
         
             org.hamcrest
             java-hamcrest
@@ -147,12 +141,6 @@
             ${h2.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             net.bytebuddy
             byte-buddy
@@ -206,9 +194,7 @@
         0.8.1
         4.3.8.RELEASE
         4.1.1
-        3.14.0
         2.0.0.0
-        1.4.200
         2.7.0
         3.14.0
         1.8
diff --git a/libraries/pom.xml b/libraries/pom.xml
index 4ecf82aa87..7bef56deb0 100644
--- a/libraries/pom.xml
+++ b/libraries/pom.xml
@@ -45,12 +45,6 @@
             javassist
             ${javaassist.version}
         
-        
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-        
         
             org.javers
             javers-core
@@ -146,12 +140,6 @@
             jmh-core
             ${jmh-core.version}
         
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
         
             info.debatty
             java-lsh
@@ -179,12 +167,6 @@
             google-oauth-client-jetty
             ${google-api.version}
         
-        
-            org.hamcrest
-            hamcrest-all
-            ${hamcrest-all.version}
-            test
-        
     
 
     
@@ -278,7 +260,6 @@
         0.7.0
         3.2.7
         1.2
-        3.6.2
         3.1.0
         2.92
         1.9.26
@@ -292,7 +273,6 @@
         1.15
         1.23.0
         0.9.4.0006L
-        1.3
         3.2.0-m7
         5.1.1
         5.0.2
diff --git a/linux-bash/text/README.md b/linux-bash/text/README.md
index 1c27abc8c6..5423ddf916 100644
--- a/linux-bash/text/README.md
+++ b/linux-bash/text/README.md
@@ -1,4 +1,3 @@
 ### Relevant Articles:
 
-- [Linux Commands – Remove All Text After X](https://www.baeldung.com/linux/remove-text-after-x-in-file)
 - [Linux Commands for Appending Multiple Lines to a File](https://www.baeldung.com/linux/appending-multiple-lines-to-file2)
diff --git a/logback-config.xml b/logback-config.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/logback-config.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/logging-modules/flogger/pom.xml b/logging-modules/flogger/pom.xml
index b96025f277..c814d31767 100644
--- a/logging-modules/flogger/pom.xml
+++ b/logging-modules/flogger/pom.xml
@@ -9,7 +9,6 @@
         com.baeldung
         logging-modules
         1.0.0-SNAPSHOT
-        ../pom.xml
     
 
     
diff --git a/logging-modules/log4j/pom.xml b/logging-modules/log4j/pom.xml
index 864e2253b5..d3c7f8287e 100644
--- a/logging-modules/log4j/pom.xml
+++ b/logging-modules/log4j/pom.xml
@@ -11,7 +11,6 @@
         com.baeldung
         logging-modules
         1.0.0-SNAPSHOT
-        ../pom.xml
     
 
     
diff --git a/logging-modules/log4j2/pom.xml b/logging-modules/log4j2/pom.xml
index aaf60a4216..0b6fa9b902 100644
--- a/logging-modules/log4j2/pom.xml
+++ b/logging-modules/log4j2/pom.xml
@@ -10,7 +10,6 @@
         com.baeldung
         logging-modules
         1.0.0-SNAPSHOT
-        ../pom.xml
     
 
     
diff --git a/logging-modules/logback/pom.xml b/logging-modules/logback/pom.xml
index 512dc9e5a3..b4ee42367f 100644
--- a/logging-modules/logback/pom.xml
+++ b/logging-modules/logback/pom.xml
@@ -11,7 +11,6 @@
         com.baeldung
         logging-modules
         1.0.0-SNAPSHOT
-        ../pom.xml
     
 
     
@@ -75,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/logging-modules/pom.xml b/logging-modules/pom.xml
index 7e358ae490..c7a770891d 100644
--- a/logging-modules/pom.xml
+++ b/logging-modules/pom.xml
@@ -11,7 +11,6 @@
         com.baeldung
         parent-modules
         1.0.0-SNAPSHOT
-        ../pom.xml
     
 
     
diff --git a/lombok/README.md b/lombok/README.md
index bda960a28a..b8073ff621 100644
--- a/lombok/README.md
+++ b/lombok/README.md
@@ -3,6 +3,7 @@
 This module contains articles about Project Lombok.
 
 ### Relevant Articles:
+
 - [Introduction to Project Lombok](https://www.baeldung.com/intro-to-project-lombok)
 - [Using Lombok’s @Builder Annotation](https://www.baeldung.com/lombok-builder)
 - [Using Lombok’s @Getter for Boolean Fields](https://www.baeldung.com/lombok-getter-boolean)
@@ -12,3 +13,5 @@ This module contains articles about Project Lombok.
 - [Setting up Lombok with Eclipse and Intellij](https://www.baeldung.com/lombok-ide)
 - [Using the @Singular Annotation with Lombok Builders](https://www.baeldung.com/lombok-builder-singular)
 - [Using Lombok’s @Accessors Annotation](https://www.baeldung.com/lombok-accessors)
+- [Omitting Getter or Setter in Lombok](https://www.baeldung.com/lombok-omit-getter-setter)
+- [Declaring Val and Var Variables in Lombok](https://www.baeldung.com/java-lombok-val-var)
diff --git a/lombok/pom.xml b/lombok/pom.xml
index c5758ea8df..2daaf9f438 100644
--- a/lombok/pom.xml
+++ b/lombok/pom.xml
@@ -26,12 +26,6 @@
             hibernate-jpa-2.1-api
             ${hibernate-jpa-2.1-api.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
     
 
     
@@ -77,7 +71,6 @@
         1.0.0.Final
         
         1.18.10.0
-        3.8.0
     
 
 
\ No newline at end of file
diff --git a/lombok/src/main/java/com/baeldung/lombok/exclusions/Employee.java b/lombok/src/main/java/com/baeldung/lombok/exclusions/Employee.java
new file mode 100644
index 0000000000..60625747a5
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/exclusions/Employee.java
@@ -0,0 +1,18 @@
+package com.baeldung.lombok.exclusions;
+
+import lombok.AccessLevel;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+@Data
+public class Employee {
+
+    @Setter(AccessLevel.NONE)
+    private String name;
+
+    private String workplace;
+
+    @Getter(AccessLevel.NONE)
+    private int workLength;
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/exclusions/User.java b/lombok/src/main/java/com/baeldung/lombok/exclusions/User.java
new file mode 100644
index 0000000000..52ebeab532
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/exclusions/User.java
@@ -0,0 +1,16 @@
+package com.baeldung.lombok.exclusions;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Setter;
+
+public class User {
+
+    @Setter(AccessLevel.NONE)
+    private  long id;
+
+    private String login;
+
+    @Getter(AccessLevel.NONE)
+    private int age;
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/valvar/ValExample.java b/lombok/src/main/java/com/baeldung/lombok/valvar/ValExample.java
new file mode 100644
index 0000000000..b7ecd95fa8
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/valvar/ValExample.java
@@ -0,0 +1,45 @@
+package com.baeldung.lombok.valvar;
+
+import lombok.val;
+import lombok.var;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+public class ValExample {
+    public Class name() {
+        val name = "name";
+        System.out.println("Name: " + name);
+        return name.getClass();
+    }
+
+    public Class age() {
+        val age = Integer.valueOf(30);
+        System.out.println("Age: " + age);
+        return age.getClass();
+    }
+
+    public Class listOf() {
+        val agenda = new ArrayList();
+        agenda.add("Day 1");
+        System.out.println("Agenda: " + agenda);
+        return agenda.getClass();
+    }
+
+    public Class mapOf() {
+        val books = new HashMap();
+        books.put(1, "Book 1");
+        books.put(2, "Book 2");
+        System.out.println("Books:");
+        for (val entry : books.entrySet()) {
+            System.out.printf("- %d. %s\n", entry.getKey(), entry.getValue());
+        }
+        return books.getClass();
+    }
+
+    public Class compoundTypes(boolean isArray) {
+        val compound = isArray ? new ArrayList() : new HashSet();
+        return compound.getClass();
+    }
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/valvar/VarExample.java b/lombok/src/main/java/com/baeldung/lombok/valvar/VarExample.java
new file mode 100644
index 0000000000..6fabf66590
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/valvar/VarExample.java
@@ -0,0 +1,47 @@
+package com.baeldung.lombok.valvar;
+
+import lombok.var;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+public class VarExample {
+    public String name() {
+        var name = "name";
+        name = "newName";
+        System.out.println("Name: " + name);
+        return name;
+    }
+
+    public Integer age() {
+        var age = Integer.valueOf(30);
+        age = 35;
+        System.out.println("Age: " + age);
+        return age;
+    }
+
+    public ArrayList listOf() {
+        var agenda = new ArrayList();
+        agenda.add("Day 1");
+        agenda = new ArrayList(Arrays.asList("Day 2"));
+        System.out.println("Agenda: " + agenda);
+        return agenda;
+    }
+
+    public Map mapOf() {
+        var books = new HashMap();
+        books.put(1, "Book 1");
+        books.put(2, "Book 2");
+        books = new HashMap();
+        books.put(3, "Book 3");
+        books.put(4, "Book 4");
+
+        System.out.println("Books:");
+        for (var entry : books.entrySet()) {
+            System.out.printf("- %d. %s\n", entry.getKey(), entry.getValue());
+        }
+        return books;
+    }
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/valvar/lombok.config b/lombok/src/main/java/com/baeldung/lombok/valvar/lombok.config
new file mode 100644
index 0000000000..be6d5d3694
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/valvar/lombok.config
@@ -0,0 +1,2 @@
+lombok.var.flagUsage = warning
+lombok.val.flagUsage = warning
\ No newline at end of file
diff --git a/lombok/src/test/java/com/baeldung/lombok/valvar/ValExampleUnitTest.java b/lombok/src/test/java/com/baeldung/lombok/valvar/ValExampleUnitTest.java
new file mode 100644
index 0000000000..b8e1102e18
--- /dev/null
+++ b/lombok/src/test/java/com/baeldung/lombok/valvar/ValExampleUnitTest.java
@@ -0,0 +1,24 @@
+package com.baeldung.lombok.valvar;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class ValExampleUnitTest {
+
+    @Test
+    void whenUsingValWithString_thenTheAssignedClassIsCorrect() {
+        ValExample val = new ValExample();
+        assertThat(val.name()).isEqualTo(String.class);
+        assertThat(val.age()).isEqualTo(Integer.class);
+        assertThat(val.listOf()).isEqualTo(ArrayList.class);
+        assertThat(val.mapOf()).isEqualTo(HashMap.class);
+        assertThat(val.compoundTypes(true)).isEqualTo(ArrayList.class);
+        assertThat(val.compoundTypes(false)).isEqualTo(HashSet.class);
+    }
+
+}
\ No newline at end of file
diff --git a/lombok/src/test/java/com/baeldung/lombok/valvar/VarExampleUnitTest.java b/lombok/src/test/java/com/baeldung/lombok/valvar/VarExampleUnitTest.java
new file mode 100644
index 0000000000..de6f76f8bb
--- /dev/null
+++ b/lombok/src/test/java/com/baeldung/lombok/valvar/VarExampleUnitTest.java
@@ -0,0 +1,20 @@
+package com.baeldung.lombok.valvar;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class VarExampleUnitTest {
+
+    @Test
+    void whenUsingVarWithString_thenTheAssignedClassIsCorrect() {
+        VarExample varExample = new VarExample();
+        assertThat(varExample.name()).isEqualTo("newName");
+        assertThat(varExample.age()).isEqualTo(35);
+        assertThat("Day 2").isIn(varExample.listOf());
+        assertThat(varExample.mapOf()).containsValue("Book 3");
+    }
+
+}
\ No newline at end of file
diff --git a/mapstruct/pom.xml b/mapstruct/pom.xml
index 48687a73b9..4696a46abb 100644
--- a/mapstruct/pom.xml
+++ b/mapstruct/pom.xml
@@ -41,12 +41,6 @@
             lombok-mapstruct-binding
             ${lombok.mapstruct.binding.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -87,7 +81,6 @@
         1.8
         1.8
         0.2.0
-        3.16.1
     
 
 
\ No newline at end of file
diff --git a/maven-archetype/pom.xml b/maven-archetype/pom.xml
index 2eab8ac614..04247f622c 100644
--- a/maven-archetype/pom.xml
+++ b/maven-archetype/pom.xml
@@ -18,7 +18,6 @@
                 ${archetype-packaging.version}
             
         
-        
     
 
     
diff --git a/maven-modules/maven-copy-files/copy-rename-maven-plugin/pom.xml b/maven-modules/maven-copy-files/copy-rename-maven-plugin/pom.xml
index 6feb8284e6..06a44ed4fb 100644
--- a/maven-modules/maven-copy-files/copy-rename-maven-plugin/pom.xml
+++ b/maven-modules/maven-copy-files/copy-rename-maven-plugin/pom.xml
@@ -54,7 +54,7 @@
                 
                 
                     maven-surefire-plugin
-                    2.22.1
+                    2.22.2
                 
                 
                     maven-jar-plugin
diff --git a/maven-modules/maven-copy-files/maven-antrun-plugin/pom.xml b/maven-modules/maven-copy-files/maven-antrun-plugin/pom.xml
index 5168e0e965..b005f4b125 100644
--- a/maven-modules/maven-copy-files/maven-antrun-plugin/pom.xml
+++ b/maven-modules/maven-copy-files/maven-antrun-plugin/pom.xml
@@ -57,7 +57,7 @@
                 
                 
                     maven-surefire-plugin
-                    2.22.1
+                    2.22.2
                 
                 
                     maven-jar-plugin
diff --git a/maven-modules/maven-copy-files/maven-resources-plugin/pom.xml b/maven-modules/maven-copy-files/maven-resources-plugin/pom.xml
index 6829898b45..a49095f528 100644
--- a/maven-modules/maven-copy-files/maven-resources-plugin/pom.xml
+++ b/maven-modules/maven-copy-files/maven-resources-plugin/pom.xml
@@ -54,7 +54,7 @@
                 
                 
                     maven-surefire-plugin
-                    2.22.1
+                    2.22.2
                 
                 
                     maven-jar-plugin
diff --git a/maven-modules/maven-copy-files/pom.xml b/maven-modules/maven-copy-files/pom.xml
index 94bf952361..57d0ddf647 100644
--- a/maven-modules/maven-copy-files/pom.xml
+++ b/maven-modules/maven-copy-files/pom.xml
@@ -51,7 +51,7 @@
                 
                 
                     maven-surefire-plugin
-                    2.22.1
+                    2.22.2
                 
                 
                     maven-jar-plugin
diff --git a/maven-modules/maven-generate-war/pom.xml b/maven-modules/maven-generate-war/pom.xml
index e5b42f5090..56256f58ea 100644
--- a/maven-modules/maven-generate-war/pom.xml
+++ b/maven-modules/maven-generate-war/pom.xml
@@ -1,62 +1,68 @@
 
-
-4.0.0
-
-    org.springframework.boot
-    spring-boot-starter-parent
-    2.5.4
-    
-    
-
-com.baeldung
-maven-generate-war
-0.0.1-SNAPSHOT
-war
-maven-generate-war
-Spring boot project to demonstrate war file generation
-
-    11
-
-
-    
-        org.springframework.boot
-        spring-boot-starter-thymeleaf
-    
-    
-        org.springframework.boot
-        spring-boot-starter-web
-    
-    
-        org.springframework.boot
-        spring-boot-starter-tomcat
-        provided
-    
-    
-        org.springframework.boot
-        spring-boot-starter-test
-        test
-    
-
-
-    maven-generate-war
-    
-        
-            maven-war-plugin
-            3.3.1
-            
-                
-                    
-                        additional_resources
-                    
-                
-                
-                    
-                        true
-                    
-                
-            
-        
-    
-
-
+
+    4.0.0
+    com.baeldung
+    maven-generate-war
+    0.0.1-SNAPSHOT
+    war
+    maven-generate-war
+    Spring boot project to demonstrate war file generation
 
+    
+        org.springframework.boot
+        spring-boot-starter-parent
+        2.5.4
+        
+        
+    
+
+    
+        
+            org.springframework.boot
+            spring-boot-starter-thymeleaf
+        
+        
+            org.springframework.boot
+            spring-boot-starter-web
+        
+        
+            org.springframework.boot
+            spring-boot-starter-tomcat
+            provided
+        
+        
+            org.springframework.boot
+            spring-boot-starter-test
+            test
+        
+    
+
+    
+        maven-generate-war
+        
+            
+                maven-war-plugin
+                3.3.1
+                
+                    
+                        
+                            additional_resources
+                        
+                    
+                    
+                        
+                            true
+                        
+                    
+                
+            
+        
+    
+
+    
+        11
+    
+
+
\ No newline at end of file
diff --git a/maven-modules/maven-integration-test/pom.xml b/maven-modules/maven-integration-test/pom.xml
index 4283baf63b..56c243e3c5 100644
--- a/maven-modules/maven-integration-test/pom.xml
+++ b/maven-modules/maven-integration-test/pom.xml
@@ -26,12 +26,6 @@
             jersey-hk2
             ${jersey.version}
         
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
     
 
     
@@ -92,8 +86,8 @@
                 
             
             
+                org.apache.maven.plugins
                 maven-surefire-plugin
-                ${maven.surefire.version}
                 
                     
                         DataTest.java
@@ -177,8 +171,8 @@
             
                 
                     
+                        org.apache.maven.plugins
                         maven-surefire-plugin
-                        ${maven.surefire.version}
                         
                             
                                 DataTest.java
@@ -223,8 +217,8 @@
             
                 
                     
+                        org.apache.maven.plugins
                         maven-surefire-plugin
-                        ${maven.surefire.version}
                         
                             
                                 integration-test
@@ -275,7 +269,6 @@
     
         3.0.2
         3.8.0
-        2.22.0
         2.22.0
         1.1
         3.0.0
diff --git a/maven-modules/maven-multi-source/pom.xml b/maven-modules/maven-multi-source/pom.xml
index 65e00419af..d9863b31a9 100644
--- a/maven-modules/maven-multi-source/pom.xml
+++ b/maven-modules/maven-multi-source/pom.xml
@@ -54,8 +54,8 @@
             
                 
                     
+                        org.apache.maven.plugins
                         maven-surefire-plugin
-                        ${maven.surefire.version}
                         
                             
                                 integration-test
@@ -81,7 +81,6 @@
     
         3.0.2
         3.8.0
-        2.22.0
         2.22.0
         1.1
         3.0.0
diff --git a/maven-modules/maven-parent-pom-resolution/aggregator/module1/pom.xml b/maven-modules/maven-parent-pom-resolution/aggregator/module1/pom.xml
index e1f411db2f..67e60fb386 100644
--- a/maven-modules/maven-parent-pom-resolution/aggregator/module1/pom.xml
+++ b/maven-modules/maven-parent-pom-resolution/aggregator/module1/pom.xml
@@ -13,4 +13,4 @@
         
     
 
-
+
\ No newline at end of file
diff --git a/maven-modules/maven-parent-pom-resolution/aggregator/module2/module3/pom.xml b/maven-modules/maven-parent-pom-resolution/aggregator/module2/module3/pom.xml
index d983f35e3e..f4e3e81e7d 100644
--- a/maven-modules/maven-parent-pom-resolution/aggregator/module2/module3/pom.xml
+++ b/maven-modules/maven-parent-pom-resolution/aggregator/module2/module3/pom.xml
@@ -15,4 +15,4 @@
         ../../pom.xml
     
 
-
+
\ No newline at end of file
diff --git a/maven-modules/maven-parent-pom-resolution/aggregator/module2/pom.xml b/maven-modules/maven-parent-pom-resolution/aggregator/module2/pom.xml
index 48c1ebab9d..9b36ef37fb 100644
--- a/maven-modules/maven-parent-pom-resolution/aggregator/module2/pom.xml
+++ b/maven-modules/maven-parent-pom-resolution/aggregator/module2/pom.xml
@@ -18,4 +18,4 @@
         module3
     
 
-
+
\ No newline at end of file
diff --git a/maven-modules/maven-parent-pom-resolution/aggregator/pom.xml b/maven-modules/maven-parent-pom-resolution/aggregator/pom.xml
index 8f6e3453a5..dde2c46370 100644
--- a/maven-modules/maven-parent-pom-resolution/aggregator/pom.xml
+++ b/maven-modules/maven-parent-pom-resolution/aggregator/pom.xml
@@ -19,4 +19,4 @@
         module2
     
 
-
+
\ No newline at end of file
diff --git a/maven-modules/maven-plugins/pom.xml b/maven-modules/maven-plugins/pom.xml
index 29b3b550ea..4aa295c8a8 100644
--- a/maven-modules/maven-plugins/pom.xml
+++ b/maven-modules/maven-plugins/pom.xml
@@ -84,8 +84,8 @@
             
                 
                     
+                        org.apache.maven.plugins
                         maven-surefire-plugin
-                        ${maven.surefire.version}
                         
                             
                                 DataTest.java
@@ -105,8 +105,8 @@
             
                 
                     
+                        org.apache.maven.plugins
                         maven-surefire-plugin
-                        ${maven.surefire.version}
                         
                             
                                 integration-test
@@ -132,7 +132,6 @@
     
         3.0.2
         3.8.0
-        2.22.0
         2.22.0
         1.1
         3.0.0
diff --git a/maven-modules/maven-properties/pom.xml b/maven-modules/maven-properties/pom.xml
index b3169a7fb0..88e13a0fb8 100644
--- a/maven-modules/maven-properties/pom.xml
+++ b/maven-modules/maven-properties/pom.xml
@@ -14,15 +14,6 @@
         ../..
     
 
-    
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
-    
-
     
         
             
diff --git a/maven-modules/maven-surefire-plugin/pom.xml b/maven-modules/maven-surefire-plugin/pom.xml
index 98decc69e1..840ffab077 100644
--- a/maven-modules/maven-surefire-plugin/pom.xml
+++ b/maven-modules/maven-surefire-plugin/pom.xml
@@ -14,4 +14,4 @@
         0.0.1-SNAPSHOT
     
 
-
+
\ No newline at end of file
diff --git a/maven-modules/pom.xml b/maven-modules/pom.xml
index 0aadb873e5..e09283efb4 100644
--- a/maven-modules/pom.xml
+++ b/maven-modules/pom.xml
@@ -37,7 +37,7 @@
         plugin-management
         maven-surefire-plugin
         maven-parent-pom-resolution
-        maven-dependency    
+        maven-dependency
     
 
     
@@ -57,8 +57,4 @@
         
     
 
-    
-        5.8.1
-    
-
 
\ No newline at end of file
diff --git a/metrics/pom.xml b/metrics/pom.xml
index 0ba590ceec..6ac1761ca0 100644
--- a/metrics/pom.xml
+++ b/metrics/pom.xml
@@ -75,12 +75,6 @@
             metrics-aspectj-deps
             ${metrics-aspectj.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             com.netflix.spectator
             spectator-api
@@ -95,7 +89,6 @@
         1.7.1
         
         2.0.7.RELEASE
-        3.11.1
         1.1.0
     
 
diff --git a/micronaut/pom.xml b/micronaut/pom.xml
index f36f565a94..019bd6ab29 100644
--- a/micronaut/pom.xml
+++ b/micronaut/pom.xml
@@ -64,12 +64,6 @@
             ${logback.version}
             runtime
         
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
         
             io.projectreactor
             reactor-core
diff --git a/mustache/pom.xml b/mustache/pom.xml
index db72e693c1..faa8bfd8a1 100644
--- a/mustache/pom.xml
+++ b/mustache/pom.xml
@@ -20,10 +20,6 @@
             compiler
             ${mustache.compiler.api.version}
         
-        
-            org.assertj
-            assertj-core
-        
         
             org.springframework.boot
             spring-boot-starter-web
diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml
index 8e8dbba54d..42081fa115 100644
--- a/parent-boot-2/pom.xml
+++ b/parent-boot-2/pom.xml
@@ -58,11 +58,6 @@
                         
                     
                 
-                
-                    org.apache.maven.plugins
-                    maven-surefire-plugin
-                    ${maven-surefire-plugin.version}
-                
             
         
     
@@ -97,7 +92,6 @@
         1.9.1
         
         3.4.0
-        2.22.2
     
 
 
\ No newline at end of file
diff --git a/parent-java/pom.xml b/parent-java/pom.xml
index 103b5f179c..808eed1c44 100644
--- a/parent-java/pom.xml
+++ b/parent-java/pom.xml
@@ -1,7 +1,7 @@
 
 
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     4.0.0
     parent-java
     0.0.1-SNAPSHOT
@@ -43,7 +43,6 @@
     
         31.0.1-jre
         2.3.7
-        2.2
     
 
 
\ No newline at end of file
diff --git a/parent-spring-4/pom.xml b/parent-spring-4/pom.xml
index e0e91cec9a..a36e1060ed 100644
--- a/parent-spring-4/pom.xml
+++ b/parent-spring-4/pom.xml
@@ -21,12 +21,6 @@
             spring-core
             ${spring.version}
         
-        
-            org.junit.jupiter
-            junit-jupiter-engine
-            ${junit-jupiter.version}
-            test
-        
     
 
     
diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml
index c4446ddda8..175e8d58f9 100644
--- a/parent-spring-5/pom.xml
+++ b/parent-spring-5/pom.xml
@@ -21,17 +21,11 @@
             spring-core
             ${spring.version}
         
-        
-            org.junit.jupiter
-            junit-jupiter-engine
-            ${junit-jupiter.version}
-            test
-        
     
 
     
-        5.3.9
-        5.2.3.RELEASE
+        5.3.13
+        5.6.0
         1.5.10.RELEASE
     
 
diff --git a/patterns/clean-architecture/pom.xml b/patterns/clean-architecture/pom.xml
index c36f9b83af..7b244e4a5e 100644
--- a/patterns/clean-architecture/pom.xml
+++ b/patterns/clean-architecture/pom.xml
@@ -29,11 +29,6 @@
             org.springframework.boot
             spring-boot-starter-data-jpa
         
-        
-            org.junit.jupiter
-            junit-jupiter-engine
-            test
-        
         
             org.springframework.boot
             spring-boot-starter-test
@@ -54,14 +49,6 @@
             org.junit.platform
             junit-platform-engine
         
-        
-            org.junit.jupiter
-            junit-jupiter-engine
-        
-        
-            org.junit.jupiter
-            junit-jupiter-api
-        
         
             org.junit.platform
             junit-platform-runner
@@ -71,7 +58,6 @@
 
     
         
-
             
                 org.springframework.boot
                 spring-boot-maven-plugin
diff --git a/patterns/design-patterns-architectural/pom.xml b/patterns/design-patterns-architectural/pom.xml
index 11194a9c92..fe7bd38df8 100644
--- a/patterns/design-patterns-architectural/pom.xml
+++ b/patterns/design-patterns-architectural/pom.xml
@@ -30,12 +30,6 @@
             rest-assured
             ${rest-assured.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             org.hibernate
             hibernate-core
@@ -50,7 +44,6 @@
     
 
     
-        3.9.1
         5.2.16.Final
         6.0.6
         2.5.3
diff --git a/patterns/design-patterns-behavioral-2/pom.xml b/patterns/design-patterns-behavioral-2/pom.xml
index f123a8f2f5..da29575526 100644
--- a/patterns/design-patterns-behavioral-2/pom.xml
+++ b/patterns/design-patterns-behavioral-2/pom.xml
@@ -14,17 +14,4 @@
         1.0.0-SNAPSHOT
     
 
-    
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-    
-
-    
-        3.12.2
-    
-
 
\ No newline at end of file
diff --git a/patterns/design-patterns-behavioral/pom.xml b/patterns/design-patterns-behavioral/pom.xml
index bc032a0f8f..3ddbd6f0fc 100644
--- a/patterns/design-patterns-behavioral/pom.xml
+++ b/patterns/design-patterns-behavioral/pom.xml
@@ -36,18 +36,11 @@
             commons-lang3
             ${commons-lang3.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
     
 
     
         16.0.2
         3.0.1
-        3.9.1
     
 
 
\ No newline at end of file
diff --git a/patterns/design-patterns-creational/pom.xml b/patterns/design-patterns-creational/pom.xml
index 21bc13c21c..de854d260e 100644
--- a/patterns/design-patterns-creational/pom.xml
+++ b/patterns/design-patterns-creational/pom.xml
@@ -26,18 +26,11 @@
             jsr305
             ${javax.annotations.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
     
 
     
         2.4.1
         3.0.2
-        3.9.1
     
 
 
\ No newline at end of file
diff --git a/patterns/dip/pom.xml b/patterns/dip/pom.xml
index 44062aaede..3618791b97 100644
--- a/patterns/dip/pom.xml
+++ b/patterns/dip/pom.xml
@@ -14,17 +14,4 @@
         1.0.0-SNAPSHOT
     
 
-    
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
-    
-
-    
-        3.12.1
-    
-
 
\ No newline at end of file
diff --git a/patterns/simplehexagonalexample/pom.xml b/patterns/simplehexagonalexample/pom.xml
deleted file mode 100644
index 31e829b7dc..0000000000
--- a/patterns/simplehexagonalexample/pom.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-    4.0.0
-    1.0.0-SNAPSHOT
-    simple-hexagonal-example
-    simple-hexagonal-example
-
-    
-        com.baeldung
-        parent-boot-2
-        0.0.1-SNAPSHOT
-        ../../parent-boot-2
-    
-
-    
-        
-            org.springframework.boot
-            spring-boot-starter-web
-        
-    
-
-    
-        
-            
-                org.springframework.boot
-                spring-boot-maven-plugin
-            
-        
-    
-
-
\ No newline at end of file
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/DailyQuoteMain.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/DailyQuoteMain.java
deleted file mode 100644
index de8b2f4793..0000000000
--- a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/DailyQuoteMain.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.baeldung.simplehexagonalex;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.CommandLineRunner;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-import com.baeldung.simplehexagonalex.controller.QuoteCliController;
-import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
-
-@SpringBootApplication
-public class DailyQuoteMain implements CommandLineRunner {
-
-    private static final Logger LOG = LoggerFactory.getLogger(DailyQuoteMain.class);
-    @Autowired
-    private QuoteCliController quoteCliController;
-
-    public static void main(final String[] args) {
-
-        SpringApplication.run(DailyQuoteMain.class, args);
-    }
-
-    @Override
-    public void run(String... args) throws Exception {
-        
-        QuoteOfTheDay quoteOfTheDay = quoteCliController.getQuote("cliController");
-        
-        LOG.info(quoteOfTheDay.toString());
-    }
-}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteCliController.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteCliController.java
deleted file mode 100644
index 9ecb2bf822..0000000000
--- a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteCliController.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.baeldung.simplehexagonalex.controller;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
-import com.baeldung.simplehexagonalex.domain.service.QuoteService;
-
-@Component
-public class QuoteCliController {
-
-    private static final Logger LOG = LoggerFactory.getLogger(QuoteCliController.class);
-
-    @Autowired
-    private QuoteService quoteService;
-
-    public QuoteOfTheDay getQuote(String userId) {
-
-        LOG.info("Getting quote");
-        return quoteService.getQuote(userId);
-    }
-}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteRestController.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteRestController.java
deleted file mode 100644
index 061cff8cec..0000000000
--- a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteRestController.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.baeldung.simplehexagonalex.controller;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
-import com.baeldung.simplehexagonalex.domain.service.QuoteService;
-
-@RestController
-@RequestMapping("/quote")
-public class QuoteRestController {
-
-    @Autowired
-    private QuoteService quoteService;
-
-    @GetMapping(path = "/{userId}")
-    public QuoteOfTheDay getEmployee(@PathVariable("userId") String userId) {
-        return quoteService.getQuote(userId);
-    }
-
-}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/QuoteOfTheDay.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/QuoteOfTheDay.java
deleted file mode 100644
index c74c224c70..0000000000
--- a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/QuoteOfTheDay.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.baeldung.simplehexagonalex.domain;
-
-import java.util.Objects;
-
-public class QuoteOfTheDay {
-
-    private String userName;
-    private String quote;
-    private String provider;
-
-    public String getUserName() {
-        return userName;
-    }
-
-    public void setUserName(String userName) {
-        this.userName = userName;
-    }
-
-    public String getQuote() {
-        return quote;
-    }
-
-    public void setQuote(String quote) {
-        this.quote = quote;
-    }
-
-    public String getProvider() {
-        return provider;
-    }
-
-    public void setProvider(String provider) {
-        this.provider = provider;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(provider, quote, userName);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        QuoteOfTheDay other = (QuoteOfTheDay) obj;
-        return Objects.equals(provider, other.provider) && Objects.equals(quote, other.quote) && Objects.equals(userName, other.userName);
-    }
-
-    @Override
-    public String toString() {
-        return "QuoteOfTheDay [userName=" + userName + ", quote=" + quote + ", provider=" + provider + "]";
-    }
-}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/repository/QuoteOfTheDayFromProvider.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/repository/QuoteOfTheDayFromProvider.java
deleted file mode 100644
index 7e70cebd12..0000000000
--- a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/repository/QuoteOfTheDayFromProvider.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.baeldung.simplehexagonalex.domain.repository;
-
-import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
-
-public interface QuoteOfTheDayFromProvider {
-
-    QuoteOfTheDay getQuote();
-}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteAggregator.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteAggregator.java
deleted file mode 100644
index 16f7015ace..0000000000
--- a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteAggregator.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.baeldung.simplehexagonalex.domain.service;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
-import com.baeldung.simplehexagonalex.domain.repository.QuoteOfTheDayFromProvider;
-
-@Service
-public class QuoteAggregator implements QuoteService {
-
-    @Autowired
-    private QuoteOfTheDayFromProvider quoteOfTheDayFromProvider;
-
-    @Override
-    public QuoteOfTheDay getQuote(String userName) {
-
-        QuoteOfTheDay quoteOfTheDay = quoteOfTheDayFromProvider.getQuote();
-        quoteOfTheDay.setUserName(userName);
-        return quoteOfTheDay;
-    }
-}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteService.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteService.java
deleted file mode 100644
index 300387a41d..0000000000
--- a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteService.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.baeldung.simplehexagonalex.domain.service;
-
-import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
-
-public interface QuoteService {
-
-    QuoteOfTheDay getQuote(String userName);
-}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuote.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuote.java
deleted file mode 100644
index 0cbbc60726..0000000000
--- a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuote.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package com.baeldung.simplehexagonalex.repository.primary.quoteadapter;
-
-import java.util.List;
-import java.util.Objects;
-
-public class ProviderQuote {
-
-    private String quote;
-    private String length;
-    private String author;
-    private List tags;
-    private String category;
-    private String language;
-    private String date;
-    private String permalink;
-    private String id;
-    private String background;
-    private String title;
-
-    public ProviderQuote() {
-
-    }
-
-    public ProviderQuote(String quote, String length, String author, List tags, String category, String language, String date, String permalink, String id, String background, String title) {
-        super();
-        this.quote = quote;
-        this.length = length;
-        this.author = author;
-        this.tags = tags;
-        this.category = category;
-        this.language = language;
-        this.date = date;
-        this.permalink = permalink;
-        this.id = id;
-        this.background = background;
-        this.title = title;
-    }
-
-    public String getQuote() {
-        return quote;
-    }
-
-    public String getLength() {
-        return length;
-    }
-
-    public String getAuthor() {
-        return author;
-    }
-
-    public List getTags() {
-        return tags;
-    }
-
-    public String getCategory() {
-        return category;
-    }
-
-    public String getLanguage() {
-        return language;
-    }
-
-    public String getDate() {
-        return date;
-    }
-
-    public String getPermalink() {
-        return permalink;
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public String getBackground() {
-        return background;
-    }
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(id);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        ProviderQuote other = (ProviderQuote) obj;
-        return Objects.equals(id, other.id);
-    }
-
-    @Override
-    public String toString() {
-        return "TheysaysoQuote [quote=" + quote + ", length=" + length + ", " + "author=" + author + ", tags=" + tags + ", category=" + category + ", language=" + language + ", date=" + date + ", permalink=" + permalink + ", id=" + id + ", background="
-            + background + ", title=" + title + "]";
-    }
-}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteAdapter.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteAdapter.java
deleted file mode 100644
index ded08f7b18..0000000000
--- a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteAdapter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.baeldung.simplehexagonalex.repository.primary.quoteadapter;
-
-import java.net.URI;
-
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Primary;
-import org.springframework.core.env.Environment;
-import org.springframework.stereotype.Service;
-
-import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
-import com.baeldung.simplehexagonalex.domain.repository.QuoteOfTheDayFromProvider;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-@Service("providerQuoteAdapter")
-@Primary
-public class ProviderQuoteAdapter implements QuoteOfTheDayFromProvider {
-
-    @Autowired
-    private Environment env;
-
-    @Override
-    public QuoteOfTheDay getQuote() {
-
-        QuoteOfTheDay quoteOfTheDay = new QuoteOfTheDay();
-        ProviderQuoteEnvelope providerQuote;
-        try {
-            providerQuote = getProviderQuote();
-            quoteOfTheDay.setQuote(providerQuote.getContents()
-                .getQuotes()
-                .get(0)
-                .getQuote());
-            quoteOfTheDay.setProvider(providerQuote.getCopyright()
-                .getUrl());
-        } catch (Exception e) {
-            quoteOfTheDay.setQuote("Unable to get the quote");
-            quoteOfTheDay.setProvider("none");
-        }
-        return quoteOfTheDay;
-    }
-
-    private ProviderQuoteEnvelope getProviderQuote() throws Exception {
-
-        HttpGet request = new HttpGet(URI.create(env.getProperty("theysayso.quote.provider.url")));
-        CloseableHttpClient client = HttpClients.createDefault();
-        CloseableHttpResponse response = client.execute(request);
-        ProviderQuoteEnvelope providersQuote = new ObjectMapper().readValue(response.getEntity()
-            .getContent(), ProviderQuoteEnvelope.class);
-        return providersQuote;
-    }
-}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteEnvelope.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteEnvelope.java
deleted file mode 100644
index 611549f23d..0000000000
--- a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteEnvelope.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.baeldung.simplehexagonalex.repository.primary.quoteadapter;
-
-import java.util.List;
-
-public class ProviderQuoteEnvelope {
-
-    private Success success;
-    private Contents contents;
-    private String baseurl;
-    private Copyright copyright;
-
-    public ProviderQuoteEnvelope() {
-        
-    }
-    
-    public ProviderQuoteEnvelope(Success success, Contents contents, String baseurl, Copyright copyright) {
-        super();
-        this.success = success;
-        this.contents = contents;
-        this.baseurl = baseurl;
-        this.copyright = copyright;
-    }
-
-    public Success getSuccess() {
-        return success;
-    }
-
-    public Contents getContents() {
-        return contents;
-    }
-
-    public String getBaseurl() {
-        return baseurl;
-    }
-
-    public Copyright getCopyright() {
-        return copyright;
-    }
-    
-    public class Contents {
-        private List quotes;
-
-         public List getQuotes() {
-            return quotes;
-        }
-    }
-
-    public class Copyright {
-        private int year;
-        private String url;
- 
-        public int getYear() {
-            return year;
-        }
-
-        public String getUrl() {
-            return url;
-        }
-    }
-
-    public class Success {
-        private int total;
-
-        public int getTotal() {
-            return total;
-        }
-    }
-}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/reposity/mock/quoteadapter/MockQuoteAdapter.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/reposity/mock/quoteadapter/MockQuoteAdapter.java
deleted file mode 100644
index 54c28fc94e..0000000000
--- a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/reposity/mock/quoteadapter/MockQuoteAdapter.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.baeldung.simplehexagonalex.reposity.mock.quoteadapter;
-
-import org.springframework.stereotype.Service;
-
-import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
-import com.baeldung.simplehexagonalex.domain.repository.QuoteOfTheDayFromProvider;
-
-@Service
-public class MockQuoteAdapter implements QuoteOfTheDayFromProvider {
-
-    @Override
-    public QuoteOfTheDay getQuote() {
-
-        QuoteOfTheDay quoteOfTheDay = new QuoteOfTheDay();
-        quoteOfTheDay.setQuote("Mock quote of the day");
-        quoteOfTheDay.setProvider("Mock Provider");
-
-        return quoteOfTheDay;
-    }
-}
diff --git a/patterns/simplehexagonalexample/src/main/resources/application.properties b/patterns/simplehexagonalexample/src/main/resources/application.properties
deleted file mode 100644
index dd9413bfd5..0000000000
--- a/patterns/simplehexagonalexample/src/main/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-theysayso.quote.provider.url=https://quotes.rest/qod?language=en
\ No newline at end of file
diff --git a/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/MockAccessProviderUnitTest.java b/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/MockAccessProviderUnitTest.java
deleted file mode 100644
index 602f7ea5d4..0000000000
--- a/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/MockAccessProviderUnitTest.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.baeldung.simplehexagonalex.repository.primaryQuoteProvider;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-import org.junit.jupiter.api.Test;
-
-import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
-import com.baeldung.simplehexagonalex.reposity.mock.quoteadapter.MockQuoteAdapter;
-
-public class MockAccessProviderUnitTest {
-
-    @Test
-    public void givenProvider_whenConnect_thenResponse() throws Exception {
-
-        MockQuoteAdapter provider = new MockQuoteAdapter();
-        QuoteOfTheDay quote = provider.getQuote();
-        assertNotNull(quote);
-        assertEquals("Mock quote of the day", quote.getQuote());
-        assertEquals("Mock Provider", quote.getProvider());
-    }
-}
diff --git a/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/PrimaryAccessProviderIntegrationTest.java b/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/PrimaryAccessProviderIntegrationTest.java
deleted file mode 100644
index 47e1dde136..0000000000
--- a/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/PrimaryAccessProviderIntegrationTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.baeldung.simplehexagonalex.repository.primaryQuoteProvider;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.boot.test.context.SpringBootTest;
-
-import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
-import com.baeldung.simplehexagonalex.domain.repository.QuoteOfTheDayFromProvider;
-
-@SpringBootTest
-public class PrimaryAccessProviderIntegrationTest {
-
-    @Autowired
-    @Qualifier("providerQuoteAdapter")
-    QuoteOfTheDayFromProvider provider;
-
-    @Test
-    public void whenQuoteProvider_thenResponse() throws Exception {
-
-        QuoteOfTheDay quote = provider.getQuote();
-        assertNotNull(quote);
-        assertThat(quote.getProvider()).contains("theysaidso");
-    }
-}
diff --git a/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/QuoteRequestIntegrationTest.java b/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/QuoteRequestIntegrationTest.java
deleted file mode 100644
index 552b5d51c2..0000000000
--- a/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/QuoteRequestIntegrationTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.baeldung.simplehexagonalex.repository.primaryQuoteProvider;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.MvcResult;
-
-@SpringBootTest
-@AutoConfigureMockMvc
-public class QuoteRequestIntegrationTest {
-
-    @Autowired
-    private MockMvc mockMvc;
-
-    @Test
-    public void whenRestQuoteRequest_thenResponse() throws Exception {
-
-        MvcResult result = this.mockMvc.perform(get("/quote/tester"))
-            .andDo(print())
-            .andExpect(status().isOk())
-            .andReturn();
-
-        String content = result.getResponse()
-            .getContentAsString();
-        
-        assertThat(content).contains("tester");
-        assertThat(content).contains("theysaidso");
-    }
-}
\ No newline at end of file
diff --git a/patterns/simplehexagonalexample/src/test/resources/application.properties b/patterns/simplehexagonalexample/src/test/resources/application.properties
deleted file mode 100644
index dd9413bfd5..0000000000
--- a/patterns/simplehexagonalexample/src/test/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-theysayso.quote.provider.url=https://quotes.rest/qod?language=en
\ No newline at end of file
diff --git a/persistence-modules/apache-derby/README.md b/persistence-modules/apache-derby/README.md
new file mode 100644
index 0000000000..502115da5e
--- /dev/null
+++ b/persistence-modules/apache-derby/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- [Getting Started With Apache Derby](https://www.baeldung.com/java-apache-derby)
diff --git a/persistence-modules/apache-derby/pom.xml b/persistence-modules/apache-derby/pom.xml
index 7728bd4d8f..f7f5ca7503 100644
--- a/persistence-modules/apache-derby/pom.xml
+++ b/persistence-modules/apache-derby/pom.xml
@@ -1,15 +1,15 @@
 
 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    4.0.0
+    apache-derby
+
     
         persistence-modules
         com.baeldung
         1.0.0-SNAPSHOT
     
-    4.0.0
-
-    apache-derby
 
     
         
@@ -18,15 +18,12 @@
             derby
             10.13.1.1
         
-
         
         
             org.apache.derby
             derbyclient
             10.13.1.1
         
-
     
 
-
 
\ No newline at end of file
diff --git a/persistence-modules/core-java-persistence-2/pom.xml b/persistence-modules/core-java-persistence-2/pom.xml
index 15676bf03e..780c1fcfca 100644
--- a/persistence-modules/core-java-persistence-2/pom.xml
+++ b/persistence-modules/core-java-persistence-2/pom.xml
@@ -44,7 +44,6 @@
     
 
     
-        1.4.200
         8.4.1.jre11
         10.2.0.4.0
         8.0.22
diff --git a/persistence-modules/core-java-persistence/pom.xml b/persistence-modules/core-java-persistence/pom.xml
index 96f8cef310..5cc1df483f 100644
--- a/persistence-modules/core-java-persistence/pom.xml
+++ b/persistence-modules/core-java-persistence/pom.xml
@@ -22,12 +22,6 @@
             ${postgresql.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             com.h2database
             h2
@@ -61,8 +55,6 @@
     
 
     
-        1.4.200
-        3.10.0
         2.4.0
         3.2.0
         0.9.5.2
diff --git a/persistence-modules/deltaspike/pom.xml b/persistence-modules/deltaspike/pom.xml
index 5003ef9daf..f151255948 100644
--- a/persistence-modules/deltaspike/pom.xml
+++ b/persistence-modules/deltaspike/pom.xml
@@ -18,8 +18,8 @@
 
     
         
-            
+            
             
                 junit
                 junit
diff --git a/persistence-modules/hibernate-annotations/pom.xml b/persistence-modules/hibernate-annotations/pom.xml
index e5c19915a4..634cd64cca 100644
--- a/persistence-modules/hibernate-annotations/pom.xml
+++ b/persistence-modules/hibernate-annotations/pom.xml
@@ -45,7 +45,6 @@
 
     
         5.4.7.Final
-        1.4.200
         true
         2.1.7.RELEASE
         5.4.7.Final
diff --git a/persistence-modules/hibernate-enterprise/pom.xml b/persistence-modules/hibernate-enterprise/pom.xml
index 1d9ebfc156..18d1a4f3a6 100644
--- a/persistence-modules/hibernate-enterprise/pom.xml
+++ b/persistence-modules/hibernate-enterprise/pom.xml
@@ -19,12 +19,6 @@
             hibernate-core
             ${hibernate.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             com.h2database
             h2
@@ -87,7 +81,6 @@
         5.3.7.Final
         6.0.6
         2.2.3
-        3.8.0
         0.9
         2.3.4
     
diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/lazyinitialization/HibernateUtil.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/lazyinitialization/HibernateUtil.java
index b84a512fd4..911e3f7540 100644
--- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/lazyinitialization/HibernateUtil.java
+++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/lazyinitialization/HibernateUtil.java
@@ -24,7 +24,7 @@ public class HibernateUtil {
                 settings.put(Environment.USER, "sa");
                 settings.put(Environment.PASS, "");
                 settings.put(Environment.DIALECT, "org.hibernate.dialect.HSQLDialect");
-                settings.put(Environment.SHOW_SQL, "true");
+                settings.put(Environment.SHOW_SQL, "false");
                 settings.put(Environment.HBM2DDL_AUTO, "update");
                 configuration.setProperties(settings);
                 configuration.addAnnotatedClass(User.class);
diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/HibernateUtil.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/HibernateUtil.java
index a40279661f..ace9e57d84 100644
--- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/HibernateUtil.java
+++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/HibernateUtil.java
@@ -27,7 +27,7 @@ public class HibernateUtil {
                 settings.put(Environment.USER, "sa");
                 settings.put(Environment.PASS, "");
                 settings.put(Environment.DIALECT, "org.hibernate.dialect.HSQLDialect");
-                settings.put(Environment.SHOW_SQL, "true");
+                settings.put(Environment.SHOW_SQL, "false");
                 settings.put(Environment.USE_SQL_COMMENTS, "true");
                 settings.put(Environment.HBM2DDL_AUTO, "update");
                 configuration.setProperties(settings);
diff --git a/persistence-modules/hibernate-jpa/pom.xml b/persistence-modules/hibernate-jpa/pom.xml
index 85bfdac07f..7779a85e79 100644
--- a/persistence-modules/hibernate-jpa/pom.xml
+++ b/persistence-modules/hibernate-jpa/pom.xml
@@ -45,12 +45,6 @@
             spring-boot-starter-test
             ${spring-boot.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             com.h2database
             h2
@@ -92,7 +86,6 @@
         5.3.7.Final
         8.0.13
         2.2.3
-        3.8.0
         2.1.7.RELEASE
     
 
diff --git a/persistence-modules/hibernate-jpa/src/test/resources/hibernate-pessimistic-locking.properties b/persistence-modules/hibernate-jpa/src/test/resources/hibernate-pessimistic-locking.properties
index 4f1ff5e93a..342f7b0bf5 100644
--- a/persistence-modules/hibernate-jpa/src/test/resources/hibernate-pessimistic-locking.properties
+++ b/persistence-modules/hibernate-jpa/src/test/resources/hibernate-pessimistic-locking.properties
@@ -1,5 +1,5 @@
 hibernate.connection.driver_class=org.h2.Driver
-hibernate.connection.url=jdbc:h2:mem:mydb3;DB_CLOSE_DELAY=-1;LOCK_TIMEOUT=100;MVCC=FALSE
+hibernate.connection.url=jdbc:h2:mem:mydb3;DB_CLOSE_DELAY=-1;LOCK_TIMEOUT=100
 hibernate.connection.username=sa
 hibernate.connection.autocommit=true
 hibernate.dialect=org.hibernate.dialect.H2Dialect
diff --git a/persistence-modules/hibernate-libraries/pom.xml b/persistence-modules/hibernate-libraries/pom.xml
index 7d552b262d..81f084e102 100644
--- a/persistence-modules/hibernate-libraries/pom.xml
+++ b/persistence-modules/hibernate-libraries/pom.xml
@@ -62,12 +62,6 @@
             ${hibernate.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             mysql
             mysql-connector-java
@@ -166,7 +160,6 @@
     
 
     
-        3.15.0
         1.6
         29.0-jre
         2.9.7
diff --git a/persistence-modules/hibernate-mapping/pom.xml b/persistence-modules/hibernate-mapping/pom.xml
index 805402951e..506283a4fb 100644
--- a/persistence-modules/hibernate-mapping/pom.xml
+++ b/persistence-modules/hibernate-mapping/pom.xml
@@ -29,12 +29,6 @@
             hibernate-types-52
             ${hibernate-types.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             com.h2database
             h2
@@ -75,9 +69,9 @@
     
 
     
+        1.4.197 
         5.4.12.Final
         2.10.4
-        3.8.0
         6.0.16.Final
         3.0.1-b11
         1.0.3
diff --git a/persistence-modules/hibernate-queries/pom.xml b/persistence-modules/hibernate-queries/pom.xml
index 83b2ea4d00..20c2da9ea9 100644
--- a/persistence-modules/hibernate-queries/pom.xml
+++ b/persistence-modules/hibernate-queries/pom.xml
@@ -19,12 +19,6 @@
             hibernate-core
             ${hibernate.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             com.h2database
             h2
@@ -60,7 +54,6 @@
     
         6.0.6
         2.2.3
-        3.8.0
     
 
 
\ No newline at end of file
diff --git a/persistence-modules/hibernate5/pom.xml b/persistence-modules/hibernate5/pom.xml
index d46d2c16d4..6bec0d4981 100644
--- a/persistence-modules/hibernate5/pom.xml
+++ b/persistence-modules/hibernate5/pom.xml
@@ -19,12 +19,6 @@
             hibernate-core
             ${hibernate.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             com.h2database
             h2
@@ -66,7 +60,6 @@
         5.4.12.Final
         6.0.6
         2.2.3
-        3.8.0
     
 
 
\ No newline at end of file
diff --git a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/CustomInterceptor.java b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/CustomInterceptor.java
index 1d60ccb6c0..24b06f9b65 100644
--- a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/CustomInterceptor.java
+++ b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/CustomInterceptor.java
@@ -16,7 +16,7 @@ public class CustomInterceptor extends EmptyInterceptor {
     @Override
     public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
         if (entity instanceof User) {
-            logger.info(((User) entity).toString());
+            logger.debug(entity.toString());
         }
         return super.onSave(entity, id, state, propertyNames, types);
     }
@@ -25,7 +25,7 @@ public class CustomInterceptor extends EmptyInterceptor {
     public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object [] previousState, String[] propertyNames, Type[] types) {
         if (entity instanceof User) {
             ((User) entity).setLastModified(new Date());
-            logger.info(((User) entity).toString());
+            logger.debug(entity.toString());
         }
         return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types);
     }
diff --git a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/entity/User.java b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/entity/User.java
index 2b1dbe702b..b627cefa33 100644
--- a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/entity/User.java
+++ b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/entity/User.java
@@ -1,7 +1,5 @@
 package com.baeldung.hibernate.interceptors.entity;
 
-import java.util.Date;
-
 import javax.persistence.Basic;
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
@@ -9,6 +7,7 @@ import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
+import java.util.Date;
 
 @Entity(name = "hbi_user")
 public class User {
diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/hilo/HibernateHiloUnitTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/hilo/HibernateHiloUnitTest.java
index 9285c30af5..d0eab565df 100644
--- a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/hilo/HibernateHiloUnitTest.java
+++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/hilo/HibernateHiloUnitTest.java
@@ -42,9 +42,9 @@ public class HibernateHiloUnitTest {
     private void configureLogger() {
         BasicConfigurator.configure();
         LogManager.getLogger("org.hibernate").setLevel(Level.ERROR);
-        LogManager.getLogger("org.hibernate.id.enhanced.SequenceStructure").setLevel(Level.DEBUG);
-        LogManager.getLogger("org.hibernate.event.internal.AbstractSaveEventListener").setLevel(Level.DEBUG);
-        LogManager.getLogger("org.hibernate.SQL").setLevel(Level.DEBUG);
+        LogManager.getLogger("org.hibernate.id.enhanced.SequenceStructure").setLevel(Level.INFO);
+        LogManager.getLogger("org.hibernate.event.internal.AbstractSaveEventListener").setLevel(Level.INFO);
+        LogManager.getLogger("org.hibernate.SQL").setLevel(Level.INFO);
     }
 
 
diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java
index 0a4caf032b..217351cd75 100644
--- a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java
+++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java
@@ -1,5 +1,8 @@
 package com.baeldung.hibernate.proxy;
 
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
 import org.hibernate.*;
 import org.hibernate.proxy.HibernateProxy;
 import org.junit.After;
diff --git a/persistence-modules/hibernate5/src/test/resources/hibernate-hilo.properties b/persistence-modules/hibernate5/src/test/resources/hibernate-hilo.properties
index 60d487c1bd..94f3597f1f 100644
--- a/persistence-modules/hibernate5/src/test/resources/hibernate-hilo.properties
+++ b/persistence-modules/hibernate5/src/test/resources/hibernate-hilo.properties
@@ -2,7 +2,7 @@ hibernate.connection.driver_class=org.h2.Driver
 hibernate.connection.url=jdbc:h2:mem:hilo_db;DB_CLOSE_DELAY=-1
 hibernate.connection.username=sa
 hibernate.dialect=org.hibernate.dialect.H2Dialect
-hibernate.show_sql=true
+hibernate.show_sql=false
 hibernate.hbm2ddl.auto=create-drop
 hibernate.c3p0.min_size=5
 hibernate.c3p0.max_size=20
diff --git a/persistence-modules/hibernate5/src/test/resources/hibernate-interceptors.properties b/persistence-modules/hibernate5/src/test/resources/hibernate-interceptors.properties
index 58b55d0a09..e5bb5a36a7 100644
--- a/persistence-modules/hibernate5/src/test/resources/hibernate-interceptors.properties
+++ b/persistence-modules/hibernate5/src/test/resources/hibernate-interceptors.properties
@@ -5,6 +5,6 @@ hibernate.connection.autocommit=true
 jdbc.password=
 
 hibernate.dialect=org.hibernate.dialect.H2Dialect
-hibernate.show_sql=true
+hibernate.show_sql=false
 hibernate.hbm2ddl.auto=create-drop
 hibernate.current_session_context_class=org.hibernate.context.internal.ThreadLocalSessionContext
\ No newline at end of file
diff --git a/persistence-modules/hibernate5/src/test/resources/hibernate-lifecycle.properties b/persistence-modules/hibernate5/src/test/resources/hibernate-lifecycle.properties
index d043b624f2..1a5e6482bf 100644
--- a/persistence-modules/hibernate5/src/test/resources/hibernate-lifecycle.properties
+++ b/persistence-modules/hibernate5/src/test/resources/hibernate-lifecycle.properties
@@ -5,5 +5,5 @@ hibernate.connection.password=
 hibernate.connection.autocommit=true
 
 hibernate.dialect=org.hibernate.dialect.H2Dialect
-hibernate.show_sql=true
+hibernate.show_sql=false
 hibernate.hbm2ddl.auto=validate
\ No newline at end of file
diff --git a/persistence-modules/hibernate5/src/test/resources/hibernate-namingstrategy.properties b/persistence-modules/hibernate5/src/test/resources/hibernate-namingstrategy.properties
index f75a35bdfe..263033823c 100644
--- a/persistence-modules/hibernate5/src/test/resources/hibernate-namingstrategy.properties
+++ b/persistence-modules/hibernate5/src/test/resources/hibernate-namingstrategy.properties
@@ -3,7 +3,7 @@ hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1
 hibernate.connection.username=sa
 hibernate.dialect=org.hibernate.dialect.H2Dialect
 
-hibernate.show_sql=true
+hibernate.show_sql=false
 hibernate.hbm2ddl.auto=create-drop
 
 hibernate.physical_naming_strategy=com.baeldung.hibernate.namingstrategy.CustomPhysicalNamingStrategy
diff --git a/persistence-modules/hibernate5/src/test/resources/hibernate-persistjson.properties b/persistence-modules/hibernate5/src/test/resources/hibernate-persistjson.properties
index 2cf8ac5b63..2481591fca 100644
--- a/persistence-modules/hibernate5/src/test/resources/hibernate-persistjson.properties
+++ b/persistence-modules/hibernate5/src/test/resources/hibernate-persistjson.properties
@@ -3,5 +3,5 @@ hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1
 hibernate.connection.username=sa
 hibernate.dialect=org.hibernate.dialect.H2Dialect
 
-hibernate.show_sql=true
+hibernate.show_sql=false
 hibernate.hbm2ddl.auto=create-drop
\ No newline at end of file
diff --git a/persistence-modules/hibernate5/src/test/resources/hibernate.properties b/persistence-modules/hibernate5/src/test/resources/hibernate.properties
index c14782ce0f..42d8e8564f 100644
--- a/persistence-modules/hibernate5/src/test/resources/hibernate.properties
+++ b/persistence-modules/hibernate5/src/test/resources/hibernate.properties
@@ -5,7 +5,7 @@ hibernate.connection.autocommit=true
 jdbc.password=
 
 hibernate.dialect=org.hibernate.dialect.H2Dialect
-hibernate.show_sql=true
+hibernate.show_sql=false
 hibernate.hbm2ddl.auto=create-drop
 
 hibernate.c3p0.min_size=5
diff --git a/persistence-modules/java-jpa-2/pom.xml b/persistence-modules/java-jpa-2/pom.xml
index 26895f3a87..884142f821 100644
--- a/persistence-modules/java-jpa-2/pom.xml
+++ b/persistence-modules/java-jpa-2/pom.xml
@@ -58,12 +58,6 @@
             querydsl-jpa
             ${querydsl.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
     
 
     
@@ -139,7 +133,6 @@
         5.4.14.Final
         2.7.4
         2.2
-        3.11.1
         3.5.1
         3.3.3
         3.0.0
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-jpa-3/pom.xml b/persistence-modules/java-jpa-3/pom.xml
index ad649d58d8..b67b8bf608 100644
--- a/persistence-modules/java-jpa-3/pom.xml
+++ b/persistence-modules/java-jpa-3/pom.xml
@@ -62,18 +62,6 @@
             ${postgresql.version}
             runtime
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-            test
-        
-        
-            org.junit.vintage
-            junit-vintage-engine
-            ${junit-jupiter.version}
-            test
-        
         
             org.testcontainers
             postgresql
@@ -100,7 +88,6 @@
         2.7.4
         8.0.21
         2.2
-        3.11.1
         3.5.1
         3.3.3
         3.0.0
diff --git a/persistence-modules/java-mongodb/README.md b/persistence-modules/java-mongodb/README.md
index b79cea6781..34acd60c57 100644
--- a/persistence-modules/java-mongodb/README.md
+++ b/persistence-modules/java-mongodb/README.md
@@ -10,5 +10,5 @@ This module contains articles about MongoDB in Java.
 - [Geospatial Support in MongoDB](https://www.baeldung.com/mongodb-geospatial-support)
 - [Introduction to Morphia – Java ODM for MongoDB](https://www.baeldung.com/mongodb-morphia)
 - [MongoDB Aggregations Using Java](https://www.baeldung.com/java-mongodb-aggregations)
-- [MongoDB BSON to JSON](https://www.baeldung.com/bson-to-json)
 - [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/jooq/pom.xml b/persistence-modules/jooq/pom.xml
index c66be9db77..b9229377ab 100644
--- a/persistence-modules/jooq/pom.xml
+++ b/persistence-modules/jooq/pom.xml
@@ -45,7 +45,6 @@
 
     
         3.13.4
-        1.4.200
     
 
 
\ No newline at end of file
diff --git a/persistence-modules/jpa-hibernate-cascade-type/pom.xml b/persistence-modules/jpa-hibernate-cascade-type/pom.xml
index 467fe11bc3..fd0ae117c7 100644
--- a/persistence-modules/jpa-hibernate-cascade-type/pom.xml
+++ b/persistence-modules/jpa-hibernate-cascade-type/pom.xml
@@ -17,12 +17,6 @@
             hibernate-core
             ${hibernate.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
         
             com.h2database
             h2
@@ -48,7 +42,6 @@
 
     
         5.4.3.Final
-        3.12.2
         6.0.17.Final
         3.0.0
         3.0.1-b11
diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml
index c3df8866b1..4d42ff54cd 100644
--- a/persistence-modules/pom.xml
+++ b/persistence-modules/pom.xml
@@ -99,9 +99,6 @@
         5.2.17.Final
 
         42.2.20
-
-        
-        2.22.2
     
 
 
\ No newline at end of file
diff --git a/persistence-modules/r2dbc/pom.xml b/persistence-modules/r2dbc/pom.xml
index ae4ca4d91d..1ce5eb3e96 100644
--- a/persistence-modules/r2dbc/pom.xml
+++ b/persistence-modules/r2dbc/pom.xml
@@ -63,7 +63,6 @@
 
     
         0.8.1.RELEASE
-        1.4.200
     
 
 
\ No newline at end of file
diff --git a/persistence-modules/r2dbc/src/test/resources/logback-test.xml b/persistence-modules/r2dbc/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/r2dbc/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-2/src/test/resources/logback-test.xml b/persistence-modules/spring-boot-persistence-2/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-2/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/lazy_load_no_trans/config/DatasourceProxyBeanPostProcessor.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/lazy_load_no_trans/config/DatasourceProxyBeanPostProcessor.java
index c087427b65..1952a26f2f 100644
--- a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/lazy_load_no_trans/config/DatasourceProxyBeanPostProcessor.java
+++ b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/lazy_load_no_trans/config/DatasourceProxyBeanPostProcessor.java
@@ -1,10 +1,7 @@
 package com.baeldung.h2db.lazy_load_no_trans.config;
 
 import net.ttddyy.dsproxy.listener.DataSourceQueryCountListener;
-import net.ttddyy.dsproxy.listener.logging.CommonsQueryLoggingListener;
-import net.ttddyy.dsproxy.listener.logging.DefaultQueryLogEntryCreator;
 import net.ttddyy.dsproxy.listener.logging.SLF4JLogLevel;
-import net.ttddyy.dsproxy.listener.logging.SLF4JQueryLoggingListener;
 import net.ttddyy.dsproxy.support.ProxyDataSource;
 import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
 import org.aopalliance.intercept.MethodInterceptor;
@@ -49,7 +46,7 @@ public class DatasourceProxyBeanPostProcessor implements BeanPostProcessor {
             this.dataSource = ProxyDataSourceBuilder.create(dataSource)
                     .name("MyDS")
                     .multiline()
-                    .logQueryBySlf4j(SLF4JLogLevel.INFO)
+                    .logQueryBySlf4j(SLF4JLogLevel.DEBUG)
                     .listener(new DataSourceQueryCountListener())
                     .build();
         }
diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/SpringBootH2Application.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/SpringBootH2Application.java
index 378093cfa9..d6d7a20f55 100644
--- a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/SpringBootH2Application.java
+++ b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/SpringBootH2Application.java
@@ -2,8 +2,10 @@ package com.baeldung.h2db.springboot;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.PropertySource;
 
 @SpringBootApplication
+@PropertySource("classpath:application-h2.properties")
 public class SpringBootH2Application {
 
     public static void main(String... args) {
diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/daos/CountryRepository.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/daos/CountryRepository.java
new file mode 100644
index 0000000000..d576be9098
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/daos/CountryRepository.java
@@ -0,0 +1,7 @@
+package com.baeldung.h2db.springboot.daos;
+
+import com.baeldung.h2db.springboot.models.Country;
+import org.springframework.data.repository.CrudRepository;
+
+public interface CountryRepository extends CrudRepository {
+}
diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/daos/UserRepository.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/daos/UserRepository.java
deleted file mode 100644
index 35e496e910..0000000000
--- a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/daos/UserRepository.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.baeldung.h2db.springboot.daos;
-
-
-
-
-import com.baeldung.h2db.springboot.models.User;
-import org.springframework.data.repository.CrudRepository;
-
-public interface UserRepository extends CrudRepository {
-}
diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/models/Country.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/models/Country.java
new file mode 100644
index 0000000000..d6edab9421
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/models/Country.java
@@ -0,0 +1,57 @@
+package com.baeldung.h2db.springboot.models;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.Objects;
+
+@Table(name = "countries")
+@Entity
+public class Country {
+
+    @Id
+    @GeneratedValue
+    private int id;
+
+    private String name;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+        Country country = (Country) o;
+        return id == country.id && name.equals(country.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, name);
+    }
+
+    @Override
+    public String toString() {
+        return "Country{" +
+          "id=" + id +
+          ", name='" + name + '\'' +
+          '}';
+    }
+}
diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/models/User.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/models/User.java
deleted file mode 100644
index fa3c01c035..0000000000
--- a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/models/User.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.baeldung.h2db.springboot.models;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Table(name = "users")
-@Entity
-public class User {
-
-    @Id
-    @GeneratedValue
-    private int id;
-
-    private String firstName;
-
-    private String lastName;
-
-    public User() { }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getFirstName() {
-        return firstName;
-    }
-
-    public void setFirstName(String firstName) {
-        this.firstName = firstName;
-    }
-
-    public String getLastName() {
-        return lastName;
-    }
-
-    public void setLastName(String lastName) {
-        this.lastName = lastName;
-    }
-
-    @Override
-    public String toString() {
-        return "User{" +
-                "id=" + id +
-                ", firstName='" + firstName + '\'' +
-                ", lastName='" + lastName + '\'' +
-                '}';
-    }
-}
diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/resources/application-h2.properties b/persistence-modules/spring-boot-persistence-h2/src/main/resources/application-h2.properties
new file mode 100644
index 0000000000..6fb436f520
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-h2/src/main/resources/application-h2.properties
@@ -0,0 +1 @@
+spring.sql.init.data-locations=data-h2.sql
diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/resources/application.properties b/persistence-modules/spring-boot-persistence-h2/src/main/resources/application.properties
index 134cda6628..2499d7cd06 100644
--- a/persistence-modules/spring-boot-persistence-h2/src/main/resources/application.properties
+++ b/persistence-modules/spring-boot-persistence-h2/src/main/resources/application.properties
@@ -4,7 +4,7 @@ spring.datasource.username=sa
 spring.datasource.password=
 spring.jpa.defer-datasource-initialization=true
 spring.jpa.hibernate.ddl-auto=create-drop
-spring.jpa.show-sql=true
+spring.jpa.show-sql=false
 spring.jpa.properties.hibernate.format_sql=true
 spring.jpa.properties.hibernate.validator.apply_to_ddl=false
 #spring.jpa.properties.hibernate.check_nullability=true
diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/resources/data-h2.sql b/persistence-modules/spring-boot-persistence-h2/src/main/resources/data-h2.sql
new file mode 100644
index 0000000000..3d04b578d2
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-h2/src/main/resources/data-h2.sql
@@ -0,0 +1,5 @@
+INSERT INTO countries (id, name) VALUES (1, 'USA');
+INSERT INTO countries (id, name) VALUES (2, 'France');
+INSERT INTO countries (id, name) VALUES (3, 'Brazil');
+INSERT INTO countries (id, name) VALUES (4, 'Italy');
+INSERT INTO countries (id, name) VALUES (5, 'Canada');
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/resources/data-trans.sql b/persistence-modules/spring-boot-persistence-h2/src/main/resources/data-trans.sql
index b8835e70cb..e4fda99437 100644
--- a/persistence-modules/spring-boot-persistence-h2/src/main/resources/data-trans.sql
+++ b/persistence-modules/spring-boot-persistence-h2/src/main/resources/data-trans.sql
@@ -1,17 +1,3 @@
-DROP TABLE IF EXISTS billionaires;
-
-CREATE TABLE billionaires (
-  id INT AUTO_INCREMENT  PRIMARY KEY,
-  first_name VARCHAR(250) NOT NULL,
-  last_name VARCHAR(250) NOT NULL,
-  career VARCHAR(250) DEFAULT NULL
-);
-
-INSERT INTO billionaires (first_name, last_name, career) VALUES
-('Aliko', 'Dangote', 'Billionaire Industrialist'),
-('Bill', 'Gates', 'Billionaire Tech Entrepreneur'),
-('Folrunsho', 'Alakija', 'Billionaire Oil Magnate');
-
 insert into USER values (101, 'user1', 'comment1');
 insert into USER values (102, 'user2', 'comment2');
 insert into USER values (103, 'user3', 'comment3');
diff --git a/persistence-modules/spring-boot-persistence-h2/src/test/java/com/baeldung/SpringBootH2IntegrationTest.java b/persistence-modules/spring-boot-persistence-h2/src/test/java/com/baeldung/SpringBootH2IntegrationTest.java
index aecc63c599..4c11ae6b0d 100644
--- a/persistence-modules/spring-boot-persistence-h2/src/test/java/com/baeldung/SpringBootH2IntegrationTest.java
+++ b/persistence-modules/spring-boot-persistence-h2/src/test/java/com/baeldung/SpringBootH2IntegrationTest.java
@@ -1,50 +1,39 @@
 package com.baeldung;
 
 import com.baeldung.h2db.springboot.SpringBootH2Application;
-import com.baeldung.h2db.springboot.daos.UserRepository;
-import com.baeldung.h2db.springboot.models.User;
+import com.baeldung.h2db.springboot.daos.CountryRepository;
+import com.baeldung.h2db.springboot.models.Country;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
-import java.util.List;
-
-import static org.junit.Assert.*;
+import static org.assertj.core.api.Assertions.assertThat;
 
 @RunWith(SpringRunner.class)
 @SpringBootTest(classes = SpringBootH2Application.class)
 public class SpringBootH2IntegrationTest {
 
+    private static final Country AN_EXPECTED_COUNTRY = buildCountry();
+
     @Autowired
-    private UserRepository userRepository;
+    private CountryRepository countryRepository;
 
     @Test
-    public void contextLoads() { }
+    public void givenInitData_whenApplicationStarts_thenDataIsLoaded() {
+        Iterable users = countryRepository.findAll();
 
-    @Test
-    public void givenUserProfile_whenAddUser_thenCreateNewUser() {
-        User user = new User();
-        user.setFirstName("John");
-        user.setLastName("Doe");
-        userRepository.save(user);
-        List users = (List) userRepository.findAll();
-        assertFalse(users.isEmpty());
+        assertThat(users)
+          .hasSize(5)
+          .contains(AN_EXPECTED_COUNTRY);
+    }
 
-        String firstName = "Aliko";
-        String lastName = "Dangote";
-        User user1 = userRepository.findById(users.get(0).getId()).get();
-        user1.setLastName(lastName);
-        user1.setFirstName(firstName);
-        userRepository.save(user1);
-
-        user = userRepository.findById(user.getId()).get();
-        assertEquals(user.getFirstName(), firstName);
-        assertEquals(user.getLastName(), lastName);
-
-        userRepository.deleteById(user.getId());
-        assertTrue( ((List) userRepository.findAll()).isEmpty());
+    private static Country buildCountry() {
+        Country c = new Country();
+        c.setId(5);
+        c.setName("Canada");
+        return c;
     }
 
 }
diff --git a/persistence-modules/spring-boot-persistence-h2/src/test/resources/logback-test.xml b/persistence-modules/spring-boot-persistence-h2/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-h2/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/test/resources/logback-test.xml b/persistence-modules/spring-boot-persistence-mongodb/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
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-boot-persistence/src/test/resources/dsrouting-db.sql b/persistence-modules/spring-boot-persistence/src/test/resources/dsrouting-db.sql
index c9ca52907a..7449b23307 100644
--- a/persistence-modules/spring-boot-persistence/src/test/resources/dsrouting-db.sql
+++ b/persistence-modules/spring-boot-persistence/src/test/resources/dsrouting-db.sql
@@ -1,3 +1,5 @@
+drop table if exists client;
+
 create table client (
   id numeric,
   name  varchar(50),
diff --git a/persistence-modules/spring-data-cassandra-2/pom.xml b/persistence-modules/spring-data-cassandra-2/pom.xml
index 0e09448d0f..1e6412dc17 100644
--- a/persistence-modules/spring-data-cassandra-2/pom.xml
+++ b/persistence-modules/spring-data-cassandra-2/pom.xml
@@ -1,72 +1,73 @@
 
-
-	4.0.0
-	
-		com.baeldung
-		parent-boot-2
-		0.0.1-SNAPSHOT
-		../../parent-boot-2
-	
+
+    4.0.0
+    org.baeldung
+    spring-data-cassandra-2
+    0.0.1-SNAPSHOT
+    spring-data-cassandra-2
+    Demo project for Spring Data Cassandra
 
-	org.baeldung
-	spring-cassandra
-	0.0.1-SNAPSHOT
-	spring-cassandra
-	Demo project for Spring Data Cassandra
+    
+        com.baeldung
+        parent-boot-2
+        0.0.1-SNAPSHOT
+        ../../parent-boot-2
+    
 
-	
-		
-			org.springframework.boot
-			spring-boot-starter-data-cassandra
-		
-		
-			org.springframework.data
-			spring-data-cassandra
-			${org.springframework.data.version}
-		
-		
-			uk.org.webcompere
-			system-stubs-core
-			${system.stubs.version}
-		
-		
-			org.springframework.boot
-			spring-boot-starter-test
-			test
-		
-		
-			org.testcontainers
-			testcontainers
-			${testcontainers.version}
-			test
-		
-		
-			org.testcontainers
-			cassandra
-			${testcontainers.version}
-			test
-		
-		
-			org.testcontainers
-			junit-jupiter
-			${testcontainers.version}
-			test
-		
-		
-			uk.org.webcompere
-			system-stubs-jupiter
-			${system.stubs.version}
-			test
-		
-	
+    
+        
+            org.springframework.boot
+            spring-boot-starter-data-cassandra
+        
+        
+            org.springframework.data
+            spring-data-cassandra
+            ${org.springframework.data.version}
+        
+        
+            uk.org.webcompere
+            system-stubs-core
+            ${system.stubs.version}
+        
+        
+            org.springframework.boot
+            spring-boot-starter-test
+            test
+        
+        
+            org.testcontainers
+            testcontainers
+            ${testcontainers.version}
+            test
+        
+        
+            org.testcontainers
+            cassandra
+            ${testcontainers.version}
+            test
+        
+        
+            org.testcontainers
+            junit-jupiter
+            ${testcontainers.version}
+            test
+        
+        
+            uk.org.webcompere
+            system-stubs-jupiter
+            ${system.stubs.version}
+            test
+        
+    
 
-	
-		11
-		3.1.11
-		1.15.3
-		1.1.0
-		5.6.2
-	
+    
+        11
+        3.1.11
+        1.15.3
+        1.1.0
+        5.6.2
+    
 
-
+
\ No newline at end of file
diff --git a/persistence-modules/spring-data-cassandra-reactive/src/test/resources/logback-test.xml b/persistence-modules/spring-data-cassandra-reactive/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/spring-data-cassandra-reactive/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/persistence-modules/spring-data-cassandra/pom.xml b/persistence-modules/spring-data-cassandra/pom.xml
index 8092c05a40..925031b141 100644
--- a/persistence-modules/spring-data-cassandra/pom.xml
+++ b/persistence-modules/spring-data-cassandra/pom.xml
@@ -49,7 +49,8 @@
             ${cassandra-unit-shaded.version}
             test
             
-                
+                
                 
                     junit
                     junit
diff --git a/persistence-modules/spring-data-eclipselink/pom.xml b/persistence-modules/spring-data-eclipselink/pom.xml
index a344d64864..561d144fe3 100644
--- a/persistence-modules/spring-data-eclipselink/pom.xml
+++ b/persistence-modules/spring-data-eclipselink/pom.xml
@@ -66,6 +66,7 @@
     
         1.5.9.RELEASE
         2.7.0
+        1.4.197 
     
 
 
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-enterprise/src/main/resources/application.properties b/persistence-modules/spring-data-jpa-enterprise/src/main/resources/application.properties
index 32d3e640f9..0ca1872207 100644
--- a/persistence-modules/spring-data-jpa-enterprise/src/main/resources/application.properties
+++ b/persistence-modules/spring-data-jpa-enterprise/src/main/resources/application.properties
@@ -9,7 +9,7 @@ spring.datasource.url=jdbc:h2:mem:baeldung
 #spring.jpa.properties.javax.persistence.schema-generation.scripts.create-source=metadata
 #spring.jpa.properties.hibernate.format_sql=true
 
-spring.jpa.show-sql=true
+spring.jpa.show-sql=false
 
 #hibernate.dialect=org.hibernate.dialect.H2Dialect
 spring.jpa.properties.hibernate.id.new_generator_mappings=false
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-enterprise/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/spring-data-jpa-enterprise/src/test/java/com/baeldung/SpringContextTest.java
index eaccf4acba..0c735d3599 100644
--- a/persistence-modules/spring-data-jpa-enterprise/src/test/java/com/baeldung/SpringContextTest.java
+++ b/persistence-modules/spring-data-jpa-enterprise/src/test/java/com/baeldung/SpringContextTest.java
@@ -3,6 +3,7 @@ package com.baeldung;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import com.baeldung.boot.Application;
diff --git a/persistence-modules/spring-data-jpa-enterprise/src/test/java/com/baeldung/partialupdate/PartialUpdateUnitTest.java b/persistence-modules/spring-data-jpa-enterprise/src/test/java/com/baeldung/partialupdate/PartialUpdateUnitTest.java
index 874e18c4ad..4a70d409df 100644
--- a/persistence-modules/spring-data-jpa-enterprise/src/test/java/com/baeldung/partialupdate/PartialUpdateUnitTest.java
+++ b/persistence-modules/spring-data-jpa-enterprise/src/test/java/com/baeldung/partialupdate/PartialUpdateUnitTest.java
@@ -7,6 +7,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import com.baeldung.partialupdate.model.Customer;
diff --git a/persistence-modules/spring-data-jpa-enterprise/src/test/resources/logback-test.xml b/persistence-modules/spring-data-jpa-enterprise/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..1595326253
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-enterprise/src/test/resources/logback-test.xml
@@ -0,0 +1,13 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+    
+
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/hibernate/FooFixtures.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/hibernate/FooFixtures.java
index da840dc027..a7763bb0f8 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/hibernate/FooFixtures.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/hibernate/FooFixtures.java
@@ -10,8 +10,13 @@ import org.hibernate.SessionFactory;
 import org.hibernate.Transaction;
 
 import com.google.common.collect.Lists;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class FooFixtures {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(FooFixtures.class);
+
     private SessionFactory sessionFactory;
 
     public FooFixtures(final SessionFactory sessionFactory) {
@@ -36,8 +41,9 @@ public class FooFixtures {
                 foo.setBar(bar);
                 session.save(foo);
                 final Foo foo2 = new Foo(null);
-                if (i % 2 == 0)
+                if (i % 2 == 0) {
                     foo2.setName("LuckyFoo" + (i + 120));
+                }
                 foo2.setBar(bar);
                 session.save(foo2);
                 bar.getFooSet().add(foo);
@@ -47,15 +53,16 @@ public class FooFixtures {
             tx.commit();
             session.flush();
         } catch (final HibernateException he) {
-            if (tx != null)
+            if (tx != null) {
                 tx.rollback();
-            System.out.println("Not able to open session");
-            he.printStackTrace();
+            }
+            LOGGER.error("Not able to open session", he);
         } catch (final Exception e) {
-            e.printStackTrace();
+            LOGGER.error(e.getLocalizedMessage(), e);
         } finally {
-            if (session != null)
+            if (session != null) {
                 session.close();
+            }
         }
 
     }
@@ -86,15 +93,16 @@ public class FooFixtures {
             tx.commit();
             session.flush();
         } catch (final HibernateException he) {
-            if (tx != null)
+            if (tx != null) {
                 tx.rollback();
-            System.out.println("Not able to open session");
-            he.printStackTrace();
+            }
+            LOGGER.error("Not able to open session", he);
         } catch (final Exception e) {
-            e.printStackTrace();
+            LOGGER.error(e.getLocalizedMessage(), e);
         } finally {
-            if (session != null)
+            if (session != null) {
                 session.close();
+            }
         }
     }
 
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/hibernate/FooSortingPersistenceIntegrationTest.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/hibernate/FooSortingPersistenceIntegrationTest.java
index 8173088af0..6078eb3af0 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/hibernate/FooSortingPersistenceIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/hibernate/FooSortingPersistenceIntegrationTest.java
@@ -15,6 +15,8 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -29,6 +31,8 @@ import com.baeldung.spring.config.PersistenceTestConfig;
 @SuppressWarnings("unchecked")
 public class FooSortingPersistenceIntegrationTest {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(FooSortingPersistenceIntegrationTest.class);
+
     @Autowired
     private SessionFactory sessionFactory;
 
@@ -56,7 +60,7 @@ public class FooSortingPersistenceIntegrationTest {
         final Query query = session.createQuery(hql);
         final List fooList = query.list();
         for (final Foo foo : fooList) {
-            System.out.println("Name: " + foo.getName() + ", Id: " + foo.getId());
+            LOGGER.debug("Name: {} , Id: {}", foo.getName(), foo.getId());
         }
     }
 
@@ -68,7 +72,7 @@ public class FooSortingPersistenceIntegrationTest {
 
         assertNull(fooList.get(fooList.toArray().length - 1).getName());
         for (final Foo foo : fooList) {
-            System.out.println("Name: " + foo.getName() + ", Id: " + foo.getId());
+            LOGGER.debug("Name: {}, Id: {}", foo.getName(), foo.getId());
         }
     }
 
@@ -79,7 +83,7 @@ public class FooSortingPersistenceIntegrationTest {
         final List fooList = query.list();
         assertNull(fooList.get(0).getName());
         for (final Foo foo : fooList) {
-            System.out.println("Name:" + foo.getName());
+            LOGGER.debug("Name: {}", foo.getName());
 
         }
     }
@@ -90,7 +94,7 @@ public class FooSortingPersistenceIntegrationTest {
         final Query query = session.createQuery(hql);
         final List fooList = query.list();
         for (final Foo foo : fooList) {
-            System.out.println("Name: " + foo.getName() + ", Id: " + foo.getId());
+            LOGGER.debug("Name: {}, Id: {}", foo.getName(), foo.getId());
         }
     }
 
@@ -100,7 +104,7 @@ public class FooSortingPersistenceIntegrationTest {
         final Query query = session.createQuery(hql);
         final List fooList = query.list();
         for (final Foo foo : fooList) {
-            System.out.println("Name: " + foo.getName() + ", Id: " + foo.getId());
+            LOGGER.debug("Name: {}, Id: {}", foo.getName(), foo.getId());
         }
     }
 
@@ -110,7 +114,7 @@ public class FooSortingPersistenceIntegrationTest {
         final Query query = session.createQuery(hql);
         final List fooList = query.list();
         for (final Foo foo : fooList) {
-            System.out.println("Name: " + foo.getName() + ", Id: " + foo.getId());
+            LOGGER.debug("Name: {}, Id: {}", foo.getName(), foo.getId());
         }
     }
 
@@ -120,7 +124,7 @@ public class FooSortingPersistenceIntegrationTest {
         criteria.addOrder(Order.asc("id"));
         final List fooList = criteria.list();
         for (final Foo foo : fooList) {
-            System.out.println("Id: " + foo.getId() + ", FirstName: " + foo.getName());
+            LOGGER.debug("Id: {}, FirstName: {}", foo.getId(), foo.getName());
         }
     }
 
@@ -131,7 +135,7 @@ public class FooSortingPersistenceIntegrationTest {
         criteria.addOrder(Order.asc("id"));
         final List fooList = criteria.list();
         for (final Foo foo : fooList) {
-            System.out.println("Id: " + foo.getId() + ", FirstName: " + foo.getName());
+            LOGGER.debug("Id: {}, FirstName: {}", foo.getId(), foo.getName());
         }
     }
 
@@ -142,7 +146,7 @@ public class FooSortingPersistenceIntegrationTest {
         final List fooList = criteria.list();
         assertNull(fooList.get(fooList.toArray().length - 1).getName());
         for (final Foo foo : fooList) {
-            System.out.println("Id: " + foo.getId() + ", FirstName: " + foo.getName());
+            LOGGER.debug("Id: {}, FirstName: {}", foo.getId(), foo.getName());
         }
     }
 
@@ -153,7 +157,7 @@ public class FooSortingPersistenceIntegrationTest {
         final List fooList = criteria.list();
         assertNull(fooList.get(0).getName());
         for (final Foo foo : fooList) {
-            System.out.println("Id: " + foo.getId() + ", FirstName: " + foo.getName());
+            LOGGER.debug("Id: {}, FirstName: {}", foo.getId(), foo.getName());
         }
     }
 
@@ -164,9 +168,9 @@ public class FooSortingPersistenceIntegrationTest {
         final List barList = query.list();
         for (final Bar bar : barList) {
             final Set fooSet = bar.getFooSet();
-            System.out.println("Bar Id:" + bar.getId());
+            LOGGER.debug("Bar Id:{}", bar.getId());
             for (final Foo foo : fooSet) {
-                System.out.println("FooName:" + foo.getName());
+                LOGGER.debug("FooName:{}", foo.getName());
             }
         }
     }
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/service/ParentServicePersistenceIntegrationTest.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/service/ParentServicePersistenceIntegrationTest.java
index 5a73e39ca2..8c766954ff 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/service/ParentServicePersistenceIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/service/ParentServicePersistenceIntegrationTest.java
@@ -1,7 +1,10 @@
 package com.baeldung.persistence.service;
 
+import com.baeldung.persistence.hibernate.FooSortingPersistenceIntegrationTest;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.DataIntegrityViolationException;
 import org.springframework.test.context.ContextConfiguration;
@@ -16,6 +19,8 @@ import com.baeldung.spring.config.PersistenceTestConfig;
 @ContextConfiguration(classes = { PersistenceTestConfig.class }, loader = AnnotationConfigContextLoader.class)
 public class ParentServicePersistenceIntegrationTest {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(ParentServicePersistenceIntegrationTest.class);
+    
     @Autowired
     private IParentService service;
 
@@ -37,11 +42,11 @@ public class ParentServicePersistenceIntegrationTest {
         final Parent parentEntity = new Parent(childEntity);
         service.create(parentEntity);
 
-        System.out.println("Child = " + childService.findOne(childEntity.getId()));
-        System.out.println("Child - parent = " + childService.findOne(childEntity.getId()).getParent());
+        LOGGER.debug("Child = {}", childService.findOne(childEntity.getId()));
+        LOGGER.debug("Child - parent = {}", childService.findOne(childEntity.getId()).getParent());
 
-        System.out.println("Parent = " + service.findOne(parentEntity.getId()));
-        System.out.println("Parent - child = " + service.findOne(parentEntity.getId()).getChild());
+        LOGGER.debug("Parent = {}", service.findOne(parentEntity.getId()));
+        LOGGER.debug("Parent - child = {}", service.findOne(parentEntity.getId()).getChild());
     }
 
     @Test(expected = DataIntegrityViolationException.class)
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/spring/config/PersistenceTestConfig.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/spring/config/PersistenceTestConfig.java
index 34301741fe..c8f14c5563 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/spring/config/PersistenceTestConfig.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/spring/config/PersistenceTestConfig.java
@@ -166,7 +166,7 @@ public class PersistenceTestConfig {
         hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
         hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
 
-        hibernateProperties.setProperty("hibernate.show_sql", "true");
+        hibernateProperties.setProperty("hibernate.show_sql", "false");
         // hibernateProperties.setProperty("hibernate.format_sql", "true");
         // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
 
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/spring/data/jpa/query/UserRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/spring/data/jpa/query/UserRepositoryIntegrationTest.java
index a9ab13feed..19760f2bfe 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/spring/data/jpa/query/UserRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/spring/data/jpa/query/UserRepositoryIntegrationTest.java
@@ -19,7 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 @RunWith(SpringRunner.class)
-@DataJpaTest(properties = "spring.sql.init.data-locations=classpath:insert_users.sql")
+@DataJpaTest(properties = "spring.sql.init.data-locations=classpath:insert_users.sql", showSql = false)
 public class UserRepositoryIntegrationTest {
 
     @Autowired
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/spring/data/jpa/query/datetime/ArticleRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/spring/data/jpa/query/datetime/ArticleRepositoryIntegrationTest.java
index e00a340615..b97fbc5275 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/spring/data/jpa/query/datetime/ArticleRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/spring/data/jpa/query/datetime/ArticleRepositoryIntegrationTest.java
@@ -17,7 +17,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 @RunWith(SpringRunner.class)
-@DataJpaTest(properties="spring.sql.init.data-locations=classpath:import_entities.sql")
+@DataJpaTest(properties="spring.sql.init.data-locations=classpath:import_entities.sql", showSql = false)
 public class ArticleRepositoryIntegrationTest {
 
     @Autowired
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/resources/fetching.cfg.xml b/persistence-modules/spring-data-jpa-query-2/src/test/resources/fetching.cfg.xml
index 55a3aeb51c..4d3ff2ae63 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/resources/fetching.cfg.xml
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/resources/fetching.cfg.xml
@@ -11,7 +11,7 @@
 		
 		org.hibernate.dialect.H2Dialect
 		update
-		true
+		false
 		
 		
         
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/resources/fetchingLazy.cfg.xml b/persistence-modules/spring-data-jpa-query-2/src/test/resources/fetchingLazy.cfg.xml
index 8fcf578660..8a2bf593cb 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/resources/fetchingLazy.cfg.xml
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/resources/fetchingLazy.cfg.xml
@@ -11,7 +11,7 @@
 		
 		org.hibernate.dialect.H2Dialect
 		update
-		true
+		false
 		
 		
 
diff --git a/persistence-modules/spring-data-jpa-query/src/main/resources/application.properties b/persistence-modules/spring-data-jpa-query/src/main/resources/application.properties
index 9bb870895d..eb0e519ef0 100644
--- a/persistence-modules/spring-data-jpa-query/src/main/resources/application.properties
+++ b/persistence-modules/spring-data-jpa-query/src/main/resources/application.properties
@@ -1,2 +1,2 @@
-spring.jpa.show-sql=true
+spring.jpa.show-sql=false
 spring.jpa.defer-datasource-initialization=true
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/aggregation/SpringDataAggregateIntegrationTest.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/aggregation/SpringDataAggregateIntegrationTest.java
index 779ade7a3f..a73ad949db 100644
--- a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/aggregation/SpringDataAggregateIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/aggregation/SpringDataAggregateIntegrationTest.java
@@ -16,8 +16,7 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 
 @RunWith(SpringRunner.class)
-@DataJpaTest
-
+@DataJpaTest(showSql = false)
 @Sql(scripts = "/test-aggregation-data.sql")
 public class SpringDataAggregateIntegrationTest {
 
diff --git a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java
index f082350019..d80380854d 100644
--- a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java
@@ -26,8 +26,7 @@ import static org.hamcrest.core.IsNot.not;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-
-@DataJpaTest
+@DataJpaTest(showSql = false)
 @RunWith(SpringRunner.class)
 public class PassengerRepositoryIntegrationTest {
 
diff --git a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/entitygraph/EntityGraphIntegrationTest.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/entitygraph/EntityGraphIntegrationTest.java
index 24880a5dff..b6bf51ac65 100644
--- a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/entitygraph/EntityGraphIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/entitygraph/EntityGraphIntegrationTest.java
@@ -14,7 +14,7 @@ import com.baeldung.entitygraph.model.Item;
 import com.baeldung.entitygraph.repository.CharacteristicsRepository;
 import com.baeldung.entitygraph.repository.ItemRepository;
 
-@DataJpaTest
+@DataJpaTest(showSql = false)
 @RunWith(SpringRunner.class)
 @Sql(scripts = "/entitygraph-data.sql")
 public class EntityGraphIntegrationTest {
diff --git a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/exists/CarRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/exists/CarRepositoryIntegrationTest.java
index d99f6671a3..53f22ed0d1 100644
--- a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/exists/CarRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/exists/CarRepositoryIntegrationTest.java
@@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.data.domain.Example;
 import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import java.util.Arrays;
diff --git a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/joins/JpaJoinsIntegrationTest.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/joins/JpaJoinsIntegrationTest.java
index 9b0d23f3e4..e24b2ae4b7 100644
--- a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/joins/JpaJoinsIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/joins/JpaJoinsIntegrationTest.java
@@ -13,10 +13,11 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
 import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.context.junit4.SpringRunner;
 
 @RunWith(SpringRunner.class)
-@DataJpaTest
+@DataJpaTest(showSql = false)
 @ActiveProfiles("joins")
 public class JpaJoinsIntegrationTest {
 
diff --git a/persistence-modules/spring-data-jpa-query/src/test/resources/logback-test.xml b/persistence-modules/spring-data-jpa-query/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/saveperformance/BookApplication.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/saveperformance/BookApplication.java
index 56ad918be3..46cb8d3453 100644
--- a/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/saveperformance/BookApplication.java
+++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/saveperformance/BookApplication.java
@@ -1,5 +1,7 @@
 package com.baeldung.spring.data.persistence.saveperformance;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -12,6 +14,8 @@ import java.util.List;
 @SpringBootApplication
 public class BookApplication {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(BookApplication.class);
+
     @Autowired
     private BookRepository bookRepository;
 
@@ -25,13 +29,13 @@ public class BookApplication {
         int bookCount = 10000;
 
         long start = System.currentTimeMillis();
-        for(int i = 0; i < bookCount; i++) {
+        for (int i = 0; i < bookCount; i++) {
             bookRepository.save(new Book("Book " + i, "Author " + i));
         }
         long end = System.currentTimeMillis();
         bookRepository.deleteAll();
 
-        System.out.println("It took " + (end - start) + "ms to execute save() for " + bookCount + " books");
+        LOGGER.debug("It took {}ms to execute save() for {} books.", (end - start), bookCount);
 
         List bookList = new ArrayList<>();
         for (int i = 0; i < bookCount; i++) {
@@ -42,7 +46,7 @@ public class BookApplication {
         bookRepository.saveAll(bookList);
         end = System.currentTimeMillis();
 
-        System.out.println("It took " + (end - start) + "ms to execute saveAll() with " + bookCount + " books\n");
+        LOGGER.debug("It took {}ms to execute saveAll() with {}} books.", (end - start), bookCount);
 
     }
 }
diff --git a/persistence-modules/spring-data-jpa-repo-2/src/test/resources/logback-test.xml b/persistence-modules/spring-data-jpa-repo-2/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-repo-2/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-repo/src/main/resources/application.properties b/persistence-modules/spring-data-jpa-repo/src/main/resources/application.properties
index ae1afe6e98..1a370121c5 100644
--- a/persistence-modules/spring-data-jpa-repo/src/main/resources/application.properties
+++ b/persistence-modules/spring-data-jpa-repo/src/main/resources/application.properties
@@ -1,4 +1,4 @@
-spring.jpa.show-sql=true
+spring.jpa.show-sql=false
 spring.jpa.defer-datasource-initialization=true
 #MySql
 #spring.datasource.url=jdbc:mysql://localhost:3306/baeldung
diff --git a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/boot/daos/JpaRepositoriesIntegrationTest.java b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/boot/daos/JpaRepositoriesIntegrationTest.java
index fe02f79a56..34de77a2b3 100644
--- a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/boot/daos/JpaRepositoriesIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/boot/daos/JpaRepositoriesIntegrationTest.java
@@ -21,7 +21,7 @@ import com.baeldung.boot.domain.Location;
 import com.baeldung.boot.domain.Store;
 
 @RunWith(SpringRunner.class)
-@DataJpaTest(properties="spring.sql.init.data-locations=classpath:import_entities.sql")
+@DataJpaTest(properties="spring.sql.init.data-locations=classpath:import_entities.sql", showSql = false)
 public class JpaRepositoriesIntegrationTest {
     @Autowired
     private LocationRepository locationRepository;
diff --git a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/repository/PassengerRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/repository/PassengerRepositoryIntegrationTest.java
index 37fcef7dab..fd06710084 100644
--- a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/repository/PassengerRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/repository/PassengerRepositoryIntegrationTest.java
@@ -18,7 +18,7 @@ import org.springframework.test.context.junit4.SpringRunner;
 
 import com.baeldung.entity.Passenger;
 
-@DataJpaTest
+@DataJpaTest(showSql = false)
 @RunWith(SpringRunner.class)
 public class PassengerRepositoryIntegrationTest {
 
diff --git a/persistence-modules/spring-data-jpa-repo/src/test/resources/logback-test.xml b/persistence-modules/spring-data-jpa-repo/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-repo/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/persistence-modules/spring-data-mongodb-reactive/pom.xml b/persistence-modules/spring-data-mongodb-reactive/pom.xml
index c1398ca80d..2220418ac3 100644
--- a/persistence-modules/spring-data-mongodb-reactive/pom.xml
+++ b/persistence-modules/spring-data-mongodb-reactive/pom.xml
@@ -71,7 +71,6 @@
         
             com.h2database
             h2
-            ${h2.version}
         
         
             org.apache.httpcomponents
@@ -126,7 +125,6 @@
     
         5.2.2.RELEASE
         4.5.2
-        1.4.200
         3.3.1.RELEASE
     
 
diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml
index 5e17f27c06..330f0d975a 100644
--- a/persistence-modules/spring-data-redis/pom.xml
+++ b/persistence-modules/spring-data-redis/pom.xml
@@ -42,10 +42,6 @@
             spring-boot-starter-test
             test
         
-        
-            org.junit.jupiter
-            junit-jupiter-api
-        
         
             org.junit.platform
             junit-platform-runner
@@ -78,7 +74,6 @@
             
                 org.apache.maven.plugins
                 maven-surefire-plugin
-                ${maven-surefire-plugin.version}
                 
                     true
                     false
diff --git a/persistence-modules/spring-data-solr/pom.xml b/persistence-modules/spring-data-solr/pom.xml
index d7523e6de2..c68c405137 100644
--- a/persistence-modules/spring-data-solr/pom.xml
+++ b/persistence-modules/spring-data-solr/pom.xml
@@ -45,7 +45,7 @@
     
 
     
-        2.0.5.RELEASE
+        4.3.14
     
 
 
\ No newline at end of file
diff --git a/persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/config/SolrConfig.java b/persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/config/SolrConfig.java
index 1fe1e5468b..54a9816114 100644
--- a/persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/config/SolrConfig.java
+++ b/persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/config/SolrConfig.java
@@ -9,13 +9,13 @@ import org.springframework.data.solr.core.SolrTemplate;
 import org.springframework.data.solr.repository.config.EnableSolrRepositories;
 
 @Configuration
-@EnableSolrRepositories(basePackages = "com.baeldung.spring.data.solr.repository", namedQueriesLocation = "classpath:solr-named-queries.properties", multicoreSupport = true)
+@EnableSolrRepositories(basePackages = "com.baeldung.spring.data.solr.repository", namedQueriesLocation = "classpath:solr-named-queries.properties")
 @ComponentScan
 public class SolrConfig {
 
     @Bean
     public SolrClient solrClient() {
-        return new HttpSolrClient("http://localhost:8983/solr");
+        return new HttpSolrClient.Builder("http://localhost:8983/solr").build();
     }
 
     @Bean
diff --git a/persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/repository/ProductRepository.java b/persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/repository/ProductRepository.java
index 5649cd7888..677073a58b 100644
--- a/persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/repository/ProductRepository.java
+++ b/persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/repository/ProductRepository.java
@@ -1,6 +1,7 @@
 package com.baeldung.spring.data.solr.repository;
 
 import java.util.List;
+import java.util.Optional;
 
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
@@ -11,6 +12,8 @@ import com.baeldung.spring.data.solr.model.Product;
 
 public interface ProductRepository extends SolrCrudRepository {
 
+    public Optional findById(String id);
+    
     public List findByName(String name);
 
     @Query("id:*?0* OR name:*?0*")
diff --git a/persistence-modules/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryLiveTest.java b/persistence-modules/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryLiveTest.java
index f86adcdc8a..2208ffadc0 100644
--- a/persistence-modules/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryLiveTest.java
+++ b/persistence-modules/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryLiveTest.java
@@ -1,4 +1,4 @@
-package com.baeldung.spring.data.solr.repo;
+	package com.baeldung.spring.data.solr.repo;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
@@ -36,7 +36,7 @@ public class ProductRepositoryLiveTest {
         product.setId("P000089998");
         product.setName("Desk");
         productRepository.save(product);
-        final Product retrievedProduct = productRepository.findOne(product.getId());
+        final Product retrievedProduct = productRepository.findById(product.getId()).get();
         assertEquals(product.getId(), retrievedProduct.getId());
     }
 
@@ -51,7 +51,7 @@ public class ProductRepositoryLiveTest {
         product.setName("Shirt");
         productRepository.save(product);
 
-        final Product retrievedProduct = productRepository.findOne(product.getId());
+        final Product retrievedProduct = productRepository.findById(product.getId()).get();
         assertEquals(product.getName(), retrievedProduct.getName());
     }
 
@@ -64,7 +64,7 @@ public class ProductRepositoryLiveTest {
 
         productRepository.delete(product);
 
-        Product retrievedProduct = productRepository.findOne(product.getId());
+        Product retrievedProduct = productRepository.findById(product.getId()).get();
         assertNull(retrievedProduct);
 
     }
@@ -97,7 +97,7 @@ public class ProductRepositoryLiveTest {
         wirelessCharger.setName("Phone Charging Cable");
         productRepository.save(wirelessCharger);
 
-        Page result = productRepository.findByCustomQuery("Phone", new PageRequest(0, 10));
+        Page result = productRepository.findByCustomQuery("Phone", PageRequest.of(0, 10));
         assertEquals(3, result.getNumberOfElements());
     }
 
@@ -118,7 +118,7 @@ public class ProductRepositoryLiveTest {
         wirelessCharger.setName("Phone Charging Cable");
         productRepository.save(wirelessCharger);
 
-        Page result = productRepository.findByNamedQuery("one", new PageRequest(0, 10));
+        Page result = productRepository.findByNamedQuery("one", PageRequest.of(0, 10));
         assertEquals(3, result.getNumberOfElements());
     }
 
diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/dynamicupdate/DynamicUpdateConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/dynamicupdate/DynamicUpdateConfig.java
index 4871a3d1e2..23e28a9e3b 100644
--- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/dynamicupdate/DynamicUpdateConfig.java
+++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/dynamicupdate/DynamicUpdateConfig.java
@@ -74,7 +74,7 @@ public class DynamicUpdateConfig {
         Properties properties = new Properties();
         properties.setProperty("hibernate.hbm2ddl.auto", Preconditions.checkNotNull(env.getProperty("hibernate.hbm2ddl.auto")));
         properties.setProperty("hibernate.dialect", Preconditions.checkNotNull(env.getProperty("hibernate.dialect")));
-        properties.setProperty("hibernate.show_sql", "true");
+        properties.setProperty("hibernate.show_sql", "false");
         return properties;
     }
 }
\ No newline at end of file
diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java
index 722f0251d1..aee4206e53 100644
--- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java
+++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java
@@ -6,8 +6,12 @@ import org.hibernate.SessionFactory;
 import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
 import org.hibernate.cfg.Configuration;
 import org.hibernate.service.ServiceRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class HibernateUtil {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(HibernateUtil.class);
     private static final SessionFactory sessionFactory = buildSessionFactory();
 
     private static SessionFactory buildSessionFactory() {
@@ -20,7 +24,7 @@ public class HibernateUtil {
             ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
             return configuration.buildSessionFactory(serviceRegistry);
         } catch (Throwable ex) {
-            System.out.println("Initial SessionFactory creation failed." + ex);
+            LOGGER.debug("Initial SessionFactory creation failed.", ex);
             throw new ExceptionInInitializerError(ex);
         }
     }
diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java
index 5f489dd027..29e8d7515a 100644
--- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java
+++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java
@@ -6,8 +6,12 @@ import org.hibernate.cfg.Configuration;
 import org.hibernate.service.ServiceRegistry;
 import com.baeldung.hibernate.manytomany.model.Employee;
 import com.baeldung.hibernate.manytomany.model.Project;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class HibernateUtil {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(HibernateUtil.class);
     private static SessionFactory sessionFactory;
 
     private static SessionFactory buildSessionFactory() {
@@ -17,25 +21,25 @@ public class HibernateUtil {
             configuration.addAnnotatedClass(Employee.class);
             configuration.addAnnotatedClass(Project.class);
             configuration.configure("manytomany.cfg.xml");
-            System.out.println("Hibernate Annotation Configuration loaded");
+            LOGGER.debug("Hibernate Annotation Configuration loaded");
 
             ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties())
-                .build();
-            System.out.println("Hibernate Annotation serviceRegistry created");
+                    .build();
+            LOGGER.debug("Hibernate Annotation serviceRegistry created");
 
             SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
 
             return sessionFactory;
         } catch (Throwable ex) {
-            System.err.println("Initial SessionFactory creation failed." + ex);
-            ex.printStackTrace();
+            LOGGER.error("Initial SessionFactory creation failed.", ex);
             throw new ExceptionInInitializerError(ex);
         }
     }
 
     public static SessionFactory getSessionFactory() {
-        if (sessionFactory == null)
+        if (sessionFactory == null) {
             sessionFactory = buildSessionFactory();
+        }
         return sessionFactory;
     }
 }
diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java
index 44cbfadb25..b8e7e1b2fd 100644
--- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java
+++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java
@@ -63,7 +63,7 @@ public class PersistenceConfig {
         final Properties hibernateProperties = new Properties();
         hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
         hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
-        hibernateProperties.setProperty("hibernate.show_sql", "true");
+        hibernateProperties.setProperty("hibernate.show_sql", "false");
      
         return hibernateProperties;
     }
diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java
index 74ac0a269e..159d6e2e8e 100644
--- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java
+++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java
@@ -71,7 +71,7 @@ public class PersistenceConfig {
         hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
         hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
 
-        hibernateProperties.setProperty("hibernate.show_sql", "true");
+        hibernateProperties.setProperty("hibernate.show_sql", "false");
 
         // Envers properties
         hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix"));
diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/immutable.cfg.xml b/persistence-modules/spring-hibernate-5/src/main/resources/immutable.cfg.xml
index a572ebeac2..4e55b4632f 100644
--- a/persistence-modules/spring-hibernate-5/src/main/resources/immutable.cfg.xml
+++ b/persistence-modules/spring-hibernate-5/src/main/resources/immutable.cfg.xml
@@ -23,7 +23,7 @@
         thread
 
         
-        true
+        false
 
         
         update
diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml b/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml
index 3c753a89af..315e2e3118 100644
--- a/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml
+++ b/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml
@@ -10,6 +10,6 @@
         tutorialuser
         org.hibernate.dialect.MySQLDialect
         thread
-        true
+        false
     
 
diff --git a/persistence-modules/spring-hibernate-5/src/test/resources/manytomany.cfg.xml b/persistence-modules/spring-hibernate-5/src/test/resources/manytomany.cfg.xml
index a7a23ec70d..2ca23d57d3 100644
--- a/persistence-modules/spring-hibernate-5/src/test/resources/manytomany.cfg.xml
+++ b/persistence-modules/spring-hibernate-5/src/test/resources/manytomany.cfg.xml
@@ -10,7 +10,7 @@
         sa
         org.hibernate.dialect.H2Dialect
         thread
-        true
+        false
         create-drop
     
 
diff --git a/persistence-modules/spring-jdbc/src/test/java/com/baeldung/spring/jdbc/template/guide/EmployeeDAOIntegrationTest.java b/persistence-modules/spring-jdbc/src/test/java/com/baeldung/spring/jdbc/template/guide/EmployeeDAOIntegrationTest.java
index c29d5c4534..b382895143 100644
--- a/persistence-modules/spring-jdbc/src/test/java/com/baeldung/spring/jdbc/template/guide/EmployeeDAOIntegrationTest.java
+++ b/persistence-modules/spring-jdbc/src/test/java/com/baeldung/spring/jdbc/template/guide/EmployeeDAOIntegrationTest.java
@@ -9,6 +9,8 @@ import com.baeldung.spring.jdbc.template.guide.config.SpringJdbcConfig;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.DuplicateKeyException;
 import org.springframework.test.context.ContextConfiguration;
@@ -19,6 +21,8 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader;
 @ContextConfiguration(classes = { SpringJdbcConfig.class }, loader = AnnotationConfigContextLoader.class)
 public class EmployeeDAOIntegrationTest {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(EmployeeDAOIntegrationTest.class);
+    
     @Autowired
     private EmployeeDAO employeeDao;
 
@@ -70,7 +74,7 @@ public class EmployeeDAOIntegrationTest {
         try {
             employeeDao.addEmplyee(7);
         } catch (final DuplicateKeyException e) {
-            System.out.println(e.getMessage());
+            LOGGER.error(e.getMessage(), e);
             Assert.assertTrue(e.getMessage().contains("Custome Exception translator - Integrity contraint voilation."));
         }
     }
diff --git a/persistence-modules/spring-jdbc/src/test/resources/logback-test.xml b/persistence-modules/spring-jdbc/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/spring-jdbc/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/persistence-modules/spring-jooq/pom.xml b/persistence-modules/spring-jooq/pom.xml
index 4c195a6c92..c842922fe5 100644
--- a/persistence-modules/spring-jooq/pom.xml
+++ b/persistence-modules/spring-jooq/pom.xml
@@ -76,7 +76,6 @@
             
                 org.apache.maven.plugins
                 maven-surefire-plugin
-                ${maven-surefire-plugin.version}
                 
                     0
                 
diff --git a/persistence-modules/spring-jpa-2/src/main/resources/persistence-h2.properties b/persistence-modules/spring-jpa-2/src/main/resources/persistence-h2.properties
index 716a96fde3..b429ce3a16 100644
--- a/persistence-modules/spring-jpa-2/src/main/resources/persistence-h2.properties
+++ b/persistence-modules/spring-jpa-2/src/main/resources/persistence-h2.properties
@@ -6,7 +6,7 @@ jdbc.pass=
 
 # hibernate.X
 hibernate.dialect=org.hibernate.dialect.H2Dialect
-hibernate.show_sql=true
+hibernate.show_sql=false
 hibernate.hbm2ddl.auto=create-drop
 hibernate.cache.use_second_level_cache=true
 hibernate.cache.use_query_cache=true
diff --git a/persistence-modules/spring-jpa-2/src/test/resources/logback-test.xml b/persistence-modules/spring-jpa-2/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/spring-jpa-2/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/persistence-modules/spring-jpa-2/src/test/resources/manytomany/test.properties b/persistence-modules/spring-jpa-2/src/test/resources/manytomany/test.properties
index 9e4236a6c2..db92a1b8c1 100644
--- a/persistence-modules/spring-jpa-2/src/test/resources/manytomany/test.properties
+++ b/persistence-modules/spring-jpa-2/src/test/resources/manytomany/test.properties
@@ -2,5 +2,5 @@ jdbc.driverClassName=org.h2.Driver
 jdbc.url=jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1
 
 hibernate.dialect=org.hibernate.dialect.H2Dialect
-hibernate.show_sql=true
+hibernate.show_sql=false
 hibernate.hbm2ddl.auto=validate
diff --git a/persistence-modules/spring-jpa/README.md b/persistence-modules/spring-jpa/README.md
index e849ec4a83..aa9e833260 100644
--- a/persistence-modules/spring-jpa/README.md
+++ b/persistence-modules/spring-jpa/README.md
@@ -5,8 +5,8 @@
 - [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)
 
 ### Eclipse Config 
diff --git a/persistence-modules/spring-jpa/pom.xml b/persistence-modules/spring-jpa/pom.xml
index 1dca2baa98..c0324e9efd 100644
--- a/persistence-modules/spring-jpa/pom.xml
+++ b/persistence-modules/spring-jpa/pom.xml
@@ -98,11 +98,6 @@
             guava
             ${guava.version}
         
-        
-            org.assertj
-            assertj-core
-            ${assertj.version}
-        
         
         
             org.apache.commons
@@ -132,7 +127,6 @@
         2.2.5
         
         21.0
-        3.8.0
     
 
 
\ No newline at end of file
diff --git a/persistence-modules/spring-jpa/src/main/resources/persistence-h2.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-h2.properties
index a3060cc796..72b51f02b7 100644
--- a/persistence-modules/spring-jpa/src/main/resources/persistence-h2.properties
+++ b/persistence-modules/spring-jpa/src/main/resources/persistence-h2.properties
@@ -6,5 +6,5 @@ jdbc.pass=
 
 # hibernate.X
 hibernate.dialect=org.hibernate.dialect.H2Dialect
-hibernate.show_sql=true
+hibernate.show_sql=false
 hibernate.hbm2ddl.auto=create-drop
\ No newline at end of file
diff --git a/persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties
index 405e6ff109..a5d2bec189 100644
--- a/persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties
+++ b/persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties
@@ -6,7 +6,7 @@ jdbc.pass=
 
 # hibernate.X
 hibernate.dialect=org.hibernate.dialect.H2Dialect
-hibernate.show_sql=true
+hibernate.show_sql=false
 hibernate.hbm2ddl.auto=create-drop
 hibernate.cache.use_second_level_cache=false
 hibernate.cache.use_query_cache=false
\ No newline at end of file
diff --git a/persistence-modules/spring-jpa/src/main/resources/persistence-student.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-student.properties
index d4c82420de..9a06518238 100644
--- a/persistence-modules/spring-jpa/src/main/resources/persistence-student.properties
+++ b/persistence-modules/spring-jpa/src/main/resources/persistence-student.properties
@@ -4,7 +4,7 @@ jdbc.user=tutorialuser
 jdbc.pass=tutorialpass
 
 hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
-hibernate.show_sql=true
+hibernate.show_sql=false
 hibernate.hbm2ddl.auto=create-drop
 
 hibernate.cache.use_second_level_cache=false
diff --git a/persistence-modules/spring-jpa/src/test/java/META-INF/persistence.xml b/persistence-modules/spring-jpa/src/test/java/META-INF/persistence.xml
index 495f076fef..76a3b61399 100644
--- a/persistence-modules/spring-jpa/src/test/java/META-INF/persistence.xml
+++ b/persistence-modules/spring-jpa/src/test/java/META-INF/persistence.xml
@@ -11,7 +11,7 @@
             
             
             
-            
+            
             
             
         
diff --git a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java
index fbda459d65..66f20a6724 100644
--- a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java
+++ b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java
@@ -20,6 +20,8 @@ import com.baeldung.persistence.model.Foo;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.context.ContextConfiguration;
@@ -31,6 +33,8 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader;
 @DirtiesContext
 public class FooPaginationPersistenceIntegrationTest {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(FooPaginationPersistenceIntegrationTest.class);
+    
     @PersistenceContext
     private EntityManager entityManager;
 
@@ -137,7 +141,7 @@ public class FooPaginationPersistenceIntegrationTest {
             typedQuery = entityManager.createQuery(select);
             typedQuery.setFirstResult(pageNumber - 1);
             typedQuery.setMaxResults(pageSize);
-            System.out.println("Current page: " + typedQuery.getResultList());
+            LOGGER.debug("Current page: {}", typedQuery.getResultList());
             pageNumber += pageSize;
         }
 
diff --git a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingIntegrationTest.java
index c3db45ab41..8d1f94edf8 100644
--- a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingIntegrationTest.java
+++ b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingIntegrationTest.java
@@ -15,6 +15,8 @@ import com.baeldung.persistence.model.Bar;
 import com.baeldung.persistence.model.Foo;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -26,6 +28,8 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader;
 @SuppressWarnings("unchecked")
 public class FooServiceSortingIntegrationTest {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(FooServiceSortingIntegrationTest.class);
+
     @PersistenceContext
     private EntityManager entityManager;
 
@@ -37,7 +41,7 @@ public class FooServiceSortingIntegrationTest {
         final Query sortQuery = entityManager.createQuery(jql);
         final List fooList = sortQuery.getResultList();
         for (final Foo foo : fooList) {
-            System.out.println("Name:" + foo.getName() + "-------Id:" + foo.getId());
+            LOGGER.debug("Name:{}-------Id:{}", foo.getName(), foo.getId());
         }
     }
 
@@ -47,7 +51,7 @@ public class FooServiceSortingIntegrationTest {
         final Query sortQuery = entityManager.createQuery(jql);
         final List fooList = sortQuery.getResultList();
         for (final Foo foo : fooList) {
-            System.out.println("Name:" + foo.getName() + "-------Id:" + foo.getId());
+            LOGGER.debug("Name:{}-------Id:{}", foo.getName(), foo.getId());
         }
     }
 
@@ -57,7 +61,7 @@ public class FooServiceSortingIntegrationTest {
         final Query sortQuery = entityManager.createQuery(jql);
         final List fooList = sortQuery.getResultList();
         for (final Foo foo : fooList) {
-            System.out.println("Name:" + foo.getName() + "-------Id:" + foo.getId());
+            LOGGER.debug("Name:{}-------Id:{}", foo.getName(), foo.getId());
         }
     }
 
@@ -67,9 +71,9 @@ public class FooServiceSortingIntegrationTest {
         final Query barJoinQuery = entityManager.createQuery(jql);
         final List fooList = barJoinQuery.getResultList();
         for (final Foo foo : fooList) {
-            System.out.println("Name:" + foo.getName());
+            LOGGER.debug("Name:{}", foo.getName());
             if (foo.getBar() != null) {
-                System.out.print("-------BarId:" + foo.getBar().getId());
+                LOGGER.debug("-------BarId:{}", foo.getBar().getId());
             }
         }
     }
@@ -80,9 +84,9 @@ public class FooServiceSortingIntegrationTest {
         final Query barQuery = entityManager.createQuery(jql);
         final List barList = barQuery.getResultList();
         for (final Bar bar : barList) {
-            System.out.println("Bar Id:" + bar.getId());
+            LOGGER.debug("Bar Id:{}", bar.getId());
             for (final Foo foo : bar.getFooList()) {
-                System.out.println("FooName:" + foo.getName());
+                LOGGER.debug("FooName:{}", foo.getName());
             }
         }
     }
@@ -97,7 +101,7 @@ public class FooServiceSortingIntegrationTest {
         final TypedQuery typedQuery = entityManager.createQuery(select);
         final List fooList = typedQuery.getResultList();
         for (final Foo foo : fooList) {
-            System.out.println("Name:" + foo.getName() + "--------Id:" + foo.getId());
+            LOGGER.debug("Name:{}-------Id:{}", foo.getName(), foo.getId());
         }
     }
 
@@ -111,7 +115,7 @@ public class FooServiceSortingIntegrationTest {
         final TypedQuery typedQuery = entityManager.createQuery(select);
         final List fooList = typedQuery.getResultList();
         for (final Foo foo : fooList) {
-            System.out.println("Name:" + foo.getName() + "-------Id:" + foo.getId());
+            LOGGER.debug("Name:{}-------Id:{}", foo.getName(), foo.getId());
         }
     }
 
diff --git a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java
index 103321fc64..b19259d9df 100644
--- a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java
+++ b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java
@@ -13,6 +13,8 @@ import com.baeldung.config.PersistenceJPAConfig;
 import com.baeldung.persistence.model.Foo;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.context.ContextConfiguration;
@@ -24,6 +26,8 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader;
 @DirtiesContext
 public class FooServiceSortingWitNullsManualIntegrationTest {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(FooServiceSortingWitNullsManualIntegrationTest.class);
+    
     @PersistenceContext
     private EntityManager entityManager;
 
@@ -43,7 +47,7 @@ public class FooServiceSortingWitNullsManualIntegrationTest {
         final List fooList = sortQuery.getResultList();
         assertNull(fooList.get(fooList.toArray().length - 1).getName());
         for (final Foo foo : fooList) {
-            System.out.println("Name:" + foo.getName());
+            LOGGER.debug("Name:{}", foo.getName());
         }
     }
 
@@ -57,7 +61,7 @@ public class FooServiceSortingWitNullsManualIntegrationTest {
         final List fooList = sortQuery.getResultList();
         assertNull(fooList.get(0).getName());
         for (final Foo foo : fooList) {
-            System.out.println("Name:" + foo.getName());
+            LOGGER.debug("Name:{}", foo.getName());
         }
     }
 
diff --git a/persistence-modules/spring-jpa/src/test/resources/persistence-student.properties b/persistence-modules/spring-jpa/src/test/resources/persistence-student.properties
index 3b6b580630..9ca389d6ab 100644
--- a/persistence-modules/spring-jpa/src/test/resources/persistence-student.properties
+++ b/persistence-modules/spring-jpa/src/test/resources/persistence-student.properties
@@ -2,7 +2,7 @@ jdbc.driverClassName=org.h2.Driver
 jdbc.url=jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1
 
 hibernate.dialect=org.hibernate.dialect.H2Dialect
-hibernate.show_sql=true
+hibernate.show_sql=false
 hibernate.hbm2ddl.auto=create
 
 hibernate.cache.use_second_level_cache=false
diff --git a/persistence-modules/spring-mybatis/pom.xml b/persistence-modules/spring-mybatis/pom.xml
index 1a55e76900..4eda66e1a9 100644
--- a/persistence-modules/spring-mybatis/pom.xml
+++ b/persistence-modules/spring-mybatis/pom.xml
@@ -64,12 +64,6 @@
             ${org.springframework.version}
             test
         
-        
-            org.assertj
-            assertj-core
-            ${assertj-core.version}
-            test
-        
     
 
     
@@ -90,8 +84,6 @@
         3.5.2
         2.1.0
         1.4.197
-        
-        3.8.0
     
 
 
\ No newline at end of file
diff --git a/persistence-modules/spring-mybatis/src/test/resources/logback-test.xml b/persistence-modules/spring-mybatis/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/spring-mybatis/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/persistence-modules/spring-persistence-simple/pom.xml b/persistence-modules/spring-persistence-simple/pom.xml
index 437a439b99..ec7c8bd3a0 100644
--- a/persistence-modules/spring-persistence-simple/pom.xml
+++ b/persistence-modules/spring-persistence-simple/pom.xml
@@ -92,7 +92,6 @@
         2.2
         1.3
         2.2.7.RELEASE
-        1.4.200
         
         0.23.0
         
diff --git a/persistence-modules/spring-persistence-simple/src/test/resources/logback-test.xml b/persistence-modules/spring-persistence-simple/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/spring-persistence-simple/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+    
+        
+            [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+        
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index f2a53f38b7..ad002650d7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,6 +7,9 @@
     com.baeldung
     parent-modules
     1.0.0-SNAPSHOT
+    
+        spring-5-webflux-2
+    
     parent-modules
     pom
 
@@ -58,6 +61,12 @@
             ${junit-jupiter.version}
             test
         
+        
+            org.assertj
+            assertj-core
+            ${assertj.version}
+            test
+        
         
             org.hamcrest
             hamcrest
@@ -113,11 +122,6 @@
                     
                 
                 
-                    
-                        org.junit.platform
-                        junit-platform-surefire-provider
-                        ${junit-platform-surefire-provider.version}
-                    
                     
                         org.junit.jupiter
                         junit-jupiter-engine
@@ -294,7 +298,6 @@
             default-first
             
                 
-
                     
                         org.apache.maven.plugins
                         maven-surefire-plugin
@@ -314,6 +317,9 @@
                                 **/JdbcTest.java
                                 **/*LiveTest.java
                             
+                            
+                                ${tutorialsproject.basedir}/logback-config.xml
+                            
                         
                     
 
@@ -472,7 +478,6 @@
                 json-path
                 jsoup
                 jta
-                junit5
                 kubernetes
                 ksqldb
                  
@@ -581,6 +586,9 @@
                                 **/*JdbcTest.java
                                 **/*LiveTest.java
                             
+                            
+                                ${tutorialsproject.basedir}/logback-config.xml
+                            
                         
                     
 
@@ -610,6 +618,7 @@
                 spring-5-reactive-oauth
                 spring-5-reactive-security
                 spring-5-webflux
+                spring-5-webflux-2
 
                 spring-activiti
                 spring-akka
@@ -764,6 +773,8 @@
                 libraries-5
                 libraries-6
 
+                spring-boot-modules/spring-boot-react
+
                 vaadin
                 vavr
                 vavr-2
@@ -787,6 +798,9 @@
                                 **/*IntegrationTest.java
                                 **/*IntTest.java
                             
+                            
+                                ${tutorialsproject.basedir}/logback-config.xml
+                            
                         
                     
                 
@@ -1044,6 +1058,9 @@
                                 **/*IntegrationTest.java
                                 **/*IntTest.java
                             
+                            
+                                ${tutorialsproject.basedir}/logback-config.xml
+                            
                         
                     
                 
@@ -1217,6 +1234,8 @@
                 libraries-5
                 libraries-6
 
+                spring-boot-modules/spring-boot-react
+
                 vaadin
                 vavr
                 vavr-2
@@ -1305,11 +1324,15 @@
                  core-java-modules/core-java-jpms
                  core-java-modules/core-java-os
                  core-java-modules/core-java-string-operations-3
+                 core-java-modules/core-java-string-operations-4
                  core-java-modules/core-java-time-measurements
+                 core-java-modules/core-java-networking-3
                  core-java-modules/multimodulemavenproject
                  persistence-modules/sirix
                  quarkus-vs-springboot
+                 quarkus-jandex
                  spring-boot-modules/spring-boot-cassandre
+                 testing-modules/testing-assertions
             
         
 
@@ -1357,11 +1380,13 @@
                 core-java-modules/core-java-os
                 core-java-modules/core-java-string-operations-3
                 core-java-modules/core-java-time-measurements
+                core-java-modules/core-java-networking-3
                 core-java-modules/multimodulemavenproject
                 core-java-modules/core-java-strings
                 persistence-modules/sirix
                 quarkus-vs-springboot
                 spring-boot-modules/spring-boot-cassandre
+                testing-modules/testing-assertions
             
         
     
@@ -1388,6 +1413,7 @@
 
         
         4.13.2
+        3.21.0
         2.2
         1.3
         3.3.0
@@ -1398,8 +1424,7 @@
         1.2.6
 
         
-        
-        2.21.0
+        2.22.2
         3.8.1
         3.0.0
         1.8
@@ -1408,6 +1433,7 @@
         1.33
         1.33
         2.21.0
+        4.4
         2.11.0
         2.6
         3.12.0
@@ -1430,7 +1456,7 @@
         
         3.13.0
         1.18.20
-        1.4.197
+        1.4.200
     
 
 
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-jandex/hello-app/.dockerignore b/quarkus-jandex/hello-app/.dockerignore
new file mode 100644
index 0000000000..94810d006e
--- /dev/null
+++ b/quarkus-jandex/hello-app/.dockerignore
@@ -0,0 +1,5 @@
+*
+!target/*-runner
+!target/*-runner.jar
+!target/lib/*
+!target/quarkus-app/*
\ No newline at end of file
diff --git a/quarkus-jandex/hello-app/.gitignore b/quarkus-jandex/hello-app/.gitignore
new file mode 100644
index 0000000000..bdf57ce3b4
--- /dev/null
+++ b/quarkus-jandex/hello-app/.gitignore
@@ -0,0 +1,39 @@
+#Maven
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+release.properties
+
+# Eclipse
+.project
+.classpath
+.settings/
+bin/
+
+# IntelliJ
+.idea
+*.ipr
+*.iml
+*.iws
+
+# NetBeans
+nb-configuration.xml
+
+# Visual Studio Code
+.vscode
+.factorypath
+
+# OSX
+.DS_Store
+
+# Vim
+*.swp
+*.swo
+
+# patch
+*.orig
+*.rej
+
+# Local environment
+.env
diff --git a/quarkus-jandex/hello-app/.mvn/wrapper/MavenWrapperDownloader.java b/quarkus-jandex/hello-app/.mvn/wrapper/MavenWrapperDownloader.java
new file mode 100644
index 0000000000..c39041cdf6
--- /dev/null
+++ b/quarkus-jandex/hello-app/.mvn/wrapper/MavenWrapperDownloader.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+    private static final String WRAPPER_VERSION = "0.5.6";
+    /**
+     * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+     */
+    private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+    /**
+     * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+     * use instead of the default one.
+     */
+    private static final String MAVEN_WRAPPER_PROPERTIES_PATH = ".mvn/wrapper/maven-wrapper.properties";
+
+    /**
+     * Path where the maven-wrapper.jar will be saved to.
+     */
+    private static final String MAVEN_WRAPPER_JAR_PATH = ".mvn/wrapper/maven-wrapper.jar";
+
+    /**
+     * Name of the property which should be used to override the default download url for the wrapper.
+     */
+    private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+    public static void main(String args[]) {
+        System.out.println("- Downloader started");
+        File baseDirectory = new File(args[0]);
+        System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+        // If the maven-wrapper.properties exists, read it and check if it contains a custom
+        // wrapperUrl parameter.
+        File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+        String url = DEFAULT_DOWNLOAD_URL;
+        if (mavenWrapperPropertyFile.exists()) {
+            FileInputStream mavenWrapperPropertyFileInputStream = null;
+            try {
+                mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+                Properties mavenWrapperProperties = new Properties();
+                mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+                url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+            } catch (IOException e) {
+                System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+            } finally {
+                try {
+                    if (mavenWrapperPropertyFileInputStream != null) {
+                        mavenWrapperPropertyFileInputStream.close();
+                    }
+                } catch (IOException e) {
+                    // Ignore ...
+                }
+            }
+        }
+        System.out.println("- Downloading from: " + url);
+
+        File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+        if (!outputFile.getParentFile().exists()) {
+            if (!outputFile.getParentFile().mkdirs()) {
+                System.out.println("- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+            }
+        }
+        System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+        try {
+            downloadFileFromURL(url, outputFile);
+            System.out.println("Done");
+            System.exit(0);
+        } catch (Throwable e) {
+            System.out.println("- Error downloading");
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+        if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+            String username = System.getenv("MVNW_USERNAME");
+            char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+            Authenticator.setDefault(new Authenticator() {
+                @Override
+                protected PasswordAuthentication getPasswordAuthentication() {
+                    return new PasswordAuthentication(username, password);
+                }
+            });
+        }
+        URL website = new URL(urlString);
+        ReadableByteChannel rbc;
+        rbc = Channels.newChannel(website.openStream());
+        FileOutputStream fos = new FileOutputStream(destination);
+        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+        fos.close();
+        rbc.close();
+    }
+
+}
diff --git a/quarkus-jandex/hello-app/.mvn/wrapper/maven-wrapper.properties b/quarkus-jandex/hello-app/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000000..ffdc10e59f
--- /dev/null
+++ b/quarkus-jandex/hello-app/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
diff --git a/quarkus-jandex/hello-app/README.md b/quarkus-jandex/hello-app/README.md
new file mode 100644
index 0000000000..769709eb00
--- /dev/null
+++ b/quarkus-jandex/hello-app/README.md
@@ -0,0 +1,51 @@
+# Hello App with Quarkus
+
+## Running the application in dev mode
+
+You can run your application in dev mode that enables live coding using:
+
+```shell script
+./mvnw compile quarkus:dev
+```
+
+You can then find the app using `http://localhost:8080`.
+
+> **_NOTE:_**  Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/.
+
+## Packaging and running the application
+
+The application can be packaged using:
+
+```shell script
+./mvnw package
+```
+
+It produces the `quarkus-run.jar` file in the `target/quarkus-app/` directory. Be aware that it’s not an _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib/` directory.
+
+The application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`.
+
+If you want to build an _über-jar_, execute the following command:
+
+```shell script
+./mvnw package -Dquarkus.package.type=uber-jar
+```
+
+The application, packaged as an _über-jar_, is now runnable using `java -jar target/*-runner.jar`.
+
+## Creating a native executable
+
+You can create a native executable using:
+
+```shell script
+./mvnw package -Pnative
+```
+
+Or, if you don't have GraalVM installed, you can run the native executable build in a container using:
+
+```shell script
+./mvnw package -Pnative -Dquarkus.native.container-build=true
+```
+
+You can then execute your native executable with: `./target/quarkus-sample-1.0-SNAPSHOT-runner`
+
+If you want to learn more about building native executables, please consult https://quarkus.io/guides/maven-tooling.html.
diff --git a/spring-boot-modules/spring-boot-keycloak/mvnw b/quarkus-jandex/hello-app/mvnw
old mode 100755
new mode 100644
similarity index 62%
rename from spring-boot-modules/spring-boot-keycloak/mvnw
rename to quarkus-jandex/hello-app/mvnw
index 5bf251c077..a16b5431b4
--- a/spring-boot-modules/spring-boot-keycloak/mvnw
+++ b/quarkus-jandex/hello-app/mvnw
@@ -8,7 +8,7 @@
 # "License"); you may not use this file except in compliance
 # with the License.  You may obtain a copy of the License at
 #
-#    http://www.apache.org/licenses/LICENSE-2.0
+#    https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing,
 # software distributed under the License is distributed on an
@@ -19,7 +19,7 @@
 # ----------------------------------------------------------------------------
 
 # ----------------------------------------------------------------------------
-# Maven2 Start Up Batch script
+# Maven Start Up Batch script
 #
 # Required ENV vars:
 # ------------------
@@ -108,13 +108,12 @@ if $cygwin ; then
     CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
 fi
 
-# For Migwn, ensure paths are in UNIX format before anything is touched
+# For Mingw, ensure paths are in UNIX format before anything is touched
 if $mingw ; then
   [ -n "$M2_HOME" ] &&
     M2_HOME="`(cd "$M2_HOME"; pwd)`"
   [ -n "$JAVA_HOME" ] &&
     JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
-  # TODO classpath?
 fi
 
 if [ -z "$JAVA_HOME" ]; then
@@ -200,8 +199,89 @@ if [ -z "$BASE_DIR" ]; then
   exit 1;
 fi
 
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found .mvn/wrapper/maven-wrapper.jar"
+    fi
+else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+    fi
+    if [ -n "$MVNW_REPOURL" ]; then
+      jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    else
+      jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    fi
+    while IFS="=" read key value; do
+      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+      esac
+    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Downloading from: $jarUrl"
+    fi
+    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+    if $cygwin; then
+      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+    fi
+
+    if command -v wget > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found wget ... using wget"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget "$jarUrl" -O "$wrapperJarPath"
+        else
+            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found curl ... using curl"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl -o "$wrapperJarPath" "$jarUrl" -f
+        else
+            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+        fi
+
+    else
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Falling back to using Java to download"
+        fi
+        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaClass=`cygpath --path --windows "$javaClass"`
+        fi
+        if [ -e "$javaClass" ]; then
+            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Compiling MavenWrapperDownloader.java ..."
+                fi
+                # Compiling the Java class
+                ("$JAVA_HOME/bin/javac" "$javaClass")
+            fi
+            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                # Running the downloader
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Running MavenWrapperDownloader.java ..."
+                fi
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
 export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
-echo $MAVEN_PROJECTBASEDIR
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+fi
 MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
 
 # For Cygwin, switch paths to Windows format before running java
@@ -216,6 +296,11 @@ if $cygwin; then
     MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
 fi
 
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
 WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
 
 exec "$JAVACMD" \
diff --git a/spring-boot-modules/spring-boot-keycloak/mvnw.cmd b/quarkus-jandex/hello-app/mvnw.cmd
similarity index 72%
rename from spring-boot-modules/spring-boot-keycloak/mvnw.cmd
rename to quarkus-jandex/hello-app/mvnw.cmd
index 019bd74d76..c8d43372c9 100644
--- a/spring-boot-modules/spring-boot-keycloak/mvnw.cmd
+++ b/quarkus-jandex/hello-app/mvnw.cmd
@@ -7,7 +7,7 @@
 @REM "License"); you may not use this file except in compliance
 @REM with the License.  You may obtain a copy of the License at
 @REM
-@REM    http://www.apache.org/licenses/LICENSE-2.0
+@REM    https://www.apache.org/licenses/LICENSE-2.0
 @REM
 @REM Unless required by applicable law or agreed to in writing,
 @REM software distributed under the License is distributed on an
@@ -18,7 +18,7 @@
 @REM ----------------------------------------------------------------------------
 
 @REM ----------------------------------------------------------------------------
-@REM Maven2 Start Up Batch script
+@REM Maven Start Up Batch script
 @REM
 @REM Required ENV vars:
 @REM JAVA_HOME - location of a JDK home dir
@@ -26,7 +26,7 @@
 @REM Optional ENV vars
 @REM M2_HOME - location of maven2's installed home dir
 @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
 @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
 @REM     e.g. to debug Maven itself, use
 @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@@ -35,7 +35,9 @@
 
 @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
 @echo off
-@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
 @if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
 
 @REM set %HOME% to equivalent of $HOME
@@ -115,10 +117,47 @@ for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do s
 :endReadAdditionalConfig
 
 SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
-
 set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
 set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
 
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
 %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
 if ERRORLEVEL 1 goto error
 goto end
diff --git a/quarkus-jandex/hello-app/pom.xml b/quarkus-jandex/hello-app/pom.xml
new file mode 100644
index 0000000000..8da874a1c7
--- /dev/null
+++ b/quarkus-jandex/hello-app/pom.xml
@@ -0,0 +1,131 @@
+
+
+    4.0.0
+
+    
+        com.baeldung.quarkus
+        quarkus-jandex
+        1.0.0-SNAPSHOT
+    
+
+    hello-app
+
+    
+        
+            io.quarkus
+            quarkus-resteasy
+        
+        
+            io.quarkus
+            quarkus-arc
+        
+        
+            io.quarkus
+            quarkus-junit5
+            test
+        
+        
+            io.rest-assured
+            rest-assured
+            test
+        
+        
+            ${project.groupId}
+            hello-service
+            ${project.version}
+        
+        
+            ${project.groupId}
+            hello-sender-beans-xml
+            ${project.version}
+        
+        
+            ${project.groupId}
+            hello-sender-maven-plugin
+            ${project.version}
+        
+        
+            ${project.groupId}
+            hello-sender-application-properties
+            ${project.version}
+        
+        
+            ${project.groupId}
+            hello-sender-undetected
+            ${project.version}
+        
+    
+    
+        
+            
+                ${quarkus.platform.group-id}
+                quarkus-maven-plugin
+                ${quarkus.platform.version}
+                true
+                
+                    
+                        
+                            build
+                            generate-code
+                            generate-code-tests
+                        
+                    
+                
+            
+            
+                maven-compiler-plugin
+                ${compiler-plugin.version}
+                
+                    ${maven.compiler.parameters}
+                
+            
+            
+                maven-surefire-plugin
+                ${surefire-plugin.version}
+                
+                    
+                        org.jboss.logmanager.LogManager
+                        ${maven.home}
+                    
+                
+            
+        
+    
+    
+        
+            native
+            
+                
+                    native
+                
+            
+            
+                
+                    
+                        maven-failsafe-plugin
+                        ${surefire-plugin.version}
+                        
+                            
+                                
+                                    integration-test
+                                    verify
+                                
+                                
+                                    
+                                        ${project.build.directory}/${project.build.finalName}-runner
+                                        org.jboss.logmanager.LogManager
+                                        ${maven.home}
+                                    
+                                
+                            
+                        
+                    
+                
+            
+            
+                native
+            
+        
+    
+
diff --git a/quarkus-jandex/hello-app/src/main/docker/Dockerfile.jvm b/quarkus-jandex/hello-app/src/main/docker/Dockerfile.jvm
new file mode 100644
index 0000000000..3eb1b4de84
--- /dev/null
+++ b/quarkus-jandex/hello-app/src/main/docker/Dockerfile.jvm
@@ -0,0 +1,55 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
+#
+# Before building the container image run:
+#
+# ./mvnw package
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/quarkus-sample-jvm .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-sample-jvm
+#
+# If you want to include the debug port into your docker image
+# you will have to expose the debug port (default 5005) like this :  EXPOSE 8080 5005
+#
+# Then run the container using :
+#
+# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-sample-jvm
+#
+###
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.4 
+
+ARG JAVA_PACKAGE=java-11-openjdk-headless
+ARG RUN_JAVA_VERSION=1.3.8
+ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
+# Install java and the run-java script
+# Also set up permissions for user `1001`
+RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
+    && microdnf update \
+    && microdnf clean all \
+    && mkdir /deployments \
+    && chown 1001 /deployments \
+    && chmod "g+rwX" /deployments \
+    && chown 1001:root /deployments \
+    && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
+    && chown 1001 /deployments/run-java.sh \
+    && chmod 540 /deployments/run-java.sh \
+    && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/conf/security/java.security
+
+# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
+ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+# We make four distinct layers so if there are application changes the library layers can be re-used
+COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/
+COPY --chown=1001 target/quarkus-app/*.jar /deployments/
+COPY --chown=1001 target/quarkus-app/app/ /deployments/app/
+COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/
+
+EXPOSE 8080
+USER 1001
+
+ENTRYPOINT [ "/deployments/run-java.sh" ]
+
diff --git a/quarkus-jandex/hello-app/src/main/docker/Dockerfile.legacy-jar b/quarkus-jandex/hello-app/src/main/docker/Dockerfile.legacy-jar
new file mode 100644
index 0000000000..f32188a45d
--- /dev/null
+++ b/quarkus-jandex/hello-app/src/main/docker/Dockerfile.legacy-jar
@@ -0,0 +1,51 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
+#
+# Before building the container image run:
+#
+# ./mvnw package -Dquarkus.package.type=legacy-jar
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/quarkus-sample-legacy-jar .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-sample-legacy-jar
+#
+# If you want to include the debug port into your docker image
+# you will have to expose the debug port (default 5005) like this :  EXPOSE 8080 5005
+#
+# Then run the container using :
+#
+# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-sample-legacy-jar
+#
+###
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.4 
+
+ARG JAVA_PACKAGE=java-11-openjdk-headless
+ARG RUN_JAVA_VERSION=1.3.8
+ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
+# Install java and the run-java script
+# Also set up permissions for user `1001`
+RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
+    && microdnf update \
+    && microdnf clean all \
+    && mkdir /deployments \
+    && chown 1001 /deployments \
+    && chmod "g+rwX" /deployments \
+    && chown 1001:root /deployments \
+    && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
+    && chown 1001 /deployments/run-java.sh \
+    && chmod 540 /deployments/run-java.sh \
+    && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/conf/security/java.security
+
+# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
+ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+COPY target/lib/* /deployments/lib/
+COPY target/*-runner.jar /deployments/app.jar
+
+EXPOSE 8080
+USER 1001
+
+ENTRYPOINT [ "/deployments/run-java.sh" ]
diff --git a/quarkus-jandex/hello-app/src/main/docker/Dockerfile.native b/quarkus-jandex/hello-app/src/main/docker/Dockerfile.native
new file mode 100644
index 0000000000..4fa16507fe
--- /dev/null
+++ b/quarkus-jandex/hello-app/src/main/docker/Dockerfile.native
@@ -0,0 +1,27 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode
+#
+# Before building the container image run:
+#
+# ./mvnw package -Pnative
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-sample .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-sample
+#
+###
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.4
+WORKDIR /work/
+RUN chown 1001 /work \
+    && chmod "g+rwX" /work \
+    && chown 1001:root /work
+COPY --chown=1001:root target/*-runner /work/application
+
+EXPOSE 8080
+USER 1001
+
+CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
diff --git a/quarkus-jandex/hello-app/src/main/docker/Dockerfile.native-distroless b/quarkus-jandex/hello-app/src/main/docker/Dockerfile.native-distroless
new file mode 100644
index 0000000000..86370b0a0b
--- /dev/null
+++ b/quarkus-jandex/hello-app/src/main/docker/Dockerfile.native-distroless
@@ -0,0 +1,23 @@
+####
+# This Dockerfile is used in order to build a distroless container that runs the Quarkus application in native (no JVM) mode
+#
+# Before building the container image run:
+#
+# ./mvnw package -Pnative
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.native-distroless -t quarkus/quarkus-sample .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-sample
+#
+###
+FROM quay.io/quarkus/quarkus-distroless-image:1.0
+COPY target/*-runner /application
+
+EXPOSE 8080
+USER nonroot
+
+CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
diff --git a/quarkus-jandex/hello-app/src/main/java/com/baeldung/quarkus/hello/HelloResource.java b/quarkus-jandex/hello-app/src/main/java/com/baeldung/quarkus/hello/HelloResource.java
new file mode 100644
index 0000000000..1867527327
--- /dev/null
+++ b/quarkus-jandex/hello-app/src/main/java/com/baeldung/quarkus/hello/HelloResource.java
@@ -0,0 +1,26 @@
+package com.baeldung.quarkus.hello;
+
+import com.baeldung.quarkus.hello.service.HelloService;
+
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("/hello")
+public class HelloResource {
+
+    @Inject
+    HelloService service;
+
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String hello() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Those are saying hello:\n=======================\n\n");
+        service.sendHello(s -> sb.append(" - ").append(s).append("\n"));
+        return sb.toString();
+    }
+
+}
diff --git a/quarkus-jandex/hello-app/src/main/resources/META-INF/resources/index.html b/quarkus-jandex/hello-app/src/main/resources/META-INF/resources/index.html
new file mode 100644
index 0000000000..ba625a1420
--- /dev/null
+++ b/quarkus-jandex/hello-app/src/main/resources/META-INF/resources/index.html
@@ -0,0 +1,14 @@
+
+
+
+    
+    qHello App
+
+
+
+

Hello App

+ +This app demonstrates how Quarkus resolves CDI managed beans. You can find the output of all resolved beans by invoking the Hello Resource. + + + diff --git a/quarkus-jandex/hello-app/src/main/resources/application.properties b/quarkus-jandex/hello-app/src/main/resources/application.properties new file mode 100644 index 0000000000..95ff9889c7 --- /dev/null +++ b/quarkus-jandex/hello-app/src/main/resources/application.properties @@ -0,0 +1,2 @@ +quarkus.index-dependency.hello-sender.group-id=com.baeldung.quarkus +quarkus.index-dependency.hello-sender.artifact-id=hello-sender-application-properties diff --git a/quarkus-jandex/hello-sender-application-properties/pom.xml b/quarkus-jandex/hello-sender-application-properties/pom.xml new file mode 100644 index 0000000000..01784b44f4 --- /dev/null +++ b/quarkus-jandex/hello-sender-application-properties/pom.xml @@ -0,0 +1,26 @@ + + + + com.baeldung.quarkus + quarkus-jandex + 1.0.0-SNAPSHOT + + 4.0.0 + + hello-sender-application-properties + + + + io.quarkus + quarkus-arc + + + ${project.groupId} + hello-service + ${project.version} + + + + diff --git a/quarkus-jandex/hello-sender-application-properties/src/main/java/com/baeldung/quarkus/hello/sender/applicationproperties/ApplicationPropertiesHelloSender.java b/quarkus-jandex/hello-sender-application-properties/src/main/java/com/baeldung/quarkus/hello/sender/applicationproperties/ApplicationPropertiesHelloSender.java new file mode 100644 index 0000000000..ffd495e92e --- /dev/null +++ b/quarkus-jandex/hello-sender-application-properties/src/main/java/com/baeldung/quarkus/hello/sender/applicationproperties/ApplicationPropertiesHelloSender.java @@ -0,0 +1,15 @@ +package com.baeldung.quarkus.hello.sender.applicationproperties; + +import com.baeldung.quarkus.hello.service.HelloRetrieving; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Observes; + +@ApplicationScoped +public class ApplicationPropertiesHelloSender { + + public void sendHello(@Observes HelloRetrieving event) { + event.getHelloReceiver().accept("Hi, I was detected by inserting this module's groupId and artifactId into the app's application.properties file."); + } + +} diff --git a/quarkus-jandex/hello-sender-beans-xml/pom.xml b/quarkus-jandex/hello-sender-beans-xml/pom.xml new file mode 100644 index 0000000000..30cabcc91d --- /dev/null +++ b/quarkus-jandex/hello-sender-beans-xml/pom.xml @@ -0,0 +1,26 @@ + + + + com.baeldung.quarkus + quarkus-jandex + 1.0.0-SNAPSHOT + + 4.0.0 + + hello-sender-beans-xml + + + + io.quarkus + quarkus-arc + + + ${project.groupId} + hello-service + ${project.version} + + + + diff --git a/quarkus-jandex/hello-sender-beans-xml/src/main/java/com/baeldung/quarkus/hello/sender/beansxml/BeansXmlHelloSender.java b/quarkus-jandex/hello-sender-beans-xml/src/main/java/com/baeldung/quarkus/hello/sender/beansxml/BeansXmlHelloSender.java new file mode 100644 index 0000000000..bed6a7793d --- /dev/null +++ b/quarkus-jandex/hello-sender-beans-xml/src/main/java/com/baeldung/quarkus/hello/sender/beansxml/BeansXmlHelloSender.java @@ -0,0 +1,15 @@ +package com.baeldung.quarkus.hello.sender.beansxml; + +import com.baeldung.quarkus.hello.service.HelloRetrieving; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Observes; + +@ApplicationScoped +public class BeansXmlHelloSender { + + public void sendHello(@Observes HelloRetrieving event) { + event.getHelloReceiver().accept("Hi, I was detected using an empty META-INF/beans.xml file."); + } + +} diff --git a/quarkus-jandex/hello-sender-beans-xml/src/main/resources/META-INF/beans.xml b/quarkus-jandex/hello-sender-beans-xml/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/quarkus-jandex/hello-sender-maven-plugin/pom.xml b/quarkus-jandex/hello-sender-maven-plugin/pom.xml new file mode 100644 index 0000000000..ad226f38dd --- /dev/null +++ b/quarkus-jandex/hello-sender-maven-plugin/pom.xml @@ -0,0 +1,46 @@ + + + + com.baeldung.quarkus + quarkus-jandex + 1.0.0-SNAPSHOT + + 4.0.0 + + hello-sender-maven-plugin + + + + io.quarkus + quarkus-arc + + + ${project.groupId} + hello-service + ${project.version} + + + + + + + + org.jboss.jandex + jandex-maven-plugin + 1.2.1 + + + make-index + + + jandex + + + + + + + + diff --git a/quarkus-jandex/hello-sender-maven-plugin/src/main/java/com/baeldung/quarkus/hello/sender/mavenplugin/MavenPluginHelloSender.java b/quarkus-jandex/hello-sender-maven-plugin/src/main/java/com/baeldung/quarkus/hello/sender/mavenplugin/MavenPluginHelloSender.java new file mode 100644 index 0000000000..ca08eef5ac --- /dev/null +++ b/quarkus-jandex/hello-sender-maven-plugin/src/main/java/com/baeldung/quarkus/hello/sender/mavenplugin/MavenPluginHelloSender.java @@ -0,0 +1,15 @@ +package com.baeldung.quarkus.hello.sender.mavenplugin; + +import com.baeldung.quarkus.hello.service.HelloRetrieving; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Observes; + +@ApplicationScoped +public class MavenPluginHelloSender { + + public void sendHello(@Observes HelloRetrieving event) { + event.getHelloReceiver().accept("Hi, I was detected using the Jandex Maven Plugin."); + } + +} diff --git a/quarkus-jandex/hello-sender-undetected/pom.xml b/quarkus-jandex/hello-sender-undetected/pom.xml new file mode 100644 index 0000000000..0d8cb29a98 --- /dev/null +++ b/quarkus-jandex/hello-sender-undetected/pom.xml @@ -0,0 +1,26 @@ + + + + com.baeldung.quarkus + quarkus-jandex + 1.0.0-SNAPSHOT + + 4.0.0 + + hello-sender-undetected + + + + io.quarkus + quarkus-arc + + + ${project.groupId} + hello-service + ${project.version} + + + + diff --git a/quarkus-jandex/hello-sender-undetected/src/main/java/com/baeldung/quarkus/hello/sender/undetected/UndetectedHelloSender.java b/quarkus-jandex/hello-sender-undetected/src/main/java/com/baeldung/quarkus/hello/sender/undetected/UndetectedHelloSender.java new file mode 100644 index 0000000000..a39e610b2a --- /dev/null +++ b/quarkus-jandex/hello-sender-undetected/src/main/java/com/baeldung/quarkus/hello/sender/undetected/UndetectedHelloSender.java @@ -0,0 +1,15 @@ +package com.baeldung.quarkus.hello.sender.undetected; + +import com.baeldung.quarkus.hello.service.HelloRetrieving; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Observes; + +@ApplicationScoped +public class UndetectedHelloSender { + + public void sendHello(@Observes HelloRetrieving event) { + event.getHelloReceiver().accept("Hi, I do not create a Jandex index, so I should not get detected."); + } + +} diff --git a/quarkus-jandex/hello-service/pom.xml b/quarkus-jandex/hello-service/pom.xml new file mode 100644 index 0000000000..274423c526 --- /dev/null +++ b/quarkus-jandex/hello-service/pom.xml @@ -0,0 +1,21 @@ + + + + com.baeldung.quarkus + quarkus-jandex + 1.0.0-SNAPSHOT + + 4.0.0 + + hello-service + + + + io.quarkus + quarkus-arc + + + + diff --git a/quarkus-jandex/hello-service/src/main/java/com/baeldung/quarkus/hello/service/HelloRetrieving.java b/quarkus-jandex/hello-service/src/main/java/com/baeldung/quarkus/hello/service/HelloRetrieving.java new file mode 100644 index 0000000000..513e2ff245 --- /dev/null +++ b/quarkus-jandex/hello-service/src/main/java/com/baeldung/quarkus/hello/service/HelloRetrieving.java @@ -0,0 +1,17 @@ +package com.baeldung.quarkus.hello.service; + +import java.util.function.Consumer; + +public class HelloRetrieving { + + private final Consumer helloReceiver; + + public HelloRetrieving(Consumer helloReceiver) { + this.helloReceiver = helloReceiver; + } + + public Consumer getHelloReceiver() { + return helloReceiver; + } + +} diff --git a/quarkus-jandex/hello-service/src/main/java/com/baeldung/quarkus/hello/service/HelloService.java b/quarkus-jandex/hello-service/src/main/java/com/baeldung/quarkus/hello/service/HelloService.java new file mode 100644 index 0000000000..4b93d2f12f --- /dev/null +++ b/quarkus-jandex/hello-service/src/main/java/com/baeldung/quarkus/hello/service/HelloService.java @@ -0,0 +1,18 @@ +package com.baeldung.quarkus.hello.service; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Event; +import javax.inject.Inject; +import java.util.function.Consumer; + +@ApplicationScoped +public class HelloService { + + @Inject + Event helloRetrievingEvent; + + public void sendHello(Consumer target) { + helloRetrievingEvent.fire(new HelloRetrieving(target)); + } + +} diff --git a/quarkus-jandex/hello-service/src/main/resources/META-INF/beans.xml b/quarkus-jandex/hello-service/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/quarkus-jandex/pom.xml b/quarkus-jandex/pom.xml new file mode 100644 index 0000000000..eb7f308599 --- /dev/null +++ b/quarkus-jandex/pom.xml @@ -0,0 +1,44 @@ + + + 4.0.0 + com.baeldung.quarkus + quarkus-jandex + 1.0.0-SNAPSHOT + pom + + + hello-service + hello-sender-beans-xml + hello-sender-maven-plugin + hello-sender-application-properties + hello-sender-undetected + hello-app + + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + + + 3.8.1 + true + 11 + 11 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus.platform + 2.4.2.Final + 3.0.0-M5 + + + diff --git a/quarkus-vs-springboot/pom.xml b/quarkus-vs-springboot/pom.xml index cf1cbb5d85..1726d076da 100644 --- a/quarkus-vs-springboot/pom.xml +++ b/quarkus-vs-springboot/pom.xml @@ -1,19 +1,19 @@ + 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 + quarkus-vs-springboot + 1.0-SNAPSHOT + quarkus-vs-springboot + pom + parent-modules com.baeldung 1.0.0-SNAPSHOT - 1.0-SNAPSHOT - quarkus-vs-springboot - quarkus-vs-springboot - pom - 4.0.0 - quarkus-project spring-project diff --git a/quarkus-vs-springboot/quarkus-project/pom.xml b/quarkus-vs-springboot/quarkus-project/pom.xml index 58d547f3b0..eeeb9d3256 100644 --- a/quarkus-vs-springboot/quarkus-project/pom.xml +++ b/quarkus-vs-springboot/quarkus-project/pom.xml @@ -1,143 +1,150 @@ - - 4.0.0 - - com.baeldung - quarkus-vs-springboot - 1.0-SNAPSHOT - - quarkus-project - 0.1-SNAPSHOT - - 3.8.1 - true - 11 - 11 - UTF-8 - UTF-8 - quarkus-bom - io.quarkus.platform - 2.2.2.Final - 3.0.0-M4 - - + 4.0.0 + quarkus-project + 0.1-SNAPSHOT + + + com.baeldung + quarkus-vs-springboot + 1.0-SNAPSHOT + + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + - - ${quarkus.platform.group-id} - ${quarkus.platform.artifact-id} - ${quarkus.platform.version} - pom - import - + + io.quarkus + quarkus-hibernate-reactive-panache + + + io.quarkus + quarkus-resteasy-reactive + + + io.quarkus + quarkus-resteasy-reactive-jackson + + + io.quarkus + quarkus-reactive-pg-client + + + io.quarkus + quarkus-arc + + + io.quarkus + quarkus-container-image-docker + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + - - - - io.quarkus - quarkus-hibernate-reactive-panache - - - io.quarkus - quarkus-resteasy-reactive - - - io.quarkus - quarkus-resteasy-reactive-jackson - - - io.quarkus - quarkus-reactive-pg-client - - - io.quarkus - quarkus-arc - - - io.quarkus - quarkus-container-image-docker - - - io.quarkus - quarkus-junit5 - test - - - io.rest-assured - rest-assured - test - - - - - - ${quarkus.platform.group-id} - quarkus-maven-plugin - ${quarkus.platform.version} - true - - - - build - generate-code - generate-code-tests - - - - - - maven-compiler-plugin - ${compiler-plugin.version} - - ${maven.compiler.parameters} - - - - maven-surefire-plugin - ${surefire-plugin.version} - - false - - org.jboss.logmanager.LogManager - - - - - - - - native - - - native - - - + + - - maven-failsafe-plugin - ${surefire-plugin.version} - - - - integration-test - verify - + + ${quarkus.platform.group-id} + quarkus-maven-plugin + ${quarkus.platform.version} + true + + + + build + generate-code + generate-code-tests + + + + + + maven-compiler-plugin + ${compiler-plugin.version} - - ${project.build.directory}/${project.build.finalName}-runner - org.jboss.logmanager.LogManager - + ${maven.compiler.parameters} - - - + + + maven-surefire-plugin + ${surefire-plugin.version} + + false + + org.jboss.logmanager.LogManager + + + - - - -H:+AllowVMInspection - native - - - - +
+ + + native + + + native + + + + + + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + + + + + + + + + -H:+AllowVMInspection + native + + + + + + 3.8.1 + true + 11 + 11 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus.platform + 2.2.2.Final + 3.0.0-M4 + + + \ No newline at end of file diff --git a/quarkus-vs-springboot/spring-project/pom.xml b/quarkus-vs-springboot/spring-project/pom.xml index be5cc57765..989e30526f 100644 --- a/quarkus-vs-springboot/spring-project/pom.xml +++ b/quarkus-vs-springboot/spring-project/pom.xml @@ -1,25 +1,18 @@ - - - org.springframework.boot - spring-boot-starter-parent - 2.5.4 - - - + 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-project com.baeldung 0.1-SNAPSHOT - - 11 - - 0.10.3 - + + org.springframework.boot + spring-boot-starter-parent + 2.6.0 + + @@ -103,6 +96,15 @@ false + + + spring-milestones + Spring Milestones + https://repo.spring.io/libs-milestone-local + + false + + @@ -113,6 +115,15 @@ false + + + spring-milestones + Spring Milestones + https://repo.spring.io/libs-milestone-local + + false + + @@ -161,11 +172,19 @@ org.apache.maven.plugins maven-surefire-plugin - -DspringAot=true -agentlib:native-image-agent=access-filter-file=src/test/resources/access-filter.json,config-merge-dir=target/classes/META-INF/native-image + -DspringAot=true + -agentlib:native-image-agent=access-filter-file=src/test/resources/access-filter.json,config-merge-dir=target/classes/META-INF/native-image + + + 11 + + 0.11.0-RC1 + + \ No newline at end of file diff --git a/quarkus/pom.xml b/quarkus/pom.xml index d826729ad7..22f5e0e991 100644 --- a/quarkus/pom.xml +++ b/quarkus/pom.xml @@ -16,8 +16,8 @@ - + junit junit diff --git a/reactor-core/pom.xml b/reactor-core/pom.xml index 420b1b028a..39a66cee3e 100644 --- a/reactor-core/pom.xml +++ b/reactor-core/pom.xml @@ -26,12 +26,6 @@ ${reactor.version} test - - org.assertj - assertj-core - ${assertj.version} - test - org.projectlombok lombok @@ -42,7 +36,6 @@ 3.4.9 - 3.6.1 \ No newline at end of file diff --git a/restx/pom.xml b/restx/pom.xml index ea9f927563..953b56e2f3 100644 --- a/restx/pom.xml +++ b/restx/pom.xml @@ -113,12 +113,6 @@ - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - @@ -153,6 +147,7 @@ 0.35-rc4 + 1.6.0 \ No newline at end of file diff --git a/rule-engines/evrete/pom.xml b/rule-engines/evrete/pom.xml index 819a912c43..cfcadcb2ea 100644 --- a/rule-engines/evrete/pom.xml +++ b/rule-engines/evrete/pom.xml @@ -8,10 +8,6 @@ 1.0 evrete - - 2.1.04 - - com.baeldung rule-engines @@ -32,4 +28,9 @@ ${evrete.version} + + + 2.1.04 + + \ No newline at end of file diff --git a/rxjava-core/pom.xml b/rxjava-core/pom.xml index cd6075e127..89ea1bf7a2 100644 --- a/rxjava-core/pom.xml +++ b/rxjava-core/pom.xml @@ -30,15 +30,9 @@ awaitility ${awaitility.version} - - org.assertj - assertj-core - ${assertj.version} - - 3.8.0 1.2.5 1.7.0 2.2.2 diff --git a/rxjava-libraries/pom.xml b/rxjava-libraries/pom.xml index 5d2c9ec3bb..f8df78d741 100644 --- a/rxjava-libraries/pom.xml +++ b/rxjava-libraries/pom.xml @@ -41,11 +41,6 @@ ${h2.version} runtime - - org.assertj - assertj-core - ${assertj.version} - @@ -53,7 +48,6 @@ 1.2.5 2.0.0 2.2.2 - 3.8.0 \ No newline at end of file diff --git a/rxjava-observables/pom.xml b/rxjava-observables/pom.xml index feb4fc1f39..bcc3c4bbce 100644 --- a/rxjava-observables/pom.xml +++ b/rxjava-observables/pom.xml @@ -25,17 +25,11 @@ rxjava-string ${rx.java.string.version} - - org.assertj - assertj-core - ${assertj.version} - 1.1.1 1.2.5 - 3.8.0 \ No newline at end of file diff --git a/rxjava-operators/pom.xml b/rxjava-operators/pom.xml index ba85dc428b..d833fb5d14 100644 --- a/rxjava-operators/pom.xml +++ b/rxjava-operators/pom.xml @@ -31,11 +31,6 @@ rxjava2-extensions ${rxjava2.ext.version} - - org.assertj - assertj-core - ${assertj.version} - io.reactivex rxjava-math @@ -51,7 +46,6 @@ 0.20.4 2.2.2 - 3.8.0 1.2.5 1.0.0 1.7.0 diff --git a/software-security/sql-injection-samples/src/test/resources/logback-test.xml b/software-security/sql-injection-samples/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/software-security/sql-injection-samples/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spf4j/spf4j-aspects-app/pom.xml b/spf4j/spf4j-aspects-app/pom.xml index c4940b9c97..09ca41ea47 100644 --- a/spf4j/spf4j-aspects-app/pom.xml +++ b/spf4j/spf4j-aspects-app/pom.xml @@ -9,10 +9,9 @@ jar - com.baeldung - parent-modules + com.baeldung.spf4j + spf4j 1.0.0-SNAPSHOT - ../../ diff --git a/spf4j/spf4j-core-app/pom.xml b/spf4j/spf4j-core-app/pom.xml index 28c104afe1..2f7f3745f1 100644 --- a/spf4j/spf4j-core-app/pom.xml +++ b/spf4j/spf4j-core-app/pom.xml @@ -9,10 +9,9 @@ jar - com.baeldung - parent-modules + com.baeldung.spf4j + spf4j 1.0.0-SNAPSHOT - ../../ diff --git a/spring-5-data-reactive/pom.xml b/spring-5-data-reactive/pom.xml index 3a9651de39..c145992737 100644 --- a/spring-5-data-reactive/pom.xml +++ b/spring-5-data-reactive/pom.xml @@ -72,7 +72,6 @@ com.h2database h2 - ${h2.version} org.apache.httpcomponents @@ -135,7 +134,6 @@ 1.0.0.RELEASE 0.8.1.RELEASE 4.5.2 - 1.4.200 1.5.23 3.3.1.RELEASE 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-2/src/test/java/com/baeldung/backpressure/BackpressureUnitTest.java b/spring-5-reactive-2/src/test/java/com/baeldung/backpressure/BackpressureUnitTest.java index e7cb60dbf9..a12d762fe5 100644 --- a/spring-5-reactive-2/src/test/java/com/baeldung/backpressure/BackpressureUnitTest.java +++ b/spring-5-reactive-2/src/test/java/com/baeldung/backpressure/BackpressureUnitTest.java @@ -1,21 +1,25 @@ package com.baeldung.backpressure; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import reactor.core.publisher.BaseSubscriber; import reactor.core.publisher.Flux; import reactor.test.StepVerifier; public class BackpressureUnitTest { + private static final Logger LOGGER = LoggerFactory.getLogger(BackpressureUnitTest.class); + @Test public void whenLimitRateSet_thenSplitIntoChunks() throws InterruptedException { Flux limit = Flux.range(1, 25); limit.limitRate(10); limit.subscribe( - value -> System.out.println(value), + value -> LOGGER.debug(String.valueOf(value)), err -> err.printStackTrace(), - () -> System.out.println("Finished!!"), + () -> LOGGER.debug("Finished!!"), subscription -> subscription.request(15) ); @@ -34,12 +38,12 @@ public class BackpressureUnitTest { Flux request = Flux.range(1, 50); request.subscribe( - System.out::println, + integer -> LOGGER.debug(String.valueOf(integer)), err -> err.printStackTrace(), - () -> System.out.println("All 50 items have been successfully processed!!!"), + () -> LOGGER.debug("All 50 items have been successfully processed!!!"), subscription -> { for (int i = 0; i < 5; i++) { - System.out.println("Requesting the next 10 elements!!!"); + LOGGER.debug("Requesting the next 10 elements!!!"); subscription.request(10); } } @@ -68,7 +72,7 @@ public class BackpressureUnitTest { @Override protected void hookOnNext(Integer value) { request(3); - System.out.println(value); + LOGGER.debug(String.valueOf(value)); cancel(); } }); diff --git a/spring-5-reactive-client/README.md b/spring-5-reactive-client/README.md index e485897d27..5a93e0b13e 100644 --- a/spring-5-reactive-client/README.md +++ b/spring-5-reactive-client/README.md @@ -12,3 +12,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring WebClient Filters](https://www.baeldung.com/spring-webclient-filters) - [Get List of JSON Objects with WebClient](https://www.baeldung.com/spring-webclient-json-list) - [Upload a File with WebClient](https://www.baeldung.com/spring-webclient-upload-file) +- [How to Get Response Body When Testing the Status Code in WebFlux WebClient](https://www.baeldung.com/spring-webclient-get-response-body) 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-2/README.md b/spring-5-webflux-2/README.md new file mode 100644 index 0000000000..0222ddbaa4 --- /dev/null +++ b/spring-5-webflux-2/README.md @@ -0,0 +1,7 @@ +## Spring 5 WebFlux 2 + +This module contains articles about Spring 5 WebFlux + +## Relevant articles: + +- [Spring Webflux and @Cacheable Annotation](https://www.baeldung.com/spring-webflux-cacheable) \ No newline at end of file diff --git a/spring-5-webflux-2/pom.xml b/spring-5-webflux-2/pom.xml new file mode 100644 index 0000000000..c90fcbe3d9 --- /dev/null +++ b/spring-5-webflux-2/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + spring-5-webflux-2 + spring-5-webflux-2 + http://www.baeldung.com + 1.0-SNAPSHOT + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + + + org.junit + junit-bom + ${junit-jupiter.version} + pom + import + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.jupiter + junit-jupiter + + + org.junit.jupiter + junit-jupiter-api + + + org.junit.platform + junit-plaform-commons + + + + + io.projectreactor.addons + reactor-extra + 3.4.5 + + + com.github.ben-manes.caffeine + caffeine + 2.9.2 + + + org.springframework.boot + spring-boot-starter-data-mongodb-reactive + + + io.projectreactor + reactor-test + test + + + org.testcontainers + mongodb + 1.16.2 + test + + + com.squareup.okhttp3 + mockwebserver + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/spring-5-webflux-2/src/main/java/caching/Item.java b/spring-5-webflux-2/src/main/java/caching/Item.java new file mode 100644 index 0000000000..627eeef740 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/caching/Item.java @@ -0,0 +1,50 @@ +package caching; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +public class Item { + + @Id + private String _id; + private String name; + private double price; + + public Item(String name, double price) { + this.name = name; + this.price = price; + } + + public Item() { + } + + public String get_id() { + return _id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + @Override + public String toString() { + return "Item{" + + "id='" + _id + '\'' + + ", name='" + name + '\'' + + ", price=" + price + + '}'; + } +} diff --git a/spring-5-webflux-2/src/main/java/caching/ItemRepository.java b/spring-5-webflux-2/src/main/java/caching/ItemRepository.java new file mode 100644 index 0000000000..d69edaf5df --- /dev/null +++ b/spring-5-webflux-2/src/main/java/caching/ItemRepository.java @@ -0,0 +1,8 @@ +package caching; + +import org.springframework.data.mongodb.repository.ReactiveMongoRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ItemRepository extends ReactiveMongoRepository { +} diff --git a/spring-5-webflux-2/src/main/java/caching/ItemService.java b/spring-5-webflux-2/src/main/java/caching/ItemService.java new file mode 100644 index 0000000000..85d7005831 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/caching/ItemService.java @@ -0,0 +1,42 @@ +package caching; + +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import reactor.cache.CacheMono; +import reactor.core.publisher.Mono; + +@Service +public class ItemService { + + private final ItemRepository repository; + private final LoadingCache cache; + + public ItemService(ItemRepository repository) { + this.repository = repository; + this.cache = Caffeine.newBuilder() + .build(this::getItem_withAddons); + } + + @Cacheable("items") + public Mono getItem(String id) { + return repository.findById(id); + } + + public Mono save(Item item) { + return repository.save(item); + } + + @Cacheable("items") + public Mono getItem_withCache(String id) { + return repository.findById(id).cache(); + } + + @Cacheable("items") + public Mono getItem_withAddons(String id) { + return CacheMono.lookup(cache.asMap(), id) + .onCacheMissResume(() -> repository.findById(id).cast(Object.class)).cast(Item.class); + } + +} diff --git a/spring-5-webflux-2/src/main/java/caching/SpringWebfluxCachingApplication.java b/spring-5-webflux-2/src/main/java/caching/SpringWebfluxCachingApplication.java new file mode 100644 index 0000000000..df648fe6a3 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/caching/SpringWebfluxCachingApplication.java @@ -0,0 +1,16 @@ +package caching; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +@SpringBootApplication +@EnableMongoRepositories +@EnableCaching +public class SpringWebfluxCachingApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringWebfluxCachingApplication.class, args); + } +} diff --git a/spring-5-webflux-2/src/main/resources/application-cache.properties b/spring-5-webflux-2/src/main/resources/application-cache.properties new file mode 100644 index 0000000000..23414da2dd --- /dev/null +++ b/spring-5-webflux-2/src/main/resources/application-cache.properties @@ -0,0 +1,2 @@ +logging.level.org.springframework.data.mongodb.core.ReactiveMongoTemplate=DEBUG +logging.level.org.springframework.cache=TRACE \ No newline at end of file diff --git a/spring-5-webflux-2/src/main/resources/logback.xml b/spring-5-webflux-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..48b68c6bf1 --- /dev/null +++ b/spring-5-webflux-2/src/main/resources/logback.xml @@ -0,0 +1,31 @@ + + + + + + %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable + + + + + + netty-access.log + + %msg%n + + + + + + + + + + + + + + + + diff --git a/spring-5-webflux-2/src/test/java/caching/MonoFluxResultCachingLiveTest.java b/spring-5-webflux-2/src/test/java/caching/MonoFluxResultCachingLiveTest.java new file mode 100644 index 0000000000..daf8367209 --- /dev/null +++ b/spring-5-webflux-2/src/test/java/caching/MonoFluxResultCachingLiveTest.java @@ -0,0 +1,95 @@ +package caching; + + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.MongoDBContainer; +import org.testcontainers.utility.DockerImageName; +import reactor.core.publisher.Mono; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@ActiveProfiles("cache") +public class MonoFluxResultCachingLiveTest { + + + @Autowired + ItemService itemService; + + final static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10")); + + @DynamicPropertySource + static void mongoDbProperties(DynamicPropertyRegistry registry) { + mongoDBContainer.start(); + registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl); + } + +@Test +public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { + Mono glass = itemService.save(new Item("glass", 1.00)); + + String id = glass.block().get_id(); + + Mono mono = itemService.getItem(id); + Item item = mono.block(); + + assertThat(item).isNotNull(); + assertThat(item.getName()).isEqualTo("glass"); + assertThat(item.getPrice()).isEqualTo(1.00); + + Mono mono2 = itemService.getItem(id); + Item item2 = mono2.block(); + + assertThat(item2).isNotNull(); + assertThat(item2.getName()).isEqualTo("glass"); + assertThat(item2.getPrice()).isEqualTo(1.00); +} + + @Test + public void givenItem_whenGetItemWithCacheIsCalled_thenMonoResultIsCached() { + Mono glass = itemService.save(new Item("glass", 1.00)); + + String id = glass.block().get_id(); + + Mono mono = itemService.getItem_withCache(id); + Item item = mono.block(); + + assertThat(item).isNotNull(); + assertThat(item.getName()).isEqualTo("glass"); + assertThat(item.getPrice()).isEqualTo(1.00); + + Mono mono2 = itemService.getItem_withCache(id); + Item item2 = mono2.block(); + + assertThat(item2).isNotNull(); + assertThat(item2.getName()).isEqualTo("glass"); + assertThat(item2.getPrice()).isEqualTo(1.00); + } + + @Test + public void givenItem_whenGetItemWithAddonsIsCalled_thenMonoResultIsCached() { + Mono glass = itemService.save(new Item("glass", 1.00)); + + String id = glass.block().get_id(); + + Mono mono = itemService.getItem_withAddons(id); + Item item = mono.block(); + + assertThat(item).isNotNull(); + assertThat(item.getName()).isEqualTo("glass"); + assertThat(item.getPrice()).isEqualTo(1.00); + + Mono mono2 = itemService.getItem_withAddons(id); + Item item2 = mono2.block(); + + assertThat(item2).isNotNull(); + assertThat(item2.getName()).isEqualTo("glass"); + assertThat(item2.getPrice()).isEqualTo(1.00); + } + +} diff --git a/spring-5-webflux-2/src/test/resources/logback-test.xml b/spring-5-webflux-2/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..12cedf5952 --- /dev/null +++ b/spring-5-webflux-2/src/test/resources/logback-test.xml @@ -0,0 +1,13 @@ + + + + + + %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable + + + + + + + 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-aop/pom.xml b/spring-aop/pom.xml index da981987fe..cbec4ef35b 100644 --- a/spring-aop/pom.xml +++ b/spring-aop/pom.xml @@ -65,6 +65,15 @@ + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.basedir}/src/main/resources/logback.xml + + + diff --git a/spring-batch-2/README.md b/spring-batch-2/README.md index 08bf1933db..9b5d59f0b9 100644 --- a/spring-batch-2/README.md +++ b/spring-batch-2/README.md @@ -1,3 +1,5 @@ ### Relevant Articles: - [Spring Boot With Spring Batch](https://www.baeldung.com/spring-boot-spring-batch) +- [How to Trigger and Stop a Scheduled Spring Batch Job](https://www.baeldung.com/spring-batch-start-stop-job) +- More articles [[<-- prev]](/spring-batch) diff --git a/spring-batch-2/pom.xml b/spring-batch-2/pom.xml index c429c272bd..12d31aca14 100644 --- a/spring-batch-2/pom.xml +++ b/spring-batch-2/pom.xml @@ -22,10 +22,8 @@ spring-boot-starter-batch - org.hsqldb - hsqldb - ${hsqldb.version} - runtime + com.h2database + h2 org.springframework.boot @@ -44,11 +42,17 @@ ${spring.batch.version} test + + org.awaitility + awaitility + ${awaitility.version} + test + 4.3.0 - 2.5.1 + 3.1.1 \ No newline at end of file diff --git a/spring-batch/src/main/java/com/baeldung/batchscheduler/SpringBatchScheduler.java b/spring-batch-2/src/main/java/com/baeldung/batchscheduler/SpringBatchScheduler.java similarity index 69% rename from spring-batch/src/main/java/com/baeldung/batchscheduler/SpringBatchScheduler.java rename to spring-batch-2/src/main/java/com/baeldung/batchscheduler/SpringBatchScheduler.java index cff4e96c89..c830a41855 100644 --- a/spring-batch/src/main/java/com/baeldung/batchscheduler/SpringBatchScheduler.java +++ b/spring-batch-2/src/main/java/com/baeldung/batchscheduler/SpringBatchScheduler.java @@ -11,26 +11,20 @@ import org.springframework.batch.core.configuration.annotation.EnableBatchProces import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.core.launch.support.SimpleJobLauncher; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder; import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; -import org.springframework.batch.support.transaction.ResourcelessTransactionManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; -import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.support.ScheduledMethodRunnable; -import javax.sql.DataSource; import java.util.Date; import java.util.IdentityHashMap; import java.util.List; @@ -58,13 +52,16 @@ public class SpringBatchScheduler { @Autowired private StepBuilderFactory stepBuilderFactory; + @Autowired + private JobLauncher jobLauncher; + @Scheduled(fixedRate = 2000) public void launchJob() throws Exception { Date date = new Date(); logger.debug("scheduler starts at " + date); if (enabled.get()) { - JobExecution jobExecution = jobLauncher().run(job(), new JobParametersBuilder().addDate("launchDate", date) - .toJobParameters()); + JobExecution jobExecution = jobLauncher.run(job(), new JobParametersBuilder().addDate("launchDate", date) + .toJobParameters()); batchRunCounter.incrementAndGet(); logger.debug("Batch job ends with status as " + jobExecution.getStatus()); } @@ -110,56 +107,33 @@ public class SpringBatchScheduler { @Bean public Job job() { - return jobBuilderFactory.get("job") - .start(readBooks()) - .build(); - } - - @Bean - public JobLauncher jobLauncher() throws Exception { - SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); - jobLauncher.setJobRepository(jobRepository()); - jobLauncher.afterPropertiesSet(); - return jobLauncher; - } - - @Bean - public JobRepository jobRepository() throws Exception { - JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); - factory.setDataSource(dataSource()); - factory.setTransactionManager(new ResourcelessTransactionManager()); - return factory.getObject(); - } - - @Bean - public DataSource dataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName("org.sqlite.JDBC"); - dataSource.setUrl("jdbc:sqlite:repository.sqlite"); - return dataSource; + return jobBuilderFactory + .get("job") + .start(readBooks()) + .build(); } @Bean protected Step readBooks() { return stepBuilderFactory.get("readBooks") - . chunk(2) - .reader(reader()) - .writer(writer()) - .build(); + . chunk(2) + .reader(reader()) + .writer(writer()) + .build(); } @Bean public FlatFileItemReader reader() { return new FlatFileItemReaderBuilder().name("bookItemReader") - .resource(new ClassPathResource("books.csv")) - .delimited() - .names(new String[] { "id", "name" }) - .fieldSetMapper(new BeanWrapperFieldSetMapper() { - { - setTargetType(Book.class); - } - }) - .build(); + .resource(new ClassPathResource("books.csv")) + .delimited() + .names(new String[] { "id", "name" }) + .fieldSetMapper(new BeanWrapperFieldSetMapper() { + { + setTargetType(Book.class); + } + }) + .build(); } @Bean diff --git a/spring-batch-2/src/main/java/com/baeldung/batchscheduler/SpringBatchSchedulerApplication.java b/spring-batch-2/src/main/java/com/baeldung/batchscheduler/SpringBatchSchedulerApplication.java new file mode 100644 index 0000000000..349a359efb --- /dev/null +++ b/spring-batch-2/src/main/java/com/baeldung/batchscheduler/SpringBatchSchedulerApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.batchscheduler; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBatchSchedulerApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBatchSchedulerApplication.class, args); + } + +} diff --git a/spring-batch/src/main/java/com/baeldung/batchscheduler/model/Book.java b/spring-batch-2/src/main/java/com/baeldung/batchscheduler/model/Book.java similarity index 98% rename from spring-batch/src/main/java/com/baeldung/batchscheduler/model/Book.java rename to spring-batch-2/src/main/java/com/baeldung/batchscheduler/model/Book.java index 8ee986c729..7deedeb63e 100644 --- a/spring-batch/src/main/java/com/baeldung/batchscheduler/model/Book.java +++ b/spring-batch-2/src/main/java/com/baeldung/batchscheduler/model/Book.java @@ -3,7 +3,7 @@ package com.baeldung.batchscheduler.model; public class Book { private int id; private String name; - + public Book() {} public Book(int id, String name) { @@ -27,7 +27,7 @@ public class Book { public void setName(String name) { this.name = name; } - + public String toString() { return "Book [id=" + id + ", name=" + name + "]"; } diff --git a/spring-batch/src/main/resources/books.csv b/spring-batch-2/src/main/resources/books.csv similarity index 100% rename from spring-batch/src/main/resources/books.csv rename to spring-batch-2/src/main/resources/books.csv diff --git a/spring-batch/src/test/java/com/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java b/spring-batch-2/src/test/java/com/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java similarity index 76% rename from spring-batch/src/test/java/com/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java rename to spring-batch-2/src/test/java/com/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java index 81877fbc39..61e5a1dd74 100644 --- a/spring-batch/src/test/java/com/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java +++ b/spring-batch-2/src/test/java/com/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java @@ -4,32 +4,40 @@ import com.baeldung.batchscheduler.SpringBatchScheduler; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.batch.test.context.SpringBatchTest; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.PropertySource; import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; import static org.awaitility.Awaitility.await; import static java.util.concurrent.TimeUnit.*; -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = SpringBatchScheduler.class) +@SpringBatchTest +@SpringBootTest +@DirtiesContext +@PropertySource("classpath:application.properties") +@RunWith(SpringRunner.class) public class SpringBatchSchedulerIntegrationTest { @Autowired private ApplicationContext context; @Test - public void stopJobsWhenSchedulerDisabled() throws Exception { + public void stopJobsWhenSchedulerDisabled() { SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter() - .get())); + .get())); schedulerBean.stop(); await().atLeast(3, SECONDS); Assert.assertEquals(2, schedulerBean.getBatchRunCounter() - .get()); + .get()); } @Test @@ -37,24 +45,24 @@ public class SpringBatchSchedulerIntegrationTest { ScheduledAnnotationBeanPostProcessor bean = context.getBean(ScheduledAnnotationBeanPostProcessor.class); SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter() - .get())); + .get())); bean.postProcessBeforeDestruction(schedulerBean, "SpringBatchScheduler"); await().atLeast(3, SECONDS); Assert.assertEquals(2, schedulerBean.getBatchRunCounter() - .get()); + .get()); } @Test public void stopJobSchedulerWhenFutureTasksCancelled() throws Exception { SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter() - .get())); + .get())); schedulerBean.cancelFutureSchedulerTasks(); await().atLeast(3, SECONDS); Assert.assertEquals(2, schedulerBean.getBatchRunCounter() - .get()); + .get()); } diff --git a/spring-batch/README.md b/spring-batch/README.md index 3a89459629..b87a2149a0 100644 --- a/spring-batch/README.md +++ b/spring-batch/README.md @@ -7,8 +7,8 @@ This module contains articles about Spring Batch - [Introduction to Spring Batch](https://www.baeldung.com/introduction-to-spring-batch) - [Spring Batch using Partitioner](https://www.baeldung.com/spring-batch-partitioner) - [Spring Batch – Tasklets vs Chunks](https://www.baeldung.com/spring-batch-tasklet-chunk) -- [How to Trigger and Stop a Scheduled Spring Batch Job](https://www.baeldung.com/spring-batch-start-stop-job) - [Configuring Skip Logic in Spring Batch](https://www.baeldung.com/spring-batch-skip-logic) - [Testing a Spring Batch Job](https://www.baeldung.com/spring-batch-testing-job) - [Configuring Retry Logic in Spring Batch](https://www.baeldung.com/spring-batch-retry-logic) - [Conditional Flow in Spring Batch](https://www.baeldung.com/spring-batch-conditional-flow) +- More articles [[next -->]](/spring-batch-2) diff --git a/spring-batch/pom.xml b/spring-batch/pom.xml index 9879a4777f..32126fec9b 100644 --- a/spring-batch/pom.xml +++ b/spring-batch/pom.xml @@ -82,12 +82,6 @@ hsqldb runtime - - org.awaitility - awaitility - ${awaitility.version} - test - @@ -97,7 +91,6 @@ 4.1 2.3.1 2.12.3 - 3.1.1 \ No newline at end of file diff --git a/spring-batch/repository.sqlite b/spring-batch/repository.sqlite index a2b87ffa00..b6a954554c 100644 Binary files a/spring-batch/repository.sqlite and b/spring-batch/repository.sqlite differ diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 9f179dd97f..9e0c49a12d 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -46,7 +46,7 @@ spring-boot-groovy spring-boot-jasypt - spring-boot-keycloak + spring-boot-libraries spring-boot-libraries-2 spring-boot-logging-log4j2 @@ -72,7 +72,6 @@ spring-boot-vue spring-boot-actuator spring-boot-data-2 - spring-boot-react spring-boot-validation @@ -95,19 +94,4 @@ - - - org.junit.jupiter - junit-jupiter - - - org.junit.vintage - junit-vintage-engine - - - - - 2.22.2 - - \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-1/README.md b/spring-boot-modules/spring-boot-1/README.md index a818f60fb5..8e5214c69a 100644 --- a/spring-boot-modules/spring-boot-1/README.md +++ b/spring-boot-modules/spring-boot-1/README.md @@ -4,3 +4,8 @@ This module contains articles about Spring Boot Actuator in Spring Boot version ## Relevant articles: - [Spring Boot Actuator](https://www.baeldung.com/spring-boot-actuators) +- [A Quick Intro to the SpringBootServletInitializer](https://www.baeldung.com/spring-boot-servlet-initializer) +- [Spring Shutdown Callbacks](https://www.baeldung.com/spring-shutdown-callbacks) +- [Dynamic DTO Validation Config Retrieved from the Database](https://www.baeldung.com/spring-dynamic-dto-validation) + + diff --git a/spring-boot-modules/spring-boot-1/pom.xml b/spring-boot-modules/spring-boot-1/pom.xml index 9f91cc8f2e..b6e3717f7c 100644 --- a/spring-boot-modules/spring-boot-1/pom.xml +++ b/spring-boot-modules/spring-boot-1/pom.xml @@ -20,14 +20,36 @@ org.springframework.boot spring-boot-starter + + org.springframework.boot + spring-boot-starter-thymeleaf + org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-tomcat + org.springframework.boot spring-boot-starter-actuator + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.apache.logging.log4j + log4j-core + ${log4j2.version} + + + com.h2database + h2 + test + org.springframework.boot spring-boot-starter-test @@ -40,8 +62,13 @@ org.springframework.boot spring-boot-maven-plugin + ${spring-boot.version} + + 2.14.1 + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java similarity index 93% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java index 5b9ce1271e..0aa0f0ae0b 100644 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java +++ b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java @@ -5,7 +5,7 @@ import java.time.LocalDateTime; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/shutdownhooks/ShutdownHookApplication.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/ShutdownHookApplication.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/shutdownhooks/ShutdownHookApplication.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/ShutdownHookApplication.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean1.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/beans/Bean1.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean1.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/beans/Bean1.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean2.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/beans/Bean2.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean2.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/beans/Bean2.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean3.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/beans/Bean3.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean3.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/beans/Bean3.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/shutdownhooks/config/ExampleServletContextListener.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/config/ExampleServletContextListener.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/shutdownhooks/config/ExampleServletContextListener.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/config/ExampleServletContextListener.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/shutdownhooks/config/ShutdownHookConfiguration.java b/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/config/ShutdownHookConfiguration.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/shutdownhooks/config/ShutdownHookConfiguration.java rename to spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/config/ShutdownHookConfiguration.java diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/servletinitializer/WarInitializerApplicationIntegrationTest.java b/spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/servletinitializer/WarInitializerApplicationIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot/src/test/java/com/baeldung/servletinitializer/WarInitializerApplicationIntegrationTest.java rename to spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/servletinitializer/WarInitializerApplicationIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-1/src/test/resources/application.properties b/spring-boot-modules/spring-boot-1/src/test/resources/application.properties new file mode 100644 index 0000000000..b14abfcc81 --- /dev/null +++ b/spring-boot-modules/spring-boot-1/src/test/resources/application.properties @@ -0,0 +1,20 @@ +spring.mail.host=localhost +spring.mail.port=8025 +spring.mail.properties.mail.smtp.auth=false + +# spring.datasource.x +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +spring.datasource.username=sa +spring.datasource.password=sa + +# hibernate.X +spring.jpa.hibernate.dialect=org.hibernate.dialect.H2Dialect +spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.hibernate.show_sql=true +spring.jpa.hibernate.hbm2ddl.auto=create-drop +spring.jpa.hibernate.cache.use_second_level_cache=true +spring.jpa.hibernate.cache.use_query_cache=true +spring.jpa.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory + +management.security.enabled=false \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-1/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-1/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-boot-modules/spring-boot-1/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-actuator/README.md b/spring-boot-modules/spring-boot-actuator/README.md index 9e2f30786f..59f7e929da 100644 --- a/spring-boot-modules/spring-boot-actuator/README.md +++ b/spring-boot-modules/spring-boot-actuator/README.md @@ -11,3 +11,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Custom Information in Spring Boot Info Endpoint](https://www.baeldung.com/spring-boot-info-actuator-custom) - [Health Indicators in Spring Boot](https://www.baeldung.com/spring-boot-health-indicators) - [How to Enable All Endpoints in Spring Boot Actuator](https://www.baeldung.com/spring-boot-actuator-enable-endpoints) +- [Spring Boot Startup Actuator Endpoint](https://www.baeldung.com/spring-boot-actuator-startup) diff --git a/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/startup/ResourceInitializer.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/startup/ResourceInitializer.java new file mode 100644 index 0000000000..e50816821c --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/startup/ResourceInitializer.java @@ -0,0 +1,17 @@ +package com.baeldung.startup; + +import org.springframework.stereotype.Component; + +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; + +@Component +public class ResourceInitializer { + + ResourceInitializer() throws Exception { + // simulate resource init with random delay of a few seconds + int randomDelay = ThreadLocalRandom.current().nextInt(5, 9); + TimeUnit.SECONDS.sleep(randomDelay); + } + +} diff --git a/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/startup/StartupTrackingApplication.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/startup/StartupTrackingApplication.java new file mode 100644 index 0000000000..a3762cb98e --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/startup/StartupTrackingApplication.java @@ -0,0 +1,38 @@ +package com.baeldung.startup; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; + +import static java.lang.Boolean.FALSE; + +@SpringBootApplication(exclude = { + SecurityAutoConfiguration.class, + ManagementWebSecurityAutoConfiguration.class} +) +public class StartupTrackingApplication { + + public static void main(String[] args) { + // only load properties for this application + System.setProperty("spring.config.location", "classpath:application-startup.properties"); + + SpringApplication app = new SpringApplication(StartupTrackingApplication.class); + BufferingApplicationStartup startup = new BufferingApplicationStartup(2048); + + if (shouldFilterSteps()) { + startup.addFilter(startupStep -> startupStep.getName().matches("spring.beans.instantiate")); + } + + app.setApplicationStartup(startup); + app.run(args); + } + + private static boolean shouldFilterSteps() { + return Boolean.parseBoolean( + System.getProperty("startup.steps.filter", FALSE.toString()) + ); + } + +} diff --git a/spring-boot-modules/spring-boot-actuator/src/main/resources/application-startup.properties b/spring-boot-modules/spring-boot-actuator/src/main/resources/application-startup.properties new file mode 100644 index 0000000000..4cb5f2a94d --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/resources/application-startup.properties @@ -0,0 +1,6 @@ +management.endpoints.web.exposure.include=startup + +# JPA is not required for startup actuator endpoint +spring.autoconfigure.exclude= org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, \ + org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, \ + org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration diff --git a/spring-boot-modules/spring-boot-admin/pom.xml b/spring-boot-modules/spring-boot-admin/pom.xml index b995b6f02e..509abfa013 100644 --- a/spring-boot-modules/spring-boot-admin/pom.xml +++ b/spring-boot-modules/spring-boot-admin/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-admin/spring-boot-admin-client/pom.xml b/spring-boot-modules/spring-boot-admin/spring-boot-admin-client/pom.xml index eca92ff3a5..72f828b259 100644 --- a/spring-boot-modules/spring-boot-admin/spring-boot-admin-client/pom.xml +++ b/spring-boot-modules/spring-boot-admin/spring-boot-admin-client/pom.xml @@ -13,7 +13,6 @@ com.baeldung.spring-boot-modules spring-boot-admin 0.0.1-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/pom.xml b/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/pom.xml index a1daa3fa19..0ccd43e0b9 100644 --- a/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/pom.xml +++ b/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/pom.xml @@ -13,7 +13,6 @@ com.baeldung.spring-boot-modules spring-boot-admin 0.0.1-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-angular/pom.xml b/spring-boot-modules/spring-boot-angular/pom.xml index 89a8814d2f..10885d5320 100644 --- a/spring-boot-modules/spring-boot-angular/pom.xml +++ b/spring-boot-modules/spring-boot-angular/pom.xml @@ -13,7 +13,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ @@ -32,7 +31,6 @@ com.h2database h2 - ${h2.version} runtime diff --git a/spring-boot-modules/spring-boot-annotations/pom.xml b/spring-boot-modules/spring-boot-annotations/pom.xml index 22572e7492..618ae6024b 100644 --- a/spring-boot-modules/spring-boot-annotations/pom.xml +++ b/spring-boot-modules/spring-boot-annotations/pom.xml @@ -11,7 +11,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-artifacts-2/pom.xml b/spring-boot-modules/spring-boot-artifacts-2/pom.xml index 8cf78b79e0..3b9390e973 100644 --- a/spring-boot-modules/spring-boot-artifacts-2/pom.xml +++ b/spring-boot-modules/spring-boot-artifacts-2/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-artifacts/pom.xml b/spring-boot-modules/spring-boot-artifacts/pom.xml index 7ed91a6626..5b4f5a1dd1 100644 --- a/spring-boot-modules/spring-boot-artifacts/pom.xml +++ b/spring-boot-modules/spring-boot-artifacts/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-autoconfiguration/pom.xml b/spring-boot-modules/spring-boot-autoconfiguration/pom.xml index bf8bcc5a87..b5e85bad59 100644 --- a/spring-boot-modules/spring-boot-autoconfiguration/pom.xml +++ b/spring-boot-modules/spring-boot-autoconfiguration/pom.xml @@ -13,7 +13,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ 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 f041c1d38a..9488618ca5 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/README.md +++ b/spring-boot-modules/spring-boot-basic-customization-2/README.md @@ -5,4 +5,6 @@ This module contains articles about Spring Boot customization 2 ### Relevant Articles: - [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) \ No newline at end of file + - [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-2/pom.xml b/spring-boot-modules/spring-boot-basic-customization-2/pom.xml index 6f3cb48b81..7a086331ab 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/pom.xml +++ b/spring-boot-modules/spring-boot-basic-customization-2/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ 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/java/com/baeldung/onceperrequestfilter/AuthenticationFilter.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/AuthenticationFilter.java new file mode 100644 index 0000000000..7ddcde7dc8 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/AuthenticationFilter.java @@ -0,0 +1,34 @@ +package com.baeldung.onceperrequestfilter; + +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Component +public class AuthenticationFilter extends OncePerRequestFilter { + + @Override + protected void doFilterInternal( + HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) throws + ServletException, IOException { + String usrName = request.getHeader("userName"); + logger.info("Successfully authenticated user " + + usrName); + filterChain.doFilter(request, response); + } + @Override + protected boolean shouldNotFilterAsyncDispatch() { + return false; + } + @Override + protected boolean shouldNotFilterErrorDispatch() { + return false; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/HelloController.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/HelloController.java new file mode 100644 index 0000000000..0a354c91ac --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/HelloController.java @@ -0,0 +1,40 @@ +package com.baeldung.onceperrequestfilter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.context.request.async.DeferredResult; + +import javax.servlet.http.HttpServletResponse; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Controller +public class HelloController implements AutoCloseable { + + private final ExecutorService executorService = Executors.newCachedThreadPool(); + + private Logger logger = LoggerFactory.getLogger(HelloController.class); + + @GetMapping(path = "/greeting") + public DeferredResult hello(HttpServletResponse response) throws Exception { + DeferredResult deferredResult = new DeferredResult<>(); + executorService.submit(() -> perform(deferredResult)); + return deferredResult; + } + + private void perform(DeferredResult dr) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + dr.setResult("OK"); + } + + @Override + public void close() throws Exception { + executorService.shutdownNow(); + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/MyOncePerRequestFilter.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/MyOncePerRequestFilter.java new file mode 100644 index 0000000000..3fd304f86b --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/MyOncePerRequestFilter.java @@ -0,0 +1,29 @@ +package com.baeldung.onceperrequestfilter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Component +public class MyOncePerRequestFilter extends OncePerRequestFilter { + private Logger logger = LoggerFactory.getLogger(MyOncePerRequestFilter.class); + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + logger.info("Inside Once Per Request Filter originated by request {}", request.getRequestURI()); + filterChain.doFilter(request, response); + } + + @Override + protected boolean shouldNotFilterAsyncDispatch() { + return true; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/OncePerRequestFilterApp.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/OncePerRequestFilterApp.java new file mode 100644 index 0000000000..ed7be518a3 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/OncePerRequestFilterApp.java @@ -0,0 +1,12 @@ +package com.baeldung.onceperrequestfilter; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + + +@SpringBootApplication(scanBasePackages = "com.baeldung.onceperrequestfilter") +public class OncePerRequestFilterApp { + public static void main(String[] args) { + SpringApplication.run(OncePerRequestFilterApp.class, args); + } +} \ No newline at end of file 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-basic-customization/pom.xml b/spring-boot-modules/spring-boot-basic-customization/pom.xml index 5ab747cff1..2782c3320e 100644 --- a/spring-boot-modules/spring-boot-basic-customization/pom.xml +++ b/spring-boot-modules/spring-boot-basic-customization/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-bootstrap/pom.xml b/spring-boot-modules/spring-boot-bootstrap/pom.xml index f94ee9ca31..caa3f6c7fc 100644 --- a/spring-boot-modules/spring-boot-bootstrap/pom.xml +++ b/spring-boot-modules/spring-boot-bootstrap/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-camel/pom.xml b/spring-boot-modules/spring-boot-camel/pom.xml index 0069dfdbff..5d5e2ce6bd 100644 --- a/spring-boot-modules/spring-boot-camel/pom.xml +++ b/spring-boot-modules/spring-boot-camel/pom.xml @@ -9,10 +9,9 @@ spring-boot-camel - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../../parent-boot-2 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-cassandre/pom.xml b/spring-boot-modules/spring-boot-cassandre/pom.xml index 14849e50d7..1f2931a2bf 100644 --- a/spring-boot-modules/spring-boot-cassandre/pom.xml +++ b/spring-boot-modules/spring-boot-cassandre/pom.xml @@ -9,10 +9,9 @@ Cassandre trading bot tutorial - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../../parent-boot-2 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-ci-cd/pom.xml b/spring-boot-modules/spring-boot-ci-cd/pom.xml index fb1810c62e..68a9f21d20 100644 --- a/spring-boot-modules/spring-boot-ci-cd/pom.xml +++ b/spring-boot-modules/spring-boot-ci-cd/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-client/pom.xml b/spring-boot-modules/spring-boot-client/pom.xml index 7f54d0e541..8ae2cbee79 100644 --- a/spring-boot-modules/spring-boot-client/pom.xml +++ b/spring-boot-modules/spring-boot-client/pom.xml @@ -13,7 +13,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-config-jpa-error/data-jpa-application/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-config-jpa-error/data-jpa-application/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-boot-modules/spring-boot-config-jpa-error/data-jpa-application/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-config-jpa-error/data-jpa-library/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-config-jpa-error/data-jpa-library/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-boot-modules/spring-boot-config-jpa-error/data-jpa-library/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-config-jpa-error/pom.xml b/spring-boot-modules/spring-boot-config-jpa-error/pom.xml index b5207f8997..6291589e7a 100644 --- a/spring-boot-modules/spring-boot-config-jpa-error/pom.xml +++ b/spring-boot-modules/spring-boot-config-jpa-error/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-crud/pom.xml b/spring-boot-modules/spring-boot-crud/pom.xml index 79eccf2fba..0a8e57be17 100644 --- a/spring-boot-modules/spring-boot-crud/pom.xml +++ b/spring-boot-modules/spring-boot-crud/pom.xml @@ -10,7 +10,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-ctx-fluent/pom.xml b/spring-boot-modules/spring-boot-ctx-fluent/pom.xml index 8a7aca076e..deefefc87c 100644 --- a/spring-boot-modules/spring-boot-ctx-fluent/pom.xml +++ b/spring-boot-modules/spring-boot-ctx-fluent/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-ctx-fluent/src/main/java/com/baeldung/ctx1/Ctx1Controller.java b/spring-boot-modules/spring-boot-ctx-fluent/src/main/java/com/baeldung/ctx1/Ctx1Controller.java index 9c7667db35..2de42251e4 100644 --- a/spring-boot-modules/spring-boot-ctx-fluent/src/main/java/com/baeldung/ctx1/Ctx1Controller.java +++ b/spring-boot-modules/spring-boot-ctx-fluent/src/main/java/com/baeldung/ctx1/Ctx1Controller.java @@ -1,22 +1,18 @@ package com.baeldung.ctx1; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ResponseBody; - import com.baeldung.parent.IHomeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; -@Controller +@RestController public class Ctx1Controller { @Autowired - IHomeService homeService; + private IHomeService homeService; @GetMapping("/home") - @ResponseBody public String greeting() { - return homeService.getGreeting(); } } diff --git a/spring-boot-modules/spring-boot-ctx-fluent/src/main/java/com/baeldung/ctx2/Ctx2Controller.java b/spring-boot-modules/spring-boot-ctx-fluent/src/main/java/com/baeldung/ctx2/Ctx2Controller.java index 850fd8021c..1b7edf6710 100644 --- a/spring-boot-modules/spring-boot-ctx-fluent/src/main/java/com/baeldung/ctx2/Ctx2Controller.java +++ b/spring-boot-modules/spring-boot-ctx-fluent/src/main/java/com/baeldung/ctx2/Ctx2Controller.java @@ -1,18 +1,17 @@ package com.baeldung.ctx2; +import com.baeldung.parent.IHomeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import com.baeldung.parent.IHomeService; - @RestController public class Ctx2Controller { @Autowired - IHomeService homeService; + private IHomeService homeService; - @GetMapping(value = "/greeting", produces = "application/json") + @GetMapping("/greeting") public String getGreeting() { return homeService.getGreeting(); } diff --git a/spring-boot-modules/spring-boot-ctx-fluent/src/main/resources/ctx1.properties b/spring-boot-modules/spring-boot-ctx-fluent/src/main/resources/ctx1.properties index 2b618d4177..d0af43abdd 100644 --- a/spring-boot-modules/spring-boot-ctx-fluent/src/main/resources/ctx1.properties +++ b/spring-boot-modules/spring-boot-ctx-fluent/src/main/resources/ctx1.properties @@ -1,4 +1,4 @@ -server.port=8081 +server.port=8074 server.servlet.context-path=/ctx1 #logging.level=debug spring.application.admin.enabled=false diff --git a/spring-boot-modules/spring-boot-ctx-fluent/src/main/resources/ctx2.properties b/spring-boot-modules/spring-boot-ctx-fluent/src/main/resources/ctx2.properties index f3599e17e0..7cd48d2f07 100644 --- a/spring-boot-modules/spring-boot-ctx-fluent/src/main/resources/ctx2.properties +++ b/spring-boot-modules/spring-boot-ctx-fluent/src/main/resources/ctx2.properties @@ -1,4 +1,4 @@ -server.port=8082 +server.port=8075 server.servlet.context-path=/ctx2 spring.application.admin.enabled=false diff --git a/spring-boot-modules/spring-boot-ctx-fluent/src/test/java/com/baeldung/SpringContextTest.java b/spring-boot-modules/spring-boot-ctx-fluent/src/test/java/com/baeldung/SpringContextTest.java index ca8989724b..07242452bf 100644 --- a/spring-boot-modules/spring-boot-ctx-fluent/src/test/java/com/baeldung/SpringContextTest.java +++ b/spring-boot-modules/spring-boot-ctx-fluent/src/test/java/com/baeldung/SpringContextTest.java @@ -7,7 +7,7 @@ import com.baeldung.parent.App; public class SpringContextTest { @Test - public final void testMain() throws Exception { + public final void testMain() { App.main(new String[] {}); } } diff --git a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-sample-app/pom.xml b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-sample-app/pom.xml index 815c3e8366..c4759af373 100644 --- a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-sample-app/pom.xml +++ b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-sample-app/pom.xml @@ -11,7 +11,6 @@ com.baeldung.spring-boot-modules spring-boot-custom-starter 0.0.1-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-custom-starter/greeter/pom.xml b/spring-boot-modules/spring-boot-custom-starter/greeter/pom.xml index f96880b1cf..5c0580d29a 100644 --- a/spring-boot-modules/spring-boot-custom-starter/greeter/pom.xml +++ b/spring-boot-modules/spring-boot-custom-starter/greeter/pom.xml @@ -8,10 +8,9 @@ greeter - com.baeldung - parent-boot-2 + com.baeldung.spring-boot-modules + spring-boot-custom-starter 0.0.1-SNAPSHOT - ../../../parent-boot-2 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-custom-starter/parent-multi-module/application/pom.xml b/spring-boot-modules/spring-boot-custom-starter/parent-multi-module/application/pom.xml index 1c26ec32d3..a00c3a3c57 100644 --- a/spring-boot-modules/spring-boot-custom-starter/parent-multi-module/application/pom.xml +++ b/spring-boot-modules/spring-boot-custom-starter/parent-multi-module/application/pom.xml @@ -9,9 +9,8 @@ com.baeldung - parent-boot-2 + parent-multi-module 0.0.1-SNAPSHOT - ../../../../parent-boot-2 diff --git a/spring-boot-modules/spring-boot-custom-starter/parent-multi-module/library/pom.xml b/spring-boot-modules/spring-boot-custom-starter/parent-multi-module/library/pom.xml index 5d45de0d1d..6e7b3ce78a 100644 --- a/spring-boot-modules/spring-boot-custom-starter/parent-multi-module/library/pom.xml +++ b/spring-boot-modules/spring-boot-custom-starter/parent-multi-module/library/pom.xml @@ -9,9 +9,8 @@ com.baeldung - parent-boot-2 + parent-multi-module 0.0.1-SNAPSHOT - ../../../../parent-boot-2 diff --git a/spring-boot-modules/spring-boot-custom-starter/parent-multi-module/pom.xml b/spring-boot-modules/spring-boot-custom-starter/parent-multi-module/pom.xml index 2a483a8fef..4bc8434d43 100644 --- a/spring-boot-modules/spring-boot-custom-starter/parent-multi-module/pom.xml +++ b/spring-boot-modules/spring-boot-custom-starter/parent-multi-module/pom.xml @@ -8,6 +8,12 @@ 0.0.1-SNAPSHOT pom + + com.baeldung.spring-boot-modules + spring-boot-custom-starter + 0.0.1-SNAPSHOT + + library application diff --git a/spring-boot-modules/spring-boot-custom-starter/pom.xml b/spring-boot-modules/spring-boot-custom-starter/pom.xml index 27e3a03153..aee98b125e 100644 --- a/spring-boot-modules/spring-boot-custom-starter/pom.xml +++ b/spring-boot-modules/spring-boot-custom-starter/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-data-2/pom.xml b/spring-boot-modules/spring-boot-data-2/pom.xml index b7006782c8..a3c2430497 100644 --- a/spring-boot-modules/spring-boot-data-2/pom.xml +++ b/spring-boot-modules/spring-boot-data-2/pom.xml @@ -9,7 +9,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-data-2/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-data-2/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-data/pom.xml b/spring-boot-modules/spring-boot-data/pom.xml index 447b730c02..7e0f764cf2 100644 --- a/spring-boot-modules/spring-boot-data/pom.xml +++ b/spring-boot-modules/spring-boot-data/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ @@ -36,7 +35,6 @@ com.h2database h2 - ${h2.version} org.springframework.boot diff --git a/spring-boot-modules/spring-boot-deployment/pom.xml b/spring-boot-modules/spring-boot-deployment/pom.xml index 7c78d20afc..c4d9fa7059 100644 --- a/spring-boot-modules/spring-boot-deployment/pom.xml +++ b/spring-boot-modules/spring-boot-deployment/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-di/pom.xml b/spring-boot-modules/spring-boot-di/pom.xml index 0e9fb49a95..af0dd7e4de 100644 --- a/spring-boot-modules/spring-boot-di/pom.xml +++ b/spring-boot-modules/spring-boot-di/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-disable-logging/disabling-console-jul/pom.xml b/spring-boot-modules/spring-boot-disable-logging/disabling-console-jul/pom.xml index deee4e435f..ace21410ea 100644 --- a/spring-boot-modules/spring-boot-disable-logging/disabling-console-jul/pom.xml +++ b/spring-boot-modules/spring-boot-disable-logging/disabling-console-jul/pom.xml @@ -11,7 +11,6 @@ com.baeldung.spring-boot-modules spring-boot-disable-logging 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-disable-logging/disabling-console-log4j2/pom.xml b/spring-boot-modules/spring-boot-disable-logging/disabling-console-log4j2/pom.xml index 0524f9d401..b71e1066e7 100644 --- a/spring-boot-modules/spring-boot-disable-logging/disabling-console-log4j2/pom.xml +++ b/spring-boot-modules/spring-boot-disable-logging/disabling-console-log4j2/pom.xml @@ -11,7 +11,6 @@ com.baeldung.spring-boot-modules spring-boot-disable-logging 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-disable-logging/disabling-console-logback/pom.xml b/spring-boot-modules/spring-boot-disable-logging/disabling-console-logback/pom.xml index 0990209ff9..37fad3ec53 100644 --- a/spring-boot-modules/spring-boot-disable-logging/disabling-console-logback/pom.xml +++ b/spring-boot-modules/spring-boot-disable-logging/disabling-console-logback/pom.xml @@ -10,7 +10,6 @@ com.baeldung.spring-boot-modules spring-boot-disable-logging 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-disable-logging/pom.xml b/spring-boot-modules/spring-boot-disable-logging/pom.xml index 65de521c63..31b02009b6 100644 --- a/spring-boot-modules/spring-boot-disable-logging/pom.xml +++ b/spring-boot-modules/spring-boot-disable-logging/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-environment/pom.xml b/spring-boot-modules/spring-boot-environment/pom.xml index d4b260ee3d..2cda396a9b 100644 --- a/spring-boot-modules/spring-boot-environment/pom.xml +++ b/spring-boot-modules/spring-boot-environment/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ @@ -30,17 +29,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - org.springframework.boot spring-boot-starter-data-jpa diff --git a/spring-boot-modules/spring-boot-exceptions/pom.xml b/spring-boot-modules/spring-boot-exceptions/pom.xml index cec1bab4ff..b1240957f6 100644 --- a/spring-boot-modules/spring-boot-exceptions/pom.xml +++ b/spring-boot-modules/spring-boot-exceptions/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-flowable/pom.xml b/spring-boot-modules/spring-boot-flowable/pom.xml index 320a684880..50500c3de6 100644 --- a/spring-boot-modules/spring-boot-flowable/pom.xml +++ b/spring-boot-modules/spring-boot-flowable/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ @@ -40,11 +39,6 @@ spring-boot-starter-test test - - org.junit.jupiter - junit-jupiter-engine - test - diff --git a/spring-boot-modules/spring-boot-groovy/pom.xml b/spring-boot-modules/spring-boot-groovy/pom.xml index ea9f3231cd..820bb0fd7a 100644 --- a/spring-boot-modules/spring-boot-groovy/pom.xml +++ b/spring-boot-modules/spring-boot-groovy/pom.xml @@ -10,10 +10,9 @@ Spring Boot Todo Application with Groovy - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../../parent-boot-2 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-jasypt/pom.xml b/spring-boot-modules/spring-boot-jasypt/pom.xml index 0a37c545ac..8595b9c639 100644 --- a/spring-boot-modules/spring-boot-jasypt/pom.xml +++ b/spring-boot-modules/spring-boot-jasypt/pom.xml @@ -13,7 +13,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-keycloak/.gitignore b/spring-boot-modules/spring-boot-keycloak/.gitignore deleted file mode 100644 index 2af7cefb0a..0000000000 --- a/spring-boot-modules/spring-boot-keycloak/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -target/ -!.mvn/wrapper/maven-wrapper.jar - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - -### NetBeans ### -nbproject/private/ -build/ -nbbuild/ -dist/ -nbdist/ -.nb-gradle/ \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/.mvn/wrapper/maven-wrapper.jar b/spring-boot-modules/spring-boot-keycloak/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 9cc84ea9b4..0000000000 Binary files a/spring-boot-modules/spring-boot-keycloak/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/spring-boot-modules/spring-boot-keycloak/.mvn/wrapper/maven-wrapper.properties b/spring-boot-modules/spring-boot-keycloak/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index 9dda3b659b..0000000000 --- a/spring-boot-modules/spring-boot-keycloak/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip diff --git a/spring-boot-modules/spring-boot-keycloak/README.md b/spring-boot-modules/spring-boot-keycloak/README.md index 2aff4664a6..7a1323d10e 100644 --- a/spring-boot-modules/spring-boot-keycloak/README.md +++ b/spring-boot-modules/spring-boot-keycloak/README.md @@ -8,4 +8,4 @@ This module contains articles about Keycloak in Spring Boot projects. - [Customizing the Login Page for Keycloak](https://www.baeldung.com/keycloak-custom-login-page) - [Keycloak User Self-Registration](https://www.baeldung.com/keycloak-user-registration) - [Customizing Themes for Keycloak](https://www.baeldung.com/spring-keycloak-custom-themes) - +- [Securing SOAP Web Services With Keycloak](https://www.baeldung.com/soap-keycloak) diff --git a/spring-boot-modules/spring-boot-keycloak/pom.xml b/spring-boot-modules/spring-boot-keycloak/pom.xml index b80dbfa191..09ddcaa724 100644 --- a/spring-boot-modules/spring-boot-keycloak/pom.xml +++ b/spring-boot-modules/spring-boot-keycloak/pom.xml @@ -64,6 +64,20 @@ org.springframework.boot spring-boot-starter-thymeleaf + + wsdl4j + wsdl4j + 1.6.3 + + + org.springframework.boot + spring-boot-starter-web-services + + + org.springframework.security + spring-security-test + test + @@ -72,11 +86,31 @@ org.springframework.boot spring-boot-maven-plugin + + org.codehaus.mojo + jaxb2-maven-plugin + 2.5.0 + + + xjc + + xjc + + + + + com.baeldung + + src/main/resources/products.xsd + + + + - 13.0.1 + 15.0.2 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java index 895ac8c562..78023aff8f 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java @@ -1,24 +1,19 @@ package com.baeldung.keycloak; import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; -import org.keycloak.adapters.springsecurity.KeycloakSecurityComponents; +import org.keycloak.adapters.springsecurity.KeycloakConfiguration; import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; import org.springframework.security.core.session.SessionRegistryImpl; import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; -@Configuration -@EnableWebSecurity -@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class) +@KeycloakConfiguration class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { // Submits the KeycloakAuthenticationProvider to the AuthenticationManager @Autowired diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java new file mode 100644 index 0000000000..66a17f4967 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java @@ -0,0 +1,54 @@ +package com.baeldung.keycloaksoap; + +import org.keycloak.adapters.KeycloakConfigResolver; +import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; +import org.keycloak.adapters.springsecurity.KeycloakConfiguration; +import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; +import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; +import org.springframework.security.core.session.SessionRegistryImpl; +import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; +import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; + +@KeycloakConfiguration +@ConditionalOnProperty(name = "keycloak.enabled", havingValue = "true") +@EnableGlobalMethodSecurity(jsr250Enabled = true) +public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + super.configure(http); + //@formatter:off + http + .csrf() + .disable() + .authorizeRequests() + .anyRequest() + .permitAll(); + //@formatter:on + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) { + KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); + keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); + auth.authenticationProvider(keycloakAuthenticationProvider); + } + + @Bean + @Override + protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { + return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); + } + + @Bean + public KeycloakConfigResolver keycloakSpringBootConfigResolver() { + return new KeycloakSpringBootConfigResolver(); + } + +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSoapServicesApplication.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSoapServicesApplication.java new file mode 100644 index 0000000000..4cf60a804a --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSoapServicesApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.keycloaksoap; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class KeycloakSoapServicesApplication { + + public static void main(String[] args) { + SpringApplication application = new SpringApplication(KeycloakSoapServicesApplication.class); + application.setAdditionalProfiles("keycloak"); + application.run(args); + } + +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/ProductsEndpoint.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/ProductsEndpoint.java new file mode 100644 index 0000000000..58f7739af0 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/ProductsEndpoint.java @@ -0,0 +1,42 @@ +package com.baeldung.keycloaksoap; + +import com.baeldung.DeleteProductRequest; +import com.baeldung.DeleteProductResponse; +import com.baeldung.GetProductDetailsRequest; +import com.baeldung.GetProductDetailsResponse; +import com.baeldung.Product; +import org.springframework.ws.server.endpoint.annotation.Endpoint; +import org.springframework.ws.server.endpoint.annotation.PayloadRoot; +import org.springframework.ws.server.endpoint.annotation.RequestPayload; +import org.springframework.ws.server.endpoint.annotation.ResponsePayload; + +import javax.annotation.security.RolesAllowed; +import java.util.Map; + +@Endpoint +public class ProductsEndpoint { + + private final Map productMap; + + public ProductsEndpoint(Map productMap) { + this.productMap = productMap; + } + + @RolesAllowed("user") + @PayloadRoot(namespace = "http://www.baeldung.com/springbootsoap/keycloak", localPart = "getProductDetailsRequest") + @ResponsePayload + public GetProductDetailsResponse getProductDetails(@RequestPayload GetProductDetailsRequest request) { + GetProductDetailsResponse response = new GetProductDetailsResponse(); + response.setProduct(productMap.get(request.getId())); + return response; + } + + @RolesAllowed("admin") + @PayloadRoot(namespace = "http://www.baeldung.com/springbootsoap/keycloak", localPart = "deleteProductRequest") + @ResponsePayload + public DeleteProductResponse deleteProduct(@RequestPayload DeleteProductRequest request) { + DeleteProductResponse response = new DeleteProductResponse(); + response.setMessage("Success! Deleted the product with the id - "+request.getId()); + return response; + } +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/WebServiceConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/WebServiceConfig.java new file mode 100644 index 0000000000..00d128fa12 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/WebServiceConfig.java @@ -0,0 +1,75 @@ +package com.baeldung.keycloaksoap; + +import com.baeldung.Product; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.ws.config.annotation.EnableWs; +import org.springframework.ws.config.annotation.WsConfigurerAdapter; +import org.springframework.ws.transport.http.MessageDispatcherServlet; +import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; +import org.springframework.xml.xsd.SimpleXsdSchema; +import org.springframework.xml.xsd.XsdSchema; + +import java.util.HashMap; +import java.util.Map; + +@EnableWs +@Configuration +public class WebServiceConfig extends WsConfigurerAdapter { + + @Value("${ws.api.path:/ws/api/v1/*}") + private String webserviceApiPath; + @Value("${ws.port.type.name:ProductsPort}") + private String webservicePortTypeName; + @Value("${ws.target.namespace:http://www.baeldung.com/springbootsoap/keycloak}") + private String webserviceTargetNamespace; + @Value("${ws.location.uri:http://localhost:18080/ws/api/v1/}") + private String locationUri; + + @Bean + public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) { + MessageDispatcherServlet servlet = new MessageDispatcherServlet(); + servlet.setApplicationContext(applicationContext); + servlet.setTransformWsdlLocations(true); + return new ServletRegistrationBean<>(servlet, webserviceApiPath); + } + + @Bean(name = "products") + public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema productsSchema) { + DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition(); + wsdl11Definition.setPortTypeName(webservicePortTypeName); + wsdl11Definition.setTargetNamespace(webserviceTargetNamespace); + wsdl11Definition.setLocationUri(locationUri); + wsdl11Definition.setSchema(productsSchema); + return wsdl11Definition; + } + + @Bean + public XsdSchema productsSchema() { + return new SimpleXsdSchema(new ClassPathResource("products.xsd")); + } + + @Bean + public Map getProducts() + { + Map map = new HashMap<>(); + Product foldsack= new Product(); + foldsack.setId("1"); + foldsack.setName("Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops"); + foldsack.setDescription("Your perfect pack for everyday use and walks in the forest. "); + + Product shirt= new Product(); + shirt.setId("2"); + shirt.setName("Mens Casual Premium Slim Fit T-Shirts"); + shirt.setDescription("Slim-fitting style, contrast raglan long sleeve, three-button henley placket."); + + map.put("1", foldsack); + map.put("2", shirt); + return map; + } + +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-keycloak.properties b/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-keycloak.properties new file mode 100644 index 0000000000..0a28b7ac48 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-keycloak.properties @@ -0,0 +1,17 @@ +server.port=18080 + +keycloak.enabled=true +keycloak.realm=baeldung-soap-services +keycloak.auth-server-url=http://localhost:8080/auth +keycloak.bearer-only=true +keycloak.credentials.secret=14da6f9e-261f-489a-9bf0-1441e4a9ddc4 +keycloak.ssl-required=external +keycloak.resource=baeldung-soap-services +keycloak.use-resource-role-mappings=true + + +# Custom properties begin here +ws.api.path=/ws/api/v1/* +ws.port.type.name=ProductsPort +ws.target.namespace=http://www.baeldung.com/springbootsoap/keycloak +ws.location.uri=http://localhost:18080/ws/api/v1/ \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/resources/products.xsd b/spring-boot-modules/spring-boot-keycloak/src/main/resources/products.xsd new file mode 100644 index 0000000000..b147118e96 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/resources/products.xsd @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapIntegrationTest.java b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapIntegrationTest.java new file mode 100644 index 0000000000..e0de897044 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapIntegrationTest.java @@ -0,0 +1,153 @@ +package com.baeldung.keycloaksoap; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.Objects; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * The class contains Live/Integration tests. + * These tests expect that the Keycloak server is up and running on port 8080. + * The tests may fail without a Keycloak server. + */ +@DisplayName("Keycloak SOAP Webservice Unit Tests") +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +@AutoConfigureMockMvc +class KeycloakSoapIntegrationTest { + + private static final Logger logger = LoggerFactory.getLogger(KeycloakSoapIntegrationTest.class); + @LocalServerPort + private int port; + @Autowired + private TestRestTemplate restTemplate; + @Autowired + private ObjectMapper objectMapper; + @Value("${grant.type}") + private String grantType; + @Value("${client.id}") + private String clientId; + @Value("${client.secret}") + private String clientSecret; + @Value("${url}") + private String keycloakUrl; + + /** + * Test a happy flow. Test the janedoe user. + * This user should be configured in Keycloak server with a role user + */ + @Test + @DisplayName("Get Products With Access Token") + void givenAccessToken_whenGetProducts_thenReturnProduct() { + + HttpHeaders headers = new HttpHeaders(); + headers.set("content-type", "text/xml"); + headers.set("Authorization", "Bearer " + generateToken("janedoe", "password")); + HttpEntity request = new HttpEntity<>(Utility.getGetProductDetailsRequest(), headers); + ResponseEntity responseEntity = restTemplate.postForEntity("http://localhost:" + port + "/ws/api/v1/", request, String.class); + + assertThat(responseEntity).isNotNull(); + assertThat(responseEntity.getStatusCodeValue()).isEqualTo(HttpStatus.OK.value()); + assertThat(responseEntity.getBody()).isNotBlank(); + assertThat(responseEntity.getBody()).containsIgnoringCase(":id>1janeadoe user. + * Keycloak returns Unauthorized. Assert 401 status and empty body. + */ + @Test + @DisplayName("Get Products With Wrong Access Token") + void givenWrongAccessToken_whenGetProducts_thenReturnError() { + + HttpHeaders headers = new HttpHeaders(); + headers.set("content-type", "text/xml"); + headers.set("Authorization", "Bearer " + generateToken("janeadoe", "password")); + HttpEntity request = new HttpEntity<>(Utility.getGetProductDetailsRequest(), headers); + ResponseEntity responseEntity = restTemplate.postForEntity("http://localhost:" + port + "/ws/api/v1/", request, String.class); + assertThat(responseEntity).isNotNull(); + assertThat(responseEntity.getStatusCodeValue()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + assertThat(responseEntity.getBody()).isBlank(); + } + + /** + * Happy flow to test deleteProduct operation. Test the jhondoe user. + * This user should be configured in Keycloak server with a role user + */ + @Test + @DisplayName("Delete Product With Access Token") + void givenAccessToken_whenDeleteProduct_thenReturnSuccess() { + HttpHeaders headers = new HttpHeaders(); + headers.set("content-type", "text/xml"); + headers.set("Authorization", "Bearer " + generateToken("jhondoe", "password")); + HttpEntity request = new HttpEntity<>(Utility.getDeleteProductsRequest(), headers); + ResponseEntity responseEntity = restTemplate.postForEntity("http://localhost:" + port + "/ws/api/v1/", request, String.class); + + assertThat(responseEntity).isNotNull(); + assertThat(responseEntity.getStatusCodeValue()).isEqualTo(HttpStatus.OK.value()); + assertThat(responseEntity.getBody()).isNotBlank(); + assertThat(responseEntity.getBody()).containsIgnoringCase("Deleted the product with the id"); + } + + /** + * Negative flow to test . Test the janedoe user. + * Obtain the access token of janedoe and access the admin operation deleteProduct + * Assume janedoe has restricted access to deleteProduct operation + */ + @Test + @DisplayName("Delete Products With Unauthorized Access Token") + void givenUnauthorizedAccessToken_whenDeleteProduct_thenReturnUnauthorized() { + HttpHeaders headers = new HttpHeaders(); + headers.set("content-type", "text/xml"); + headers.set("Authorization", "Bearer " + generateToken("janedoe", "password")); + HttpEntity request = new HttpEntity<>(Utility.getDeleteProductsRequest(), headers); + ResponseEntity responseEntity = restTemplate.postForEntity("http://localhost:" + port + "/ws/api/v1/", request, String.class); + + assertThat(responseEntity).isNotNull(); + assertThat(responseEntity.getStatusCodeValue()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR.value()); + assertThat(responseEntity.getBody()).isNotBlank(); + assertThat(responseEntity.getBody()).containsIgnoringCase("Access is denied"); + } + + private String generateToken(String username, String password) { + + try { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("grant_type", grantType); + map.add("client_id", clientId); + map.add("client_secret", clientSecret); + map.add("username", username); + map.add("password", password); + HttpEntity> entity = new HttpEntity<>(map, headers); + ResponseEntity response = restTemplate.exchange(keycloakUrl, HttpMethod.POST, entity, String.class); + return Objects.requireNonNull(response.getBody()).contains("access_token") ? objectMapper.readTree(response.getBody()).get("access_token").asText() : ""; + } catch (Exception ex) { + logger.error("There is an internal server error. Returning an empty access token", ex); + return ""; + } + + } + +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/Utility.java b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/Utility.java new file mode 100644 index 0000000000..1535d9f171 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/Utility.java @@ -0,0 +1,12 @@ +package com.baeldung.keycloaksoap; + +public class Utility { + public static String getGetProductDetailsRequest() { + return "\n" + " \n" + " \n" + " \n" + + " 1\n" + " \n" + " \n" + ""; + } + public static String getDeleteProductsRequest() { + return "\n" + " \n" + " \n" + " \n" + + " 1\n" + " \n" + " \n" + ""; + } +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/resources/application-test.properties b/spring-boot-modules/spring-boot-keycloak/src/test/resources/application-test.properties new file mode 100644 index 0000000000..a818b5be7a --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/test/resources/application-test.properties @@ -0,0 +1,4 @@ +grant.type=password +client.id=baeldung-soap-services +client.secret=d2ba7af8-f7d2-4c97-b4a5-3c88b59920ae +url=http://localhost:8080/auth/realms/baeldung-soap-services/protocol/openid-connect/token diff --git a/spring-boot-modules/spring-boot-libraries-2/README.md b/spring-boot-modules/spring-boot-libraries-2/README.md index 7bf51b5424..cf07279258 100644 --- a/spring-boot-modules/spring-boot-libraries-2/README.md +++ b/spring-boot-modules/spring-boot-libraries-2/README.md @@ -6,3 +6,5 @@ This module contains articles about various Spring Boot libraries - [Background Jobs in Spring with JobRunr](https://www.baeldung.com/java-jobrunr-spring) - [Open API Server Implementation Using OpenAPI Generator](https://www.baeldung.com/java-openapi-generator-server) +- [An Introduction to Kong](https://www.baeldung.com/kong) + More articles: [[prev -->]](/spring-boot-modules/spring-boot-libraries) diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/kong/QueryController.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/kong/QueryController.java similarity index 100% rename from spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/kong/QueryController.java rename to spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/kong/QueryController.java diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/kong/StockApp.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/kong/StockApp.java similarity index 100% rename from spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/kong/StockApp.java rename to spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/kong/StockApp.java diff --git a/spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/KongAdminAPILiveTest.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/KongAdminAPILiveTest.java similarity index 100% rename from spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/KongAdminAPILiveTest.java rename to spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/KongAdminAPILiveTest.java diff --git a/spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/KongLoadBalanceLiveTest.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/KongLoadBalanceLiveTest.java similarity index 100% rename from spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/KongLoadBalanceLiveTest.java rename to spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/KongLoadBalanceLiveTest.java diff --git a/spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/domain/APIObject.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/domain/APIObject.java similarity index 100% rename from spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/domain/APIObject.java rename to spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/domain/APIObject.java diff --git a/spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/domain/ConsumerObject.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/domain/ConsumerObject.java similarity index 100% rename from spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/domain/ConsumerObject.java rename to spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/domain/ConsumerObject.java diff --git a/spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/domain/KeyAuthObject.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/domain/KeyAuthObject.java similarity index 100% rename from spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/domain/KeyAuthObject.java rename to spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/domain/KeyAuthObject.java diff --git a/spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/domain/PluginObject.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/domain/PluginObject.java similarity index 100% rename from spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/domain/PluginObject.java rename to spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/domain/PluginObject.java diff --git a/spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/domain/TargetObject.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/domain/TargetObject.java similarity index 100% rename from spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/domain/TargetObject.java rename to spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/domain/TargetObject.java diff --git a/spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/domain/UpstreamObject.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/domain/UpstreamObject.java similarity index 100% rename from spring-boot-modules/spring-boot-libraries/src/test/java/com/baeldung/kong/domain/UpstreamObject.java rename to spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/domain/UpstreamObject.java diff --git a/spring-boot-modules/spring-boot-libraries/README.md b/spring-boot-modules/spring-boot-libraries/README.md index 6976435866..b72815e4a9 100644 --- a/spring-boot-modules/spring-boot-libraries/README.md +++ b/spring-boot-modules/spring-boot-libraries/README.md @@ -14,7 +14,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring Boot and Caffeine Cache](https://www.baeldung.com/spring-boot-caffeine-cache) - [Spring Boot and Togglz Aspect](https://www.baeldung.com/spring-togglz) - [Getting Started with GraphQL and Spring Boot](https://www.baeldung.com/spring-graphql) -- [An Introduction to Kong](https://www.baeldung.com/kong) +- More articles: [[next -->]](/spring-boot-modules/spring-boot-libraries-2) ### GraphQL sample queries diff --git a/spring-boot-modules/spring-boot-libraries/pom.xml b/spring-boot-modules/spring-boot-libraries/pom.xml index ad00629e14..97fde60a16 100644 --- a/spring-boot-modules/spring-boot-libraries/pom.xml +++ b/spring-boot-modules/spring-boot-libraries/pom.xml @@ -11,7 +11,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ @@ -83,7 +82,6 @@ com.h2database h2 - ${h2.version} @@ -240,7 +238,6 @@ 2.2.4 2.3.2 0.23.0 - 1.4.200 2.1.0 1.5-beta1 2.1 diff --git a/spring-boot-modules/spring-boot-logging-log4j2/pom.xml b/spring-boot-modules/spring-boot-logging-log4j2/pom.xml index dafbddb93f..8cf052deb3 100644 --- a/spring-boot-modules/spring-boot-logging-log4j2/pom.xml +++ b/spring-boot-modules/spring-boot-logging-log4j2/pom.xml @@ -18,8 +18,8 @@ - + junit junit diff --git a/spring-boot-modules/spring-boot-mvc-2/README.md b/spring-boot-modules/spring-boot-mvc-2/README.md index f9becb721f..0d0e05daf0 100644 --- a/spring-boot-modules/spring-boot-mvc-2/README.md +++ b/spring-boot-modules/spring-boot-mvc-2/README.md @@ -7,7 +7,6 @@ This module contains articles about Spring Web MVC in Spring Boot projects. - [Functional Controllers in Spring MVC](https://www.baeldung.com/spring-mvc-functional-controllers) - [Specify an Array of Strings as Body Parameters in Swagger](https://www.baeldung.com/swagger-body-array-of-strings) - [Swagger @ApiParam vs @ApiModelProperty](https://www.baeldung.com/swagger-apiparam-vs-apimodelproperty) -- [ETags for REST with Spring](https://www.baeldung.com/etags-for-rest-with-spring) - [Testing REST with multiple MIME types](https://www.baeldung.com/testing-rest-api-with-multiple-media-types) - [Testing Web APIs with Postman Collections](https://www.baeldung.com/postman-testing-collections) - [Spring Boot Consuming and Producing JSON](https://www.baeldung.com/spring-boot-json) diff --git a/spring-boot-modules/spring-boot-mvc-2/pom.xml b/spring-boot-modules/spring-boot-mvc-2/pom.xml index d347b36b3b..f303171df8 100644 --- a/spring-boot-modules/spring-boot-mvc-2/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-2/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/mime/Foo.java b/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/mime/Foo.java new file mode 100644 index 0000000000..a8e379fc79 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/mime/Foo.java @@ -0,0 +1,93 @@ +package com.baeldung.mime; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Version; +import java.io.Serializable; + +@Entity +public class Foo implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + + @Column(nullable = false) + private String name; + + @Version + private long version; + + public Foo() { + super(); + } + + public Foo(final String name) { + super(); + + this.name = name; + } + + // API + + public long getId() { + return id; + } + + public void setId(final long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } + + // + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final Foo other = (Foo) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Foo [name=").append(name).append("]"); + return builder.toString(); + } +} diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/mime/FooController.java b/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/mime/FooController.java new file mode 100644 index 0000000000..d7da9bd849 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/mime/FooController.java @@ -0,0 +1,36 @@ +package com.baeldung.mime; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; + +import javax.servlet.http.HttpServletResponse; + +@RestController +@RequestMapping(value = "/foos") +public class FooController { + + @Autowired + private FooDao fooDao; + + @GetMapping(value = "/{id}") + public Foo findById(@PathVariable("id") final Long id, final HttpServletResponse response) { + return fooDao.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public Foo create(@RequestBody final Foo resource, final HttpServletResponse response) { + return fooDao.save(resource); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/mime/FooDao.java b/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/mime/FooDao.java new file mode 100644 index 0000000000..9fc99e1124 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/mime/FooDao.java @@ -0,0 +1,8 @@ +package com.baeldung.mime; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface FooDao extends CrudRepository{ +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/mime/FooLiveTest.java b/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/mime/FooLiveTest.java index e65b106ead..86dd4915b4 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/mime/FooLiveTest.java +++ b/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/mime/FooLiveTest.java @@ -14,15 +14,12 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import com.baeldung.etag.Foo; -import com.baeldung.etag.WebConfig; - import io.restassured.RestAssured; import io.restassured.response.Response; @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes= WebConfig.class, webEnvironment = WebEnvironment.RANDOM_PORT) -@ComponentScan({"com.baeldung.mime", "com.baeldung.etag"}) +@SpringBootTest(classes = FooController.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@ComponentScan({"com.baeldung.mime"}) @EnableAutoConfiguration @ActiveProfiles("test") public class FooLiveTest { @@ -47,12 +44,12 @@ public class FooLiveTest { createAsUri(resource); } - private final String createAsUri(final Foo resource) { + private String createAsUri(final Foo resource) { final Response response = createAsResponse(resource); return getURL() + "/" + response.getBody().as(Foo.class).getId(); } - private final Response createAsResponse(final Foo resource) { + private Response createAsResponse(final Foo resource) { final String resourceAsString = marshaller.encode(resource); return RestAssured.given() diff --git a/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/mime/JacksonMarshaller.java b/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/mime/JacksonMarshaller.java index 9dee0ef2cd..c6d14a9427 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/mime/JacksonMarshaller.java +++ b/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/mime/JacksonMarshaller.java @@ -7,7 +7,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; -import com.baeldung.etag.Foo; +import com.baeldung.mime.Foo; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/mime/XStreamMarshaller.java b/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/mime/XStreamMarshaller.java index 2c67694e83..8a4188ceca 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/mime/XStreamMarshaller.java +++ b/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/mime/XStreamMarshaller.java @@ -4,7 +4,7 @@ import java.util.List; import org.springframework.http.MediaType; -import com.baeldung.etag.Foo; +import com.baeldung.mime.Foo; import com.thoughtworks.xstream.XStream; public final class XStreamMarshaller implements IMarshaller { diff --git a/spring-boot-modules/spring-boot-mvc-3/README.md b/spring-boot-modules/spring-boot-mvc-3/README.md index f9c6989b3c..fa24ac11ed 100644 --- a/spring-boot-modules/spring-boot-mvc-3/README.md +++ b/spring-boot-modules/spring-boot-mvc-3/README.md @@ -10,4 +10,5 @@ This module contains articles about Spring Web MVC in Spring Boot projects. - [Differences in @Valid and @Validated Annotations in Spring](https://www.baeldung.com/spring-valid-vs-validated) - [CharacterEncodingFilter In SpringBoot](https://www.baeldung.com/spring-boot-characterencodingfilter) - [HandlerInterceptors vs. Filters in Spring MVC](https://www.baeldung.com/spring-mvc-handlerinterceptor-vs-filter) +- [ETags for REST with Spring](https://www.baeldung.com/etags-for-rest-with-spring) - More articles: [[prev -->]](/spring-boot-modules/spring-boot-mvc-2) diff --git a/spring-boot-modules/spring-boot-mvc-3/pom.xml b/spring-boot-modules/spring-boot-mvc-3/pom.xml index a46837e315..43a492786e 100644 --- a/spring-boot-modules/spring-boot-mvc-3/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-3/pom.xml @@ -4,15 +4,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-mvc-3 - jar spring-boot-mvc-3 + jar Module For Spring Boot MVC Web com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ @@ -28,6 +27,14 @@ org.springframework.boot spring-boot-starter-thymeleaf + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + commons-io commons-io diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/etag/Foo.java b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/etag/Foo.java similarity index 99% rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/etag/Foo.java rename to spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/etag/Foo.java index e553ca1b72..9790bca663 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/etag/Foo.java +++ b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/etag/Foo.java @@ -1,13 +1,12 @@ package com.baeldung.etag; -import java.io.Serializable; - import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Version; +import java.io.Serializable; @Entity public class Foo implements Serializable { diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/etag/FooController.java b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/etag/FooController.java similarity index 100% rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/etag/FooController.java rename to spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/etag/FooController.java index 58f366501d..d40a5e7809 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/etag/FooController.java +++ b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/etag/FooController.java @@ -1,7 +1,5 @@ package com.baeldung.etag; -import javax.servlet.http.HttpServletResponse; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -16,6 +14,8 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ResponseStatusException; +import javax.servlet.http.HttpServletResponse; + @RestController @RequestMapping(value = "/foos") public class FooController { diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/etag/FooDao.java b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/etag/FooDao.java similarity index 100% rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/etag/FooDao.java rename to spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/etag/FooDao.java diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/etag/SpringBootEtagApplication.java b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/etag/SpringBootEtagApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/etag/SpringBootEtagApplication.java rename to spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/etag/SpringBootEtagApplication.java diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/etag/WebConfig.java b/spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/etag/WebConfig.java similarity index 100% rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/etag/WebConfig.java rename to spring-boot-modules/spring-boot-mvc-3/src/main/java/com/baeldung/etag/WebConfig.java diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/resources/WEB-INF/web.xml b/spring-boot-modules/spring-boot-mvc-3/src/main/resources/WEB-INF/web.xml similarity index 100% rename from spring-boot-modules/spring-boot-mvc-2/src/main/resources/WEB-INF/web.xml rename to spring-boot-modules/spring-boot-mvc-3/src/main/resources/WEB-INF/web.xml diff --git a/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/etag/EtagIntegrationTest.java b/spring-boot-modules/spring-boot-mvc-3/src/test/java/com/baeldung/etag/EtagIntegrationTest.java similarity index 99% rename from spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/etag/EtagIntegrationTest.java rename to spring-boot-modules/spring-boot-mvc-3/src/test/java/com/baeldung/etag/EtagIntegrationTest.java index 88c5ae1686..97de6d06f1 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/test/java/com/baeldung/etag/EtagIntegrationTest.java +++ b/spring-boot-modules/spring-boot-mvc-3/src/test/java/com/baeldung/etag/EtagIntegrationTest.java @@ -1,10 +1,10 @@ package com.baeldung.etag; -import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.restassured.RestAssured; +import io.restassured.http.ContentType; +import io.restassured.response.Response; import org.assertj.core.util.Preconditions; import org.junit.Ignore; import org.junit.Test; @@ -18,12 +18,10 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -import io.restassured.RestAssured; -import io.restassured.http.ContentType; -import io.restassured.response.Response; +import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) diff --git a/spring-boot-modules/spring-boot-mvc-jersey/pom.xml b/spring-boot-modules/spring-boot-mvc-jersey/pom.xml index b6e2c62663..34b459d1dc 100644 --- a/spring-boot-modules/spring-boot-mvc-jersey/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-jersey/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/pom.xml b/spring-boot-modules/spring-boot-mvc/pom.xml index 3e835691aa..6d3f722146 100644 --- a/spring-boot-modules/spring-boot-mvc/pom.xml +++ b/spring-boot-modules/spring-boot-mvc/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-nashorn/pom.xml b/spring-boot-modules/spring-boot-nashorn/pom.xml index 89b0b984bc..0ae108ffd0 100644 --- a/spring-boot-modules/spring-boot-nashorn/pom.xml +++ b/spring-boot-modules/spring-boot-nashorn/pom.xml @@ -13,7 +13,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-parent/pom.xml b/spring-boot-modules/spring-boot-parent/pom.xml index 28a940bcd0..d9c23b66ac 100644 --- a/spring-boot-modules/spring-boot-parent/pom.xml +++ b/spring-boot-modules/spring-boot-parent/pom.xml @@ -13,7 +13,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml b/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml index a61a5fd057..18fa4c53d9 100644 --- a/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml +++ b/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml @@ -11,7 +11,6 @@ com.baeldung.spring-boot-modules spring-boot-parent 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml b/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml index 2568714278..e65f590c9b 100644 --- a/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml +++ b/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-parent 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-performance/pom.xml b/spring-boot-modules/spring-boot-performance/pom.xml index f1f9b52dc4..38f5758c1f 100644 --- a/spring-boot-modules/spring-boot-performance/pom.xml +++ b/spring-boot-modules/spring-boot-performance/pom.xml @@ -11,7 +11,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-properties-2/README.md b/spring-boot-modules/spring-boot-properties-2/README.md index c81ad50e40..501beed092 100644 --- a/spring-boot-modules/spring-boot-properties-2/README.md +++ b/spring-boot-modules/spring-boot-properties-2/README.md @@ -3,7 +3,6 @@ This module contains articles about Properties in Spring Boot. ### Relevant Articles: -- [Load Spring Boot Properties From a JSON File](https://www.baeldung.com/spring-boot-json-properties) - [A Quick Guide to Spring @Value](https://www.baeldung.com/spring-value-annotation) - [Using Spring @Value with Defaults](https://www.baeldung.com/spring-value-defaults) - [How to Inject a Property Value Into a Class Not Managed by Spring?](https://www.baeldung.com/inject-properties-value-non-spring-class) diff --git a/spring-boot-modules/spring-boot-properties-2/pom.xml b/spring-boot-modules/spring-boot-properties-2/pom.xml index 62f23da450..d5aaab54d3 100644 --- a/spring-boot-modules/spring-boot-properties-2/pom.xml +++ b/spring-boot-modules/spring-boot-properties-2/pom.xml @@ -13,7 +13,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-properties-2/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-properties-2/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-2/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties-3/README.md b/spring-boot-modules/spring-boot-properties-3/README.md index df272be7f4..a682ae0ac8 100644 --- a/spring-boot-modules/spring-boot-properties-3/README.md +++ b/spring-boot-modules/spring-boot-properties-3/README.md @@ -7,3 +7,4 @@ - [How to Define a Map in YAML for a POJO?](https://www.baeldung.com/yaml-map-pojo) - [Using application.yml vs application.properties in Spring Boot](https://www.baeldung.com/spring-boot-yaml-vs-properties) +- [Load Spring Boot Properties From a JSON File](https://www.baeldung.com/spring-boot-json-properties) \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties-3/pom.xml b/spring-boot-modules/spring-boot-properties-3/pom.xml index b5e6ef8701..d72c410d9b 100644 --- a/spring-boot-modules/spring-boot-properties-3/pom.xml +++ b/spring-boot-modules/spring-boot-properties-3/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/json/ConfigPropertiesDemoApplication.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/json/ConfigPropertiesDemoApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/json/ConfigPropertiesDemoApplication.java rename to spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/json/ConfigPropertiesDemoApplication.java diff --git a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/json/CustomJsonProperties.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/json/CustomJsonProperties.java similarity index 100% rename from spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/json/CustomJsonProperties.java rename to spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/json/CustomJsonProperties.java diff --git a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/json/JsonProperties.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/json/JsonProperties.java similarity index 100% rename from spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/json/JsonProperties.java rename to spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/json/JsonProperties.java diff --git a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/json/JsonPropertyContextInitializer.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/json/JsonPropertyContextInitializer.java similarity index 100% rename from spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/json/JsonPropertyContextInitializer.java rename to spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/json/JsonPropertyContextInitializer.java diff --git a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/json/factory/JsonPropertySourceFactory.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/json/factory/JsonPropertySourceFactory.java similarity index 100% rename from spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/json/factory/JsonPropertySourceFactory.java rename to spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/json/factory/JsonPropertySourceFactory.java diff --git a/spring-boot-modules/spring-boot-properties-2/src/main/resources/configprops.json b/spring-boot-modules/spring-boot-properties-3/src/main/resources/configprops.json similarity index 100% rename from spring-boot-modules/spring-boot-properties-2/src/main/resources/configprops.json rename to spring-boot-modules/spring-boot-properties-3/src/main/resources/configprops.json diff --git a/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/json/JsonPropertiesIntegrationTest.java b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/properties/json/JsonPropertiesIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/json/JsonPropertiesIntegrationTest.java rename to spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/properties/json/JsonPropertiesIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-properties/pom.xml b/spring-boot-modules/spring-boot-properties/pom.xml index 0ef44e0546..8cbaccdac5 100644 --- a/spring-boot-modules/spring-boot-properties/pom.xml +++ b/spring-boot-modules/spring-boot-properties/pom.xml @@ -4,16 +4,15 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-properties - jar 0.0.1-SNAPSHOT spring-boot-properties + jar Spring Boot Properties Module com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-properties/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-properties/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-property-exp/property-exp-default-config/pom.xml b/spring-boot-modules/spring-boot-property-exp/property-exp-default-config/pom.xml index 496004b0e2..b1c44de9a9 100644 --- a/spring-boot-modules/spring-boot-property-exp/property-exp-default-config/pom.xml +++ b/spring-boot-modules/spring-boot-property-exp/property-exp-default-config/pom.xml @@ -9,10 +9,9 @@ jar - com.baeldung - parent-boot-2 + com.baeldung.spring-boot-modules + spring-boot-property-exp 0.0.1-SNAPSHOT - ../../../parent-boot-2 diff --git a/spring-boot-modules/spring-boot-react/pom.xml b/spring-boot-modules/spring-boot-react/pom.xml index 3e8a9a7bd1..d515aed6ce 100644 --- a/spring-boot-modules/spring-boot-react/pom.xml +++ b/spring-boot-modules/spring-boot-react/pom.xml @@ -25,7 +25,6 @@ com.h2database h2 - ${h2.version} runtime @@ -128,7 +127,6 @@ v14.18.0 v1.12.1 2.4.4 - 1.4.200 1.0.2 diff --git a/spring-boot-modules/spring-boot-runtime-2/README.md b/spring-boot-modules/spring-boot-runtime-2/README.md index 9f0d814d8d..f439b0d0bd 100644 --- a/spring-boot-modules/spring-boot-runtime-2/README.md +++ b/spring-boot-modules/spring-boot-runtime-2/README.md @@ -4,3 +4,5 @@ This module contains articles about administering a Spring Boot runtime ### Relevant Articles: - [Configure the Heap Size When Starting a Spring Boot Application](https://www.baeldung.com/spring-boot-heap-size) + - [CORS with Spring](https://www.baeldung.com/spring-cors) + - [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-runtime-2/pom.xml b/spring-boot-modules/spring-boot-runtime-2/pom.xml index c177529a41..5174900c79 100644 --- a/spring-boot-modules/spring-boot-runtime-2/pom.xml +++ b/spring-boot-modules/spring-boot-runtime-2/pom.xml @@ -4,15 +4,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-runtime-2 - jar spring-boot-runtime-2 + jar Demo project for Spring Boot com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ @@ -25,6 +24,10 @@ spring-boot-starter-test test + + org.springframework.security + spring-security-test + diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/Account.java b/spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/Account.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/Account.java rename to spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/Account.java diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/AccountController.java b/spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/AccountController.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/AccountController.java rename to spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/AccountController.java diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/config/WebConfig.java b/spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/config/WebConfig.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/config/WebConfig.java rename to spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/config/WebConfig.java diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/maxhttpheadersize/MaxHttpHeaderSizeApplication.java b/spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/maxhttpheadersize/MaxHttpHeaderSizeApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/maxhttpheadersize/MaxHttpHeaderSizeApplication.java rename to spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/maxhttpheadersize/MaxHttpHeaderSizeApplication.java diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/maxhttpheadersize/config/MaxHTTPHeaderSizeConfig.java b/spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/maxhttpheadersize/config/MaxHTTPHeaderSizeConfig.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/maxhttpheadersize/config/MaxHTTPHeaderSizeConfig.java rename to spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/maxhttpheadersize/config/MaxHTTPHeaderSizeConfig.java diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/maxhttpheadersize/controller/MaxHttpHeaderSizeController.java b/spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/maxhttpheadersize/controller/MaxHttpHeaderSizeController.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/maxhttpheadersize/controller/MaxHttpHeaderSizeController.java rename to spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/maxhttpheadersize/controller/MaxHttpHeaderSizeController.java diff --git a/spring-boot-modules/spring-boot-runtime/src/test/java/com/baeldung/maxhttpheadersize/controller/MaxHttpHeaderSizeControllerIntegrationTest.java b/spring-boot-modules/spring-boot-runtime-2/src/test/java/com/baeldung/maxhttpheadersize/controller/MaxHttpHeaderSizeControllerIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime/src/test/java/com/baeldung/maxhttpheadersize/controller/MaxHttpHeaderSizeControllerIntegrationTest.java rename to spring-boot-modules/spring-boot-runtime-2/src/test/java/com/baeldung/maxhttpheadersize/controller/MaxHttpHeaderSizeControllerIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-runtime/src/test/java/com/baeldung/maxhttpheadersize/controller/MaxHttpHeaderSizeControllerLiveTest.java b/spring-boot-modules/spring-boot-runtime-2/src/test/java/com/baeldung/maxhttpheadersize/controller/MaxHttpHeaderSizeControllerLiveTest.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime/src/test/java/com/baeldung/maxhttpheadersize/controller/MaxHttpHeaderSizeControllerLiveTest.java rename to spring-boot-modules/spring-boot-runtime-2/src/test/java/com/baeldung/maxhttpheadersize/controller/MaxHttpHeaderSizeControllerLiveTest.java diff --git a/spring-boot-modules/spring-boot-runtime/README.md b/spring-boot-modules/spring-boot-runtime/README.md index 072bd16a78..6f21efe793 100644 --- a/spring-boot-modules/spring-boot-runtime/README.md +++ b/spring-boot-modules/spring-boot-runtime/README.md @@ -8,7 +8,5 @@ This module contains articles about administering a Spring Boot runtime - [Logging HTTP Requests with Spring Boot Actuator HTTP Tracing](https://www.baeldung.com/spring-boot-actuator-http) - [Spring Boot Embedded Tomcat Logs](https://www.baeldung.com/spring-boot-embedded-tomcat-logs) - [Project Configuration with Spring](https://www.baeldung.com/project-configuration-with-spring) - - [CORS with Spring](https://www.baeldung.com/spring-cors) - [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-runtime/pom.xml b/spring-boot-modules/spring-boot-runtime/pom.xml index 92b1458cf6..d42ae303a7 100644 --- a/spring-boot-modules/spring-boot-runtime/pom.xml +++ b/spring-boot-modules/spring-boot-runtime/pom.xml @@ -4,15 +4,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-runtime - jar spring-boot-runtime + jar Demo project for Spring Boot Runtime com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-security/README.md b/spring-boot-modules/spring-boot-security/README.md index 2c9d37eac0..b9966709cb 100644 --- a/spring-boot-modules/spring-boot-security/README.md +++ b/spring-boot-modules/spring-boot-security/README.md @@ -9,6 +9,7 @@ This module contains articles about Spring Boot Security - [Introduction to Spring Security Taglibs](https://www.baeldung.com/spring-security-taglibs) - [Guide to @CurrentSecurityContext in Spring Security](https://www.baeldung.com/spring-currentsecuritycontext) - [Disable Security for a Profile in Spring Boot](https://www.baeldung.com/spring-security-disable-profile) +- [Spring @EnableWebSecurity vs. @EnableGlobalMethodSecurity](https://www.baeldung.com/spring-enablewebsecurity-vs-enableglobalmethodsecurity) ### Spring Boot Security Auto-Configuration diff --git a/spring-boot-modules/spring-boot-security/pom.xml b/spring-boot-modules/spring-boot-security/pom.xml index 11e5a38eeb..41dbcff38d 100644 --- a/spring-boot-modules/spring-boot-security/pom.xml +++ b/spring-boot-modules/spring-boot-security/pom.xml @@ -4,15 +4,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-security - jar spring-boot-security + jar Spring Boot Security Auto-Configuration com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-springdoc/pom.xml b/spring-boot-modules/spring-boot-springdoc/pom.xml index 892fbfe4ca..10bd9a7534 100644 --- a/spring-boot-modules/spring-boot-springdoc/pom.xml +++ b/spring-boot-modules/spring-boot-springdoc/pom.xml @@ -5,15 +5,14 @@ 4.0.0 spring-boot-springdoc 0.0.1-SNAPSHOT - jar spring-boot-springdoc + jar Project for Springdoc integration com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-swagger-jwt/pom.xml b/spring-boot-modules/spring-boot-swagger-jwt/pom.xml index c296b06388..e0d96627cd 100644 --- a/spring-boot-modules/spring-boot-swagger-jwt/pom.xml +++ b/spring-boot-modules/spring-boot-swagger-jwt/pom.xml @@ -13,7 +13,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml index a9d8a943e4..d6b62bce3c 100644 --- a/spring-boot-modules/spring-boot-swagger/pom.xml +++ b/spring-boot-modules/spring-boot-swagger/pom.xml @@ -13,7 +13,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ @@ -41,4 +40,4 @@ 3.0.0 - \ No newline at end of file + diff --git a/spring-boot-modules/spring-boot-testing/pom.xml b/spring-boot-modules/spring-boot-testing/pom.xml index f70e77b31a..658eb7728e 100644 --- a/spring-boot-modules/spring-boot-testing/pom.xml +++ b/spring-boot-modules/spring-boot-testing/pom.xml @@ -4,15 +4,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-testing - war spring-boot-testing + war This is simple boot application for demonstrating testing features. com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ @@ -49,17 +48,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - it.ozimov diff --git a/spring-boot-modules/spring-boot-validation/pom.xml b/spring-boot-modules/spring-boot-validation/pom.xml index 86e0a47d0d..fa4e8439e6 100644 --- a/spring-boot-modules/spring-boot-validation/pom.xml +++ b/spring-boot-modules/spring-boot-validation/pom.xml @@ -8,10 +8,9 @@ 0.0.1-SNAPSHOT - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../../parent-boot-2 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-validation/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-validation/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-boot-modules/spring-boot-validation/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-vue/pom.xml b/spring-boot-modules/spring-boot-vue/pom.xml index 3d3d51797c..c552a9583f 100644 --- a/spring-boot-modules/spring-boot-vue/pom.xml +++ b/spring-boot-modules/spring-boot-vue/pom.xml @@ -5,15 +5,14 @@ 4.0.0 spring-boot-vue 0.0.1-SNAPSHOT - jar spring-boot-vue + jar Demo project for Spring Boot Vue project com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ diff --git a/spring-boot-modules/spring-boot/README.md b/spring-boot-modules/spring-boot/README.md index 5a45502fd8..fdc8093806 100644 --- a/spring-boot-modules/spring-boot/README.md +++ b/spring-boot-modules/spring-boot/README.md @@ -8,12 +8,9 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [A Guide to Spring in Eclipse STS](https://www.baeldung.com/eclipse-sts-spring) -- [How to Register a Servlet in Java](https://www.baeldung.com/register-servlet) -- [Guide to Spring WebUtils and ServletRequestUtils](https://www.baeldung.com/spring-webutils-servletrequestutils) -- [Dynamic DTO Validation Config Retrieved from the Database](https://www.baeldung.com/spring-dynamic-dto-validation) - [Guide to Spring Type Conversions](https://www.baeldung.com/spring-type-conversions) - [Spring Boot: Configuring a Main Class](https://www.baeldung.com/spring-boot-main-class) -- [A Quick Intro to the SpringBootServletInitializer](https://www.baeldung.com/spring-boot-servlet-initializer) -- [Spring Shutdown Callbacks](https://www.baeldung.com/spring-shutdown-callbacks) - [Container Configuration in Spring Boot 2](https://www.baeldung.com/embeddedservletcontainercustomizer-configurableembeddedservletcontainer-spring-boot) - [Validation in Spring Boot](https://www.baeldung.com/spring-boot-bean-validation) +- [How to Register a Servlet in Java](https://www.baeldung.com/register-servlet) +- [Guide to Spring WebUtils and ServletRequestUtils](https://www.baeldung.com/spring-webutils-servletrequestutils) diff --git a/spring-boot-modules/spring-boot/pom.xml b/spring-boot-modules/spring-boot/pom.xml index 8df16a1f9c..49effa3700 100644 --- a/spring-boot-modules/spring-boot/pom.xml +++ b/spring-boot-modules/spring-boot/pom.xml @@ -13,7 +13,6 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - ../ @@ -54,17 +53,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - io.dropwizard.metrics metrics-core 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-caching/src/main/java/com/baeldung/ehcache/calculator/SquaredCalculator.java b/spring-caching/src/main/java/com/baeldung/ehcache/calculator/SquaredCalculator.java index caf1df2a1b..e653e84048 100644 --- a/spring-caching/src/main/java/com/baeldung/ehcache/calculator/SquaredCalculator.java +++ b/spring-caching/src/main/java/com/baeldung/ehcache/calculator/SquaredCalculator.java @@ -1,8 +1,12 @@ package com.baeldung.ehcache.calculator; import com.baeldung.ehcache.config.CacheHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class SquaredCalculator { + + private static final Logger LOGGER = LoggerFactory.getLogger(SquaredCalculator.class); private CacheHelper cache; public int getSquareValueOfNumber(int input) { @@ -10,7 +14,7 @@ public class SquaredCalculator { return cache.getSquareNumberCache().get(input); } - System.out.println("Calculating square value of " + input + " and caching result."); + LOGGER.debug("Calculating square value of {} and caching result.", input); int squaredValue = (int) Math.pow(input, 2); cache.getSquareNumberCache().put(input, squaredValue); diff --git a/spring-caching/src/test/java/com/baeldung/ehcache/SquareCalculatorUnitTest.java b/spring-caching/src/test/java/com/baeldung/ehcache/SquareCalculatorUnitTest.java index 37df749bab..6a6c51bd9e 100644 --- a/spring-caching/src/test/java/com/baeldung/ehcache/SquareCalculatorUnitTest.java +++ b/spring-caching/src/test/java/com/baeldung/ehcache/SquareCalculatorUnitTest.java @@ -4,13 +4,18 @@ import com.baeldung.ehcache.calculator.SquaredCalculator; import com.baeldung.ehcache.config.CacheHelper; import org.junit.Before; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class SquareCalculatorUnitTest { - private SquaredCalculator squaredCalculator = new SquaredCalculator(); - private CacheHelper cacheHelper = new CacheHelper(); + + private static final Logger LOGGER = LoggerFactory.getLogger(SquareCalculatorUnitTest.class); + + private final SquaredCalculator squaredCalculator = new SquaredCalculator(); + private final CacheHelper cacheHelper = new CacheHelper(); @Before public void setup() { @@ -21,7 +26,7 @@ public class SquareCalculatorUnitTest { public void whenCalculatingSquareValueOnce_thenCacheDontHaveValues() { for (int i = 10; i < 15; i++) { assertFalse(cacheHelper.getSquareNumberCache().containsKey(i)); - System.out.println("Square value of " + i + " is: " + squaredCalculator.getSquareValueOfNumber(i) + "\n"); + LOGGER.debug("Square value of {} is: {}", i, squaredCalculator.getSquareValueOfNumber(i)); } } @@ -29,12 +34,12 @@ public class SquareCalculatorUnitTest { public void whenCalculatingSquareValueAgain_thenCacheHasAllValues() { for (int i = 10; i < 15; i++) { assertFalse(cacheHelper.getSquareNumberCache().containsKey(i)); - System.out.println("Square value of " + i + " is: " + squaredCalculator.getSquareValueOfNumber(i) + "\n"); + LOGGER.debug("Square value of {} is: {}", i, squaredCalculator.getSquareValueOfNumber(i)); } for (int i = 10; i < 15; i++) { assertTrue(cacheHelper.getSquareNumberCache().containsKey(i)); - System.out.println("Square value of " + i + " is: " + squaredCalculator.getSquareValueOfNumber(i) + "\n"); + LOGGER.debug("Square value of {} is: {}", i, squaredCalculator.getSquareValueOfNumber(i) + "\n"); } } } 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-data-flow/pom.xml b/spring-cloud-data-flow/pom.xml index f81daeeabc..49a5accb90 100644 --- a/spring-cloud-data-flow/pom.xml +++ b/spring-cloud-data-flow/pom.xml @@ -7,7 +7,6 @@ 0.0.1-SNAPSHOT spring-cloud-data-flow pom - com.baeldung parent-boot-2 diff --git a/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/test/resources/logback-test.xml b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/test/resources/logback-test.xml b/spring-cloud/spring-cloud-archaius/basic-config/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-archaius/extra-configs/src/test/resources/logback-test.xml b/spring-cloud/spring-cloud-archaius/extra-configs/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/extra-configs/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/test/resources/logback-test.xml b/spring-cloud/spring-cloud-archaius/jdbc-config/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-archaius/pom.xml b/spring-cloud/spring-cloud-archaius/pom.xml index efd912f8db..ba977bbdc9 100644 --- a/spring-cloud/spring-cloud-archaius/pom.xml +++ b/spring-cloud/spring-cloud-archaius/pom.xml @@ -46,11 +46,6 @@ org.springframework.boot spring-boot-starter-test
- - org.assertj - assertj-core - test - org.junit.platform junit-platform-runner diff --git a/spring-cloud/spring-cloud-aws/pom.xml b/spring-cloud/spring-cloud-aws/pom.xml index c9cd56bea6..c313e2026a 100644 --- a/spring-cloud/spring-cloud-aws/pom.xml +++ b/spring-cloud/spring-cloud-aws/pom.xml @@ -18,8 +18,8 @@ - + junit junit diff --git a/spring-cloud/spring-cloud-bootstrap/order-service/order-client/pom.xml b/spring-cloud/spring-cloud-bootstrap/order-service/order-client/pom.xml index dc6e196325..5326e181e0 100644 --- a/spring-cloud/spring-cloud-bootstrap/order-service/order-client/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/order-service/order-client/pom.xml @@ -16,4 +16,4 @@ 1.0.0-SNAPSHOT - + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-config/client/pom.xml b/spring-cloud/spring-cloud-config/client/pom.xml index 55c6e77a72..0f463b6d6d 100644 --- a/spring-cloud/spring-cloud-config/client/pom.xml +++ b/spring-cloud/spring-cloud-config/client/pom.xml @@ -26,17 +26,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - 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 new file mode 100644 index 0000000000..a96e6189a1 --- /dev/null +++ b/spring-cloud/spring-cloud-config/client/src/main/resources/application.properties @@ -0,0 +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 diff --git a/spring-cloud/spring-cloud-config/client/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-config/client/src/main/resources/bootstrap.properties deleted file mode 100644 index 5dde8baa28..0000000000 --- a/spring-cloud/spring-cloud-config/client/src/main/resources/bootstrap.properties +++ /dev/null @@ -1,6 +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 diff --git a/spring-cloud/spring-cloud-config/server/pom.xml b/spring-cloud/spring-cloud-config/server/pom.xml index 36d1b5b3aa..b41277113f 100644 --- a/spring-cloud/spring-cloud-config/server/pom.xml +++ b/spring-cloud/spring-cloud-config/server/pom.xml @@ -30,17 +30,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - -
diff --git a/spring-cloud/spring-cloud-config/server/src/main/resources/application.properties b/spring-cloud/spring-cloud-config/server/src/main/resources/application.properties index 18d4b3596a..366ecddf86 100644 --- a/spring-cloud/spring-cloud-config/server/src/main/resources/application.properties +++ b/spring-cloud/spring-cloud-config/server/src/main/resources/application.properties @@ -3,3 +3,8 @@ spring.cloud.config.server.git.uri= spring.cloud.config.server.git.clone-on-start=true spring.security.user.name=root spring.security.user.password=s3cr3t + +encrypt.keyStore.location=classpath:/config-server.jks +encrypt.keyStore.password=my-s70r3-s3cr3t +encrypt.keyStore.alias=config-server-key +encrypt.keyStore.secret=my-k34-s3cr3t diff --git a/spring-cloud/spring-cloud-config/server/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-config/server/src/main/resources/bootstrap.properties deleted file mode 100644 index f2d75f5846..0000000000 --- a/spring-cloud/spring-cloud-config/server/src/main/resources/bootstrap.properties +++ /dev/null @@ -1,4 +0,0 @@ -encrypt.keyStore.location=classpath:/config-server.jks -encrypt.keyStore.password=my-s70r3-s3cr3t -encrypt.keyStore.alias=config-server-key -encrypt.keyStore.secret=my-k34-s3cr3t diff --git a/spring-cloud/spring-cloud-connectors-heroku/pom.xml b/spring-cloud/spring-cloud-connectors-heroku/pom.xml index 967b1b3caf..b13c512cc0 100644 --- a/spring-cloud/spring-cloud-connectors-heroku/pom.xml +++ b/spring-cloud/spring-cloud-connectors-heroku/pom.xml @@ -28,7 +28,7 @@
- + org.springframework.boot spring-boot-starter-cloud-connectors ${spring-boot-starter-cloud-connectors.version} @@ -57,9 +57,9 @@ - 2.2.6.RELEASE + 2.2.6.RELEASE Hoxton.SR4 42.2.10 - + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-dapr/pom.xml b/spring-cloud/spring-cloud-dapr/pom.xml index c2e9edaedc..436666b08e 100644 --- a/spring-cloud/spring-cloud-dapr/pom.xml +++ b/spring-cloud/spring-cloud-dapr/pom.xml @@ -17,4 +17,4 @@ greeting
- + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-docker/docker-message-server/pom.xml b/spring-cloud/spring-cloud-docker/docker-message-server/pom.xml index 1c8c58c762..91cd587ff3 100644 --- a/spring-cloud/spring-cloud-docker/docker-message-server/pom.xml +++ b/spring-cloud/spring-cloud-docker/docker-message-server/pom.xml @@ -23,17 +23,6 @@ spring-boot-starter-test test
- - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - diff --git a/spring-cloud/spring-cloud-docker/docker-product-server/pom.xml b/spring-cloud/spring-cloud-docker/docker-product-server/pom.xml index be65a6d7d3..ba4cf63ad8 100644 --- a/spring-cloud/spring-cloud-docker/docker-product-server/pom.xml +++ b/spring-cloud/spring-cloud-docker/docker-product-server/pom.xml @@ -4,8 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 docker-product-server - docker-product-server 1.0.0 + docker-product-server com.baeldung.spring.cloud @@ -23,17 +23,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - diff --git a/spring-cloud/spring-cloud-docker/pom.xml b/spring-cloud/spring-cloud-docker/pom.xml index 3e407df6a1..f0f6b84fb0 100644 --- a/spring-cloud/spring-cloud-docker/pom.xml +++ b/spring-cloud/spring-cloud-docker/pom.xml @@ -4,8 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-cloud-docker - spring-cloud-docker 1.0.0-SNAPSHOT + spring-cloud-docker pom diff --git a/spring-cloud/spring-cloud-functions/src/test/resources/logback-test.xml b/spring-cloud/spring-cloud-functions/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-cloud/spring-cloud-functions/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-hystrix/rest-consumer/pom.xml b/spring-cloud/spring-cloud-hystrix/rest-consumer/pom.xml index 73a0859785..741457529c 100644 --- a/spring-cloud/spring-cloud-hystrix/rest-consumer/pom.xml +++ b/spring-cloud/spring-cloud-hystrix/rest-consumer/pom.xml @@ -12,7 +12,6 @@ com.baeldung.spring.cloud spring-cloud-hystrix 1.0.0-SNAPSHOT - ../ diff --git a/spring-cloud/spring-cloud-kubernetes/kubernetes-guide/client-service/pom.xml b/spring-cloud/spring-cloud-kubernetes/kubernetes-guide/client-service/pom.xml index e916f2bc3e..cedd46dfef 100644 --- a/spring-cloud/spring-cloud-kubernetes/kubernetes-guide/client-service/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/kubernetes-guide/client-service/pom.xml @@ -4,8 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 client-service - client-service 1.0-SNAPSHOT + client-service com.baeldung.spring.cloud diff --git a/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/liveness-example/pom.xml b/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/liveness-example/pom.xml index 725aa9cd3d..928f401405 100644 --- a/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/liveness-example/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/liveness-example/pom.xml @@ -4,8 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 liveness-example - liveness-example 1.0-SNAPSHOT + liveness-example com.baeldung.spring.cloud diff --git a/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/liveness-example/src/test/resources/logback-test.xml b/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/liveness-example/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/liveness-example/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/readiness-example/src/test/resources/logback-test.xml b/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/readiness-example/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/readiness-example/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-ribbon-retry/pom.xml b/spring-cloud/spring-cloud-ribbon-retry/pom.xml index e0075b4f41..02fc103533 100644 --- a/spring-cloud/spring-cloud-ribbon-retry/pom.xml +++ b/spring-cloud/spring-cloud-ribbon-retry/pom.xml @@ -45,7 +45,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} 0 diff --git a/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml index ba6cee1fce..1c8fa4e694 100644 --- a/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml +++ b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml @@ -18,8 +18,8 @@ - + junit junit 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-cloud/spring-cloud-zookeeper/Greeting/pom.xml b/spring-cloud/spring-cloud-zookeeper/Greeting/pom.xml index 8e7b87c220..8248884632 100644 --- a/spring-cloud/spring-cloud-zookeeper/Greeting/pom.xml +++ b/spring-cloud/spring-cloud-zookeeper/Greeting/pom.xml @@ -68,16 +68,6 @@ spring-boot-starter-test ${spring-boot.version} - - org.hamcrest - hamcrest-core - ${hamcrest-core.version} - test - - - 1.3 - - \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/pom.xml b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/pom.xml index 7c3f668473..c071b8863a 100644 --- a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/pom.xml +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/pom.xml @@ -27,11 +27,6 @@ spring-test test - - org.hamcrest - hamcrest - test - org.mockito mockito-core diff --git a/spring-core-2/pom.xml b/spring-core-2/pom.xml index de5c7c0d4d..19e7fb5f28 100644 --- a/spring-core-2/pom.xml +++ b/spring-core-2/pom.xml @@ -129,16 +129,6 @@ spring-test test - - org.assertj - assertj-core - test - - - org.hamcrest - hamcrest - test - org.mockito mockito-core @@ -205,7 +195,6 @@ 25.1-jre 3.6 - 3.6.1 2.1.0 3.22.0-GA 3.2.2 diff --git a/spring-core-3/pom.xml b/spring-core-3/pom.xml index 50d2e7ac5e..9e777a4a03 100644 --- a/spring-core-3/pom.xml +++ b/spring-core-3/pom.xml @@ -55,18 +55,6 @@ ${spring.version} test - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - diff --git a/spring-core-4/pom.xml b/spring-core-4/pom.xml index 5706b2ee75..1c3e138670 100644 --- a/spring-core-4/pom.xml +++ b/spring-core-4/pom.xml @@ -55,30 +55,12 @@ ${spring.version} test - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - org.awaitility awaitility ${awaitility.version} test - - org.assertj - assertj-core - ${assertj-core.version} - test - javax.servlet javax.servlet-api @@ -91,7 +73,6 @@ 2.2.2.RELEASE 28.2-jre 4.0.2 - 2.9.1 \ No newline at end of file diff --git a/spring-core-5/src/test/resources/logback-test.xml b/spring-core-5/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-core-5/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-core/README.md b/spring-core/README.md index b8d46f6b34..3f0fe4b4e4 100644 --- a/spring-core/README.md +++ b/spring-core/README.md @@ -11,5 +11,6 @@ This module contains articles about core Spring functionality - [Spring Application Context Events](https://www.baeldung.com/spring-context-events) - [What is a Spring Bean?](https://www.baeldung.com/spring-bean) - [Spring PostConstruct and PreDestroy Annotations](https://www.baeldung.com/spring-postconstruct-predestroy) +- [Intro to the Spring ClassPathXmlApplicationContext](http://www.baeldung.com/spring-classpathxmlapplicationcontext) - More articles: [[next -->]](/spring-core-2) diff --git a/spring-core/pom.xml b/spring-core/pom.xml index ab41670224..7afcf7addd 100644 --- a/spring-core/pom.xml +++ b/spring-core/pom.xml @@ -57,12 +57,6 @@ ${mockito.spring.boot.version} test - - org.assertj - assertj-core - ${assertj.version} - test - commons-io commons-io @@ -89,7 +83,6 @@ 20.0 1.5.2.RELEASE 1.10.19 - 3.12.2 \ No newline at end of file diff --git a/spring-core/src/test/java/com/baeldung/applicationcontext/README.md b/spring-core/src/test/java/com/baeldung/applicationcontext/README.md deleted file mode 100644 index 211007e0cf..0000000000 --- a/spring-core/src/test/java/com/baeldung/applicationcontext/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant Articles: -- [Introduction to Java Servlets](http://www.baeldung.com/intro-to-servlets) -- [Intro to the Spring ClassPathXmlApplicationContext](http://www.baeldung.com/spring-classpathxmlapplicationcontext) diff --git a/spring-di-2/src/test/resources/logback-test.xml b/spring-di-2/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-di-2/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-di/pom.xml b/spring-di/pom.xml index cbd49242e4..a7fa65067b 100644 --- a/spring-di/pom.xml +++ b/spring-di/pom.xml @@ -20,14 +20,14 @@ org.springframework spring-framework-bom - ${org.springframework.version} + ${spring.version} pom import org.springframework spring-core - ${org.springframework.version} + ${spring.version} @@ -74,12 +74,6 @@ ${mockito.spring.boot.version} test - - org.assertj - assertj-core - ${assertj.version} - test - commons-io commons-io @@ -149,14 +143,12 @@ org.baeldung.org.baeldung.sample.App - 5.0.6.RELEASE 1.3.2 1.4.4.RELEASE 1 20.0 1.5.2.RELEASE 1.10.19 - 3.12.2 1.9.5 diff --git a/spring-ejb/ejb-beans/pom.xml b/spring-ejb/ejb-beans/pom.xml index 10bc6d3104..6f20d949b0 100644 --- a/spring-ejb/ejb-beans/pom.xml +++ b/spring-ejb/ejb-beans/pom.xml @@ -80,12 +80,6 @@ arquillian-junit-container test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - joda-time @@ -141,7 +135,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} always diff --git a/spring-ejb/pom.xml b/spring-ejb/pom.xml index 0b52fa52b1..003b428ff9 100755 --- a/spring-ejb/pom.xml +++ b/spring-ejb/pom.xml @@ -14,7 +14,6 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ @@ -26,8 +25,8 @@ - + junit junit diff --git a/spring-ejb/spring-ejb-remote/pom.xml b/spring-ejb/spring-ejb-remote/pom.xml index b7bf2aa79b..a180955dcf 100644 --- a/spring-ejb/spring-ejb-remote/pom.xml +++ b/spring-ejb/spring-ejb-remote/pom.xml @@ -19,12 +19,6 @@ javaee-api provided - - org.assertj - assertj-core - ${assertj.version} - test - @@ -86,7 +80,6 @@ - 3.9.0 1.6.1 1.1.0.Alpha5 diff --git a/spring-jenkins-pipeline/pom.xml b/spring-jenkins-pipeline/pom.xml index 6f00dd5820..4e84bb8c70 100644 --- a/spring-jenkins-pipeline/pom.xml +++ b/spring-jenkins-pipeline/pom.xml @@ -62,6 +62,7 @@ + org.apache.maven.plugins maven-surefire-plugin diff --git a/spring-jersey/pom.xml b/spring-jersey/pom.xml index 64a34074bb..197469ccf9 100644 --- a/spring-jersey/pom.xml +++ b/spring-jersey/pom.xml @@ -105,12 +105,6 @@ slf4j-jdk14 ${org.slf4j.version} - - org.assertj - assertj-core - ${assertj-core.version} - test - org.springframework.boot @@ -218,7 +212,6 @@ 4.5.5 4.0.0 2.27.2 - 3.10.0 1.5.10.RELEASE diff --git a/spring-quartz/pom.xml b/spring-quartz/pom.xml index 19ea302a1d..53b6962a60 100644 --- a/spring-quartz/pom.xml +++ b/spring-quartz/pom.xml @@ -4,8 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-quartz - spring-quartz 0.0.1-SNAPSHOT + spring-quartz jar Demo project for Scheduling in Spring with Quartz diff --git a/spring-security-modules/spring-5-security-oauth/pom.xml b/spring-security-modules/spring-5-security-oauth/pom.xml index 194ace35b0..aa4958ae47 100644 --- a/spring-security-modules/spring-5-security-oauth/pom.xml +++ b/spring-security-modules/spring-5-security-oauth/pom.xml @@ -68,7 +68,8 @@ - + 2.5.2 com.baeldung.oauth2.SpringOAuthApplication diff --git a/spring-security-modules/spring-5-security/src/test/resources/logback-test.xml b/spring-security-modules/spring-5-security/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-security-modules/spring-5-security/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-security-modules/spring-ldap/pom.xml b/spring-security-modules/spring-ldap/pom.xml index 44f754673f..086be2df5a 100644 --- a/spring-security-modules/spring-ldap/pom.xml +++ b/spring-security-modules/spring-ldap/pom.xml @@ -106,7 +106,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} integration-test diff --git a/spring-security-modules/spring-security-core/README.md b/spring-security-modules/spring-security-core/README.md index f9c6d2e5fb..9f8e4dda53 100644 --- a/spring-security-modules/spring-security-core/README.md +++ b/spring-security-modules/spring-security-core/README.md @@ -10,7 +10,6 @@ This module contains articles about core Spring Security - [Deny Access on Missing @PreAuthorize to Spring Controller Methods](https://www.baeldung.com/spring-deny-access) - [Spring Security: Check If a User Has a Role in Java](https://www.baeldung.com/spring-security-check-user-role) - [Filtering Jackson JSON Output Based on Spring Security Role](https://www.baeldung.com/spring-security-role-filter-json) -- [Spring @EnableWebSecurity vs. @EnableGlobalMethodSecurity](https://www.baeldung.com/spring-enablewebsecurity-vs-enableglobalmethodsecurity) ### Build the Project diff --git a/spring-security-modules/spring-security-oidc/src/test/resources/logback-test.xml b/spring-security-modules/spring-security-oidc/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-security-modules/spring-security-oidc/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-boot-1/pom.xml b/spring-security-modules/spring-security-web-boot-1/pom.xml index a376a49b4c..3f6001686d 100644 --- a/spring-security-modules/spring-security-web-boot-1/pom.xml +++ b/spring-security-modules/spring-security-web-boot-1/pom.xml @@ -59,11 +59,6 @@ postgresql runtime - - org.hamcrest - hamcrest - test - org.springframework spring-test diff --git a/spring-security-modules/spring-security-web-boot-2/pom.xml b/spring-security-modules/spring-security-web-boot-2/pom.xml index ade644741d..91b6ff8724 100644 --- a/spring-security-modules/spring-security-web-boot-2/pom.xml +++ b/spring-security-modules/spring-security-web-boot-2/pom.xml @@ -59,11 +59,6 @@ postgresql runtime - - org.hamcrest - hamcrest - test - org.springframework spring-test diff --git a/spring-security-modules/spring-security-web-boot-3/pom.xml b/spring-security-modules/spring-security-web-boot-3/pom.xml index 9d09d60611..b26ca094be 100644 --- a/spring-security-modules/spring-security-web-boot-3/pom.xml +++ b/spring-security-modules/spring-security-web-boot-3/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-security-web-boot-3 0.0.1-SNAPSHOT diff --git a/spring-security-modules/spring-security-web-boot-3/src/test/resources/logback-test.xml b/spring-security-modules/spring-security-web-boot-3/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-mvc-custom/pom.xml b/spring-security-modules/spring-security-web-mvc-custom/pom.xml index 533a1bf83d..ba6b50a7bc 100644 --- a/spring-security-modules/spring-security-web-mvc-custom/pom.xml +++ b/spring-security-modules/spring-security-web-mvc-custom/pom.xml @@ -97,12 +97,6 @@ ${jstl.version} runtime - - - - - - com.fasterxml.jackson.core diff --git a/spring-security-modules/spring-security-web-persistent-login/pom.xml b/spring-security-modules/spring-security-web-persistent-login/pom.xml index 2d931c416c..8a61868172 100644 --- a/spring-security-modules/spring-security-web-persistent-login/pom.xml +++ b/spring-security-modules/spring-security-web-persistent-login/pom.xml @@ -127,12 +127,6 @@ ${spring-boot.version} test - - - - - - diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java index f8acdfe2ac..226459db75 100644 --- a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java @@ -1,18 +1,20 @@ package com.baeldung.spring; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @EnableWebMvc @Configuration -public class MvcConfig extends WebMvcConfigurerAdapter { +@ComponentScan(basePackages = { "com.baeldung.spring" }) +public class MvcConfig implements WebMvcConfigurer { public MvcConfig() { super(); @@ -22,8 +24,6 @@ public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/anonymous.html"); registry.addViewController("/login.html"); @@ -35,7 +35,7 @@ public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("/WEB-INF/view/react/build/static/"); - + registry.addResourceHandler("/*.js").addResourceLocations("/WEB-INF/view/react/build/"); registry.addResourceHandler("/*.json").addResourceLocations("/WEB-INF/view/react/build/"); registry.addResourceHandler("/*.ico").addResourceLocations("/WEB-INF/view/react/build/"); diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java new file mode 100644 index 0000000000..4084df9698 --- /dev/null +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java @@ -0,0 +1,31 @@ +package com.baeldung.spring; +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; +import org.springframework.security.web.csrf.CsrfToken; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/rest") +public class RestController { + + private static final Logger LOGGER = LoggerFactory.getLogger(RestController.class); + + @GetMapping + public ResponseEntity get(HttpServletRequest request) { + CsrfToken token = (CsrfToken) request.getAttribute("_csrf"); + LOGGER.info("{}={}", token.getHeaderName(), token.getToken()); + return ResponseEntity.ok().build(); + } + + @PostMapping + public ResponseEntity post(HttpServletRequest request) { + // Same impl as GET for testing purpose + return this.get(request); + } +} diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java index 7b67028647..d560589cce 100644 --- a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java @@ -7,6 +7,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.csrf.CookieCsrfTokenRepository; @Configuration @EnableWebSecurity @@ -21,11 +22,11 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(final AuthenticationManagerBuilder auth) throws Exception { // @formatter:off auth.inMemoryAuthentication() - .withUser("user1").password("user1Pass").roles("USER") + .withUser("user1").password("{noop}user1Pass").roles("USER") .and() - .withUser("user2").password("user2Pass").roles("USER") + .withUser("user2").password("{noop}user2Pass").roles("USER") .and() - .withUser("admin").password("admin0Pass").roles("ADMIN"); + .withUser("admin").password("{noop}admin0Pass").roles("ADMIN"); // @formatter:on } @@ -33,11 +34,11 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(final HttpSecurity http) throws Exception { // @formatter:off http - .csrf().disable() + .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and() .authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/anonymous*").anonymous() - .antMatchers(HttpMethod.GET, "/index*", "/static/**", "/*.js", "/*.json", "/*.ico").permitAll() + .antMatchers(HttpMethod.GET, "/index*", "/static/**", "/*.js", "/*.json", "/*.ico", "/rest").permitAll() .anyRequest().authenticated() .and() .formLogin() diff --git a/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml b/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml index 25f3f36d1a..2cc702de59 100644 --- a/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml +++ b/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml @@ -12,7 +12,7 @@ - + diff --git a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp index c9d88cbc9b..d64f80a5cb 100644 --- a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp +++ b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp @@ -1,11 +1,30 @@ <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> - + + +

This is the body of the sample view

+
+

CSRF Testing

+
+ CSRF Token: + + +
+
+
+   + +
+
+
Request Result:

+
+ +

Roles

This text is only visible to a user

@@ -22,5 +41,26 @@ ">Logout + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js new file mode 100644 index 0000000000..657cc31f41 --- /dev/null +++ b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js @@ -0,0 +1,3 @@ +window.getCsrfToken = () => { + return document.cookie.replace(/(?:(?:^|.*;\s*)XSRF-TOKEN\s*\=\s*([^;]*).*$)|^.*$/, '$1'); +} diff --git a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html index 0c3f78d7b3..6d4894da42 100644 --- a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html +++ b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html @@ -6,6 +6,7 @@ + - - - - - - - - - - - org.apache.httpcomponents httpcore diff --git a/spring-security-modules/spring-security-web-rest-custom/pom.xml b/spring-security-modules/spring-security-web-rest-custom/pom.xml index 85e50412ad..1403154767 100644 --- a/spring-security-modules/spring-security-web-rest-custom/pom.xml +++ b/spring-security-modules/spring-security-web-rest-custom/pom.xml @@ -116,11 +116,6 @@ ${commons-lang3.version} - - org.hamcrest - hamcrest - test - org.mockito mockito-core diff --git a/spring-security-modules/spring-security-web-thymeleaf/pom.xml b/spring-security-modules/spring-security-web-thymeleaf/pom.xml index 8e6e0856af..c13aa6a471 100644 --- a/spring-security-modules/spring-security-web-thymeleaf/pom.xml +++ b/spring-security-modules/spring-security-web-thymeleaf/pom.xml @@ -29,7 +29,6 @@ org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-test @@ -46,13 +45,4 @@ - - - - org.springframework.boot - spring-boot-maven-plugin - - - - \ No newline at end of file diff --git a/spring-security-modules/spring-session/spring-session-jdbc/pom.xml b/spring-security-modules/spring-session/spring-session-jdbc/pom.xml index 64bbce44f2..3cc2b8d18e 100644 --- a/spring-security-modules/spring-session/spring-session-jdbc/pom.xml +++ b/spring-security-modules/spring-session/spring-session-jdbc/pom.xml @@ -28,7 +28,6 @@ com.h2database h2 - ${h2.version} runtime diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/README.md b/spring-swagger-codegen/custom-validations-opeanpi-codegen/README.md new file mode 100644 index 0000000000..3a2b74af70 --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/README.md @@ -0,0 +1,5 @@ +# This is a sample on how we can merge the OpenApi code generation with the a custom annotation using ConstraintValidator + +### Relevant Articles: + +- [Custom Validation with Swagger Codegen](https://www.baeldung.com/java-swagger-custom-validation) diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml new file mode 100644 index 0000000000..70b9e2acd5 --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml @@ -0,0 +1,103 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.5.4 + + + com.example + custom-validations-opeanpi-codegen + 0.0.1-SNAPSHOT + custom-validations-opeanpi-codegen + Demo project for Swagger Custom Validations Codegen + + 11 + 3.0.0 + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.hibernate + hibernate-validator + 6.0.10.Final + + + javax.validation + validation-api + 2.0.1.Final + + + org.openapitools + openapi-generator + 3.3.4 + + + io.springfox + springfox-oas + ${springfox-version} + + + io.springfox + springfox-swagger-ui + ${springfox-version} + + + com.fasterxml.jackson.core + jackson-databind + 2.10.0.pr3 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.openapitools + openapi-generator-maven-plugin + 5.1.0 + + + + generate + + + + ${project.basedir}/src/main/resources/petstore.yml + + spring + com.baeldung.openapi.api + com.baeldung.openapi.model + + ApiUtil.java + + + false + java8-localdatetime + + + src/main/resources/openapi/templates + + + + + + + + + + diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/PetstoreApplication.java b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/PetstoreApplication.java new file mode 100644 index 0000000000..5a6372ba22 --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/PetstoreApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.openapi.petstore; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class PetstoreApplication { + + public static void main(String[] args) { + SpringApplication.run(PetstoreApplication.class, args); + } + +} diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/controller/PetController.java b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/controller/PetController.java new file mode 100644 index 0000000000..081d0cb6f9 --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/controller/PetController.java @@ -0,0 +1,17 @@ +package com.baeldung.openapi.petstore.controller; + +import com.baeldung.openapi.api.PetsApi; +import com.baeldung.openapi.model.Pet; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; + +import java.util.Arrays; +import java.util.List; + +@Controller +public class PetController implements PetsApi { + + public ResponseEntity> findPetsByName(String name) { + return ResponseEntity.ok(Arrays.asList(new Pet().id(1L).name(name))); + } +} diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/controller/PetControllerAdvice.java b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/controller/PetControllerAdvice.java new file mode 100644 index 0000000000..cf243dbb46 --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/controller/PetControllerAdvice.java @@ -0,0 +1,20 @@ +package com.baeldung.openapi.petstore.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import javax.validation.ConstraintViolationException; + +@ControllerAdvice +public class PetControllerAdvice { + + @ResponseBody + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(ConstraintViolationException.class) + public void handleConstraintViolationException() { + + } +} diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/Capitalized.java b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/Capitalized.java new file mode 100644 index 0000000000..de83297c53 --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/Capitalized.java @@ -0,0 +1,22 @@ +package com.baeldung.openapi.petstore.validation; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +@Documented +@Constraint(validatedBy = {CapitalizedValidator.class}) +@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Capitalized { + + String message() default "Name should be capitalized."; + + boolean required() default true; + + Class[] groups() default {}; + + Class[] payload() default {}; + + String[] values() default {}; +} \ No newline at end of file diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/CapitalizedValidator.java b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/CapitalizedValidator.java new file mode 100644 index 0000000000..969dc0c56c --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/java/com/baeldung/openapi/petstore/validation/CapitalizedValidator.java @@ -0,0 +1,35 @@ +package com.baeldung.openapi.petstore.validation; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.Objects; + +public class CapitalizedValidator implements ConstraintValidator { + + private Capitalized uppercaseAnnotation; + + public void initialize(Capitalized constraintAnnotation) { + this.uppercaseAnnotation = constraintAnnotation; + } + + @Override + public boolean isValid(String nameField, ConstraintValidatorContext context) { + String correctName = buildCorrectName(nameField); + if (uppercaseAnnotation.required() + && (Objects.isNull(nameField) || nameField.isBlank() + || !correctName.equals(nameField))) { + context = context + .buildConstraintViolationWithTemplate(this.uppercaseAnnotation.message()) + .addConstraintViolation(); + context.disableDefaultConstraintViolation(); + return false; + } + return true; + } + + private String buildCorrectName(String nameField) { + String upCase = String.valueOf(nameField.charAt(0)).toUpperCase(); + String lowCase = nameField.substring(1).toLowerCase(); + return upCase.concat(lowCase); + } +} \ No newline at end of file diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/application.properties b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/application.properties new file mode 100644 index 0000000000..d5e4d42eb8 --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/application.properties @@ -0,0 +1 @@ +openapi.petStore.base-path=/ 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 new file mode 100644 index 0000000000..34f4afac3a --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/api.mustache @@ -0,0 +1,150 @@ +/** + * NOTE: This class is auto generated by OpenAPI Generator (https://com.baeldung.openapi-generator.tech) ({{{generatorVersion}}}). + * https://com.baeldung.openapi-generator.tech + * Do not edit the class manually. + */ +package {{package}}; + +{{#imports}}import {{import}}; +{{/imports}} +import io.swagger.annotations.*; +import com.baeldung.openapi.petstore.validation.Capitalized; +{{#jdk8-no-delegate}} +{{#virtualService}} +import io.virtualan.annotation.ApiVirtual; +import io.virtualan.annotation.VirtualService; +{{/virtualService}} +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +{{/jdk8-no-delegate}} +import org.springframework.http.ResponseEntity; +{{#useBeanValidation}} +import org.springframework.validation.annotation.Validated; +{{/useBeanValidation}} +{{#vendorExtensions.x-spring-paginated}} +import org.springframework.data.domain.Pageable; +{{/vendorExtensions.x-spring-paginated}} +import org.springframework.web.bind.annotation.*; +{{#jdk8-no-delegate}} + {{^reactive}} +import org.springframework.web.context.request.NativeWebRequest; + {{/reactive}} +{{/jdk8-no-delegate}} +import org.springframework.web.multipart.MultipartFile; +{{#reactive}} +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import org.springframework.http.codec.multipart.Part; +{{/reactive}} +import springfox.documentation.annotations.ApiIgnore; + +{{#useBeanValidation}} +import javax.validation.Valid; +import javax.validation.constraints.*; +{{/useBeanValidation}} +import java.util.List; +import java.util.Map; +{{#jdk8-no-delegate}} +import java.util.Optional; +{{/jdk8-no-delegate}} +{{^jdk8-no-delegate}} + {{#useOptional}} +import java.util.Optional; + {{/useOptional}} +{{/jdk8-no-delegate}} +{{#async}} +import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}}; +{{/async}} +{{>generatedAnnotation}} +{{#useBeanValidation}} +@Validated +{{/useBeanValidation}} +@Api(value = "{{{baseName}}}", tags = "All") +{{#operations}} +{{#virtualService}} +@VirtualService +{{/virtualService}} +public interface {{classname}} { +{{#jdk8-default-interface}} + {{^isDelegate}} + {{^reactive}} + + default Optional getRequest() { + return Optional.empty(); + } + {{/reactive}} + {{/isDelegate}} + {{#isDelegate}} + + default {{classname}}Delegate getDelegate() { + return new {{classname}}Delegate() {}; + } + {{/isDelegate}} +{{/jdk8-default-interface}} +{{#operation}} + + /** + * {{httpMethod}} {{{path}}}{{#summary}} : {{.}}{{/summary}} + {{#notes}} + * {{.}} + {{/notes}} + * + {{#allParams}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}} + {{/allParams}} + * @return {{#responses}}{{message}} (status code {{code}}){{^-last}} + * or {{/-last}}{{/responses}} + {{#isDeprecated}} + * @deprecated + {{/isDeprecated}} + {{#externalDocs}} + * {{description}} + * @see {{summary}} Documentation + {{/externalDocs}} + */ + {{#virtualService}} + @ApiVirtual + {{/virtualService}} + @ApiOperation(value = "{{{summary}}}", nickname = "{{{operationId}}}", notes = "{{{notes}}}"{{#returnBaseType}}, response = {{{returnBaseType}}}.class{{/returnBaseType}}{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}}{{#hasAuthMethods}}, authorizations = { + {{#authMethods}}{{#isOAuth}}@Authorization(value = "{{name}}", scopes = { + {{#scopes}}@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}}, + {{/-last}}{{/scopes}} }){{^-last}},{{/-last}}{{/isOAuth}} + {{^isOAuth}}@Authorization(value = "{{name}}"){{^-last}},{{/-last}} + {{/isOAuth}}{{/authMethods}} }{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}",{{/vendorExtensions.x-tags}} }) + @ApiResponses(value = { {{#responses}} + @ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{baseType}}}.class{{/baseType}}{{#containerType}}, responseContainer = "{{{containerType}}}"{{/containerType}}){{^-last}},{{/-last}}{{/responses}} }) + {{#implicitHeaders}} + @ApiImplicitParams({ + {{#headerParams}} + {{>implicitHeader}} + {{/headerParams}} + }) + {{/implicitHeaders}} + @RequestMapping( + method = RequestMethod.{{httpMethod}}, + value = "{{{path}}}"{{#singleContentTypes}}{{#hasProduces}}, + produces = "{{{vendorExtensions.x-accepts}}}"{{/hasProduces}}{{#hasConsumes}}, + consumes = "{{{vendorExtensions.x-contentType}}}"{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}}, + produces = { {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }{{/hasProduces}}{{#hasConsumes}}, + consumes = { {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }{{/hasConsumes}}{{/singleContentTypes}} + ) + {{#jdk8-default-interface}}default {{/jdk8-default-interface}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}}{{^-last}},{{/-last}}{{#-last}}{{#reactive}}, {{/reactive}}{{/-last}}{{/allParams}}{{#reactive}}@ApiIgnore final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, @ApiIgnore final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{^jdk8-default-interface}};{{/jdk8-default-interface}}{{#jdk8-default-interface}}{{#unhandledException}} throws Exception{{/unhandledException}} { + {{#delegate-method}} + return {{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, pageable{{/vendorExtensions.x-spring-paginated}}); + } + + // Override this method + {{#jdk8-default-interface}}default {{/jdk8-default-interface}} {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{{dataType}}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#reactive}}Flux{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}@ApiIgnore final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, @ApiIgnore final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}} { + {{/delegate-method}} + {{^isDelegate}} + {{>methodBody}} + {{/isDelegate}} + {{#isDelegate}} + return getDelegate().{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, pageable{{/vendorExtensions.x-spring-paginated}}); + {{/isDelegate}} + }{{/jdk8-default-interface}} + +{{/operation}} +} +{{/operations}} \ No newline at end of file diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/beanValidationCore.mustache b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/beanValidationCore.mustache new file mode 100644 index 0000000000..e3c19c6474 --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/beanValidationCore.mustache @@ -0,0 +1,26 @@ +{{{ vendorExtensions.x-constraints }}} +{{#errorMessage}}@Mandatory(errorMessage="{{{pattern}}}") {{/errorMessage}} +{{#pattern}}@Pattern(regexp="{{{pattern}}}") {{/pattern}}{{! +minLength && maxLength set +}}{{#minLength}}{{#maxLength}}@Size(min={{minLength}},max={{maxLength}}) {{/maxLength}}{{/minLength}}{{! +minLength set, maxLength not +}}{{#minLength}}{{^maxLength}}@Size(min={{minLength}}) {{/maxLength}}{{/minLength}}{{! +minLength not set, maxLength set +}}{{^minLength}}{{#maxLength}}@Size(max={{maxLength}}) {{/maxLength}}{{/minLength}}{{! +@Size: minItems && maxItems set +}}{{#minItems}}{{#maxItems}}@Size(min={{minItems}},max={{maxItems}}) {{/maxItems}}{{/minItems}}{{! +@Size: minItems set, maxItems not +}}{{#minItems}}{{^maxItems}}@Size(min={{minItems}}) {{/maxItems}}{{/minItems}}{{! +@Size: minItems not set && maxItems set +}}{{^minItems}}{{#maxItems}}@Size(max={{maxItems}}) {{/maxItems}}{{/minItems}}{{! +@Email: useBeanValidation set && isEmail && java8 set +}}{{#useBeanValidation}}{{#isEmail}}{{#java8}}@javax.validation.constraints.Email{{/java8}}{{/isEmail}}{{/useBeanValidation}}{{! +@Email: performBeanValidation set && isEmail && not java8 set +}}{{#performBeanValidation}}{{#isEmail}}{{^java8}}@org.hibernate.validator.constraints.Email{{/java8}}{{/isEmail}}{{/performBeanValidation}}{{! +check for integer or long / all others=decimal type with @Decimal* +isInteger set +}}{{#isInteger}}{{#minimum}}@Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}) {{/maximum}}{{/isInteger}}{{! +isLong set +}}{{#isLong}}{{#minimum}}@Min({{minimum}}L){{/minimum}}{{#maximum}} @Max({{maximum}}L) {{/maximum}}{{/isLong}}{{! +Not Integer, not Long => we have a decimal value! +}}{{^isInteger}}{{^isLong}}{{#minimum}}@DecimalMin({{#exclusiveMinimum}}value={{/exclusiveMinimum}}"{{minimum}}"{{#exclusiveMinimum}},inclusive=false{{/exclusiveMinimum}}){{/minimum}}{{#maximum}} @DecimalMax({{#exclusiveMaximum}}value={{/exclusiveMaximum}}"{{maximum}}"{{#exclusiveMaximum}},inclusive=false{{/exclusiveMaximum}}) {{/maximum}}{{/isLong}}{{/isInteger}} \ No newline at end of file diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/cookieParams.mustache b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/cookieParams.mustache new file mode 100644 index 0000000000..e21bd9ff4b --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/cookieParams.mustache @@ -0,0 +1 @@ +{{#isCookieParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}},required=true{{/required}}{{#allowableValues}}, allowableValues = "{{#enumVars}}{{#lambdaEscapeDoubleQuote}}{{{value}}}{{/lambdaEscapeDoubleQuote}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/enumVars}}"{{/allowableValues}}{{^isContainer}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}{{/isContainer}}) @CookieValue("{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isCookieParam}} \ No newline at end of file diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/enum.mustache b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/enum.mustache new file mode 100644 index 0000000000..3cdae7f3cc --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/enum.mustache @@ -0,0 +1,31 @@ +class {{classname}} { + /// The underlying value of this enum member. + {{dataType}} value; + + {{classname}}._internal(this.value); + {{ vendorExtensions.x-enum-varnames }} + {{ vendorExtensions.x-enum-descriptions }} + {{#allowableValues}} + {{#enumVars}} + {{#description}} + /// {{description}} + {{/description}} + static {{classname}} {{name}} = {{classname}}._internal({{{value}}}); + {{/enumVars}} + {{/allowableValues}} + + {{classname}}.fromJson(dynamic data) { + switch (data) { + {{#allowableValues}} + {{#enumVars}} + case {{{value}}}: value = data; break; + {{/enumVars}} + {{/allowableValues}} + default: throw('Unknown enum value to decode: $data'); + } + } + + static dynamic encode({{classname}} data) { + return data.value; + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..4546a811ef --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/model.mustache @@ -0,0 +1,42 @@ +package {{package}}; + +{{#imports}}import {{import}}; +{{/imports}} +import com.fasterxml.jackson.databind.annotation.*; +import com.fasterxml.jackson.annotation.*; +import com.baeldung.openapi.petstore.validation.Capitalized; +{{^supportJava6}} +import java.util.Objects; +import java.util.Arrays; +{{/supportJava6}} +{{#supportJava6}} +import org.apache.commons.lang3.ObjectUtils; +{{/supportJava6}} +{{#imports}} +import {{import}}; +{{/imports}} +{{#serializableModel}} +import java.io.Serializable; +{{/serializableModel}} +{{#jackson}} +{{#withXml}} +import com.fasterxml.jackson.dataformat.xml.annotation.*; +{{/withXml}} +{{/jackson}} +{{#withXml}} +import javax.xml.bind.annotation.*; +{{/withXml}} +{{#parcelableModel}} +import android.os.Parcelable; +import android.os.Parcel; +{{/parcelableModel}} +{{#useBeanValidation}} +import javax.validation.constraints.*; +import javax.validation.Valid; +{{/useBeanValidation}} + +{{#models}} +{{#model}} +{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{>pojo}}{{/isEnum}} +{{/model}} +{{/models}} \ No newline at end of file diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/modelEnum.mustache b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/modelEnum.mustache new file mode 100644 index 0000000000..29f27bd851 --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/modelEnum.mustache @@ -0,0 +1,68 @@ +{{#jackson}} +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +{{/jackson}} +{{#gson}} +import java.io.IOException; +import com.google.gson.TypeAdapter; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +{{/gson}} + +/** + * {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}} + */ +{{#gson}} +@JsonAdapter({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.Adapter.class) +{{/gson}} +public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} { + {{#allowableValues}}{{#enumVars}} + {{{name}}}({{{value}}}){{^-last}}, + {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}} + + private {{{dataType}}} value; + + {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) { + this.value = value; + } + +{{#jackson}} + @JsonValue +{{/jackson}} + public {{{dataType}}} getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + +{{#jackson}} + @JsonCreator +{{/jackson}} + public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue{{#jackson}}({{{dataType}}} value){{/jackson}}{{^jackson}}(String text){{/jackson}} { + for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) { + if ({{#jackson}}b.value.equals(value){{/jackson}}{{^jackson}}String.valueOf(b.value).equals(text){{/jackson}}) { + return b; + } + } + throw new UlpValidationException(UlpBundleKey.{{vendorExtensions.x-enum-invalidtag}}); + } +{{#gson}} + + public static class Adapter extends TypeAdapter<{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}> { + @Override + public void write(final JsonWriter jsonWriter, final {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} enumeration) throws IOException { + jsonWriter.value(enumeration.getValue()); + } + + @Override + public {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} read(final JsonReader jsonReader) throws IOException { + {{#isNumber}}BigDecimal value = new BigDecimal(jsonReader.nextDouble()){{/isNumber}}{{^isNumber}}{{#isInteger}}Integer value {{/isInteger}}{{^isInteger}}String value {{/isInteger}}= jsonReader.{{#isInteger}}nextInt(){{/isInteger}}{{^isInteger}}nextString(){{/isInteger}}{{/isNumber}}; + return {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.fromValue({{#jackson}}value{{/jackson}}{{^jackson}}String.valueOf(value){{/jackson}}); + } + } +{{/gson}} +} \ No newline at end of file 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 new file mode 100644 index 0000000000..c5fbd830bb --- /dev/null +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/petstore.yml @@ -0,0 +1,65 @@ +openapi: 3.0.1 +info: + version: "1.0" + title: PetStore +paths: + /pets: + post: + tags: + - pet + summary: Add a new pet to the store + description: Add a new pet to the store + operationId: addPet + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + responses: + '201': + description: default response, returning the new pet id + content: + application/json: + schema: + type: integer + '400': + description: Invalid input + get: + tags: + - pet + summary: Finds Pets by name + description: 'Find pets by name' + operationId: findPetsByName + parameters: + - name: name + in: query + schema: + type: string + description: Tags to filter by + x-constraints: "@Capitalized(required = true)" + responses: + '200': + description: default response + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid name value +components: + schemas: + Pet: + type: object + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + x-constraints: "@Capitalized(required = true)" \ No newline at end of file diff --git a/spring-vertx/pom.xml b/spring-vertx/pom.xml index bd2dfa6cf6..e24bb3f1ee 100644 --- a/spring-vertx/pom.xml +++ b/spring-vertx/pom.xml @@ -47,15 +47,6 @@ - - - - org.springframework.boot - spring-boot-maven-plugin - - - - 3.4.1 diff --git a/spring-web-modules/spring-5-mvc/pom.xml b/spring-web-modules/spring-5-mvc/pom.xml index 79a4f73ace..23bcb00801 100644 --- a/spring-web-modules/spring-5-mvc/pom.xml +++ b/spring-web-modules/spring-5-mvc/pom.xml @@ -81,12 +81,6 @@ ${project.basedir}/src/test/kotlin - - - org.springframework.boot - spring-boot-maven-plugin - - diff --git a/spring-web-modules/spring-boot-jsp/pom.xml b/spring-web-modules/spring-boot-jsp/pom.xml index 222facd100..b9b4a97e6b 100644 --- a/spring-web-modules/spring-boot-jsp/pom.xml +++ b/spring-web-modules/spring-boot-jsp/pom.xml @@ -92,7 +92,6 @@ 1.2 2.4.4 - 2.22.2 \ No newline at end of file diff --git a/spring-web-modules/spring-boot-jsp/src/test/resources/logback-test.xml b/spring-web-modules/spring-boot-jsp/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-web-modules/spring-boot-jsp/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-basics/src/test/resources/logback-test.xml b/spring-web-modules/spring-mvc-basics/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-web-modules/spring-mvc-basics/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-java-2/src/test/resources/logback-test.xml b/spring-web-modules/spring-mvc-java-2/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-web-modules/spring-mvc-java-2/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-web-modules/spring-rest-http/src/test/resources/logback-test.xml b/spring-web-modules/spring-rest-http/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-web-modules/spring-rest-http/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-web-modules/spring-rest-query-language/pom.xml b/spring-web-modules/spring-rest-query-language/pom.xml index c5a8c172f3..65f28f5be0 100644 --- a/spring-web-modules/spring-rest-query-language/pom.xml +++ b/spring-web-modules/spring-rest-query-language/pom.xml @@ -181,11 +181,6 @@ spring-test test - - org.hamcrest - hamcrest - test - org.mockito mockito-core diff --git a/spring-web-modules/spring-rest-shell/pom.xml b/spring-web-modules/spring-rest-shell/pom.xml index b83a0b6002..992092f43f 100644 --- a/spring-web-modules/spring-rest-shell/pom.xml +++ b/spring-web-modules/spring-rest-shell/pom.xml @@ -37,13 +37,4 @@ - - - - org.springframework.boot - spring-boot-maven-plugin - - - - \ No newline at end of file diff --git a/spring-web-modules/spring-rest-simple/pom.xml b/spring-web-modules/spring-rest-simple/pom.xml index 46bfa5d04c..2f8d6eac27 100644 --- a/spring-web-modules/spring-rest-simple/pom.xml +++ b/spring-web-modules/spring-rest-simple/pom.xml @@ -120,16 +120,6 @@ ${com.squareup.okhttp3.version} - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest - test - org.mockito mockito-core diff --git a/spring-web-modules/spring-rest-testing/pom.xml b/spring-web-modules/spring-rest-testing/pom.xml index dc5fdcd323..93942e97b6 100644 --- a/spring-web-modules/spring-rest-testing/pom.xml +++ b/spring-web-modules/spring-rest-testing/pom.xml @@ -165,11 +165,6 @@ spring-test test - - org.hamcrest - hamcrest - test - org.mockito mockito-core diff --git a/spring-web-modules/spring-resttemplate-2/pom.xml b/spring-web-modules/spring-resttemplate-2/pom.xml index d0191b970e..b87b245da9 100644 --- a/spring-web-modules/spring-resttemplate-2/pom.xml +++ b/spring-web-modules/spring-resttemplate-2/pom.xml @@ -66,13 +66,4 @@ - - - - org.springframework.boot - spring-boot-maven-plugin - - - - \ No newline at end of file diff --git a/spring-web-modules/spring-resttemplate-2/src/test/resources/logback-test.xml b/spring-web-modules/spring-resttemplate-2/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-web-modules/spring-resttemplate-2/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-web-modules/spring-resttemplate-3/pom.xml b/spring-web-modules/spring-resttemplate-3/pom.xml index 8e313ccf39..b036a5ffcb 100644 --- a/spring-web-modules/spring-resttemplate-3/pom.xml +++ b/spring-web-modules/spring-resttemplate-3/pom.xml @@ -16,7 +16,6 @@ - org.springframework.boot spring-boot-starter-web diff --git a/spring-web-modules/spring-resttemplate/pom.xml b/spring-web-modules/spring-resttemplate/pom.xml index 1379e40d23..5cac186fad 100644 --- a/spring-web-modules/spring-resttemplate/pom.xml +++ b/spring-web-modules/spring-resttemplate/pom.xml @@ -108,16 +108,6 @@ ${com.squareup.okhttp3.version} - - - org.junit.vintage - junit-vintage-engine - - - org.hamcrest - hamcrest - test - org.mockito mockito-core diff --git a/spring-web-modules/spring-thymeleaf-2/pom.xml b/spring-web-modules/spring-thymeleaf-2/pom.xml index b2b893ecd5..14e4de668b 100644 --- a/spring-web-modules/spring-thymeleaf-2/pom.xml +++ b/spring-web-modules/spring-thymeleaf-2/pom.xml @@ -65,8 +65,6 @@
- 1.8 - 1.8 2.2 diff --git a/spring-web-modules/spring-thymeleaf-2/src/test/resources/logback-test.xml b/spring-web-modules/spring-thymeleaf-2/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-2/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-webflux-amqp/pom.xml b/spring-webflux-amqp/pom.xml index 498556da2d..3ceb33dc3b 100755 --- a/spring-webflux-amqp/pom.xml +++ b/spring-webflux-amqp/pom.xml @@ -61,13 +61,4 @@ - - - - org.springframework.boot - spring-boot-maven-plugin - - - - \ No newline at end of file diff --git a/spring-webflux-threads/pom.xml b/spring-webflux-threads/pom.xml index bc5050b660..fedfaa6967 100644 --- a/spring-webflux-threads/pom.xml +++ b/spring-webflux-threads/pom.xml @@ -62,13 +62,4 @@ - - - - org.springframework.boot - spring-boot-maven-plugin - - - - \ 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/tensorflow-java/pom.xml b/tensorflow-java/pom.xml index 2ac4d28a37..4dd86d45e3 100644 --- a/tensorflow-java/pom.xml +++ b/tensorflow-java/pom.xml @@ -21,18 +21,6 @@ tensorflow ${tensorflow.version} - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - diff --git a/testing-modules/assertion-libraries/pom.xml b/testing-modules/assertion-libraries/pom.xml index 14e0379a3c..ea9a37afaf 100644 --- a/testing-modules/assertion-libraries/pom.xml +++ b/testing-modules/assertion-libraries/pom.xml @@ -11,6 +11,7 @@ com.baeldung testing-modules 1.0.0-SNAPSHOT + ../ @@ -19,7 +20,8 @@ truth ${truth.version} - + junit junit @@ -37,12 +39,6 @@ assertj-guava ${assertj-guava.version} - - org.assertj - assertj-core - ${assertj-core.version} - test - org.javalite javalite-common @@ -54,7 +50,8 @@ ${jgotesting.version} test - + junit junit @@ -80,8 +77,7 @@ 0.32 - 3.1.0 - 3.9.0 + 3.4.0 2.1.0 1.4.13 0.12 diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJConditionUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJConditionUnitTest.java index ec2d93500f..4ed7fc3ee0 100644 --- a/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJConditionUnitTest.java +++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJConditionUnitTest.java @@ -25,7 +25,7 @@ public class AssertJConditionUnitTest { assertThat(member).isNot(senior); fail(); } catch (AssertionError e) { - assertThat(e).hasMessageContaining("not to be "); + assertThat(e).hasMessageContaining("not to be senior"); } } @@ -38,7 +38,7 @@ public class AssertJConditionUnitTest { assertThat(member).has(nameJohn); fail(); } catch (AssertionError e) { - assertThat(e).hasMessageContaining(""); + assertThat(e).hasMessageContaining("name John"); } } diff --git a/testing-modules/easy-random/pom.xml b/testing-modules/easy-random/pom.xml index 1ea6fbc387..f338519df3 100644 --- a/testing-modules/easy-random/pom.xml +++ b/testing-modules/easy-random/pom.xml @@ -8,9 +8,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/easymock/pom.xml b/testing-modules/easymock/pom.xml index a8e37da8eb..fd7db5dbb1 100644 --- a/testing-modules/easymock/pom.xml +++ b/testing-modules/easymock/pom.xml @@ -11,6 +11,7 @@ com.baeldung testing-modules 1.0.0-SNAPSHOT + ../ diff --git a/testing-modules/gatling/pom.xml b/testing-modules/gatling/pom.xml index 281c74d6b3..f1c9906581 100644 --- a/testing-modules/gatling/pom.xml +++ b/testing-modules/gatling/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -109,10 +109,10 @@ 1.8 1.8 UTF-8 - 2.12.6 - 3.3.1 - 4.3.0 - 3.0.4 + 2.12.6 + 3.3.1 + 4.3.0 + 3.0.4 \ No newline at end of file diff --git a/testing-modules/groovy-spock/pom.xml b/testing-modules/groovy-spock/pom.xml index 3c1f00abdf..65db332acb 100644 --- a/testing-modules/groovy-spock/pom.xml +++ b/testing-modules/groovy-spock/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/junit-4/pom.xml b/testing-modules/junit-4/pom.xml index 0ae6b71f82..f58d1709d3 100644 --- a/testing-modules/junit-4/pom.xml +++ b/testing-modules/junit-4/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/junit-5-advanced/pom.xml b/testing-modules/junit-5-advanced/pom.xml index 3f11c215ff..f37a41690b 100644 --- a/testing-modules/junit-5-advanced/pom.xml +++ b/testing-modules/junit-5-advanced/pom.xml @@ -10,29 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ - - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - \ No newline at end of file diff --git a/testing-modules/junit-5-basics/pom.xml b/testing-modules/junit-5-basics/pom.xml index d92ee55682..4dcba2db96 100644 --- a/testing-modules/junit-5-basics/pom.xml +++ b/testing-modules/junit-5-basics/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -22,36 +22,12 @@ ${junit-platform.version} test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.junit.jupiter junit-jupiter-migrationsupport ${junit-jupiter.version} test - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-params - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - com.h2database h2 @@ -97,8 +73,8 @@ + org.apache.maven.surefire maven-surefire-plugin - ${maven-surefire-plugin.version} **/*IntegrationTest.java @@ -116,8 +92,8 @@ + org.apache.maven.surefire maven-surefire-plugin - ${maven-surefire-plugin.version} com.baeldung.categories.UnitTest com.baeldung.categories.IntegrationTest @@ -134,8 +110,8 @@ + org.apache.maven.surefire maven-surefire-plugin - ${maven-surefire-plugin.version} UnitTest IntegrationTest @@ -148,6 +124,7 @@ 5.0.6.RELEASE + 1.4.197 \ No newline at end of file diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/BeforeAndAfterAnnotationsUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/BeforeAndAfterAnnotationsUnitTest.java index 6022de123f..3e09a3adbb 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/BeforeAndAfterAnnotationsUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/BeforeAndAfterAnnotationsUnitTest.java @@ -23,19 +23,19 @@ public class BeforeAndAfterAnnotationsUnitTest { @Before public void init() { - LOG.info("startup"); + LOG.debug("startup"); list = new ArrayList<>(Arrays.asList("test1", "test2")); } @After public void teardown() { - LOG.info("teardown"); + LOG.debug("teardown"); list.clear(); } @Test public void whenCheckingListSize_thenSizeEqualsToInit() { - LOG.info("executing test"); + LOG.debug("executing test"); assertEquals(2, list.size()); list.add("another test"); @@ -43,7 +43,7 @@ public class BeforeAndAfterAnnotationsUnitTest { @Test public void whenCheckingListSizeAgain_thenSizeEqualsToInit() { - LOG.info("executing another test"); + LOG.debug("executing another test"); assertEquals(2, list.size()); list.add("yet another test"); diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/BeforeClassAndAfterClassAnnotationsUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/BeforeClassAndAfterClassAnnotationsUnitTest.java index 8a82a75d3d..8b0ddd259f 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/BeforeClassAndAfterClassAnnotationsUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/BeforeClassAndAfterClassAnnotationsUnitTest.java @@ -12,24 +12,24 @@ import org.slf4j.LoggerFactory; public class BeforeClassAndAfterClassAnnotationsUnitTest { private static final Logger LOG = LoggerFactory.getLogger(BeforeClassAndAfterClassAnnotationsUnitTest.class); - + @BeforeClass public static void setup() { - LOG.info("startup - creating DB connection"); + LOG.debug("startup - creating DB connection"); } @AfterClass public static void tearDown() { - LOG.info("closing DB connection"); + LOG.debug("closing DB connection"); } @Test public void simpleTest() { - LOG.info("simple test"); + LOG.debug("simple test"); } @Test public void anotherSimpleTest() { - LOG.info("another simple test"); + LOG.debug("another simple test"); } } diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/RuleExampleUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/RuleExampleUnitTest.java index 969d1b370e..9cf6eafd7e 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/RuleExampleUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/RuleExampleUnitTest.java @@ -1,18 +1,21 @@ package com.baeldung.migration.junit4; +import com.baeldung.migration.junit4.rules.TraceUnitTestRule; import org.junit.Rule; import org.junit.Test; - -import com.baeldung.migration.junit4.rules.TraceUnitTestRule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class RuleExampleUnitTest { - + + private static final Logger LOGGER = LoggerFactory.getLogger(RuleExampleUnitTest.class); + @Rule public final TraceUnitTestRule traceRuleTests = new TraceUnitTestRule(); @Test public void whenTracingTests() { - System.out.println("This is my test"); + LOGGER.debug("This is my test"); /*...*/ } } diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java index 5c993f17fd..b17e0b07c8 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java @@ -1,15 +1,19 @@ package com.baeldung.migration.junit4.rules; -import java.util.ArrayList; -import java.util.List; - import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; public class TraceUnitTestRule implements TestRule { + private static final Logger LOGGER = LoggerFactory.getLogger(TraceUnitTestRule.class); + @Override public Statement apply(Statement base, Description description) { @@ -18,13 +22,13 @@ public class TraceUnitTestRule implements TestRule { public void evaluate() throws Throwable { List errors = new ArrayList(); - System.out.println("Starting test ... " + description.getMethodName()); + LOGGER.debug("Starting test ... {}", description.getMethodName()); try { base.evaluate(); } catch (Throwable e) { errors.add(e); } finally { - System.out.println("... test finished. " + description.getMethodName()); + LOGGER.debug("... test finished. {}", description.getMethodName()); } MultipleFailureException.assertEmpty(errors); diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java index b81e9b7b8e..5181d54a46 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java @@ -15,21 +15,21 @@ public class BeforeAllAndAfterAllAnnotationsUnitTest { @BeforeAll public static void setup() { - LOG.info("startup - creating DB connection"); + LOG.debug("startup - creating DB connection"); } @AfterAll public static void tearDown() { - LOG.info("closing DB connection"); + LOG.debug("closing DB connection"); } @Test public void simpleTest() { - LOG.info("simple test"); + LOG.debug("simple test"); } @Test public void anotherSimpleTest() { - LOG.info("another simple test"); + LOG.debug("another simple test"); } } diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java index f0093b3bf6..b2112ef2c3 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java @@ -23,19 +23,19 @@ public class BeforeEachAndAfterEachAnnotationsUnitTest { @BeforeEach public void init() { - LOG.info("startup"); + LOG.debug("startup"); list = new ArrayList<>(Arrays.asList("test1", "test2")); } @AfterEach public void teardown() { - LOG.info("teardown"); + LOG.debug("teardown"); list.clear(); } @Test public void whenCheckingListSize_ThenSizeEqualsToInit() { - LOG.info("executing test"); + LOG.debug("executing test"); assertEquals(2, list.size()); list.add("another test"); @@ -43,7 +43,7 @@ public class BeforeEachAndAfterEachAnnotationsUnitTest { @Test public void whenCheckingListSizeAgain_ThenSizeEqualsToInit() { - LOG.info("executing another test"); + LOG.debug("executing another test"); assertEquals(2, list.size()); list.add("yet another test"); diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java index 7b1bcda730..c67a57dcbd 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java @@ -1,19 +1,22 @@ package com.baeldung.migration.junit5; +import com.baeldung.migration.junit5.extensions.TraceUnitExtension; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; - -import com.baeldung.migration.junit5.extensions.TraceUnitExtension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @RunWith(JUnitPlatform.class) @ExtendWith(TraceUnitExtension.class) public class RuleExampleUnitTest { + private static final Logger LOGGER = LoggerFactory.getLogger(RuleExampleUnitTest.class); + @Test public void whenTracingTests() { - System.out.println("This is my test"); + LOGGER.debug("This is my test"); /*...*/ } } diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java index db5d3e2573..165ca8741a 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java @@ -3,17 +3,21 @@ package com.baeldung.migration.junit5.extensions; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class TraceUnitExtension implements AfterEachCallback, BeforeEachCallback { + private static final Logger LOGGER = LoggerFactory.getLogger(TraceUnitExtension.class); + @Override public void beforeEach(ExtensionContext context) throws Exception { - System.out.println("Starting test ... " + context.getDisplayName()); + LOGGER.debug("Starting test ... {}", context.getDisplayName()); } @Override public void afterEach(ExtensionContext context) throws Exception { - System.out.println("... test finished. " + context.getDisplayName()); + LOGGER.debug("... test finished. {}", context.getDisplayName()); } } diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/resourcedirectory/ReadResourceDirectoryUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/resourcedirectory/ReadResourceDirectoryUnitTest.java index eb8cab2462..b8358449c0 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/resourcedirectory/ReadResourceDirectoryUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/resourcedirectory/ReadResourceDirectoryUnitTest.java @@ -1,7 +1,10 @@ package com.baeldung.resourcedirectory; +import com.baeldung.migration.junit5.extensions.TraceUnitExtension; import org.junit.Assert; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.nio.file.Path; @@ -9,6 +12,8 @@ import java.nio.file.Paths; public class ReadResourceDirectoryUnitTest { + private static final Logger LOGGER = LoggerFactory.getLogger(TraceUnitExtension.class); + @Test public void givenResourcePath_whenReadAbsolutePathWithFile_thenAbsolutePathEndsWithDirectory() { String path = "src/test/resources"; @@ -16,7 +21,7 @@ public class ReadResourceDirectoryUnitTest { File file = new File(path); String absolutePath = file.getAbsolutePath(); - System.out.println(absolutePath); + LOGGER.debug(absolutePath); Assert.assertTrue(absolutePath.endsWith("src" + File.separator + "test" + File.separator + "resources")); } @@ -26,7 +31,7 @@ public class ReadResourceDirectoryUnitTest { String absolutePath = resourceDirectory.toFile().getAbsolutePath(); - System.out.println(absolutePath); + LOGGER.debug(absolutePath); Assert.assertTrue(absolutePath.endsWith("src" + File.separator + "test" + File.separator + "resources")); } @@ -38,7 +43,7 @@ public class ReadResourceDirectoryUnitTest { File file = new File(classLoader.getResource(resourceName).getFile()); String absolutePath = file.getAbsolutePath(); - System.out.println(absolutePath); + LOGGER.debug(absolutePath); Assert.assertTrue(absolutePath.endsWith(File.separator + "example_resource.txt")); } diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml index 148abecb0f..7a511dfe7a 100644 --- a/testing-modules/junit-5/pom.xml +++ b/testing-modules/junit-5/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -22,36 +22,18 @@ junit-platform-engine ${junit-platform.version} - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - org.junit.platform junit-platform-runner ${junit-platform.version} test - org.junit.platform junit-platform-console-standalone ${junit-platform.version} test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.junit.jupiter junit-jupiter-migrationsupport @@ -140,7 +122,6 @@ 2.23.0 2.8.2 2.0.0 - 2.22.0 5.0.1.RELEASE 3.0.0-M3 diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/order/AlphanumericOrderUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/order/AlphanumericOrderUnitTest.java index d62ca0c666..873df30400 100644 --- a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/order/AlphanumericOrderUnitTest.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/order/AlphanumericOrderUnitTest.java @@ -3,29 +3,29 @@ package com.baeldung.junit5.order; import static org.junit.Assert.assertEquals; import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.MethodOrderer.Alphanumeric; +import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; -@TestMethodOrder(Alphanumeric.class) +@TestMethodOrder(MethodOrderer.MethodName.class) public class AlphanumericOrderUnitTest { private static StringBuilder output = new StringBuilder(""); - + @Test public void myATest() { output.append("A"); } - + @Test public void myBTest() { - output.append("B"); + output.append("B"); } - + @Test public void myaTest() { output.append("a"); } - + @AfterAll public static void assertOutput() { assertEquals(output.toString(), "ABa"); diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/order/DefaultOrderUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/order/DefaultOrderUnitTest.java new file mode 100644 index 0000000000..65cee3e987 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/order/DefaultOrderUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.junit5.order; + +import static org.junit.Assert.assertEquals; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class DefaultOrderUnitTest { + + private static StringBuilder output = new StringBuilder(""); + + @Test + @DisplayName("Test A") + public void myATest() { + output.append("A"); + } + + @Test + @DisplayName("Test B") + public void myBTest() { + output.append("B"); + } + + @Test + @DisplayName("Test C") + public void myCTest() { + output.append("C"); + } + + @AfterAll + public static void assertOutput() { + assertEquals(output.toString(), "ABC"); + } + +} diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/order/RandomOrderUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/order/RandomOrderUnitTest.java new file mode 100644 index 0000000000..0f64f5bb31 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/order/RandomOrderUnitTest.java @@ -0,0 +1,35 @@ +package com.baeldung.junit5.order; + +import static org.junit.Assert.assertEquals; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; + +@TestMethodOrder(MethodOrderer.Random.class) +public class RandomOrderUnitTest { + + private static StringBuilder output = new StringBuilder(""); + + @Test + public void myATest() { + output.append("A"); + } + + @Test + public void myBTest() { + output.append("B"); + } + + @Test + public void myCTest() { + output.append("C"); + } + + @AfterAll + public static void assertOutput() { + assertEquals(output.toString(), "ACB"); + } + +} diff --git a/testing-modules/junit-5/src/test/resources/junit-platform.properties b/testing-modules/junit-5/src/test/resources/junit-platform.properties new file mode 100644 index 0000000000..a02be290e0 --- /dev/null +++ b/testing-modules/junit-5/src/test/resources/junit-platform.properties @@ -0,0 +1,2 @@ +junit.jupiter.execution.order.random.seed=100 +junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$DisplayName diff --git a/testing-modules/junit5-annotations/pom.xml b/testing-modules/junit5-annotations/pom.xml index 79600eb589..95c0d2d448 100644 --- a/testing-modules/junit5-annotations/pom.xml +++ b/testing-modules/junit5-annotations/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -21,16 +21,6 @@ junit-platform-engine ${junit-platform.version} - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - - - org.junit.jupiter - junit-jupiter-params - ${junit-jupiter.version} - org.junit.jupiter junit-jupiter-api @@ -47,17 +37,10 @@ ${junit-platform.version} test - - org.assertj - assertj-core - ${assertj-core.version} - test - 2.8.2 - 3.11.1 \ No newline at end of file diff --git a/testing-modules/junit5-annotations/src/main/java/com/baeldung/junit5/registerextension/RegisterExtensionSampleExtension.java b/testing-modules/junit5-annotations/src/main/java/com/baeldung/junit5/registerextension/RegisterExtensionSampleExtension.java index 5339f98875..31d45955ca 100644 --- a/testing-modules/junit5-annotations/src/main/java/com/baeldung/junit5/registerextension/RegisterExtensionSampleExtension.java +++ b/testing-modules/junit5-annotations/src/main/java/com/baeldung/junit5/registerextension/RegisterExtensionSampleExtension.java @@ -20,12 +20,12 @@ public class RegisterExtensionSampleExtension implements BeforeAllCallback, Befo @Override public void beforeAll(ExtensionContext extensionContext) throws Exception { - logger.info("Type {} In beforeAll : {}", type, extensionContext.getDisplayName()); + logger.debug("Type {} In beforeAll : {}", type, extensionContext.getDisplayName()); } @Override public void beforeEach(ExtensionContext extensionContext) throws Exception { - logger.info("Type {} In beforeEach : {}", type, extensionContext.getDisplayName()); + logger.debug("Type {} In beforeEach : {}", type, extensionContext.getDisplayName()); } public String getType() { diff --git a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/RepeatedTestAnnotationUnitTest.java b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/RepeatedTestAnnotationUnitTest.java index f9121d8790..c3e6d19568 100644 --- a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/RepeatedTestAnnotationUnitTest.java +++ b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/RepeatedTestAnnotationUnitTest.java @@ -1,41 +1,45 @@ package com.baeldung.junit5; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.RepetitionInfo; import org.junit.jupiter.api.TestInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.jupiter.api.Assertions.assertEquals; public class RepeatedTestAnnotationUnitTest { + private static final Logger LOGGER = LoggerFactory.getLogger(RepeatedTestAnnotationUnitTest.class); + @BeforeEach void beforeEachTest() { - System.out.println("Before Each Test"); + LOGGER.debug("Before Each Test"); } @AfterEach void afterEachTest() { - System.out.println("After Each Test"); - System.out.println("====================="); + LOGGER.debug("After Each Test"); + LOGGER.debug("====================="); } @RepeatedTest(3) void repeatedTest(TestInfo testInfo) { - System.out.println("Executing repeated test"); + LOGGER.debug("Executing repeated test"); assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2"); } @RepeatedTest(value = 3, name = RepeatedTest.LONG_DISPLAY_NAME) void repeatedTestWithLongName() { - System.out.println("Executing repeated test with long name"); + LOGGER.debug("Executing repeated test with long name"); assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2"); } @RepeatedTest(value = 3, name = RepeatedTest.SHORT_DISPLAY_NAME) void repeatedTestWithShortName() { - System.out.println("Executing repeated test with long name"); + LOGGER.debug("Executing repeated test with long name"); assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2"); } @@ -46,7 +50,7 @@ public class RepeatedTestAnnotationUnitTest { @RepeatedTest(3) void repeatedTestWithRepetitionInfo(RepetitionInfo repetitionInfo) { - System.out.println("Repetition #" + repetitionInfo.getCurrentRepetition()); + LOGGER.debug("Repetition # {}", repetitionInfo.getCurrentRepetition()); assertEquals(3, repetitionInfo.getTotalRepetitions()); } } diff --git a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/conditional/ConditionalAnnotationsUnitTest.java b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/conditional/ConditionalAnnotationsUnitTest.java index ba840a1c33..0d4013116f 100644 --- a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/conditional/ConditionalAnnotationsUnitTest.java +++ b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/conditional/ConditionalAnnotationsUnitTest.java @@ -2,7 +2,20 @@ package com.baeldung.junit5.conditional; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.*; +import org.junit.jupiter.api.condition.DisabledForJreRange; +import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable; +import org.junit.jupiter.api.condition.DisabledIfSystemProperty; +import org.junit.jupiter.api.condition.DisabledOnJre; +import org.junit.jupiter.api.condition.DisabledOnOs; +import org.junit.jupiter.api.condition.EnabledForJreRange; +import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; +import org.junit.jupiter.api.condition.EnabledIfSystemProperty; +import org.junit.jupiter.api.condition.EnabledOnJre; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.JRE; +import org.junit.jupiter.api.condition.OS; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -11,64 +24,66 @@ import java.lang.annotation.Target; public class ConditionalAnnotationsUnitTest { + private static final Logger LOGGER = LoggerFactory.getLogger(ConditionalAnnotationsUnitTest.class); + @Test @EnabledOnOs({OS.WINDOWS, OS.MAC}) public void shouldRunBothWindowsAndMac() { - System.out.println("runs on Windows and Mac"); + LOGGER.debug("runs on Windows and Mac"); } @Test @DisabledOnOs(OS.LINUX) public void shouldNotRunAtLinux() { - System.out.println("will not run on Linux"); + LOGGER.debug("will not run on Linux"); } @Test @EnabledOnJre({JRE.JAVA_10, JRE.JAVA_11}) public void shouldOnlyRunOnJava10And11() { - System.out.println("runs with java 10 and 11"); + LOGGER.debug("runs with java 10 and 11"); } @Test @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_13) public void shouldOnlyRunOnJava8UntilJava13() { - System.out.println("runs with Java 8, 9, 10, 11, 12 and 13!"); + LOGGER.debug("runs with Java 8, 9, 10, 11, 12 and 13!"); } @Test @DisabledForJreRange(min = JRE.JAVA_14, max = JRE.JAVA_15) public void shouldNotBeRunOnJava14AndJava15() { - System.out.println("Shouldn't be run on Java 14 and 15."); + LOGGER.debug("Shouldn't be run on Java 14 and 15."); } @Test @DisabledOnJre(JRE.OTHER) public void thisTestOnlyRunsWithUpToDateJREs() { - System.out.println("this test will only run on java8, 9, 10 and 11."); + LOGGER.debug("this test will only run on java8, 9, 10 and 11."); } @Test @EnabledIfSystemProperty(named = "java.vm.vendor", matches = "Oracle.*") public void onlyIfVendorNameStartsWithOracle() { - System.out.println("runs only if vendor name starts with Oracle"); + LOGGER.debug("runs only if vendor name starts with Oracle"); } @Test @DisabledIfSystemProperty(named = "file.separator", matches = "[/]") public void disabledIfFileSeperatorIsSlash() { - System.out.println("Will not run if file.sepeartor property is /"); + LOGGER.debug("Will not run if file.sepeartor property is /"); } @Test @EnabledIfEnvironmentVariable(named = "GDMSESSION", matches = "ubuntu") public void onlyRunOnUbuntuServer() { - System.out.println("only runs if GDMSESSION is ubuntu"); + LOGGER.debug("only runs if GDMSESSION is ubuntu"); } @Test @DisabledIfEnvironmentVariable(named = "LC_TIME", matches = ".*UTF-8.") public void shouldNotRunWhenTimeIsNotUTF8() { - System.out.println("will not run if environment variable LC_TIME is UTF-8"); + LOGGER.debug("will not run if environment variable LC_TIME is UTF-8"); } // Commented codes are going to work prior JUnit 5.5 @@ -76,13 +91,13 @@ public class ConditionalAnnotationsUnitTest { @Test // @EnabledIf("'FR' == systemProperty.get('user.country')") public void onlyFrenchPeopleWillRunThisMethod() { - System.out.println("will run only if user.country is FR"); + LOGGER.debug("will run only if user.country is FR"); } @Test // @DisabledIf("java.lang.System.getProperty('os.name').toLowerCase().contains('mac')") public void shouldNotRunOnMacOS() { - System.out.println("will not run if our os.name is mac"); + LOGGER.debug("will not run if our os.name is mac"); } @Test @@ -97,14 +112,14 @@ public class ConditionalAnnotationsUnitTest { engine = "nashorn", reason = "Self-fulfilling: {result}")*/ public void onlyRunsInFebruary() { - System.out.println("this test only runs in February"); + LOGGER.debug("this test only runs in February"); } @Test /*@DisabledIf("systemEnvironment.get('XPC_SERVICE_NAME') != null " + "&& systemEnvironment.get('XPC_SERVICE_NAME').contains('intellij')")*/ public void notValidForIntelliJ() { - System.out.println("this test will run if our ide is INTELLIJ"); + LOGGER.debug("this test will run if our ide is INTELLIJ"); } @Target(ElementType.METHOD) @@ -117,7 +132,7 @@ public class ConditionalAnnotationsUnitTest { @ThisTestWillOnlyRunAtLinuxAndMacWithJava9Or10Or11 public void someSuperTestMethodHere() { - System.out.println("this method will run with java9, 10, 11 and Linux or macOS."); + LOGGER.debug("this method will run with java9, 10, 11 and Linux or macOS."); } @Target(ElementType.METHOD) @@ -129,6 +144,6 @@ public class ConditionalAnnotationsUnitTest { @RepeatedTest(2) @CoinToss public void gamble() { - System.out.println("This tests run status is a gamble with %50 rate"); + LOGGER.debug("This tests run status is a gamble with %50 rate"); } } diff --git a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/DisabledOnQAEnvironmentExtension.java b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/DisabledOnQAEnvironmentExtension.java index cd8b7b677d..fec2980b6f 100644 --- a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/DisabledOnQAEnvironmentExtension.java +++ b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/DisabledOnQAEnvironmentExtension.java @@ -3,11 +3,16 @@ package com.baeldung.junit5.templates; import org.junit.jupiter.api.extension.ConditionEvaluationResult; import org.junit.jupiter.api.extension.ExecutionCondition; import org.junit.jupiter.api.extension.ExtensionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Properties; public class DisabledOnQAEnvironmentExtension implements ExecutionCondition { + + private static final Logger LOGGER = LoggerFactory.getLogger(DisabledOnQAEnvironmentExtension.class); + @Override public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { Properties properties = new Properties(); @@ -16,7 +21,7 @@ public class DisabledOnQAEnvironmentExtension implements ExecutionCondition { .getResourceAsStream("application.properties")); if ("qa".equalsIgnoreCase(properties.getProperty("env"))) { String reason = String.format("The test '%s' is disabled on QA environment", context.getDisplayName()); - System.out.println(reason); + LOGGER.debug(reason); return ConditionEvaluationResult.disabled(reason); } } catch (IOException e) { diff --git a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorTestInvocationContextProvider.java b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorTestInvocationContextProvider.java index 277ec03f05..3e1aaaabd3 100644 --- a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorTestInvocationContextProvider.java +++ b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorTestInvocationContextProvider.java @@ -1,6 +1,15 @@ package com.baeldung.junit5.templates; -import org.junit.jupiter.api.extension.*; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.AfterTestExecutionCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.BeforeTestExecutionCallback; +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.TestTemplateInvocationContext; +import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.List; import java.util.stream.Stream; @@ -9,6 +18,8 @@ import static java.util.Arrays.asList; public class UserIdGeneratorTestInvocationContextProvider implements TestTemplateInvocationContextProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(UserIdGeneratorTestInvocationContextProvider.class); + @Override public boolean supportsTestTemplate(ExtensionContext extensionContext) { return true; @@ -44,13 +55,13 @@ public class UserIdGeneratorTestInvocationContextProvider implements TestTemplat new BeforeTestExecutionCallback() { @Override public void beforeTestExecution(ExtensionContext extensionContext) { - System.out.println("BeforeTestExecutionCallback:Disabled context"); + LOGGER.debug("BeforeTestExecutionCallback:Disabled context"); } }, new AfterTestExecutionCallback() { @Override public void afterTestExecution(ExtensionContext extensionContext) { - System.out.println("AfterTestExecutionCallback:Disabled context"); + LOGGER.debug("AfterTestExecutionCallback:Disabled context"); } }); } @@ -72,13 +83,13 @@ public class UserIdGeneratorTestInvocationContextProvider implements TestTemplat new BeforeEachCallback() { @Override public void beforeEach(ExtensionContext extensionContext) { - System.out.println("BeforeEachCallback:Enabled context"); + LOGGER.debug("BeforeEachCallback:Enabled context"); } }, new AfterEachCallback() { @Override public void afterEach(ExtensionContext extensionContext) { - System.out.println("AfterEachCallback:Enabled context"); + LOGGER.debug("AfterEachCallback:Enabled context"); } }); } diff --git a/testing-modules/junit5-migration/pom.xml b/testing-modules/junit5-migration/pom.xml index 07f11e2b3a..3e34c1dee5 100644 --- a/testing-modules/junit5-migration/pom.xml +++ b/testing-modules/junit5-migration/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -27,12 +27,6 @@ ${junit-platform.version} test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.junit.jupiter junit-jupiter-migrationsupport @@ -50,8 +44,4 @@
- - 2.21.0 - - \ No newline at end of file diff --git a/testing-modules/load-testing-comparison/pom.xml b/testing-modules/load-testing-comparison/pom.xml index 63f2d9ce2f..d5a389d311 100644 --- a/testing-modules/load-testing-comparison/pom.xml +++ b/testing-modules/load-testing-comparison/pom.xml @@ -57,57 +57,11 @@ - - - - - - - - - - org.springframework.boot spring-boot-maven-plugin - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -115,10 +69,10 @@ 1.8 1.8 UTF-8 - 2.12.12 - 3.4.0 - 4.4.0 - 3.1.0 + 2.12.12 + 3.4.0 + 4.4.0 + 3.1.0 5.0 diff --git a/testing-modules/mockito-2/pom.xml b/testing-modules/mockito-2/pom.xml index 558ac59d08..cff7598edc 100644 --- a/testing-modules/mockito-2/pom.xml +++ b/testing-modules/mockito-2/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/mockito-3/pom.xml b/testing-modules/mockito-3/pom.xml index 5a150ccbf9..10130290df 100644 --- a/testing-modules/mockito-3/pom.xml +++ b/testing-modules/mockito-3/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -22,17 +22,10 @@ ${mockito.version} test - - org.assertj - assertj-core - ${assertj.version} - test - 3.8.0 - 3.8.0 \ No newline at end of file diff --git a/testing-modules/mocks/pom.xml b/testing-modules/mocks/pom.xml index 17700a835e..3fabde037c 100644 --- a/testing-modules/mocks/pom.xml +++ b/testing-modules/mocks/pom.xml @@ -8,9 +8,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/mockserver/pom.xml b/testing-modules/mockserver/pom.xml index c039d6a0ab..3495ddb09d 100644 --- a/testing-modules/mockserver/pom.xml +++ b/testing-modules/mockserver/pom.xml @@ -9,9 +9,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/parallel-tests-junit/math-test-functions/pom.xml b/testing-modules/parallel-tests-junit/math-test-functions/pom.xml index eae1bf61e7..7ead2051e2 100644 --- a/testing-modules/parallel-tests-junit/math-test-functions/pom.xml +++ b/testing-modules/parallel-tests-junit/math-test-functions/pom.xml @@ -13,21 +13,11 @@ 0.0.1-SNAPSHOT - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} all 10 @@ -45,8 +35,4 @@ - - 2.22.0 - - \ No newline at end of file diff --git a/testing-modules/parallel-tests-junit/string-test-functions/pom.xml b/testing-modules/parallel-tests-junit/string-test-functions/pom.xml index c838558fc2..86b4078eb3 100644 --- a/testing-modules/parallel-tests-junit/string-test-functions/pom.xml +++ b/testing-modules/parallel-tests-junit/string-test-functions/pom.xml @@ -13,21 +13,11 @@ 0.0.1-SNAPSHOT - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} all true @@ -37,8 +27,4 @@ - - 2.22.0 - - \ No newline at end of file diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml index 28c743b2b3..58ea74484e 100644 --- a/testing-modules/pom.xml +++ b/testing-modules/pom.xml @@ -42,7 +42,6 @@ spring-testing-2 spring-testing test-containers - testing-assertions testing-libraries-2 testing-libraries testng diff --git a/testing-modules/powermock/pom.xml b/testing-modules/powermock/pom.xml index 7179f3ffbe..fad338bb9b 100644 --- a/testing-modules/powermock/pom.xml +++ b/testing-modules/powermock/pom.xml @@ -6,9 +6,10 @@ powermock - testing-modules com.baeldung + testing-modules 1.0.0-SNAPSHOT + ../ diff --git a/testing-modules/selenium-junit-testng/pom.xml b/testing-modules/selenium-junit-testng/pom.xml index 9f132c7562..dfa19c48d4 100644 --- a/testing-modules/selenium-junit-testng/pom.xml +++ b/testing-modules/selenium-junit-testng/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 selenium-junit-testng 0.0.1-SNAPSHOT @@ -9,9 +9,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -31,17 +31,6 @@ testng ${testng.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - org.hamcrest - hamcrest-all - ${hamcrest-all.version} - ru.yandex.qatools.ashot ashot diff --git a/testing-modules/spring-testing-2/README.md b/testing-modules/spring-testing-2/README.md index 16b47adeac..434388d683 100644 --- a/testing-modules/spring-testing-2/README.md +++ b/testing-modules/spring-testing-2/README.md @@ -3,3 +3,4 @@ - [Guide to @DynamicPropertySource in Spring](https://www.baeldung.com/spring-dynamicpropertysource) - [Concurrent Test Execution in Spring 5](https://www.baeldung.com/spring-5-concurrent-tests) - [Spring 5 Testing with @EnabledIf Annotation](https://www.baeldung.com/spring-5-enabledIf) +- [The Spring TestExecutionListener](https://www.baeldung.com/spring-testexecutionlistener) diff --git a/testing-modules/spring-testing-2/pom.xml b/testing-modules/spring-testing-2/pom.xml index 419b8d512a..6bdec33d96 100644 --- a/testing-modules/spring-testing-2/pom.xml +++ b/testing-modules/spring-testing-2/pom.xml @@ -26,7 +26,6 @@ com.h2database h2 - ${h2.version} org.postgresql @@ -55,7 +54,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} methods true @@ -65,7 +63,7 @@
- 1.12.2 + 1.16.2 \ No newline at end of file diff --git a/testing-modules/spring-testing/src/main/java/com/baeldung/testexecutionlisteners/AdditionService.java b/testing-modules/spring-testing-2/src/main/java/com/baeldung/testexecutionlisteners/AdditionService.java similarity index 100% rename from testing-modules/spring-testing/src/main/java/com/baeldung/testexecutionlisteners/AdditionService.java rename to testing-modules/spring-testing-2/src/main/java/com/baeldung/testexecutionlisteners/AdditionService.java 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/spring-testing/src/test/java/com/baeldung/testexecutionlisteners/AdditionServiceUnitTest.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/testexecutionlisteners/AdditionServiceUnitTest.java similarity index 92% rename from testing-modules/spring-testing/src/test/java/com/baeldung/testexecutionlisteners/AdditionServiceUnitTest.java rename to testing-modules/spring-testing-2/src/test/java/com/baeldung/testexecutionlisteners/AdditionServiceUnitTest.java index bbe537a3ce..6c5d08f478 100644 --- a/testing-modules/spring-testing/src/test/java/com/baeldung/testexecutionlisteners/AdditionServiceUnitTest.java +++ b/testing-modules/spring-testing-2/src/test/java/com/baeldung/testexecutionlisteners/AdditionServiceUnitTest.java @@ -1,7 +1,5 @@ package com.baeldung.testexecutionlisteners; -import static org.junit.Assert.assertThat; - import org.hamcrest.Matchers; import org.junit.Test; import org.junit.runner.RunWith; @@ -9,9 +7,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; +import static org.hamcrest.MatcherAssert.assertThat; + @RunWith(SpringRunner.class) @ContextConfiguration(classes = AdditionService.class) public class AdditionServiceUnitTest { + @Autowired private AdditionService additionService; diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/testexecutionlisteners/CustomTestExecutionListener.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/testexecutionlisteners/CustomTestExecutionListener.java similarity index 100% rename from testing-modules/spring-testing/src/test/java/com/baeldung/testexecutionlisteners/CustomTestExecutionListener.java rename to testing-modules/spring-testing-2/src/test/java/com/baeldung/testexecutionlisteners/CustomTestExecutionListener.java diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/testexecutionlisteners/TestExecutionListenersWithMergeModeUnitTest.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/testexecutionlisteners/TestExecutionListenersWithMergeModeUnitTest.java similarity index 93% rename from testing-modules/spring-testing/src/test/java/com/baeldung/testexecutionlisteners/TestExecutionListenersWithMergeModeUnitTest.java rename to testing-modules/spring-testing-2/src/test/java/com/baeldung/testexecutionlisteners/TestExecutionListenersWithMergeModeUnitTest.java index 44937aa755..de1501c54d 100644 --- a/testing-modules/spring-testing/src/test/java/com/baeldung/testexecutionlisteners/TestExecutionListenersWithMergeModeUnitTest.java +++ b/testing-modules/spring-testing-2/src/test/java/com/baeldung/testexecutionlisteners/TestExecutionListenersWithMergeModeUnitTest.java @@ -1,7 +1,5 @@ package com.baeldung.testexecutionlisteners; -import static org.junit.Assert.assertThat; - import org.hamcrest.Matchers; import org.junit.Test; import org.junit.runner.RunWith; @@ -11,11 +9,14 @@ import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.TestExecutionListeners.MergeMode; import org.springframework.test.context.junit4.SpringRunner; +import static org.hamcrest.MatcherAssert.assertThat; + @RunWith(SpringRunner.class) -@TestExecutionListeners(value = { CustomTestExecutionListener.class }, +@TestExecutionListeners(value = { CustomTestExecutionListener.class }, mergeMode = MergeMode.MERGE_WITH_DEFAULTS) @ContextConfiguration(classes = AdditionService.class) public class TestExecutionListenersWithMergeModeUnitTest { + @Autowired private AdditionService additionService; diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/testexecutionlisteners/TestExecutionListenersWithoutMergeModeUnitTest.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/testexecutionlisteners/TestExecutionListenersWithoutMergeModeUnitTest.java similarity index 94% rename from testing-modules/spring-testing/src/test/java/com/baeldung/testexecutionlisteners/TestExecutionListenersWithoutMergeModeUnitTest.java rename to testing-modules/spring-testing-2/src/test/java/com/baeldung/testexecutionlisteners/TestExecutionListenersWithoutMergeModeUnitTest.java index e25ab9f381..b4cc861c29 100644 --- a/testing-modules/spring-testing/src/test/java/com/baeldung/testexecutionlisteners/TestExecutionListenersWithoutMergeModeUnitTest.java +++ b/testing-modules/spring-testing-2/src/test/java/com/baeldung/testexecutionlisteners/TestExecutionListenersWithoutMergeModeUnitTest.java @@ -1,7 +1,5 @@ package com.baeldung.testexecutionlisteners; -import static org.junit.Assert.assertThat; - import org.hamcrest.Matchers; import org.junit.Test; import org.junit.runner.RunWith; @@ -11,11 +9,14 @@ import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; +import static org.hamcrest.MatcherAssert.assertThat; + @RunWith(SpringRunner.class) @TestExecutionListeners(value = {CustomTestExecutionListener.class, DependencyInjectionTestExecutionListener.class}) @ContextConfiguration(classes = AdditionService.class) public class TestExecutionListenersWithoutMergeModeUnitTest { + @Autowired private AdditionService additionService; diff --git a/testing-modules/spring-testing/README.md b/testing-modules/spring-testing/README.md index a4de9c5c57..2427dfabbe 100644 --- a/testing-modules/spring-testing/README.md +++ b/testing-modules/spring-testing/README.md @@ -7,4 +7,3 @@ - [Using SpringJUnit4ClassRunner with Parameterized](https://www.baeldung.com/springjunit4classrunner-parameterized) - [Override Properties in Spring’s Tests](https://www.baeldung.com/spring-tests-override-properties) - [A Quick Guide to @DirtiesContext](https://www.baeldung.com/spring-dirtiescontext) -- [The Spring TestExecutionListener](https://www.baeldung.com/spring-testexecutionlistener) diff --git a/testing-modules/spring-testing/pom.xml b/testing-modules/spring-testing/pom.xml index e687f8d6fd..08b56c9a1a 100644 --- a/testing-modules/spring-testing/pom.xml +++ b/testing-modules/spring-testing/pom.xml @@ -36,17 +36,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - org.springframework spring-core @@ -71,28 +60,6 @@ org.springframework.data spring-data-jpa - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - org.awaitility awaitility diff --git a/testing-modules/test-containers/pom.xml b/testing-modules/test-containers/pom.xml index 24f686d741..687bc418ad 100644 --- a/testing-modules/test-containers/pom.xml +++ b/testing-modules/test-containers/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -23,18 +23,6 @@ ${junit-platform.version} test - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.apache.logging.log4j log4j-core @@ -87,7 +75,6 @@ 1.11.4 42.2.6 3.141.59 - 2.22.2 \ No newline at end of file diff --git a/testing-modules/testing-assertions/README.md b/testing-modules/testing-assertions/README.md index ea238af599..2349834fa3 100644 --- a/testing-modules/testing-assertions/README.md +++ b/testing-modules/testing-assertions/README.md @@ -2,3 +2,5 @@ - [Asserting Log Messages With JUnit](https://www.baeldung.com/junit-asserting-logs) - [Assert Two Lists for Equality Ignoring Order in Java](https://www.baeldung.com/java-assert-lists-equality-ignore-order) +- [Assert That a Java Optional Has a Certain Value](https://www.baeldung.com/java-optional-assert-value) +- [Assert that an Object is from a Specific Type](https://www.baeldung.com/java-assert-object-of-type) diff --git a/testing-modules/testing-assertions/pom.xml b/testing-modules/testing-assertions/pom.xml index d5c5981b33..09f4291b78 100644 --- a/testing-modules/testing-assertions/pom.xml +++ b/testing-modules/testing-assertions/pom.xml @@ -18,30 +18,6 @@ logback-classic ${logback.version} - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - - - org.assertj - assertj-core - ${assertj-core.version} - test - - - org.hamcrest - hamcrest-all - ${hamcrest-all.version} - test - org.apache.commons commons-collections4 @@ -50,9 +26,4 @@ - - 3.16.1 - 4.4 - - \ No newline at end of file diff --git a/testing-modules/testing-assertions/src/main/java/com/baeldung/junit/log/BusinessWorker.java b/testing-modules/testing-assertions/src/main/java/com/baeldung/junit/log/BusinessWorker.java index 86cd38824c..b95faa7874 100644 --- a/testing-modules/testing-assertions/src/main/java/com/baeldung/junit/log/BusinessWorker.java +++ b/testing-modules/testing-assertions/src/main/java/com/baeldung/junit/log/BusinessWorker.java @@ -4,7 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class BusinessWorker { - private static Logger LOGGER = LoggerFactory.getLogger(BusinessWorker.class); + private static final Logger LOGGER = LoggerFactory.getLogger(BusinessWorker.class); public void generateLogs(String msg) { LOGGER.trace(msg); diff --git a/testing-modules/testing-assertions/src/main/java/com/baeldung/object/type/Deciduous.java b/testing-modules/testing-assertions/src/main/java/com/baeldung/object/type/Deciduous.java new file mode 100644 index 0000000000..ae96446a63 --- /dev/null +++ b/testing-modules/testing-assertions/src/main/java/com/baeldung/object/type/Deciduous.java @@ -0,0 +1,15 @@ +package com.baeldung.object.type; + +public class Deciduous implements Tree { + + private String name; + + public Deciduous(String name) { + this.name = name; + } + + @Override + public boolean isEvergreen() { + return false; + } +} diff --git a/testing-modules/testing-assertions/src/main/java/com/baeldung/object/type/Evergreen.java b/testing-modules/testing-assertions/src/main/java/com/baeldung/object/type/Evergreen.java new file mode 100644 index 0000000000..56cda60d22 --- /dev/null +++ b/testing-modules/testing-assertions/src/main/java/com/baeldung/object/type/Evergreen.java @@ -0,0 +1,16 @@ +package com.baeldung.object.type; + +public class Evergreen implements Tree { + + private String name; + + public Evergreen(String name) { + this.name = name; + } + + + @Override + public boolean isEvergreen() { + return true; + } +} diff --git a/testing-modules/testing-assertions/src/main/java/com/baeldung/object/type/Tree.java b/testing-modules/testing-assertions/src/main/java/com/baeldung/object/type/Tree.java new file mode 100644 index 0000000000..0230c61e38 --- /dev/null +++ b/testing-modules/testing-assertions/src/main/java/com/baeldung/object/type/Tree.java @@ -0,0 +1,6 @@ +package com.baeldung.object.type; + +public interface Tree { + + public boolean isEvergreen(); +} diff --git a/testing-modules/testing-assertions/src/main/java/com/baeldung/object/type/TreeSorter.java b/testing-modules/testing-assertions/src/main/java/com/baeldung/object/type/TreeSorter.java new file mode 100644 index 0000000000..af4a6e5ef8 --- /dev/null +++ b/testing-modules/testing-assertions/src/main/java/com/baeldung/object/type/TreeSorter.java @@ -0,0 +1,19 @@ +package com.baeldung.object.type; + +import java.util.List; + +public class TreeSorter { + protected Tree sortTree(String name) { + + final List deciduous = List.of("Beech", "Birch", "Ash", "Whitebeam", "Hornbeam", "Hazel & Willow"); + final List evergreen = List.of("Cedar", "Holly", "Laurel", "Olive", "Pine"); + + if (deciduous.contains(name)) { + return new Deciduous(name); + } else if (evergreen.contains(name)) { + return new Evergreen(name); + } else { + throw new RuntimeException("Tree could not be classified"); + } + } +} diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/object/type/TreeSorterAssertJUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/object/type/TreeSorterAssertJUnitTest.java new file mode 100644 index 0000000000..74b0eec4d9 --- /dev/null +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/object/type/TreeSorterAssertJUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.object.type; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class TreeSorterAssertJUnitTest { + private final TreeSorter tested = new TreeSorter(); + + @Test + public void sortTreeShouldReturnEvergreen_WhenPineIsPassed() { + Tree tree = tested.sortTree("Pine"); + assertThat(tree).isExactlyInstanceOf(Evergreen.class); + } + + @Test + public void sortTreeShouldReturnDecidious_WhenBirchIsPassed() { + Tree tree = tested.sortTree("Birch"); + assertThat(tree).hasSameClassAs(new Deciduous("Birch")); + } + +} \ No newline at end of file diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/object/type/TreeSorterHamcrestUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/object/type/TreeSorterHamcrestUnitTest.java new file mode 100644 index 0000000000..7d35d5c0d0 --- /dev/null +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/object/type/TreeSorterHamcrestUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.object.type; + +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class TreeSorterHamcrestUnitTest { + private final TreeSorter tested = new TreeSorter(); + + @Test + public void sortTreeShouldReturnEvergreen_WhenPineIsPassed() { + Tree tree = tested.sortTree("Pine"); + //with JUnit assertEquals: + assertEquals(tree.getClass(), Evergreen.class); + //with Hamcrest instanceOf: + assertThat(tree, instanceOf(Evergreen.class)); + + } + + @Test + public void sortTreeShouldReturnDecidious_WhenBirchIsPassed() { + Tree tree = tested.sortTree("Birch"); + assertThat(tree, instanceOf(Deciduous.class)); + } + +} \ No newline at end of file diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/optional/OptionalUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/optional/OptionalUnitTest.java new file mode 100644 index 0000000000..351b3dd3e0 --- /dev/null +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/optional/OptionalUnitTest.java @@ -0,0 +1,58 @@ +package com.baeldung.optional; + +import org.junit.jupiter.api.Test; + +import java.util.Optional; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class OptionalUnitTest { + + private static final String OPTIONAL_RETURN_VALUE = "optionalReturnValue"; + + @Test + public void givenOptionalWithValue_whenAssertThatIsNotEmpty_thenOk() { + assertThat(Optional.of(OPTIONAL_RETURN_VALUE)).isNotEmpty(); + } + + @Test + public void givenOptionalWithValue_whenAssertThatHasValue_thenOk() { + assertThat(Optional.of(OPTIONAL_RETURN_VALUE)).hasValue(OPTIONAL_RETURN_VALUE); + } + + @Test + public void givenOptionalWithValue_whenAssertEqualsOptionalObject_thenOk() { + Optional expected = Optional.of(OPTIONAL_RETURN_VALUE); + Optional actual = Optional.of(OPTIONAL_RETURN_VALUE); + assertEquals(expected, actual); + } + + @Test + public void givenOptionalWithValue_whenAssertEqualsGet_thenOk() { + Optional optional = Optional.of(OPTIONAL_RETURN_VALUE); + assertEquals(OPTIONAL_RETURN_VALUE, optional.get()); + } + + @Test + public void givenOptionalWithValue_whenIsPresentAndGetSplit_thenOk() { + Optional optional = Optional.of(OPTIONAL_RETURN_VALUE); + + assertTrue(optional.isPresent()); + assertEquals(OPTIONAL_RETURN_VALUE, optional.get()); + } + + @Test + public void givenEmptyOptional_whenAssertThatIsEmpty_thenOk() { + Optional emptyOptional = Optional.empty(); + assertThat(emptyOptional).isEmpty(); + } + + @Test + public void givenEmptyOptional_whenAssertIsNotPresent_thenOk() { + Optional emptyOptional = Optional.empty(); + assertFalse(emptyOptional.isPresent()); + } +} diff --git a/testing-modules/testing-libraries-2/pom.xml b/testing-modules/testing-libraries-2/pom.xml index 82e4bbfdf0..c7e9ea0e2b 100644 --- a/testing-modules/testing-libraries-2/pom.xml +++ b/testing-modules/testing-libraries-2/pom.xml @@ -30,12 +30,6 @@ ${lombok.version} provided - - org.assertj - assertj-core - ${assertj-core.version} - test - com.github.stefanbirkner system-rules @@ -60,31 +54,6 @@ ${system-stubs.version} test - - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-params - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - @@ -139,7 +108,6 @@ 1.19.0 1.0.0 1.1.0 - 3.16.1 \ No newline at end of file diff --git a/testing-modules/testing-libraries/pom.xml b/testing-modules/testing-libraries/pom.xml index f9443fa792..8c0fca775b 100644 --- a/testing-modules/testing-libraries/pom.xml +++ b/testing-modules/testing-libraries/pom.xml @@ -10,6 +10,7 @@ com.baeldung testing-modules 1.0.0-SNAPSHOT + ../ diff --git a/testing-modules/testng/pom.xml b/testing-modules/testng/pom.xml index 8b6a46a694..5d3bf6b560 100644 --- a/testing-modules/testng/pom.xml +++ b/testing-modules/testng/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 testng 0.1.0-SNAPSHOT @@ -10,13 +10,12 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ - org.testng testng @@ -41,8 +40,46 @@ + + + default-second + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src\test\resources\parametrized_testng.xml + src\test\resources\test_suite.xml + src\test\resources\test_unit.xml + + + + + + + + integration-lite-second + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src\test\resources\test_group.xml + src\test\resources\test_setup.xml + src\test\resources\test_int.xml + + + + + + + + - 7.1.0 diff --git a/testing-modules/testng/src/test/resources/test_int.xml b/testing-modules/testng/src/test/resources/test_int.xml new file mode 100644 index 0000000000..9eb86739b6 --- /dev/null +++ b/testing-modules/testng/src/test/resources/test_int.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/testing-modules/testng/src/test/resources/test_unit.xml b/testing-modules/testng/src/test/resources/test_unit.xml new file mode 100644 index 0000000000..76c97db735 --- /dev/null +++ b/testing-modules/testng/src/test/resources/test_unit.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/testing-modules/xmlunit-2/pom.xml b/testing-modules/xmlunit-2/pom.xml index 07153ab042..a35d9c2b87 100644 --- a/testing-modules/xmlunit-2/pom.xml +++ b/testing-modules/xmlunit-2/pom.xml @@ -8,9 +8,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/zerocode/pom.xml b/testing-modules/zerocode/pom.xml index 48030166b5..ea12385a26 100644 --- a/testing-modules/zerocode/pom.xml +++ b/testing-modules/zerocode/pom.xml @@ -7,9 +7,10 @@ 1.0-SNAPSHOT - testing-modules com.baeldung + testing-modules 1.0.0-SNAPSHOT + ../ diff --git a/video-tutorials/jackson-annotations/pom.xml b/video-tutorials/jackson-annotations/pom.xml index 827715fe5f..eaec50c1f7 100644 --- a/video-tutorials/jackson-annotations/pom.xml +++ b/video-tutorials/jackson-annotations/pom.xml @@ -100,12 +100,6 @@ ${json-schema-validator.version} test - - org.assertj - assertj-core - ${assertj-core.version} - test - @@ -122,11 +116,9 @@ 2.9.6 2.8.0 - 4.1 3.0.1 3.0.0 - 3.6.1 2.2.6 3.0.1 diff --git a/xml/README.md b/xml/README.md index 367a0334f6..16942c6836 100644 --- a/xml/README.md +++ b/xml/README.md @@ -12,3 +12,4 @@ This module contains articles about eXtensible Markup Language (XML) - [Convert XML to HTML in Java](https://www.baeldung.com/java-convert-xml-to-html) - [Parsing an XML File Using StAX](https://www.baeldung.com/java-stax) - [Parsing an XML File Using SAX Parser](https://www.baeldung.com/java-sax-parser) +- [Remove HTML Tags Using Java](https://www.baeldung.com/java-remove-html-tags) diff --git a/xml/pom.xml b/xml/pom.xml index 6bae312452..0764c9d145 100644 --- a/xml/pom.xml +++ b/xml/pom.xml @@ -14,6 +14,22 @@ + + org.jsoup + jsoup + ${jsoup.version} + + + net.sourceforge.htmlcleaner + htmlcleaner + ${htmlcleaner.version} + + + net.htmlparser.jericho + jericho-html + ${jericho.version} + + org.dom4j @@ -107,24 +123,6 @@ commons-lang ${commons-lang.version} - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - org.assertj - assertj-core - ${assertj-core.version} - test - org.xmlunit xmlunit-assertj @@ -190,8 +188,8 @@ ${maven-compiler-plugin.version} + org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} @@ -254,7 +252,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} CustomerTest.java @@ -358,22 +355,20 @@ 1.2.0 2.0.6 1.6.2 - 4.1 1.2.4.5 2.3.1 1.4.2 2.3.0.1 2.3.2 1.0-2 - 3.12.2 2.6.3 2.3.29 0.9.6 - - 2.4 1.3.1 - 3.8.0 + 1.14.3 + 2.25 + 3.4 \ No newline at end of file diff --git a/xml/src/test/java/com/baeldung/xmlhtml/delhtmltags/RemoveHtmlTagsLiveTest.java b/xml/src/test/java/com/baeldung/xmlhtml/delhtmltags/RemoveHtmlTagsLiveTest.java new file mode 100644 index 0000000000..b05123cbdc --- /dev/null +++ b/xml/src/test/java/com/baeldung/xmlhtml/delhtmltags/RemoveHtmlTagsLiveTest.java @@ -0,0 +1,61 @@ +package com.baeldung.xmlhtml.delhtmltags; + +import net.htmlparser.jericho.Renderer; +import net.htmlparser.jericho.Segment; +import net.htmlparser.jericho.Source; +import org.htmlcleaner.CleanerProperties; +import org.htmlcleaner.HtmlCleaner; +import org.jsoup.Jsoup; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Paths; + +class RemoveHtmlTagsLiveTest { + + @Test + void givenHtml1_whenRemoveTagsByRegex_thenPrintText() throws IOException, URISyntaxException { + String html = new String(Files.readAllBytes( + (Paths.get(getClass().getResource("/xmlhtml/delhtmltags/example1.html").toURI())))); + String result = html.replaceAll("<[^>]*>", "") + .replaceAll("(?m)^\\s*$", ""); // remove empty and blank lines + System.out.println(result); + } + + @Test + void givenHtml2_whenRemoveTagsByRegex_thenPrintText() throws IOException, URISyntaxException { + String html = new String(Files.readAllBytes( + (Paths.get(getClass().getResource("/xmlhtml/delhtmltags/example2.html").toURI())))); + String result = html.replaceAll("<[^>]*>", ""); + System.out.println(result); + } + + @Test + void givenHtml2_whenRemoveTagsByJsoup_thenPrintText() throws IOException, URISyntaxException { + String html = new String(Files.readAllBytes( + (Paths.get(getClass().getResource("/xmlhtml/delhtmltags/example2.html").toURI())))); + System.out.println(Jsoup.parse(html).text()); + } + + @Test + void givenHtml2_whenRemoveTagsByHtmlCleaner_thenPrintText() throws IOException, URISyntaxException { + String html = new String(Files.readAllBytes( + (Paths.get(getClass().getResource("/xmlhtml/delhtmltags/example2.html").toURI())))); + CleanerProperties props = new CleanerProperties(); + props.setPruneTags("script"); + String result = new HtmlCleaner(props).clean(html).getText().toString(); + System.out.println(result); + } + + @Test + void givenHtml2_whenRemoveTagsByJericho_thenPrintText() throws IOException, URISyntaxException { + String html = new String(Files.readAllBytes( + (Paths.get(getClass().getResource("/xmlhtml/delhtmltags/example2.html").toURI())))); + Source htmlSource = new Source(html); + Segment segment = new Segment(htmlSource, 0, htmlSource.length()); + Renderer htmlRender = new Renderer(segment).setIncludeHyperlinkURLs(true); + System.out.println(htmlRender); + } +} diff --git a/xml/src/test/resources/xmlhtml/delhtmltags/example1.html b/xml/src/test/resources/xmlhtml/delhtmltags/example1.html new file mode 100644 index 0000000000..43f3a22ef4 --- /dev/null +++ b/xml/src/test/resources/xmlhtml/delhtmltags/example1.html @@ -0,0 +1,15 @@ + + + + This is the page title + + +

+ If the application X doesn't start, the possible causes could be:
+ 1. Maven is not installed.
+ 2. Not enough disk space.
+ 3. Not enough memory. +

+ + \ No newline at end of file diff --git a/xml/src/test/resources/xmlhtml/delhtmltags/example2.html b/xml/src/test/resources/xmlhtml/delhtmltags/example2.html new file mode 100644 index 0000000000..532eadc101 --- /dev/null +++ b/xml/src/test/resources/xmlhtml/delhtmltags/example2.html @@ -0,0 +1,22 @@ + + + + This is the page title + + + +

+ If the application X doesn't start, the possible causes could be:
+ 1. + Maven + is not installed.
+ 2. Not enough (<1G) disk space.
+ 3. Not enough (<64MB) memory.
+

+ + \ No newline at end of file