diff --git a/core-java-modules/core-java-14/pom.xml b/core-java-modules/core-java-14/pom.xml
index 35ea0bd2d0..f78edd622a 100644
--- a/core-java-modules/core-java-14/pom.xml
+++ b/core-java-modules/core-java-14/pom.xml
@@ -14,6 +14,15 @@
1.0.0-SNAPSHOT
+
+
+ org.projectlombok
+ lombok
+ 1.18.24
+ provided
+
+
+
diff --git a/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/ColorData.java b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/ColorData.java
new file mode 100644
index 0000000000..6d50c63ba5
--- /dev/null
+++ b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/ColorData.java
@@ -0,0 +1,18 @@
+package com.baeldung.java14.recordvslombok;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class ColorData {
+
+ private int red;
+ private int green;
+ private int blue;
+
+ public String getHexString() {
+ return String.format("#%02X%02X%02X", red, green, blue);
+ }
+
+}
diff --git a/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/ColorRecord.java b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/ColorRecord.java
new file mode 100644
index 0000000000..03d1f5c264
--- /dev/null
+++ b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/ColorRecord.java
@@ -0,0 +1,8 @@
+package com.baeldung.java14.recordvslombok;
+
+public record ColorRecord(int red, int green, int blue) {
+
+ public String getHexString() {
+ return String.format("#%02X%02X%02X", red, green, blue);
+ }
+}
diff --git a/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/ColorValueObject.java b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/ColorValueObject.java
new file mode 100644
index 0000000000..eca33662c2
--- /dev/null
+++ b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/ColorValueObject.java
@@ -0,0 +1,17 @@
+package com.baeldung.java14.recordvslombok;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Value;
+
+@Value
+@Getter(AccessLevel.NONE)
+public class ColorValueObject {
+ int red;
+ int green;
+ int blue;
+
+ public String getHexString() {
+ return String.format("#%02X%02X%02X", red, green, blue);
+ }
+}
diff --git a/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/MonochromeColor.java b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/MonochromeColor.java
new file mode 100644
index 0000000000..6672cb49ea
--- /dev/null
+++ b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/MonochromeColor.java
@@ -0,0 +1,12 @@
+package com.baeldung.java14.recordvslombok;
+
+import lombok.Value;
+
+@Value
+public class MonochromeColor extends ColorData {
+
+ public MonochromeColor(int grayScale) {
+ super(grayScale, grayScale, grayScale);
+ }
+
+}
diff --git a/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/StudentBuilder.java b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/StudentBuilder.java
new file mode 100644
index 0000000000..318634788e
--- /dev/null
+++ b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/StudentBuilder.java
@@ -0,0 +1,17 @@
+package com.baeldung.java14.recordvslombok;
+
+import lombok.Builder;
+import lombok.Getter;
+
+@Getter
+@Builder
+public class StudentBuilder {
+ private String firstName;
+ private String lastName;
+ private Long studentId;
+ private String email;
+ private String phoneNumber;
+ private String address;
+ private String country;
+ private int age;
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/StudentRecord.java b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/StudentRecord.java
new file mode 100644
index 0000000000..2d51fadd12
--- /dev/null
+++ b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/recordvslombok/StudentRecord.java
@@ -0,0 +1,4 @@
+package com.baeldung.java14.recordvslombok;
+
+public record StudentRecord(String firstName, String lastName, Long studentId, String email, String phoneNumber, String address, String country, int age) {
+}
diff --git a/core-java-modules/core-java-14/src/test/java/com/baeldung/java14/recordvslombok/RecordVsLombokUntTest.java b/core-java-modules/core-java-14/src/test/java/com/baeldung/java14/recordvslombok/RecordVsLombokUntTest.java
new file mode 100644
index 0000000000..1cca13133f
--- /dev/null
+++ b/core-java-modules/core-java-14/src/test/java/com/baeldung/java14/recordvslombok/RecordVsLombokUntTest.java
@@ -0,0 +1,43 @@
+package com.baeldung.java14.recordvslombok;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+public class RecordVsLombokUntTest {
+
+ @Test
+ public void givenAColorRecord_hexStringIsCorrect() {
+ var red = new ColorRecord(255, 0, 0);
+
+ assertThat(red.getHexString()).isEqualTo("#FF0000");
+ }
+
+ @Test
+ public void givenAColorValueObject_hexStringIsCorrect() {
+ var red = new ColorValueObject(255, 0, 0);
+
+ assertThat(red.getHexString()).isEqualTo("#FF0000");
+ }
+
+ @Test
+ public void givenRecordWithManyAttributes_firstNameShouldBeJohn() {
+ StudentRecord john = new StudentRecord("John", "Doe", null, "john@doe.com", null, null, "England", 20);
+
+ assertThat(john.firstName()).isEqualTo("John");
+ }
+
+ @Test
+ public void givenBuilderWithManyAttributes_firstNameShouldBeJohn() {
+ StudentBuilder john = StudentBuilder.builder()
+ .firstName("John")
+ .lastName("Doe")
+ .email("john@doe.com")
+ .country("England")
+ .age(20)
+ .build();
+
+ assertThat(john.getFirstName()).isEqualTo("John");
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-15/README.md b/core-java-modules/core-java-15/README.md
index 4b163fcfb5..6c4fcff419 100644
--- a/core-java-modules/core-java-15/README.md
+++ b/core-java-modules/core-java-15/README.md
@@ -5,4 +5,3 @@ This module contains articles about Java 15.
### Relevant articles
- [Hidden Classes in Java 15](https://www.baeldung.com/java-hidden-classes)
-- [Sealed Classes and Interfaces in Java 15](https://www.baeldung.com/java-sealed-classes-interfaces)
diff --git a/core-java-modules/core-java-17/README.md b/core-java-modules/core-java-17/README.md
index 1f061bd7c1..d77a487932 100644
--- a/core-java-modules/core-java-17/README.md
+++ b/core-java-modules/core-java-17/README.md
@@ -5,3 +5,4 @@
- [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)
- [Random Number Generators in Java 17](https://www.baeldung.com/java-17-random-number-generators)
+- [Sealed Classes and Interfaces in Java 17](https://www.baeldung.com/java-sealed-classes-interfaces)
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/alternative/Vehicles.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/alternative/Vehicles.java
similarity index 100%
rename from core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/alternative/Vehicles.java
rename to core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/alternative/Vehicles.java
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Car.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/classes/Car.java
similarity index 100%
rename from core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Car.java
rename to core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/classes/Car.java
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Service.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/classes/Service.java
similarity index 100%
rename from core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Service.java
rename to core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/classes/Service.java
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Truck.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/classes/Truck.java
similarity index 100%
rename from core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Truck.java
rename to core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/classes/Truck.java
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Vehicle.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/classes/Vehicle.java
similarity index 100%
rename from core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/classes/Vehicle.java
rename to core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/classes/Vehicle.java
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Car.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/records/Car.java
similarity index 100%
rename from core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Car.java
rename to core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/records/Car.java
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Truck.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/records/Truck.java
similarity index 100%
rename from core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Truck.java
rename to core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/records/Truck.java
diff --git a/core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Vehicle.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/records/Vehicle.java
similarity index 100%
rename from core-java-modules/core-java-15/src/main/java/com/baeldung/sealed/records/Vehicle.java
rename to core-java-modules/core-java-17/src/main/java/com/baeldung/sealed/records/Vehicle.java
diff --git a/core-java-modules/core-java-15/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java
similarity index 93%
rename from core-java-modules/core-java-15/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java
rename to core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java
index b614981a43..73d8aad810 100644
--- a/core-java-modules/core-java-15/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java
+++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java
@@ -21,7 +21,7 @@ public class VehicleUnitTest {
public void givenCar_whenUsingReflectionAPI_thenSuperClassIsSealed() {
Assertions.assertThat(car.getClass().isSealed()).isEqualTo(false);
Assertions.assertThat(car.getClass().getSuperclass().isSealed()).isEqualTo(true);
- Assertions.assertThat(car.getClass().getSuperclass().permittedSubclasses())
+ Assertions.assertThat(car.getClass().getSuperclass().getPermittedSubclasses())
.contains(ClassDesc.of(car.getClass().getCanonicalName()));
}
@@ -29,7 +29,7 @@ public class VehicleUnitTest {
public void givenTruck_whenUsingReflectionAPI_thenSuperClassIsSealed() {
Assertions.assertThat(truck.getClass().isSealed()).isEqualTo(false);
Assertions.assertThat(truck.getClass().getSuperclass().isSealed()).isEqualTo(true);
- Assertions.assertThat(truck.getClass().getSuperclass().permittedSubclasses())
+ Assertions.assertThat(truck.getClass().getSuperclass().getPermittedSubclasses())
.contains(ClassDesc.of(truck.getClass().getCanonicalName()));
}
diff --git a/core-java-modules/core-java-15/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-15/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java
rename to core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java
diff --git a/core-java-modules/core-java-function/README.md b/core-java-modules/core-java-function/README.md
index 677f148bdb..7fe6044835 100644
--- a/core-java-modules/core-java-function/README.md
+++ b/core-java-modules/core-java-function/README.md
@@ -3,4 +3,5 @@
## Core Java 8 Cookbooks and Examples
### Relevant Articles:
-- [Java 8 Predicate Chain](https://www.baeldung.com/java-predicate-chain)
\ No newline at end of file
+- [Java 8 Predicate Chain](https://www.baeldung.com/java-predicate-chain)
+- [Use Cases for Static Methods in Java](https://www.baeldung.com/java-static-methods-use-cases)
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 9abb539066..c83a3fb1d7 100644
--- a/core-java-modules/core-java-io-conversions-2/README.md
+++ b/core-java-modules/core-java-io-conversions-2/README.md
@@ -9,4 +9,5 @@ This module contains articles about core Java input/output(IO) conversions.
- [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)
- [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv)
+- [How to Convert InputStream to Base64 String](https://www.baeldung.com/java-inputstream-to-base64-string)
- More articles: [[<-- prev]](/core-java-modules/core-java-io-conversions)
diff --git a/core-java-modules/core-java-jar/src/main/java/com/baeldung/jar/MySampleGUIAppn.java b/core-java-modules/core-java-jar/src/main/java/com/baeldung/jar/MySampleGUIAppn.java
new file mode 100644
index 0000000000..86d52eed56
--- /dev/null
+++ b/core-java-modules/core-java-jar/src/main/java/com/baeldung/jar/MySampleGUIAppn.java
@@ -0,0 +1,31 @@
+package com.baeldung.jar;
+
+import java.awt.event.*;
+import java.awt.*;
+
+import javax.swing.*;
+
+public class MySampleGUIAppn extends JFrame {
+ public MySampleGUIAppn() {
+ if (!GraphicsEnvironment.isHeadless()) {
+ setSize(300,300);
+ setTitle("MySampleGUIAppn");
+ Button b = new Button("Click Me!");
+ b.setBounds(30,100,80,30);
+ add(b);
+ setVisible(true);
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ dispose();
+ System.exit(0);
+ }
+ });
+ }
+ else {
+ System.exit(0);
+ }
+ }
+ public static void main(String[] args) {
+ MySampleGUIAppn app=new MySampleGUIAppn();
+ }
+}
diff --git a/core-java-modules/core-java-jar/src/test/java/com/baeldung/jar/MySampleGUIAppnUnitTest.java b/core-java-modules/core-java-jar/src/test/java/com/baeldung/jar/MySampleGUIAppnUnitTest.java
new file mode 100644
index 0000000000..106531008c
--- /dev/null
+++ b/core-java-modules/core-java-jar/src/test/java/com/baeldung/jar/MySampleGUIAppnUnitTest.java
@@ -0,0 +1,15 @@
+package com.baeldung.jar;
+
+import java.io.IOException;
+
+import org.junit.jupiter.api.Test;
+
+class MySampleGUIAppnUnitTest {
+ @Test
+ void testMain() throws IOException {
+ System.setProperty("java.awt.headless", "true");
+ String [] args = null;
+ System.exit(0);
+ MySampleGUIAppn.main(args);
+ }
+}
\ 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 c5e2a75f25..474d0c8a22 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
@@ -6,3 +6,4 @@ This module contains articles about types in Java
- [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-search-enum-values)
+- [Generate a Random Value From an Enum](https://www.baeldung.com/java-enum-random-value)
diff --git a/core-java-modules/core-java-numbers-4/README.md b/core-java-modules/core-java-numbers-4/README.md
index 697d791b82..f8cc655f55 100644
--- a/core-java-modules/core-java-numbers-4/README.md
+++ b/core-java-modules/core-java-numbers-4/README.md
@@ -7,7 +7,6 @@
- [Automorphic Numbers in Java](https://www.baeldung.com/java-automorphic-numbers)
- [Convert Byte Size Into a Human-Readable Format in Java](https://www.baeldung.com/java-human-readable-byte-size)
- [Convert boolean to int in Java](https://www.baeldung.com/java-boolean-to-int)
-- [Generate a Random Value From an Enum](https://www.baeldung.com/java-enum-random-value)
- [Reverse a Number in Java](https://www.baeldung.com/java-reverse-number)
- [Check if BigDecimal Value Is Zero](https://www.baeldung.com/java-bigdecimal-zero)
- More articles: [[<-- prev]](../core-java-numbers-3) [[next -->]](../core-java-numbers-5)
\ No newline at end of file
diff --git a/core-java-modules/core-java-streams-4/README.md b/core-java-modules/core-java-streams-4/README.md
index 6eeee943aa..86b293566a 100644
--- a/core-java-modules/core-java-streams-4/README.md
+++ b/core-java-modules/core-java-streams-4/README.md
@@ -1,3 +1,4 @@
## Relevant Articles:
- [Count Occurrences Using Java groupingBy Collector](https://www.baeldung.com/java-groupingby-count)
+- [How to Split a Stream into Multiple Streams](https://www.baeldung.com/java-split-stream)
diff --git a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/truncate/TruncateString.java b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/truncate/TruncateString.java
new file mode 100644
index 0000000000..788a180f19
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/truncate/TruncateString.java
@@ -0,0 +1,105 @@
+package com.baeldung.truncate;
+
+import java.util.Optional;
+import java.util.regex.MatchResult;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.common.base.Splitter;
+
+public class TruncateString {
+
+ private static final String EMPTY = "";
+
+ public static String usingSubstringMethod(String text, int length) {
+ if (length < 0) {
+ throw new IllegalArgumentException("length cannot be negative");
+ }
+
+ if (text == null) {
+ return EMPTY;
+ }
+
+ if (text.length() <= length) {
+ return text;
+ } else {
+ return text.substring(0, length);
+ }
+ }
+
+ public static String usingSplitMethod(String text, int length) {
+ if (length < 0) {
+ throw new IllegalArgumentException("length cannot be negative");
+ }
+
+ if (text == null) {
+ return EMPTY;
+ }
+
+ String[] results = text.split("(?<=\\G.{" + length + "})");
+
+ return results[0];
+ }
+
+ public static String usingPattern(String text, int length) {
+ if (length < 0) {
+ throw new IllegalArgumentException("length cannot be negative");
+ }
+
+ if (text == null) {
+ return EMPTY;
+ }
+
+ Optional result = Pattern.compile(".{1," + length + "}")
+ .matcher(text)
+ .results()
+ .map(MatchResult::group)
+ .findFirst();
+
+ return result.isPresent() ? result.get() : EMPTY;
+
+ }
+
+ public static String usingCodePointsMethod(String text, int length) {
+ if (length < 0) {
+ throw new IllegalArgumentException("length cannot be negative");
+ }
+
+ if (text == null) {
+ return EMPTY;
+ }
+
+ return text.codePoints()
+ .limit(length)
+ .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
+ .toString();
+ }
+
+ public static String usingLeftMethod(String text, int length) {
+
+ return StringUtils.left(text, length);
+ }
+
+ public static String usingTruncateMethod(String text, int length) {
+
+ return StringUtils.truncate(text, length);
+ }
+
+ public static String usingSplitter(String text, int length) {
+ if (length < 0) {
+ throw new IllegalArgumentException("length cannot be negative");
+ }
+
+ if (text == null) {
+ return EMPTY;
+ }
+
+ Iterable parts = Splitter.fixedLength(length)
+ .split(text);
+
+ return parts.iterator()
+ .next();
+ }
+
+}
diff --git a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/truncate/TruncateStringUnitTest.java b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/truncate/TruncateStringUnitTest.java
new file mode 100644
index 0000000000..fd44e37546
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/truncate/TruncateStringUnitTest.java
@@ -0,0 +1,53 @@
+package com.baeldung.truncate;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class TruncateStringUnitTest {
+
+ private static final String TEXT = "Welcome to baeldung.com";
+
+ @Test
+ public void givenStringAndLength_whenUsingSubstringMethod_thenTruncate() {
+
+ assertEquals(TruncateString.usingSubstringMethod(TEXT, 10), "Welcome to");
+ }
+
+ @Test
+ public void givenStringAndLength_whenUsingSplitMethod_thenTruncate() {
+
+ assertEquals(TruncateString.usingSplitMethod(TEXT, 13), "Welcome to ba");
+ }
+
+ @Test
+ public void givenStringAndLength_whenUsingPattern_thenTruncate() {
+
+ assertEquals(TruncateString.usingPattern(TEXT, 19), "Welcome to baeldung");
+ }
+
+ @Test
+ public void givenStringAndLength_whenUsingCodePointsMethod_thenTruncate() {
+
+ assertEquals(TruncateString.usingCodePointsMethod(TEXT, 6), "Welcom");
+ }
+
+ @Test
+ public void givenStringAndLength_whenUsingLeftMethod_thenTruncate() {
+
+ assertEquals(TruncateString.usingLeftMethod(TEXT, 15), "Welcome to bael");
+ }
+
+ @Test
+ public void givenStringAndLength_whenUsingTruncateMethod_thenTruncate() {
+
+ assertEquals(TruncateString.usingTruncateMethod(TEXT, 20), "Welcome to baeldung.");
+ }
+
+ @Test
+ public void givenStringAndLength_whenUsingSplitter_thenTruncate() {
+
+ assertEquals(TruncateString.usingSplitter(TEXT, 3), "Wel");
+ }
+
+}
diff --git a/docker-modules/docker-environment-variables/README.md b/docker-modules/docker-environment-variables/README.md
new file mode 100644
index 0000000000..12da2931a3
--- /dev/null
+++ b/docker-modules/docker-environment-variables/README.md
@@ -0,0 +1,3 @@
+
+## Relevant Articles:
+- [How to Pass Environment Variable Value into Dockerfile](https://www.baeldung.com/ops/dockerfile-env-variable)
diff --git a/docker-modules/docker-java-jar/Dockerfile b/docker-modules/docker-java-jar/Dockerfile
new file mode 100644
index 0000000000..bc26e031c3
--- /dev/null
+++ b/docker-modules/docker-java-jar/Dockerfile
@@ -0,0 +1,4 @@
+FROM openjdk:11
+MAINTAINER baeldung.com
+COPY target/docker-java-jar-0.0.1-SNAPSHOT.jar app.jar
+ENTRYPOINT ["java","-jar","/app.jar"]
diff --git a/docker-modules/docker-java-jar/pom.xml b/docker-modules/docker-java-jar/pom.xml
new file mode 100644
index 0000000000..0ca0146ac0
--- /dev/null
+++ b/docker-modules/docker-java-jar/pom.xml
@@ -0,0 +1,37 @@
+
+
+
+ com.baeldung
+ parent-boot-2
+ 0.0.1-SNAPSHOT
+ ../../parent-boot-2
+
+ 4.0.0
+
+ docker-java-jar
+
+
+ 11
+ 11
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${maven-jar-plugin.version}
+
+
+
+ com.baeldung.HelloWorld
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docker-modules/docker-java-jar/src/main/java/com/baeldung/HelloWorld.java b/docker-modules/docker-java-jar/src/main/java/com/baeldung/HelloWorld.java
new file mode 100644
index 0000000000..50e0044c48
--- /dev/null
+++ b/docker-modules/docker-java-jar/src/main/java/com/baeldung/HelloWorld.java
@@ -0,0 +1,8 @@
+package com.baeldung;
+
+public class HelloWorld {
+
+ public static void main(String[] args){
+ System.out.println("Welcome to our application");
+ }
+}
diff --git a/docker-modules/pom.xml b/docker-modules/pom.xml
index f2b8f059a1..d80e5341b0 100644
--- a/docker-modules/pom.xml
+++ b/docker-modules/pom.xml
@@ -23,6 +23,7 @@
docker-images
docker-spring-boot
docker-spring-boot-postgres
+ docker-java-jar
diff --git a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/Application.java b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/Application.java
index ee819b844b..cee73f674e 100644
--- a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/Application.java
+++ b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/Application.java
@@ -1,5 +1,6 @@
package com.baeldung.libraries.opencsv;
+import com.baeldung.libraries.opencsv.beans.CsvBean;
import com.baeldung.libraries.opencsv.beans.NamedColumnBean;
import com.baeldung.libraries.opencsv.beans.SimplePositionBean;
import com.baeldung.libraries.opencsv.examples.sync.BeanExamples;
@@ -7,102 +8,60 @@ import com.baeldung.libraries.opencsv.examples.sync.CsvReaderExamples;
import com.baeldung.libraries.opencsv.examples.sync.CsvWriterExamples;
import com.baeldung.libraries.opencsv.helpers.Helpers;
-import java.io.Reader;
-import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.List;
public class Application {
- /*
- * Bean Examples.
- */
-
- public static String simpleSyncPositionBeanExample() {
- Path path = null;
- try {
- path = Helpers.twoColumnCsvPath();
- } catch (Exception ex) {
- Helpers.err(ex);
- }
- return BeanExamples.beanBuilderExample(path, SimplePositionBean.class).toString();
+ // CSV Reader Examples
+ public static List readLineByLineSyncExample() throws Exception {
+ Path path = Helpers.twoColumnCsvPath();
+ return CsvReaderExamples.readLineByLine(path);
}
- public static String namedSyncColumnBeanExample() {
- Path path = null;
- try {
- path = Helpers.namedColumnCsvPath();
- } catch (Exception ex) {
- Helpers.err(ex);
- }
- return BeanExamples.beanBuilderExample(path, NamedColumnBean.class).toString();
+ public static List readAllLinesSyncExample() throws Exception {
+ Path path = Helpers.twoColumnCsvPath();
+ return CsvReaderExamples.readAllLines(path);
}
- public static String writeSyncCsvFromBeanExample() {
- Path path = null;
- try {
- path = Helpers.fileOutBeanPath();
- } catch (Exception ex) {
- Helpers.err(ex);
- }
+ // CSV Writer Examples
+ public static String writeLineByLineSyncExample() throws Exception {
+ Path path = Helpers.fileOutOnePath();
+ return CsvWriterExamples.writeLineByLine(Helpers.fourColumnCsvString(), path);
+ }
+
+ public static String writeAllLinesSyncExample() throws Exception {
+ Path path = Helpers.fileOutAllPath();
+ return CsvWriterExamples.writeAllLines(Helpers.fourColumnCsvString(), path);
+ }
+
+ // Bean Examples
+ public static List simpleSyncPositionBeanExample() throws Exception {
+ Path path = Helpers.twoColumnCsvPath();
+ return BeanExamples.beanBuilderExample(path, SimplePositionBean.class);
+ }
+
+ public static List namedSyncColumnBeanExample() throws Exception {
+ Path path = Helpers.namedColumnCsvPath();
+ return BeanExamples.beanBuilderExample(path, NamedColumnBean.class);
+ }
+
+ public static String writeSyncCsvFromBeanExample() throws Exception {
+ Path path = Helpers.fileOutBeanPath();
return BeanExamples.writeCsvFromBean(path);
}
- /*
- * CSV Reader Examples.
- */
-
- public static String oneByOneSyncExample() {
- Reader reader = null;
- try {
- reader = Files.newBufferedReader(Helpers.twoColumnCsvPath());
- } catch (Exception ex) {
- Helpers.err(ex);
- }
- return CsvReaderExamples.oneByOne(reader).toString();
- }
-
- public static String readAllSyncExample() {
- Reader reader = null;
- try {
- reader = Files.newBufferedReader(Helpers.twoColumnCsvPath());
- } catch (Exception ex) {
- Helpers.err(ex);
- }
- return CsvReaderExamples.readAll(reader).toString();
- }
-
- /*
- * CSV Writer Examples.
- */
-
-
- public static String csvWriterSyncOneByOne() {
- Path path = null;
- try {
- path = Helpers.fileOutOnePath();
- } catch (Exception ex) {
- Helpers.err(ex);
- }
- return CsvWriterExamples.csvWriterOneByOne(Helpers.fourColumnCsvString(), path);
- }
-
- public static String csvWriterSyncAll() {
- Path path = null;
- try {
- path = Helpers.fileOutAllPath();
- } catch (Exception ex) {
- Helpers.err(ex);
- }
- return CsvWriterExamples.csvWriterAll(Helpers.fourColumnCsvString(), path);
- }
-
public static void main(String[] args) {
- simpleSyncPositionBeanExample();
- namedSyncColumnBeanExample();
- writeSyncCsvFromBeanExample();
- oneByOneSyncExample();
- readAllSyncExample();
- csvWriterSyncOneByOne();
- csvWriterSyncAll();
+ try {
+ simpleSyncPositionBeanExample();
+ namedSyncColumnBeanExample();
+ writeSyncCsvFromBeanExample();
+ readLineByLineSyncExample();
+ readAllLinesSyncExample();
+ writeLineByLineSyncExample();
+ writeAllLinesSyncExample();
+ } catch (Exception e) {
+ throw new RuntimeException("Error during csv processing", e);
+ }
}
}
diff --git a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/beans/NamedColumnBean.java b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/beans/NamedColumnBean.java
index 0021584e4f..f8c6537d3a 100644
--- a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/beans/NamedColumnBean.java
+++ b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/beans/NamedColumnBean.java
@@ -27,5 +27,10 @@ public class NamedColumnBean extends CsvBean {
this.age = age;
}
+ @Override
+ public String toString() {
+ return name + ',' + age;
+ }
+
}
diff --git a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/beans/SimplePositionBean.java b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/beans/SimplePositionBean.java
index c1710d784a..2306ccc560 100644
--- a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/beans/SimplePositionBean.java
+++ b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/beans/SimplePositionBean.java
@@ -26,4 +26,8 @@ public class SimplePositionBean extends CsvBean {
this.exampleColTwo = exampleColTwo;
}
+ @Override
+ public String toString() {
+ return exampleColOne + ',' + exampleColTwo;
+ }
}
diff --git a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/beans/WriteExampleBean.java b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/beans/WriteExampleBean.java
index f5e6466512..62b14dc321 100644
--- a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/beans/WriteExampleBean.java
+++ b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/beans/WriteExampleBean.java
@@ -37,4 +37,9 @@ public class WriteExampleBean extends CsvBean {
public void setColC(String colC) {
this.colC = colC;
}
+
+ @Override
+ public String toString() {
+ return colA + ',' + colB + "," + colC;
+ }
}
diff --git a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/examples/sync/BeanExamples.java b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/examples/sync/BeanExamples.java
index f401c7c77c..b2a00be0ee 100644
--- a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/examples/sync/BeanExamples.java
+++ b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/examples/sync/BeanExamples.java
@@ -4,60 +4,49 @@ import com.baeldung.libraries.opencsv.beans.CsvBean;
import com.baeldung.libraries.opencsv.beans.WriteExampleBean;
import com.baeldung.libraries.opencsv.helpers.Helpers;
import com.baeldung.libraries.opencsv.pojos.CsvTransfer;
-import com.opencsv.CSVWriter;
-import com.opencsv.bean.*;
+import com.opencsv.bean.CsvToBean;
+import com.opencsv.bean.CsvToBeanBuilder;
+import com.opencsv.bean.StatefulBeanToCsv;
+import com.opencsv.bean.StatefulBeanToCsvBuilder;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
public class BeanExamples {
- public static List beanBuilderExample(Path path, Class clazz) {
- ColumnPositionMappingStrategy ms = new ColumnPositionMappingStrategy();
- return beanBuilderExample(path, clazz, ms);
- }
-
- public static List beanBuilderExample(Path path, Class clazz, MappingStrategy ms) {
+ public static List beanBuilderExample(Path path, Class extends CsvBean> clazz) throws Exception {
CsvTransfer csvTransfer = new CsvTransfer();
- try {
- ms.setType(clazz);
-
- Reader reader = Files.newBufferedReader(path);
- CsvToBean cb = new CsvToBeanBuilder(reader).withType(clazz)
- .withMappingStrategy(ms)
- .build();
+ try (Reader reader = Files.newBufferedReader(path)) {
+ CsvToBean cb = new CsvToBeanBuilder(reader)
+ .withType(clazz)
+ .build();
csvTransfer.setCsvList(cb.parse());
- reader.close();
-
- } catch (Exception ex) {
- Helpers.err(ex);
}
+
return csvTransfer.getCsvList();
}
- public static String writeCsvFromBean(Path path) {
- try {
- Writer writer = new FileWriter(path.toString());
+ public static String writeCsvFromBean(Path path) throws Exception {
- StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(writer).withSeparator(CSVWriter.DEFAULT_SEPARATOR)
- .build();
+ List sampleData = Arrays.asList(
+ new WriteExampleBean("Test1", "sample", "data"),
+ new WriteExampleBean("Test2", "ipso", "facto")
+ );
- List list = new ArrayList<>();
- list.add(new WriteExampleBean("Test1", "sfdsf", "fdfd"));
- list.add(new WriteExampleBean("Test2", "ipso", "facto"));
+ try (Writer writer = new FileWriter(path.toString())) {
+ StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(writer)
+ .withQuotechar('\'')
+ .build();
- sbc.write(list);
- writer.close();
-
- } catch (Exception ex) {
- Helpers.err(ex);
+ sbc.write(sampleData);
}
+
return Helpers.readFile(path);
}
}
\ No newline at end of file
diff --git a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/examples/sync/CsvReaderExamples.java b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/examples/sync/CsvReaderExamples.java
index 2f7d979b2f..2bafe0d764 100644
--- a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/examples/sync/CsvReaderExamples.java
+++ b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/examples/sync/CsvReaderExamples.java
@@ -1,61 +1,58 @@
package com.baeldung.libraries.opencsv.examples.sync;
-import com.baeldung.libraries.opencsv.helpers.Helpers;
import com.opencsv.CSVParser;
import com.opencsv.CSVParserBuilder;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import java.io.Reader;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
public class CsvReaderExamples {
- public static List readAll(Reader reader) {
+ public static List readAllLines(Path filePath) throws Exception {
CSVParser parser = new CSVParserBuilder()
- .withSeparator(',')
- .withIgnoreQuotations(true)
- .build();
+ .withSeparator(',')
+ .withIgnoreQuotations(true)
+ .build();
- CSVReader csvReader = new CSVReaderBuilder(reader)
- .withSkipLines(0)
- .withCSVParser(parser)
- .build();
+ try (Reader reader = Files.newBufferedReader(filePath)) {
+ CSVReaderBuilder csvReaderBuilder = new CSVReaderBuilder(reader)
+ .withSkipLines(0)
+ .withCSVParser(parser);
- List list = new ArrayList<>();
- try {
- list = csvReader.readAll();
- reader.close();
- csvReader.close();
- } catch (Exception ex) {
- Helpers.err(ex);
+ try (CSVReader csvReader = csvReaderBuilder.build()) {
+ return csvReader.readAll();
+ }
}
- return list;
+
}
- public static List oneByOne(Reader reader) {
+ public static List readLineByLine(Path filePath) throws Exception {
List list = new ArrayList<>();
- try {
- CSVParser parser = new CSVParserBuilder()
- .withSeparator(',')
- .withIgnoreQuotations(true)
- .build();
- CSVReader csvReader = new CSVReaderBuilder(reader)
- .withSkipLines(0)
- .withCSVParser(parser)
- .build();
+ CSVParser parser = new CSVParserBuilder()
+ .withSeparator(',')
+ .withIgnoreQuotations(true)
+ .build();
- String[] line;
- while ((line = csvReader.readNext()) != null) {
- list.add(line);
+ try (Reader reader = Files.newBufferedReader(filePath)) {
+
+ CSVReaderBuilder csvReaderBuilder = new CSVReaderBuilder(reader)
+ .withSkipLines(0)
+ .withCSVParser(parser);
+
+ try (CSVReader csvReader = csvReaderBuilder.build()) {
+ String[] line;
+ while ((line = csvReader.readNext()) != null) {
+ list.add(line);
+ }
}
- reader.close();
- csvReader.close();
- } catch (Exception ex) {
- Helpers.err(ex);
+
}
return list;
}
diff --git a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/examples/sync/CsvWriterExamples.java b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/examples/sync/CsvWriterExamples.java
index b5c23bd99d..7f14b2547f 100644
--- a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/examples/sync/CsvWriterExamples.java
+++ b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/examples/sync/CsvWriterExamples.java
@@ -9,26 +9,21 @@ import java.util.List;
public class CsvWriterExamples {
- public static String csvWriterOneByOne(List stringArray, Path path) {
- try {
- CSVWriter writer = new CSVWriter(new FileWriter(path.toString()));
- for (String[] array : stringArray) {
- writer.writeNext(array);
+ public static String writeLineByLine(List lines, Path path) throws Exception {
+
+ try (CSVWriter writer = new CSVWriter(new FileWriter(path.toString()))) {
+ for (String[] line : lines) {
+ writer.writeNext(line);
}
- writer.close();
- } catch (Exception ex) {
- Helpers.err(ex);
}
+
return Helpers.readFile(path);
}
- public static String csvWriterAll(List stringArray, Path path) {
- try {
- CSVWriter writer = new CSVWriter(new FileWriter(path.toString()));
- writer.writeAll(stringArray);
- writer.close();
- } catch (Exception ex) {
- Helpers.err(ex);
+ public static String writeAllLines(List lines, Path path) throws Exception {
+
+ try (CSVWriter writer = new CSVWriter(new FileWriter(path.toString()))) {
+ writer.writeAll(lines);
}
return Helpers.readFile(path);
}
diff --git a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/helpers/Helpers.java b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/helpers/Helpers.java
index b703d0e82d..fd9e0ba386 100644
--- a/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/helpers/Helpers.java
+++ b/libraries-data-io/src/main/java/com/baeldung/libraries/opencsv/helpers/Helpers.java
@@ -1,9 +1,9 @@
package com.baeldung.libraries.opencsv.helpers;
import com.baeldung.libraries.opencsv.Constants;
+import org.apache.commons.io.IOUtils;
-import java.io.BufferedReader;
-import java.io.FileReader;
+import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
@@ -13,9 +13,7 @@ import java.util.List;
public class Helpers {
- /**
- * Write Files
- */
+ // Write Files
public static Path fileOutAllPath() throws URISyntaxException {
URI uri = ClassLoader.getSystemResource(Constants.CSV_All).toURI();
@@ -32,9 +30,7 @@ public class Helpers {
return Paths.get(uri);
}
- /**
- * Read Files
- */
+ // Read Files
public static Path twoColumnCsvPath() throws URISyntaxException {
URI uri = ClassLoader.getSystemResource(Constants.TWO_COLUMN_CSV).toURI();
@@ -51,33 +47,12 @@ public class Helpers {
return Paths.get(uri);
}
- /**
- * Simple File Reader
- */
-
- public static String readFile(Path path) {
- String response = "";
- try {
- FileReader fr = new FileReader(path.toString());
- BufferedReader br = new BufferedReader(fr);
- String strLine;
- StringBuffer sb = new StringBuffer();
- while ((strLine = br.readLine()) != null) {
- sb.append(strLine);
- }
- response = sb.toString();
- System.out.println(response);
- fr.close();
- br.close();
- } catch (Exception ex) {
- Helpers.err(ex);
- }
- return response;
+ public static String readFile(Path path) throws IOException {
+ return IOUtils.toString(path.toUri());
}
- /**
- * Dummy Data for Writing.
- */
+
+ // Dummy Data for Writing
public static List twoColumnCsvString() {
List list = new ArrayList<>();
@@ -94,15 +69,4 @@ public class Helpers {
return list;
}
- /**
- * Message Helpers
- */
-
- public static void print(String msg) {
- System.out.println(msg);
- }
-
- public static void err(Exception ex) {
- System.out.println(Constants.GENERIC_EXCEPTION + " " + ex);
- }
}
diff --git a/libraries-data-io/src/main/resources/csv/twoColumn.csv b/libraries-data-io/src/main/resources/csv/twoColumn.csv
index 56d8fa1901..527e15af72 100644
--- a/libraries-data-io/src/main/resources/csv/twoColumn.csv
+++ b/libraries-data-io/src/main/resources/csv/twoColumn.csv
@@ -1,5 +1,5 @@
-colA, ColB
-A, B
-C, D
-G, G
-G, F
\ No newline at end of file
+colA,colB
+A,B
+C,D
+G,G
+G,F
\ No newline at end of file
diff --git a/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java b/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java
index b0db4309d9..7cfe8984e7 100644
--- a/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java
+++ b/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java
@@ -1,66 +1,107 @@
package com.baeldung.libraries.opencsv;
-import com.baeldung.libraries.opencsv.helpers.Helpers;
-import org.junit.After;
-import org.junit.Before;
+import com.baeldung.libraries.opencsv.beans.CsvBean;
import org.junit.Test;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
public class OpenCsvIntegrationTest {
- private Object testReadCsv(Object result) {
- assert (result != null);
- assert (result instanceof String);
- assert (!((String) result).isEmpty());
- System.out.println(result);
- return result;
- }
+ private static final String NEW_LINE = System.lineSeparator();
- private Object testWriteCsv(Object result) {
- assert (result instanceof String);
- assert (!((String) result).isEmpty());
- return result;
- }
+ @Test
+ public void givenSampleData_whenReadUsingPosition_thenContentsRead() throws Exception {
+ List values = Application.simpleSyncPositionBeanExample();
- @Before
- public void setup() {
+ assertThat(values)
+ .extracting(Object::toString)
+ .containsExactly(
+ "colA,colB",
+ "A,B",
+ "C,D",
+ "G,G",
+ "G,F"
+ );
}
@Test
- public void positionExampleTest() {
- testReadCsv(Application.simpleSyncPositionBeanExample());
+ public void givenSampleData_whenReadUsingNamedColumn_thenContentsRead() throws Exception {
+ List values = Application.namedSyncColumnBeanExample();
+
+ assertThat(values)
+ .extracting(Object::toString)
+ .containsExactly(
+ "Joe,27",
+ "Jane,32",
+ "Bob,53"
+ );
}
@Test
- public void namedColumnExampleTest() {
- testReadCsv(Application.namedSyncColumnBeanExample());
+ public void givenSampleData_whenReadLineByLine_thenContentsRead() throws Exception {
+ List lineByLineContents = Application.readLineByLineSyncExample();
+
+ assertThat(lineByLineContents)
+ .containsExactly(
+ new String[] {"colA", "colB"},
+ new String[] {"A", "B"},
+ new String[] {"C", "D"},
+ new String[] {"G", "G"},
+ new String[] {"G", "F"}
+ );
}
@Test
- public void writeCsvUsingBeanBuilderTest() {
- testWriteCsv(Application.writeSyncCsvFromBeanExample());
+ public void givenSampleData_whenReadAllLines_thenContentsRead() throws Exception {
+
+ List contents = Application.readAllLinesSyncExample();
+
+ assertThat(contents)
+ .containsExactly(
+ new String[] {"colA", "colB"},
+ new String[] {"A", "B"},
+ new String[] {"C", "D"},
+ new String[] {"G", "G"},
+ new String[] {"G", "F"}
+ );
}
@Test
- public void oneByOneExampleTest() {
- testReadCsv(Application.oneByOneSyncExample());
+ public void givenSampleData_whenWriteCsvUsingBean_thenContentsWritten() throws Exception {
+ String contents = Application.writeSyncCsvFromBeanExample();
+
+ assertThat(contents.split(NEW_LINE))
+ .containsExactly(
+ "'colA','colB','colC'",
+ "'Test1','sample','data'",
+ "'Test2','ipso','facto'"
+ );
}
@Test
- public void readAllExampleTest() {
- testReadCsv(Application.readAllSyncExample());
+ public void givenSampleData_whenWriteCsvLineByLine_thenContentsWritten() throws Exception {
+ String contents = Application.writeLineByLineSyncExample();
+
+ assertThat(contents.split(NEW_LINE))
+ .containsExactly(
+ "\"ColA\",\"ColB\",\"ColC\",\"ColD\"",
+ "\"A\",\"B\",\"A\",\"B\"",
+ "\"BB\",\"AB\",\"AA\",\"B\""
+ );
}
@Test
- public void csvWriterOneByOneTest() {
- testWriteCsv(Application.csvWriterSyncOneByOne());
+ public void givenSampleData_whenWriteCsvAllLines_thenContentsWritten() throws Exception {
+ String contents = Application.writeAllLinesSyncExample();
+
+ assertThat(contents.split(NEW_LINE))
+ .containsExactly(
+ "\"ColA\",\"ColB\",\"ColC\",\"ColD\"",
+ "\"A\",\"B\",\"A\",\"B\"",
+ "\"BB\",\"AB\",\"AA\",\"B\""
+ );
}
- @Test
- public void csvWriterAllTest() {
- testWriteCsv(Application.csvWriterSyncAll());
- }
-
- @After
- public void close() {
- }
}
\ No newline at end of file
diff --git a/persistence-modules/java-mongodb-3/src/main/java/com/baeldung/mongo/find/FindWithObjectId.java b/persistence-modules/java-mongodb-3/src/main/java/com/baeldung/mongo/find/FindWithObjectId.java
new file mode 100644
index 0000000000..b82dcb6c5b
--- /dev/null
+++ b/persistence-modules/java-mongodb-3/src/main/java/com/baeldung/mongo/find/FindWithObjectId.java
@@ -0,0 +1,80 @@
+package com.baeldung.mongo.find;
+
+import com.mongodb.MongoClient;
+import com.mongodb.client.FindIterable;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoCursor;
+import com.mongodb.client.MongoDatabase;
+import org.bson.Document;
+import org.bson.types.ObjectId;
+
+import static com.mongodb.client.model.Filters.eq;
+
+public class FindWithObjectId {
+
+ private static final String OBJECT_ID_FIELD = "_id";
+
+ private static MongoClient mongoClient;
+ private static MongoDatabase database;
+ private static MongoCollection collection;
+ private static String collectionName;
+ private static String databaseName;
+
+ public static void setUp() {
+ if (mongoClient == null) {
+ mongoClient = new MongoClient("localhost", 27017);
+
+ databaseName = "baeldung";
+ collectionName = "employee";
+
+ database = mongoClient.getDatabase(databaseName);
+ collection = database.getCollection(collectionName);
+ }
+ }
+
+ public static void retrieveAllDocumentsUsingFindWithObjectId() {
+ Document document = collection.find()
+ .first();
+ System.out.println(document);
+
+ FindIterable documents = collection.find(eq(OBJECT_ID_FIELD, document.get(OBJECT_ID_FIELD)));
+
+ MongoCursor cursor = documents.iterator();
+ while (cursor.hasNext()) {
+ System.out.println(cursor.next());
+ }
+ }
+
+ public static void retrieveFirstDocumentWithObjectId() {
+ Document document = collection.find()
+ .first();
+ System.out.println(document);
+
+ FindIterable documents = collection.find(eq(OBJECT_ID_FIELD, document.get(OBJECT_ID_FIELD)));
+ Document queriedDocument = documents.first();
+
+ System.out.println(queriedDocument);
+ }
+
+ public static void retrieveDocumentWithRandomObjectId() {
+ FindIterable documents = collection.find(eq(OBJECT_ID_FIELD, new ObjectId()));
+ Document queriedDocument = documents.first();
+
+ if (queriedDocument != null) {
+ System.out.println(queriedDocument);
+ } else {
+ System.out.println("No documents found");
+ }
+ }
+
+ public static void main(String args[]) {
+
+ setUp();
+
+ retrieveAllDocumentsUsingFindWithObjectId();
+
+ retrieveFirstDocumentWithObjectId();
+
+ retrieveDocumentWithRandomObjectId();
+ }
+}
diff --git a/persistence-modules/java-mongodb-3/src/test/java/com/baeldung/mongo/find/FindWithObjectIdLiveTest.java b/persistence-modules/java-mongodb-3/src/test/java/com/baeldung/mongo/find/FindWithObjectIdLiveTest.java
new file mode 100644
index 0000000000..590758855c
--- /dev/null
+++ b/persistence-modules/java-mongodb-3/src/test/java/com/baeldung/mongo/find/FindWithObjectIdLiveTest.java
@@ -0,0 +1,87 @@
+package com.baeldung.mongo.find;
+
+import com.mongodb.MongoClient;
+import com.mongodb.client.FindIterable;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoCursor;
+import com.mongodb.client.MongoDatabase;
+import org.bson.Document;
+import org.bson.types.ObjectId;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import static com.mongodb.client.model.Filters.eq;
+import static org.junit.Assert.*;
+
+public class FindWithObjectIdLiveTest {
+
+ private static final String OBJECT_ID_FIELD = "_id";
+
+ private static MongoClient mongoClient;
+ private static MongoDatabase database;
+ private static MongoCollection collection;
+ private static final String DATASET_JSON = "/employee.json";
+
+ @BeforeClass
+ public static void setUp() throws IOException {
+ if (mongoClient == null) {
+ mongoClient = new MongoClient("localhost", 27017);
+
+ database = mongoClient.getDatabase("baeldung");
+ collection = database.getCollection("employee");
+
+ collection.drop();
+
+ InputStream is = FindOperationLiveTest.class.getResourceAsStream(DATASET_JSON);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ reader.lines()
+ .forEach(line -> collection.insertOne(Document.parse(line)));
+ reader.close();
+ }
+ }
+
+ @Test
+ public void givenEmployeeCollection_whenFetchingDocumentsUsingObjectId_thenCheckingForDocuments() {
+ Document employee = collection.find()
+ .first();
+ ObjectId objectId = (ObjectId) employee.get(OBJECT_ID_FIELD);
+
+ FindIterable documents = collection.find(eq(OBJECT_ID_FIELD, objectId));
+ MongoCursor cursor = documents.iterator();
+
+ assertNotNull(cursor);
+ assertTrue(cursor.hasNext());
+ }
+
+ @Test
+ public void givenEmployeeCollection_whenFetchingFirstDocumentUsingObjectId_thenCheckingForDocument() {
+ Document employee = collection.find()
+ .first();
+ ObjectId objectId = (ObjectId) employee.get(OBJECT_ID_FIELD);
+
+ Document queriedEmployee = collection.find(eq(OBJECT_ID_FIELD, objectId))
+ .first();
+
+ assertNotNull(queriedEmployee);
+ assertEquals(employee.get(OBJECT_ID_FIELD), queriedEmployee.get(OBJECT_ID_FIELD));
+ }
+
+ @Test
+ public void givenEmployeeCollection_whenFetchingUsingRandomObjectId_thenCheckingForDocument() {
+ Document employee = collection.find(eq(OBJECT_ID_FIELD, new ObjectId()))
+ .first();
+
+ assertNull(employee);
+ }
+
+ @AfterClass
+ public static void cleanUp() {
+ mongoClient.close();
+ }
+}
diff --git a/persistence-modules/java-mongodb-queries/README.md b/persistence-modules/java-mongodb-queries/README.md
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/persistence-modules/java-mongodb-queries/pom.xml b/persistence-modules/java-mongodb-queries/pom.xml
new file mode 100644
index 0000000000..58d7af1bc9
--- /dev/null
+++ b/persistence-modules/java-mongodb-queries/pom.xml
@@ -0,0 +1,33 @@
+
+
+
+ com.baeldung
+ persistence-modules
+ 1.0.0-SNAPSHOT
+
+ 4.0.0
+
+ java-mongodb-queries
+
+
+
+ org.mongodb
+ mongodb-driver-sync
+ 4.6.0
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.8.1
+ compile
+
+
+
+
+ 8
+ 8
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/java-mongodb-queries/src/main/java/com/baeldung/mongo/crud/CrudClient.java b/persistence-modules/java-mongodb-queries/src/main/java/com/baeldung/mongo/crud/CrudClient.java
new file mode 100644
index 0000000000..b71b88406d
--- /dev/null
+++ b/persistence-modules/java-mongodb-queries/src/main/java/com/baeldung/mongo/crud/CrudClient.java
@@ -0,0 +1,183 @@
+package com.baeldung.mongo.crud;
+
+import com.baeldung.mongo.crud.model.Event;
+import com.mongodb.BasicDBObject;
+import com.mongodb.BasicDBObjectBuilder;
+import com.mongodb.MongoException;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoDatabase;
+import com.mongodb.client.model.UpdateOptions;
+import com.mongodb.client.model.Updates;
+import com.mongodb.client.result.InsertOneResult;
+import com.mongodb.client.result.DeleteResult;
+import com.mongodb.client.result.UpdateResult;
+import org.bson.BsonValue;
+import org.bson.Document;
+import org.bson.codecs.configuration.CodecProvider;
+import org.bson.codecs.configuration.CodecRegistry;
+import org.bson.codecs.pojo.PojoCodecProvider;
+import org.bson.conversions.Bson;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.mongodb.client.model.Filters.and;
+import static com.mongodb.client.model.Filters.eq;
+import static com.mongodb.MongoClientSettings.getDefaultCodecRegistry;
+import static com.mongodb.client.model.Filters.gte;
+import static com.mongodb.client.model.Filters.lt;
+import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
+import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
+
+public class CrudClient {
+
+ private static String uri = "mongodb://localhost:27017";
+ private static MongoClient mongoClient = MongoClients.create(uri);
+ private static MongoDatabase db;
+ private static MongoCollection collection;
+
+ public static OffsetDateTime offsetDateTime = OffsetDateTime.of(LocalDateTime.of(2022, 6, 4, 11, 0, 0),
+ ZoneOffset.ofHours(2));
+
+ public static Event pianoLessons = new Event(
+ "Piano lessons",
+ "Foo Bvld",
+ LocalDateTime.of(2022, 6, 4, 11, 0, 0));
+
+ public static Event soccerGame = new Event(
+ "Soccer game",
+ "Bar Avenue",
+ LocalDateTime.of(2022, 6, 10, 17, 0, 0));
+
+ public static Event pianoLessonsTZ = new Event(
+ "Piano lessons",
+ "Baz Bvld",
+ LocalDateTime.of(2022, 12, 31, 12, 0, 0),
+ ZoneOffset.ofHours(2).toString());
+
+ public static LocalDateTime dateQuery = LocalDateTime.of(2022, 6, 10, 17, 0, 0);
+ public static LocalDateTime dateQueryEventWithTZ = LocalDateTime.of(2022, 12, 31, 12, 0, 0);
+
+ public static LocalDateTime from = LocalDateTime.of(2022, 06, 04, 12, 0, 0);
+ public static LocalDateTime to = LocalDateTime.of(2022, 06, 10, 17, 0, 0);
+
+ public static LocalDate updateManyFrom = LocalDate.of(2022, 1, 1);
+ public static LocalDate updateManyTo = LocalDate.of(2023, 1, 1);
+
+ public static LocalDate deleteFrom = LocalDate.of(2022, 1, 1);
+ public static LocalDate deleteTo = LocalDate.of(2023, 01, 01);
+
+ public static void setup() {
+ CodecProvider codecProvider = PojoCodecProvider.builder().automatic(true).build();
+ CodecRegistry codecRegistry = fromRegistries(getDefaultCodecRegistry(), fromProviders(codecProvider));
+
+ db = mongoClient.getDatabase("calendar").withCodecRegistry(codecRegistry);
+ collection = db.getCollection("my_events", Event.class);
+ }
+
+ public static void close() {
+ mongoClient.close();
+ }
+
+ public static BsonValue insertEventsWithDate(Event e) {
+ try {
+ InsertOneResult insertResult = collection.insertOne(e);
+ return insertResult.getInsertedId();
+ } catch (MongoException me) {
+ System.err.println("Failed to insert with error: " + me);
+ throw me;
+ }
+ }
+
+ public static Event readEventsByDate(LocalDateTime localDateTime) {
+ try {
+ Event event = collection
+ .find(eq("dateTime", localDateTime))
+ .first();
+ return event;
+ } catch (MongoException me) {
+ System.err.println("Failed to read with error: " + me);
+ throw me;
+ }
+ }
+
+ public static List readEventsByDateRange(LocalDateTime from, LocalDateTime to) {
+ BasicDBObject object = new BasicDBObject();
+ object.put("dateTime", BasicDBObjectBuilder
+ .start("$gte", from)
+ .add("$lte", to)
+ .get());
+ try {
+ List list = new ArrayList(collection.find(object).into(new ArrayList()));
+ return list;
+ } catch (MongoException me) {
+ System.err.println("Failed to read with error: " + me);
+ throw me;
+ }
+ }
+
+ public static LocalDateTime readEventsByDateWithTZ(LocalDateTime localDateTime) {
+ try {
+ Event event = collection
+ .find(eq("dateTime", localDateTime))
+ .first();
+ OffsetDateTime offsetDateTime = OffsetDateTime.of(event.dateTime, ZoneOffset.of(pianoLessonsTZ.timeZoneOffset));
+ ZonedDateTime zoned = offsetDateTime.atZoneSameInstant(ZoneId.of("America/Toronto"));
+ return zoned.toLocalDateTime();
+ } catch (MongoException me) {
+ System.err.println("Failed to read with error: " + me);
+ throw me;
+ }
+ }
+
+ public static long updateDateField() {
+ Document document = new Document().append("title", "Piano lessons");
+ Bson update = Updates.currentDate("updatedAt");
+ UpdateOptions options = new UpdateOptions().upsert(false);
+ try {
+ UpdateResult result = collection.updateOne(document, update, options);
+ return result.getModifiedCount();
+ } catch (MongoException me) {
+ System.err.println("Failed to update with error: " + me);
+ throw me;
+ }
+ }
+
+ public static long updateManyEventsWithDateCriteria(LocalDate updateManyFrom, LocalDate updateManyTo) {
+ Bson query = and(gte("dateTime", updateManyFrom), lt("dateTime", updateManyTo));
+ Bson updates = Updates.currentDate("dateTime");
+ try {
+ UpdateResult result = collection.updateMany(query, updates);
+ return result.getModifiedCount();
+ } catch(MongoException me) {
+ System.err.println("Failed to replace/update with error: " + me);
+ throw me;
+ }
+ }
+
+ public static long deleteEventsByDate(LocalDate from, LocalDate to) {
+ Bson query = and(gte("dateTime", from), lt("dateTime", to));
+ try {
+ DeleteResult result = collection.deleteMany(query);
+ return result.getDeletedCount();
+ } catch (MongoException me) {
+ System.err.println("Failed to delete with error: " + me);
+ throw me;
+ }
+ }
+
+ public static void dropDb() {
+ db.drop();
+ }
+
+ public static void main(String[] args) {
+ }
+}
diff --git a/persistence-modules/java-mongodb-queries/src/main/java/com/baeldung/mongo/crud/model/Event.java b/persistence-modules/java-mongodb-queries/src/main/java/com/baeldung/mongo/crud/model/Event.java
new file mode 100644
index 0000000000..751dc5d6eb
--- /dev/null
+++ b/persistence-modules/java-mongodb-queries/src/main/java/com/baeldung/mongo/crud/model/Event.java
@@ -0,0 +1,28 @@
+package com.baeldung.mongo.crud.model;
+
+import java.time.LocalDateTime;
+
+public class Event {
+ public String title;
+ public String location;
+ public LocalDateTime dateTime;
+ public String timeZoneOffset;
+
+ public Event() {}
+ public Event(String title, String location, LocalDateTime dateTime) {
+ this.title = title;
+ this.location = location;
+ this.dateTime = dateTime;
+ }
+
+ public Event(String title, String location, LocalDateTime dateTime, String timeZoneOffset) {
+ this.title = title;
+ this.location = location;
+ this.dateTime = dateTime;
+ this.timeZoneOffset = timeZoneOffset;
+ }
+
+ @Override
+ public String toString() { return "\nEvent: " + title + "\nWhere: " + location + "\nWhen: " + dateTime; }
+}
+
diff --git a/persistence-modules/java-mongodb-queries/src/test/java/com/baeldung/mongo/crud/CrudClientLiveTest.java b/persistence-modules/java-mongodb-queries/src/test/java/com/baeldung/mongo/crud/CrudClientLiveTest.java
new file mode 100644
index 0000000000..5b5004fd9f
--- /dev/null
+++ b/persistence-modules/java-mongodb-queries/src/test/java/com/baeldung/mongo/crud/CrudClientLiveTest.java
@@ -0,0 +1,95 @@
+package com.baeldung.mongo.crud;
+
+import com.baeldung.mongo.crud.model.Event;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import java.io.IOException;
+import java.util.List;
+
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+public class CrudClientLiveTest {
+
+ @BeforeAll
+ public static void setup() {
+ CrudClient.setup();
+ }
+
+ @Test
+ @Order(1)
+ public void whenInsertingEventsWithDate_thenCheckForDocument() {
+ Assertions.assertNotNull(CrudClient.insertEventsWithDate(CrudClient.pianoLessons));
+ Assertions.assertNotNull(CrudClient.insertEventsWithDate(CrudClient.soccerGame));
+ }
+
+ @Test
+ @Order(2)
+ public void whenReadingEventsByDate_thenCheckForReturnedDocument() {
+ Assertions.assertNotNull(CrudClient.readEventsByDate(CrudClient.dateQuery));
+ Event event = CrudClient.readEventsByDate(CrudClient.dateQuery);
+ Assertions.assertNotNull(event);
+ Assertions.assertEquals("Soccer game", event.title);
+ Assertions.assertEquals("Bar Avenue", event.location);
+ Assertions.assertEquals(CrudClient.soccerGame.dateTime, event.dateTime);
+ }
+
+ @Test
+ @Order(3)
+ public void whenReadingEventsByDateRange_thenCheckForReturnedDocument() {
+ List events = CrudClient.readEventsByDateRange(CrudClient.from, CrudClient.to);
+ Assertions.assertNotNull(events);
+ Assertions.assertEquals(1, events.size());
+ Assertions.assertEquals("Soccer game", events.get(0).title);
+ Assertions.assertEquals("Bar Avenue", events.get(0).location);
+ Assertions.assertEquals(CrudClient.soccerGame.dateTime, events.get(0).dateTime);
+ }
+
+ @Test
+ @Order(5)
+ public void whenUpdatingEventsDateField_thenCheckUpdatedCount() {
+ Assertions.assertEquals(1, CrudClient.updateDateField());
+ }
+
+ @Test
+ @Order(6)
+ public void whenUpdatingManyEvents_thenCheckUpdatedCount() {
+ long updates = CrudClient.updateManyEventsWithDateCriteria(CrudClient.updateManyFrom, CrudClient.updateManyTo);
+ Assertions.assertTrue(1 < updates);
+ }
+
+ @Test
+ @Order(7)
+ public void whenDeletingEventsWithDate_thenCheckDeletedCount() {
+ Assertions.assertEquals(2, CrudClient.deleteEventsByDate(CrudClient.deleteFrom, CrudClient.deleteTo));
+ }
+
+ @Test
+ @Order(8)
+ public void whenInsertingEventWithDateAndTimeZone_thenCheckForDocument() {
+ Assertions.assertNotNull(CrudClient.insertEventsWithDate(CrudClient.pianoLessonsTZ));
+ }
+
+ @Test
+ @Order(9)
+ public void whenReadingEventsWithDateAndTimeZone_thenCheckInsertedCount() {
+ Assertions.assertNotEquals(CrudClient.pianoLessonsTZ.dateTime, CrudClient.readEventsByDateWithTZ(CrudClient.dateQueryEventWithTZ));
+ }
+
+ @Test
+ @Order(10)
+ public void whenDeletingEventsWithDateAndTimeZone_thenCheckDeletedCount() {
+ Assertions.assertEquals(1, CrudClient.deleteEventsByDate(CrudClient.deleteFrom, CrudClient.deleteTo));
+ }
+
+ @AfterAll
+ public static void close() throws IOException {
+ CrudClient.dropDb();
+ CrudClient.close();
+ }
+
+}
diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml
index 4bab0631bd..ee4807933a 100644
--- a/persistence-modules/pom.xml
+++ b/persistence-modules/pom.xml
@@ -45,6 +45,7 @@
java-mongodb
java-mongodb-2
java-mongodb-3
+ java-mongodb-queries
jnosql
jooq
jpa-hibernate-cascade-type
diff --git a/persistence-modules/spring-data-mongodb/README.md b/persistence-modules/spring-data-mongodb/README.md
index acc978c68e..be2071440b 100644
--- a/persistence-modules/spring-data-mongodb/README.md
+++ b/persistence-modules/spring-data-mongodb/README.md
@@ -11,6 +11,7 @@
- [Spring Data MongoDB: Projections and Aggregations](http://www.baeldung.com/spring-data-mongodb-projections-aggregations)
- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
- [Spring Data MongoDB Transactions](https://www.baeldung.com/spring-data-mongodb-transactions)
+- [UUID as Entity ID in MongoDB](https://www.baeldung.com/java-mongodb-uuid)
## Spring Data MongoDB Live Testing
diff --git a/pom.xml b/pom.xml
index 0801fbab46..0e0aa876eb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
com.baeldung
parent-modules
1.0.0-SNAPSHOT
- parent-modules
+ parent-modules
pom
@@ -1246,6 +1246,7 @@
core-java-modules/core-java-networking-3
core-java-modules/core-java-strings
core-java-modules/core-java-httpclient
+ spring-core-6
ddd-contexts
docker-modules
apache-httpclient-2
@@ -1328,6 +1329,7 @@
testing-modules/testing-assertions
persistence-modules/fauna
lightrun
+ spring-core-6
@@ -1398,6 +1400,7 @@
1.18.20
1.4.200
31.0.1-jre
+ 3.2.2
-
+
\ No newline at end of file
diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml
index bf3f79e5e5..1fd6202376 100644
--- a/spring-boot-modules/pom.xml
+++ b/spring-boot-modules/pom.xml
@@ -44,6 +44,7 @@
spring-boot-groovy
spring-boot-jasypt
+ spring-boot-jsp
spring-boot-keycloak
spring-boot-keycloak-2
spring-boot-libraries
diff --git a/spring-web-modules/spring-boot-jsp/README.md b/spring-boot-modules/spring-boot-jsp/README.md
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/README.md
rename to spring-boot-modules/spring-boot-jsp/README.md
diff --git a/spring-web-modules/spring-boot-jsp/pom.xml b/spring-boot-modules/spring-boot-jsp/pom.xml
similarity index 95%
rename from spring-web-modules/spring-boot-jsp/pom.xml
rename to spring-boot-modules/spring-boot-jsp/pom.xml
index d2a363bafa..ab81d65cc6 100644
--- a/spring-web-modules/spring-boot-jsp/pom.xml
+++ b/spring-boot-modules/spring-boot-jsp/pom.xml
@@ -9,9 +9,9 @@
war
- com.baeldung
- spring-web-modules
- 0.0.1-SNAPSHOT
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
diff --git a/spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/SpringBootJspApplication.java b/spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/SpringBootJspApplication.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/SpringBootJspApplication.java
rename to spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/SpringBootJspApplication.java
diff --git a/spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/SpringBootJspConfiguration.java b/spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/SpringBootJspConfiguration.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/SpringBootJspConfiguration.java
rename to spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/SpringBootJspConfiguration.java
diff --git a/spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/controller/BookController.java b/spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/controller/BookController.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/controller/BookController.java
rename to spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/controller/BookController.java
diff --git a/spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/dto/Book.java b/spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/dto/Book.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/dto/Book.java
rename to spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/dto/Book.java
diff --git a/spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/exception/DuplicateBookException.java b/spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/exception/DuplicateBookException.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/exception/DuplicateBookException.java
rename to spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/exception/DuplicateBookException.java
diff --git a/spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/exception/LibraryControllerAdvice.java b/spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/exception/LibraryControllerAdvice.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/exception/LibraryControllerAdvice.java
rename to spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/exception/LibraryControllerAdvice.java
diff --git a/spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/repository/BookRepository.java b/spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/repository/BookRepository.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/repository/BookRepository.java
rename to spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/repository/BookRepository.java
diff --git a/spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/repository/impl/InMemoryBookRepository.java b/spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/repository/impl/InMemoryBookRepository.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/repository/impl/InMemoryBookRepository.java
rename to spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/repository/impl/InMemoryBookRepository.java
diff --git a/spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/repository/model/BookData.java b/spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/repository/model/BookData.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/repository/model/BookData.java
rename to spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/repository/model/BookData.java
diff --git a/spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/service/BookService.java b/spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/service/BookService.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/service/BookService.java
rename to spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/service/BookService.java
diff --git a/spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/service/impl/BookServiceImpl.java b/spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/service/impl/BookServiceImpl.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/service/impl/BookServiceImpl.java
rename to spring-boot-modules/spring-boot-jsp/src/main/java/com/baeldung/boot/jsp/service/impl/BookServiceImpl.java
diff --git a/spring-web-modules/spring-boot-jsp/src/main/resources/application.properties b/spring-boot-modules/spring-boot-jsp/src/main/resources/application.properties
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/resources/application.properties
rename to spring-boot-modules/spring-boot-jsp/src/main/resources/application.properties
diff --git a/spring-web-modules/spring-boot-jsp/src/main/resources/static/css/common.css b/spring-boot-modules/spring-boot-jsp/src/main/resources/static/css/common.css
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/resources/static/css/common.css
rename to spring-boot-modules/spring-boot-jsp/src/main/resources/static/css/common.css
diff --git a/spring-web-modules/spring-boot-jsp/src/main/resources/static/error/4xx.html b/spring-boot-modules/spring-boot-jsp/src/main/resources/static/error/4xx.html
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/resources/static/error/4xx.html
rename to spring-boot-modules/spring-boot-jsp/src/main/resources/static/error/4xx.html
diff --git a/spring-web-modules/spring-boot-jsp/src/main/webapp/WEB-INF/jsp/add-book.jsp b/spring-boot-modules/spring-boot-jsp/src/main/webapp/WEB-INF/jsp/add-book.jsp
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/webapp/WEB-INF/jsp/add-book.jsp
rename to spring-boot-modules/spring-boot-jsp/src/main/webapp/WEB-INF/jsp/add-book.jsp
diff --git a/spring-web-modules/spring-boot-jsp/src/main/webapp/WEB-INF/jsp/error-book.jsp b/spring-boot-modules/spring-boot-jsp/src/main/webapp/WEB-INF/jsp/error-book.jsp
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/webapp/WEB-INF/jsp/error-book.jsp
rename to spring-boot-modules/spring-boot-jsp/src/main/webapp/WEB-INF/jsp/error-book.jsp
diff --git a/spring-web-modules/spring-boot-jsp/src/main/webapp/WEB-INF/jsp/view-books.jsp b/spring-boot-modules/spring-boot-jsp/src/main/webapp/WEB-INF/jsp/view-books.jsp
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/main/webapp/WEB-INF/jsp/view-books.jsp
rename to spring-boot-modules/spring-boot-jsp/src/main/webapp/WEB-INF/jsp/view-books.jsp
diff --git a/spring-web-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/controller/BookControllerIntegrationTest.java b/spring-boot-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/controller/BookControllerIntegrationTest.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/controller/BookControllerIntegrationTest.java
rename to spring-boot-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/controller/BookControllerIntegrationTest.java
diff --git a/spring-web-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/controller/BookControllerUnitTest.java b/spring-boot-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/controller/BookControllerUnitTest.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/controller/BookControllerUnitTest.java
rename to spring-boot-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/controller/BookControllerUnitTest.java
diff --git a/spring-web-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/repository/impl/InMemoryBookRepositoryUnitTest.java b/spring-boot-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/repository/impl/InMemoryBookRepositoryUnitTest.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/repository/impl/InMemoryBookRepositoryUnitTest.java
rename to spring-boot-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/repository/impl/InMemoryBookRepositoryUnitTest.java
diff --git a/spring-web-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/service/BookServiceIntegrationTest.java b/spring-boot-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/service/BookServiceIntegrationTest.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/service/BookServiceIntegrationTest.java
rename to spring-boot-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/service/BookServiceIntegrationTest.java
diff --git a/spring-web-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/service/impl/BookServiceImplUnitTest.java b/spring-boot-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/service/impl/BookServiceImplUnitTest.java
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/service/impl/BookServiceImplUnitTest.java
rename to spring-boot-modules/spring-boot-jsp/src/test/java/com/baeldung/boot/jsp/service/impl/BookServiceImplUnitTest.java
diff --git a/spring-web-modules/spring-boot-jsp/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-jsp/src/test/resources/logback-test.xml
similarity index 100%
rename from spring-web-modules/spring-boot-jsp/src/test/resources/logback-test.xml
rename to spring-boot-modules/spring-boot-jsp/src/test/resources/logback-test.xml
diff --git a/spring-cloud-modules/spring-cloud-gateway/README.md b/spring-cloud-modules/spring-cloud-gateway/README.md
index 808536ce80..5bf416fccd 100644
--- a/spring-cloud-modules/spring-cloud-gateway/README.md
+++ b/spring-cloud-modules/spring-cloud-gateway/README.md
@@ -10,3 +10,4 @@ This module contains articles about Spring Cloud Gateway
- [Spring Cloud Gateway WebFilter Factories](https://www.baeldung.com/spring-cloud-gateway-webfilter-factories)
- [Using Spring Cloud Gateway with OAuth 2.0 Patterns](https://www.baeldung.com/spring-cloud-gateway-oauth2)
- [URL Rewriting With Spring Cloud Gateway](https://www.baeldung.com/spring-cloud-gateway-url-rewriting)
+- [Processing the Response Body in Spring Cloud Gateway](https://www.baeldung.com/spring-cloud-gateway-response-body)
diff --git a/spring-core-6/pom.xml b/spring-core-6/pom.xml
new file mode 100644
index 0000000000..92cd343234
--- /dev/null
+++ b/spring-core-6/pom.xml
@@ -0,0 +1,76 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ spring-core-6
+ 0.0.1-SNAPSHOT
+ spring-core-6
+ http://www.baeldung.com
+
+
+ UTF-8
+ 11
+ 11
+
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ 2.0.0.RELEASE
+
+
+
+
+
+
+
+ maven-clean-plugin
+ 3.1.0
+
+
+ maven-resources-plugin
+ 3.0.2
+
+
+ maven-compiler-plugin
+ 3.8.0
+
+
+ maven-surefire-plugin
+ 2.22.1
+
+
+ maven-jar-plugin
+ 3.0.2
+
+
+ maven-install-plugin
+ 2.5.2
+
+
+ maven-deploy-plugin
+ 2.8.2
+
+
+
+ maven-site-plugin
+ 3.7.1
+
+
+ maven-project-info-reports-plugin
+ 3.0.0
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/Person.java b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/Person.java
new file mode 100644
index 0000000000..04fa6577ac
--- /dev/null
+++ b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/Person.java
@@ -0,0 +1,17 @@
+package com.baeldung.multibeaninstantiation.solution1;
+
+public class Person {
+ private String firstName;
+ private String lastName;
+
+ public Person(String firstName, String secondName) {
+ super();
+ this.firstName = firstName;
+ this.lastName = secondName;
+ }
+
+ @Override
+ public String toString() {
+ return "Person [firstName=" + firstName + ", secondName=" + lastName + "]";
+ }
+}
\ No newline at end of file
diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/PersonConfig.java b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/PersonConfig.java
new file mode 100644
index 0000000000..ac05ffc0fa
--- /dev/null
+++ b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/PersonConfig.java
@@ -0,0 +1,17 @@
+package com.baeldung.multibeaninstantiation.solution1;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class PersonConfig {
+ @Bean
+ public Person personOne() {
+ return new Person("Harold", "Finch");
+ }
+
+ @Bean
+ public Person personTwo() {
+ return new Person("John", "Reese");
+ }
+}
\ No newline at end of file
diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/SpringApp1.java b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/SpringApp1.java
new file mode 100644
index 0000000000..c2bc70f3ba
--- /dev/null
+++ b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/SpringApp1.java
@@ -0,0 +1,11 @@
+package com.baeldung.multibeaninstantiation.solution1;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringApp1 {
+ public static void main(String[] args) {
+ SpringApplication.run(SpringApp1.class, args);
+ }
+}
\ No newline at end of file
diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/Person.java b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/Person.java
new file mode 100644
index 0000000000..a1801d1fd2
--- /dev/null
+++ b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/Person.java
@@ -0,0 +1,17 @@
+package com.baeldung.multibeaninstantiation.solution2;
+
+public class Person {
+ private String firstName;
+ private String lastName;
+
+ public Person(String firstName, String secondName) {
+ super();
+ this.firstName = firstName;
+ this.lastName = secondName;
+ }
+
+ @Override
+ public String toString() {
+ return "Person [firstName=" + firstName + ", secondName=" + lastName + "]";
+ }
+}
\ No newline at end of file
diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonConfig.java b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonConfig.java
new file mode 100644
index 0000000000..da97314579
--- /dev/null
+++ b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonConfig.java
@@ -0,0 +1,10 @@
+package com.baeldung.multibeaninstantiation.solution2;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan("com.baeldung.multibeaninstantiation.solution2")
+public class PersonConfig {
+
+}
\ No newline at end of file
diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonOne.java b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonOne.java
new file mode 100644
index 0000000000..5d56082f71
--- /dev/null
+++ b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonOne.java
@@ -0,0 +1,13 @@
+package com.baeldung.multibeaninstantiation.solution2;
+
+import org.springframework.stereotype.Component;
+
+import com.baeldung.multibeaninstantiation.solution2.Person;
+
+@Component
+public class PersonOne extends Person {
+
+ public PersonOne() {
+ super("Harold", "Finch");
+ }
+}
\ No newline at end of file
diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonTwo.java b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonTwo.java
new file mode 100644
index 0000000000..436bd0e96e
--- /dev/null
+++ b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonTwo.java
@@ -0,0 +1,13 @@
+package com.baeldung.multibeaninstantiation.solution2;
+
+import org.springframework.stereotype.Component;
+
+import com.baeldung.multibeaninstantiation.solution2.Person;
+
+@Component
+public class PersonTwo extends Person {
+
+ public PersonTwo() {
+ super("John", "Reese");
+ }
+}
\ No newline at end of file
diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/SpringApp2.java b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/SpringApp2.java
new file mode 100644
index 0000000000..328ba32777
--- /dev/null
+++ b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/SpringApp2.java
@@ -0,0 +1,11 @@
+package com.baeldung.multibeaninstantiation.solution2;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringApp2 {
+ public static void main(String[] args) {
+ SpringApplication.run(SpringApp2.class, args);
+ }
+}
\ No newline at end of file
diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/Human.java b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/Human.java
new file mode 100644
index 0000000000..d73bd9dfdc
--- /dev/null
+++ b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/Human.java
@@ -0,0 +1,33 @@
+package com.baeldung.multibeaninstantiation.solution3;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.Assert;
+
+public class Human implements InitializingBean {
+
+ private Person personOne;
+
+ private Person personTwo;
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(personOne, "Harold is alive!");
+ Assert.notNull(personTwo, "John is alive!");
+ }
+
+ /* Setter injection */
+ @Autowired
+ public void setPersonOne(Person personOne) {
+ this.personOne = personOne;
+ this.personOne.setFirstName("Harold");
+ this.personOne.setSecondName("Finch");
+ }
+
+ @Autowired
+ public void setPersonTwo(Person personTwo) {
+ this.personTwo = personTwo;
+ this.personTwo.setFirstName("John");
+ this.personTwo.setSecondName("Reese");
+ }
+}
\ No newline at end of file
diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/MultiBeanFactory.java b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/MultiBeanFactory.java
new file mode 100644
index 0000000000..1753d28d7e
--- /dev/null
+++ b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/MultiBeanFactory.java
@@ -0,0 +1,9 @@
+package com.baeldung.multibeaninstantiation.solution3;
+
+import java.util.List;
+
+public interface MultiBeanFactory {
+ List getObject(String name) throws Exception;
+
+ Class> getObjectType();
+}
\ No newline at end of file
diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/Person.java b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/Person.java
new file mode 100644
index 0000000000..a26aee121f
--- /dev/null
+++ b/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/Person.java
@@ -0,0 +1,49 @@
+package com.baeldung.multibeaninstantiation.solution3;
+
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.annotation.Qualifier;
+
+@Qualifier(value = "personOne, personTwo")
+public class Person implements FactoryBean