diff --git a/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/helpfulnullpointerexceptions/HelpfulNullPointerException.java b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/npe/HelpfulNullPointerException.java
similarity index 95%
rename from core-java-modules/core-java-14/src/main/java/com/baeldung/java14/helpfulnullpointerexceptions/HelpfulNullPointerException.java
rename to core-java-modules/core-java-14/src/main/java/com/baeldung/java14/npe/HelpfulNullPointerException.java
index ef5dbb754c..913f796cd4 100644
--- a/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/helpfulnullpointerexceptions/HelpfulNullPointerException.java
+++ b/core-java-modules/core-java-14/src/main/java/com/baeldung/java14/npe/HelpfulNullPointerException.java
@@ -1,4 +1,4 @@
-package com.baeldung.java14.helpfulnullpointerexceptions;
+package com.baeldung.java14.npe;
public class HelpfulNullPointerException {
diff --git a/core-java-modules/core-java-14/src/test/java/com/baeldung/java14/helpfulnullpointerexceptions/HelpfulNullPointerExceptionUnitTest.java b/core-java-modules/core-java-14/src/test/java/com/baeldung/java14/npe/HelpfulNullPointerExceptionUnitTest.java
similarity index 95%
rename from core-java-modules/core-java-14/src/test/java/com/baeldung/java14/helpfulnullpointerexceptions/HelpfulNullPointerExceptionUnitTest.java
rename to core-java-modules/core-java-14/src/test/java/com/baeldung/java14/npe/HelpfulNullPointerExceptionUnitTest.java
index fae331bb92..1b5153c706 100644
--- a/core-java-modules/core-java-14/src/test/java/com/baeldung/java14/helpfulnullpointerexceptions/HelpfulNullPointerExceptionUnitTest.java
+++ b/core-java-modules/core-java-14/src/test/java/com/baeldung/java14/npe/HelpfulNullPointerExceptionUnitTest.java
@@ -1,4 +1,4 @@
-package com.baeldung.java14.helpfulnullpointerexceptions;
+package com.baeldung.java14.npe;
import org.junit.Test;
diff --git a/core-java-modules/core-java-arrays-sorting/README.md b/core-java-modules/core-java-arrays-sorting/README.md
index f83dd43526..dedc0340c0 100644
--- a/core-java-modules/core-java-arrays-sorting/README.md
+++ b/core-java-modules/core-java-arrays-sorting/README.md
@@ -5,5 +5,5 @@ This module contains articles about sorting arrays in Java
### Relevant Articles:
- [Sorting Arrays in Java](https://www.baeldung.com/java-sorting-arrays)
- [Checking If an Array Is Sorted in Java](https://www.baeldung.com/java-check-sorted-array)
-- [How to Reverse an Array in Java](http://www.baeldung.com/java-invert-array)
+- [How to Reverse an Array in Java](https://www.baeldung.com/java-invert-array)
- [Arrays.sort vs Arrays.parallelSort](https://www.baeldung.com/java-arrays-sort-vs-parallelsort)
diff --git a/core-java-modules/core-java-concurrency-2/README.md b/core-java-modules/core-java-concurrency-2/README.md
index 749d174968..ab7eebc26a 100644
--- a/core-java-modules/core-java-concurrency-2/README.md
+++ b/core-java-modules/core-java-concurrency-2/README.md
@@ -4,4 +4,5 @@
### Relevant Articles:
- [Using a Mutex Object in Java](https://www.baeldung.com/java-mutex)
+- [Testing Multi-Threaded Code in Java] (https://www.baeldung.com/java-testing-multithreaded)
diff --git a/core-java-modules/core-java-concurrency-2/pom.xml b/core-java-modules/core-java-concurrency-2/pom.xml
index a9a01b70f3..dfb5674c8e 100644
--- a/core-java-modules/core-java-concurrency-2/pom.xml
+++ b/core-java-modules/core-java-concurrency-2/pom.xml
@@ -15,6 +15,38 @@
0.0.1-SNAPSHOT
../../parent-java
+
+
+
+ junit
+ junit
+ 4.13
+ test
+
+
+ com.googlecode.thread-weaver
+ threadweaver
+ 0.2
+ test
+
+
+ com.google.code.tempus-fugit
+ tempus-fugit
+ 1.1
+ test
+
+
+ com.googlecode.multithreadedtc
+ multithreadedtc
+ 1.01
+ test
+
+
+ org.openjdk.jcstress
+ jcstress-core
+ 0.5
+
+
core-java-concurrency-2
@@ -24,6 +56,51 @@
true
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+ ${javac.target}
+ ${javac.target}
+ ${javac.target}
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 2.2
+
+
+ main
+ package
+
+ shade
+
+
+ jcstress
+
+
+ org.openjdk.jcstress.Main
+
+
+ META-INF/TestList
+
+
+
+
+
+
+
+
+
+ 1.8
+
diff --git a/core-java-modules/core-java-concurrency-testing/src/main/java/com/baeldung/concurrent/MyCounter.java b/core-java-modules/core-java-concurrency-2/src/main/java/com/baeldung/concurrent/MyCounter.java
similarity index 100%
rename from core-java-modules/core-java-concurrency-testing/src/main/java/com/baeldung/concurrent/MyCounter.java
rename to core-java-modules/core-java-concurrency-2/src/main/java/com/baeldung/concurrent/MyCounter.java
diff --git a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterJCStressUnitTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterJCStressUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterJCStressUnitTest.java
rename to core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterJCStressUnitTest.java
diff --git a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCUnitTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCUnitTest.java
similarity index 90%
rename from core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCUnitTest.java
rename to core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCUnitTest.java
index eb4e77cae9..8a0bedf6c2 100644
--- a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCUnitTest.java
+++ b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCUnitTest.java
@@ -1,5 +1,6 @@
package com.baeldung.concurrent;
+import org.junit.Ignore;
import org.junit.Test;
import edu.umd.cs.mtc.MultithreadedTestCase;
@@ -25,9 +26,10 @@ public class MyCounterMultithreadedTCUnitTest extends MultithreadedTestCase {
@SuppressWarnings("deprecation")
@Override
public void finish() {
- assertEquals(2, counter.getCount());
+ assertEquals(2, counter.getCount());
}
+ @Ignore
@Test
public void testCounter() throws Throwable {
TestFramework.runManyTimes(new MyCounterMultithreadedTCUnitTest(), 1000);
diff --git a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterSimpleUnitTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterSimpleUnitTest.java
similarity index 96%
rename from core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterSimpleUnitTest.java
rename to core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterSimpleUnitTest.java
index 4f3409b923..9a405e7e24 100644
--- a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterSimpleUnitTest.java
+++ b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterSimpleUnitTest.java
@@ -6,6 +6,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import org.junit.Ignore;
import org.junit.Test;
public class MyCounterSimpleUnitTest {
@@ -18,7 +19,8 @@ public class MyCounterSimpleUnitTest {
assertEquals(500, counter.getCount());
}
- // @Test
+ @Ignore
+ @Test
public void testCounterWithConcurrency() throws InterruptedException {
int numberOfThreads = 100;
ExecutorService service = Executors.newFixedThreadPool(10);
@@ -34,7 +36,8 @@ public class MyCounterSimpleUnitTest {
assertEquals(numberOfThreads, counter.getCount());
}
- // @Test
+ @Ignore
+ @Test
public void testSummationWithConcurrencyAndWait() throws InterruptedException {
int numberOfThreads = 2;
ExecutorService service = Executors.newFixedThreadPool(10);
diff --git a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitUnitTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitUnitTest.java
similarity index 96%
rename from core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitUnitTest.java
rename to core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitUnitTest.java
index 360c61b4f4..36a2031e78 100644
--- a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitUnitTest.java
+++ b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitUnitTest.java
@@ -3,6 +3,7 @@ package com.baeldung.concurrent;
import static org.junit.Assert.assertEquals;
import org.junit.AfterClass;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@@ -20,6 +21,7 @@ public class MyCounterTempusFugitUnitTest {
private static MyCounter counter = new MyCounter();
+ @Ignore
@Test
@Concurrent(count = 2)
@Repeating(repetition = 10)
diff --git a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverUnitTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverUnitTest.java
similarity index 96%
rename from core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverUnitTest.java
rename to core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverUnitTest.java
index 29b08996cd..e65a963584 100644
--- a/core-java-modules/core-java-concurrency-testing/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverUnitTest.java
+++ b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverUnitTest.java
@@ -2,6 +2,7 @@ package com.baeldung.concurrent;
import static org.junit.Assert.assertEquals;
+import org.junit.Ignore;
import org.junit.Test;
import com.google.testing.threadtester.AnnotatedTestRunner;
@@ -34,6 +35,7 @@ public class MyCounterThreadWeaverUnitTest {
assertEquals(2, counter.getCount());
}
+ @Ignore
@Test
public void testCounter() {
new AnnotatedTestRunner().runTests(this.getClass(), MyCounter.class);
diff --git a/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/deadlockAndLivelock/DeadlockExample.java b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/deadlockAndLivelock/DeadlockExample.java
new file mode 100644
index 0000000000..bcdaf302ea
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/deadlockAndLivelock/DeadlockExample.java
@@ -0,0 +1,60 @@
+package com.baeldung.deadlockAndLivelock;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class DeadlockExample {
+
+ private Lock lock1 = new ReentrantLock(true);
+ private Lock lock2 = new ReentrantLock(true);
+
+ public static void main(String[] args) {
+ DeadlockExample deadlock = new DeadlockExample();
+ new Thread(deadlock::operation1, "T1").start();
+ new Thread(deadlock::operation2, "T2").start();
+
+ }
+
+ public void operation1() {
+ lock1.lock();
+ print("lock1 acquired, waiting to acquire lock2.");
+ sleep(50);
+
+ lock2.lock();
+ print("lock2 acquired");
+
+ print("executing first operation.");
+
+ lock2.unlock();
+ lock1.unlock();
+
+ }
+
+ public void operation2() {
+ lock2.lock();
+ print("lock2 acquired, waiting to acquire lock1.");
+ sleep(50);
+
+ lock1.lock();
+ print("lock1 acquired");
+
+ print("executing second operation.");
+
+ lock1.unlock();
+ lock2.unlock();
+ }
+
+ public void print(String message) {
+ System.out.println("Thread " + Thread.currentThread()
+ .getName() + ": " + message);
+ }
+
+ public void sleep(long millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/deadlockAndLivelock/LivelockExample.java b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/deadlockAndLivelock/LivelockExample.java
new file mode 100644
index 0000000000..b0d66a92c2
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/deadlockAndLivelock/LivelockExample.java
@@ -0,0 +1,86 @@
+package com.baeldung.deadlockAndLivelock;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class LivelockExample {
+
+ private Lock lock1 = new ReentrantLock(true);
+ private Lock lock2 = new ReentrantLock(true);
+
+ public static void main(String[] args) {
+ LivelockExample livelock = new LivelockExample();
+ new Thread(livelock::operation1, "T1").start();
+ new Thread(livelock::operation2, "T2").start();
+
+ }
+
+ public void operation1() {
+ while (true) {
+ tryLock(lock1, 50);
+ print("lock1 acquired, trying to acquire lock2.");
+ sleep(50);
+
+ if (tryLock(lock2)) {
+ print("lock2 acquired.");
+ } else {
+ print("cannot acquire lock2, releasing lock1.");
+ lock1.unlock();
+ continue;
+ }
+
+ print("executing first operation.");
+ break;
+ }
+ lock2.unlock();
+ lock1.unlock();
+ }
+
+ public void operation2() {
+ while (true) {
+ tryLock(lock2, 50);
+ print("lock2 acquired, trying to acquire lock1.");
+ sleep(50);
+
+ if (tryLock(lock1)) {
+ print("lock1 acquired.");
+ } else {
+ print("cannot acquire lock1, releasing lock2.");
+ lock2.unlock();
+ continue;
+ }
+
+ print("executing second operation.");
+ break;
+ }
+ lock1.unlock();
+ lock2.unlock();
+ }
+
+ public void print(String message) {
+ System.out.println("Thread " + Thread.currentThread()
+ .getName() + ": " + message);
+ }
+
+ public void sleep(long millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void tryLock(Lock lock, long millis) {
+ try {
+ lock.tryLock(10, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public boolean tryLock(Lock lock) {
+ return lock.tryLock();
+ }
+
+}
diff --git a/core-java-modules/core-java-concurrency-testing/README.md b/core-java-modules/core-java-concurrency-testing/README.md
deleted file mode 100644
index fef74a6750..0000000000
--- a/core-java-modules/core-java-concurrency-testing/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-=========
-
-## Core Java Concurrency Testing Examples
-
-### Relevant Articles:
-- [Testing Multi-Threaded Code in Java](https://www.baeldung.com/java-testing-multithreaded)
-
diff --git a/core-java-modules/core-java-concurrency-testing/pom.xml b/core-java-modules/core-java-concurrency-testing/pom.xml
deleted file mode 100644
index 51de83f67c..0000000000
--- a/core-java-modules/core-java-concurrency-testing/pom.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
- 4.0.0
- core-java-concurrency-testing
- 0.1.0-SNAPSHOT
- core-java-concurrency-testing
- jar
-
-
- com.baeldung
- parent-java
- 0.0.1-SNAPSHOT
- ../../parent-java
-
-
-
-
- junit
- junit
- 4.13
- test
-
-
- com.googlecode.thread-weaver
- threadweaver
- 0.2
- test
-
-
- com.google.code.tempus-fugit
- tempus-fugit
- 1.1
- test
-
-
- com.googlecode.multithreadedtc
- multithreadedtc
- 1.01
- test
-
-
- org.openjdk.jcstress
- jcstress-core
- 0.5
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.1
-
- ${javac.target}
- ${javac.target}
- ${javac.target}
-
-
-
-
- org.apache.maven.plugins
- maven-shade-plugin
- 2.2
-
-
- main
- package
-
- shade
-
-
- jcstress
-
-
- org.openjdk.jcstress.Main
-
-
- META-INF/TestList
-
-
-
-
-
-
-
-
-
-
diff --git a/core-java-modules/core-java-concurrency-testing/src/main/resources/logback.xml b/core-java-modules/core-java-concurrency-testing/src/main/resources/logback.xml
deleted file mode 100644
index 56af2d397e..0000000000
--- a/core-java-modules/core-java-concurrency-testing/src/main/resources/logback.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
- %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-concurrency-testing/src/test/resources/.gitignore b/core-java-modules/core-java-concurrency-testing/src/test/resources/.gitignore
deleted file mode 100644
index 83c05e60c8..0000000000
--- a/core-java-modules/core-java-concurrency-testing/src/test/resources/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-*.class
-
-#folders#
-/target
-/neoDb*
-/data
-/src/main/webapp/WEB-INF/classes
-*/META-INF/*
-
-# Packaged files #
-*.jar
-*.war
-*.ear
\ No newline at end of file
diff --git a/core-java-modules/core-java-exceptions/pom.xml b/core-java-modules/core-java-exceptions/pom.xml
index 60c5e2650a..0778b6b5a3 100644
--- a/core-java-modules/core-java-exceptions/pom.xml
+++ b/core-java-modules/core-java-exceptions/pom.xml
@@ -29,6 +29,11 @@
${lombok.version}
provided
+
+ org.apache.commons
+ commons-lang3
+ ${commons.lang3.version}
+
org.assertj
@@ -40,6 +45,7 @@
1.5.0-b01
+ 3.10
3.10.0
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/Arithmetic.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/Arithmetic.java
new file mode 100644
index 0000000000..db29198b39
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/Arithmetic.java
@@ -0,0 +1,20 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Arithmetic {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(Arithmetic.class);
+
+ public static void main(String[] args) {
+
+ try {
+ int result = 30 / 0; // Trying to divide by zero
+ } catch (ArithmeticException e) {
+ LOGGER.error("ArithmeticException caught!");
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/ArrayIndexOutOfBounds.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/ArrayIndexOutOfBounds.java
new file mode 100644
index 0000000000..54c95f224c
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/ArrayIndexOutOfBounds.java
@@ -0,0 +1,24 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ArrayIndexOutOfBounds {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(ArrayIndexOutOfBounds.class);
+
+ public static void main(String[] args) {
+
+ int[] nums = new int[] { 1, 2, 3 };
+
+ try {
+ int numFromNegativeIndex = nums[-1]; // Trying to access at negative index
+ int numFromGreaterIndex = nums[4]; // Trying to access at greater index
+ int numFromLengthIndex = nums[3]; // Trying to access at index equal to size of the array
+ } catch (ArrayIndexOutOfBoundsException e) {
+ LOGGER.error("ArrayIndexOutOfBoundsException caught");
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/ClassCast.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/ClassCast.java
new file mode 100644
index 0000000000..8f8a6cf9e6
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/ClassCast.java
@@ -0,0 +1,36 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class Animal {
+
+}
+
+class Dog extends Animal {
+
+}
+
+class Lion extends Animal {
+
+}
+
+public class ClassCast {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(ClassCast.class);
+
+ public static void main(String[] args) {
+
+ try {
+ Animal animalOne = new Dog(); // At runtime the instance is dog
+ Dog bruno = (Dog) animalOne; // Downcasting
+
+ Animal animalTwo = new Lion(); // At runtime the instance is animal
+ Dog tommy = (Dog) animalTwo; // Downcasting
+ } catch (ClassCastException e) {
+ LOGGER.error("ClassCastException caught!");
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/FileNotFound.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/FileNotFound.java
new file mode 100644
index 0000000000..a9f2e5ee84
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/FileNotFound.java
@@ -0,0 +1,25 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FileNotFound {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(FileNotFound.class);
+
+ public static void main(String[] args) {
+
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new FileReader(new File("/invalid/file/location")));
+ } catch (FileNotFoundException e) {
+ LOGGER.error("FileNotFoundException caught!");
+ }
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/GlobalExceptionHandler.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/GlobalExceptionHandler.java
new file mode 100644
index 0000000000..f2e89f44e3
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/GlobalExceptionHandler.java
@@ -0,0 +1,28 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GlobalExceptionHandler {
+
+ public static void main(String[] args) {
+
+ Handler globalExceptionHandler = new Handler();
+ Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler);
+ new GlobalExceptionHandler().performArithmeticOperation(10, 0);
+ }
+
+ public int performArithmeticOperation(int num1, int num2) {
+ return num1/num2;
+ }
+
+}
+
+class Handler implements Thread.UncaughtExceptionHandler {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(Handler.class);
+
+ public void uncaughtException(Thread t, Throwable e) {
+ LOGGER.info("Unhandled exception caught!");
+ }
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/IllegalArgument.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/IllegalArgument.java
new file mode 100644
index 0000000000..d54757dfac
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/IllegalArgument.java
@@ -0,0 +1,18 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IllegalArgument {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(IllegalArgument.class);
+
+ public static void main(String[] args) {
+ try {
+ Thread.sleep(-1000);
+ } catch (InterruptedException e) {
+ LOGGER.error("IllegalArgumentException caught!");
+ }
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/IllegalState.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/IllegalState.java
new file mode 100644
index 0000000000..0a812d2b82
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/IllegalState.java
@@ -0,0 +1,32 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IllegalState {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(IllegalState.class);
+
+ public static void main(String[] args) {
+
+ List intList = new ArrayList<>();
+
+ for (int i = 0; i < 10; i++) {
+ intList.add(i);
+ }
+
+ Iterator intListIterator = intList.iterator(); // Initialized with index at -1
+
+ try {
+ intListIterator.remove(); // IllegalStateException
+ } catch (IllegalStateException e) {
+ LOGGER.error("IllegalStateException caught!");
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/InterruptedExceptionExample.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/InterruptedExceptionExample.java
new file mode 100644
index 0000000000..d0c8bb2cd0
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/InterruptedExceptionExample.java
@@ -0,0 +1,28 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class ChildThread extends Thread {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(ChildThread.class);
+
+ public void run() {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ LOGGER.error("InterruptedException caught!");
+ }
+ }
+
+}
+
+public class InterruptedExceptionExample {
+
+ public static void main(String[] args) throws InterruptedException {
+ ChildThread childThread = new ChildThread();
+ childThread.start();
+ childThread.interrupt();
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/MalformedURL.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/MalformedURL.java
new file mode 100644
index 0000000000..9a02f005fd
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/MalformedURL.java
@@ -0,0 +1,25 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MalformedURL {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(MalformedURL.class);
+
+ public static void main(String[] args) {
+
+ URL baeldungURL = null;
+
+ try {
+ baeldungURL = new URL("malformedurl");
+ } catch (MalformedURLException e) {
+ LOGGER.error("MalformedURLException caught!");
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/NullPointer.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/NullPointer.java
new file mode 100644
index 0000000000..445cbecdc8
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/NullPointer.java
@@ -0,0 +1,36 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NullPointer {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(NullPointer.class);
+
+ public static void main(String[] args) {
+
+ Person personObj = null;
+
+ try {
+ String name = personObj.personName; // Accessing the field of a null object
+ personObj.personName = "Jon Doe"; // Modifying the field of a null object
+ } catch (NullPointerException e) {
+ LOGGER.error("NullPointerException caught!");
+ }
+
+ }
+}
+
+class Person {
+
+ public String personName;
+
+ public String getPersonName() {
+ return personName;
+ }
+
+ public void setPersonName(String personName) {
+ this.personName = personName;
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/NumberFormat.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/NumberFormat.java
new file mode 100644
index 0000000000..576fe51f78
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/NumberFormat.java
@@ -0,0 +1,23 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NumberFormat {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(NumberFormat.class);
+
+ public static void main(String[] args) {
+
+ String str1 = "100ABCD";
+
+ try {
+ int x = Integer.parseInt(str1); // Converting string with inappropriate format
+ int y = Integer.valueOf(str1);
+ } catch (NumberFormatException e) {
+ LOGGER.error("NumberFormatException caught!");
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/ParseExceptionExample.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/ParseExceptionExample.java
new file mode 100644
index 0000000000..e3b3e04b10
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/ParseExceptionExample.java
@@ -0,0 +1,25 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ParseExceptionExample {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(ParseExceptionExample.class);
+
+ public static void main(String[] args) {
+
+ DateFormat format = new SimpleDateFormat("MM, dd, yyyy");
+
+ try {
+ format.parse("01, , 2010");
+ } catch (ParseException e) {
+ LOGGER.error("ParseException caught!");
+ }
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/StringIndexOutOfBounds.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/StringIndexOutOfBounds.java
new file mode 100644
index 0000000000..0ee132e568
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/globalexceptionhandler/StringIndexOutOfBounds.java
@@ -0,0 +1,23 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class StringIndexOutOfBounds {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(StringIndexOutOfBounds.class);
+
+ public static void main(String[] args) {
+
+ String str = "Hello World";
+
+ try {
+ char charAtNegativeIndex = str.charAt(-1); // Trying to access at negative index
+ char charAtLengthIndex = str.charAt(11); // Trying to access at index equal to size of the string
+ } catch (StringIndexOutOfBoundsException e) {
+ LOGGER.error("StringIndexOutOfBoundsException caught");
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/rootcausefinder/RootCauseFinder.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/rootcausefinder/RootCauseFinder.java
new file mode 100644
index 0000000000..06610f3874
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/rootcausefinder/RootCauseFinder.java
@@ -0,0 +1,95 @@
+package com.baeldung.exceptions.rootcausefinder;
+
+import java.time.LocalDate;
+import java.time.Period;
+import java.time.format.DateTimeParseException;
+import java.util.Objects;
+
+/**
+ * Utility class to find root cause exceptions.
+ */
+public class RootCauseFinder {
+
+ public static Throwable findCauseUsingPlainJava(Throwable throwable) {
+ Objects.requireNonNull(throwable);
+ Throwable rootCause = throwable;
+ while (rootCause.getCause() != null) {
+ rootCause = rootCause.getCause();
+ }
+ return rootCause;
+ }
+
+ /**
+ * Calculates the age of a person from a given date.
+ */
+ static class AgeCalculator {
+
+ private AgeCalculator() {
+ }
+
+ public static int calculateAge(String birthDate) throws CalculationException {
+ if (birthDate == null || birthDate.isEmpty()) {
+ throw new IllegalArgumentException();
+ }
+
+ try {
+ return Period
+ .between(parseDate(birthDate), LocalDate.now())
+ .getYears();
+ } catch (DateParseException ex) {
+ throw new CalculationException(ex);
+ }
+ }
+
+ private static LocalDate parseDate(String birthDateAsString) throws DateParseException {
+
+ LocalDate birthDate;
+ try {
+ birthDate = LocalDate.parse(birthDateAsString);
+ } catch (DateTimeParseException ex) {
+ throw new InvalidFormatException(birthDateAsString, ex);
+ }
+
+ if (birthDate.isAfter(LocalDate.now())) {
+ throw new DateOutOfRangeException(birthDateAsString);
+ }
+
+ return birthDate;
+ }
+
+ }
+
+ static class CalculationException extends Exception {
+
+ CalculationException(DateParseException ex) {
+ super(ex);
+ }
+ }
+
+ static class DateParseException extends Exception {
+
+ DateParseException(String input) {
+ super(input);
+ }
+
+ DateParseException(String input, Throwable thr) {
+ super(input, thr);
+ }
+ }
+
+ static class InvalidFormatException extends DateParseException {
+
+ InvalidFormatException(String input, Throwable thr) {
+ super("Invalid date format: " + input, thr);
+ }
+ }
+
+ static class DateOutOfRangeException extends DateParseException {
+
+ DateOutOfRangeException(String date) {
+ super("Date out of range: " + date);
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exceptions/globalexceptionhandler/GlobalExceptionHandlerUnitTest.java b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exceptions/globalexceptionhandler/GlobalExceptionHandlerUnitTest.java
new file mode 100644
index 0000000000..74ceb3b442
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exceptions/globalexceptionhandler/GlobalExceptionHandlerUnitTest.java
@@ -0,0 +1,64 @@
+package com.baeldung.exceptions.globalexceptionhandler;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.slf4j.LoggerFactory;
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.core.Appender;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.verify;
+
+@RunWith(MockitoJUnitRunner.class)
+public class GlobalExceptionHandlerUnitTest {
+
+ @Mock
+ private Appender mockAppender;
+
+ @Captor
+ private ArgumentCaptor captorLoggingEvent;
+
+ @Before
+ public void setup() {
+ final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+ logger.addAppender(mockAppender);
+
+ Handler globalExceptionHandler = new Handler();
+ Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler);
+ }
+
+ @After
+ public void teardown() {
+ final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+ logger.detachAppender(mockAppender);
+ }
+
+ @Test
+ public void whenArithmeticException_thenUseUncaughtExceptionHandler() throws InterruptedException {
+
+ Thread globalExceptionHandlerThread = new Thread() {
+ public void run() {
+ GlobalExceptionHandler globalExceptionHandlerObj = new GlobalExceptionHandler();
+ globalExceptionHandlerObj.performArithmeticOperation(99, 0);
+ }
+ };
+
+ globalExceptionHandlerThread.start();
+ globalExceptionHandlerThread.join();
+
+ verify(mockAppender).doAppend(captorLoggingEvent.capture());
+ LoggingEvent loggingEvent = captorLoggingEvent.getValue();
+
+ assertThat(loggingEvent.getLevel()).isEqualTo(Level.INFO);
+ assertThat(loggingEvent.getFormattedMessage()).isEqualTo("Unhandled exception caught!");
+ }
+
+}
diff --git a/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exceptions/rootcausefinder/RootCauseFinderUnitTest.java b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exceptions/rootcausefinder/RootCauseFinderUnitTest.java
new file mode 100644
index 0000000000..f42388857a
--- /dev/null
+++ b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exceptions/rootcausefinder/RootCauseFinderUnitTest.java
@@ -0,0 +1,99 @@
+package com.baeldung.exceptions.rootcausefinder;
+
+import com.baeldung.exceptions.rootcausefinder.RootCauseFinder.CalculationException;
+import com.baeldung.exceptions.rootcausefinder.RootCauseFinder.DateOutOfRangeException;
+import com.google.common.base.Throwables;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoUnit;
+
+import static com.baeldung.exceptions.rootcausefinder.RootCauseFinder.AgeCalculator;
+import static com.baeldung.exceptions.rootcausefinder.RootCauseFinder.findCauseUsingPlainJava;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Tests the {@link RootCauseFinder}.
+ */
+public class RootCauseFinderUnitTest {
+
+ @Test
+ public void givenBirthDate_whenCalculatingAge_thenAgeReturned() {
+ try {
+ int age = AgeCalculator.calculateAge("1990-01-01");
+ Assertions.assertEquals(1990, LocalDate
+ .now()
+ .minus(age, ChronoUnit.YEARS)
+ .getYear());
+ } catch (CalculationException e) {
+ Assertions.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void givenWrongFormatDate_whenFindingRootCauseUsingJava_thenRootCauseFound() {
+ try {
+ AgeCalculator.calculateAge("010102");
+ } catch (CalculationException ex) {
+ assertTrue(findCauseUsingPlainJava(ex) instanceof DateTimeParseException);
+ }
+ }
+
+ @Test
+ public void givenOutOfRangeDate_whenFindingRootCauseUsingJava_thenRootCauseFound() {
+ try {
+ AgeCalculator.calculateAge("2020-04-04");
+ } catch (CalculationException ex) {
+ assertTrue(findCauseUsingPlainJava(ex) instanceof DateOutOfRangeException);
+ }
+ }
+
+ @Test
+ public void givenNullDate_whenFindingRootCauseUsingJava_thenRootCauseFound() {
+ try {
+ AgeCalculator.calculateAge(null);
+ } catch (Exception ex) {
+ assertTrue(findCauseUsingPlainJava(ex) instanceof IllegalArgumentException);
+ }
+ }
+
+ @Test
+ public void givenWrongFormatDate_whenFindingRootCauseUsingApacheCommons_thenRootCauseFound() {
+ try {
+ AgeCalculator.calculateAge("010102");
+ } catch (CalculationException ex) {
+ assertTrue(ExceptionUtils.getRootCause(ex) instanceof DateTimeParseException);
+ }
+ }
+
+ @Test
+ public void givenOutOfRangeDate_whenFindingRootCauseUsingApacheCommons_thenRootCauseFound() {
+ try {
+ AgeCalculator.calculateAge("2020-04-04");
+ } catch (CalculationException ex) {
+ assertTrue(ExceptionUtils.getRootCause(ex) instanceof DateOutOfRangeException);
+ }
+ }
+
+ @Test
+ public void givenWrongFormatDate_whenFindingRootCauseUsingGuava_thenRootCauseFound() {
+ try {
+ AgeCalculator.calculateAge("010102");
+ } catch (CalculationException ex) {
+ assertTrue(Throwables.getRootCause(ex) instanceof DateTimeParseException);
+ }
+ }
+
+ @Test
+ public void givenOutOfRangeDate_whenFindingRootCauseUsingGuava_thenRootCauseFound() {
+ try {
+ AgeCalculator.calculateAge("2020-04-04");
+ } catch (CalculationException ex) {
+ assertTrue(Throwables.getRootCause(ex) instanceof DateOutOfRangeException);
+ }
+ }
+
+}
diff --git a/core-java-modules/core-java-lang-2/src/test/java/com/baeldung/exceptions/RootCauseFinder.java b/core-java-modules/core-java-lang-2/src/test/java/com/baeldung/exceptions/RootCauseFinder.java
new file mode 100644
index 0000000000..e05dc7a6cd
--- /dev/null
+++ b/core-java-modules/core-java-lang-2/src/test/java/com/baeldung/exceptions/RootCauseFinder.java
@@ -0,0 +1,95 @@
+package com.baeldung.exceptions;
+
+import java.time.LocalDate;
+import java.time.Period;
+import java.time.format.DateTimeParseException;
+import java.util.Objects;
+
+/**
+ * Utility class to find root cause exceptions.
+ */
+public class RootCauseFinder {
+
+ public static Throwable findCauseUsingPlainJava(Throwable throwable) {
+ Objects.requireNonNull(throwable);
+ Throwable rootCause = throwable;
+ while (rootCause.getCause() != null) {
+ rootCause = rootCause.getCause();
+ }
+ return rootCause;
+ }
+
+ /**
+ * Calculates the age of a person from a given date.
+ */
+ static class AgeCalculator {
+
+ private AgeCalculator() {
+ }
+
+ public static int calculateAge(String birthDate) throws CalculationException {
+ if (birthDate == null || birthDate.isEmpty()) {
+ throw new IllegalArgumentException();
+ }
+
+ try {
+ return Period
+ .between(parseDate(birthDate), LocalDate.now())
+ .getYears();
+ } catch (DateParseException ex) {
+ throw new CalculationException(ex);
+ }
+ }
+
+ private static LocalDate parseDate(String birthDateAsString) throws DateParseException {
+
+ LocalDate birthDate;
+ try {
+ birthDate = LocalDate.parse(birthDateAsString);
+ } catch (DateTimeParseException ex) {
+ throw new InvalidFormatException(birthDateAsString, ex);
+ }
+
+ if (birthDate.isAfter(LocalDate.now())) {
+ throw new DateOutOfRangeException(birthDateAsString);
+ }
+
+ return birthDate;
+ }
+
+ }
+
+ static class CalculationException extends Exception {
+
+ CalculationException(DateParseException ex) {
+ super(ex);
+ }
+ }
+
+ static class DateParseException extends Exception {
+
+ DateParseException(String input) {
+ super(input);
+ }
+
+ DateParseException(String input, Throwable thr) {
+ super(input, thr);
+ }
+ }
+
+ static class InvalidFormatException extends DateParseException {
+
+ InvalidFormatException(String input, Throwable thr) {
+ super("Invalid date format: " + input, thr);
+ }
+ }
+
+ static class DateOutOfRangeException extends DateParseException {
+
+ DateOutOfRangeException(String date) {
+ super("Date out of range: " + date);
+ }
+
+ }
+
+}
diff --git a/core-java-modules/core-java-time-measurements/pom.xml b/core-java-modules/core-java-time-measurements/pom.xml
index 71a012ca2b..b751cc0d74 100644
--- a/core-java-modules/core-java-time-measurements/pom.xml
+++ b/core-java-modules/core-java-time-measurements/pom.xml
@@ -96,7 +96,7 @@
3.6.1
1.8.9
- 2.0.0-RC.4
+ 2.0.0
1.44
2.22.1
diff --git a/core-kotlin-modules/core-kotlin-collections/src/test/kotlin/com/baeldung/foldvsreduce/FoldAndReduceTest.kt b/core-kotlin-modules/core-kotlin-collections/src/test/kotlin/com/baeldung/foldvsreduce/FoldAndReduceTest.kt
new file mode 100644
index 0000000000..7b263914c6
--- /dev/null
+++ b/core-kotlin-modules/core-kotlin-collections/src/test/kotlin/com/baeldung/foldvsreduce/FoldAndReduceTest.kt
@@ -0,0 +1,59 @@
+package com.baeldung.foldvsreduce
+
+import org.junit.Test
+import org.junit.jupiter.api.assertThrows
+import java.lang.RuntimeException
+import kotlin.test.assertEquals
+
+class FoldAndReduceTest {
+
+ @Test
+ fun testReduceLimitations() {
+ val numbers: List = listOf(1, 2, 3)
+ val sum: Number = numbers.reduce { acc, next -> acc + next }
+ assertEquals(6, sum)
+
+ val emptyList = listOf()
+ assertThrows { emptyList.reduce { acc, next -> acc + next } }
+
+ // doesn't compile
+ // val sum = numbers.reduce { acc, next -> acc.toLong() + next.toLong()}
+ }
+
+ @Test
+ fun testFold() {
+
+ val numbers: List = listOf(1, 2, 3)
+ val sum: Int = numbers.fold(0, { acc, next -> acc + next })
+ assertEquals(6, sum)
+
+ //change result type
+ val sumLong: Long = numbers.fold(0L, { acc, next -> acc + next.toLong() })
+ assertEquals(6L, sumLong)
+
+ val emptyList = listOf()
+ val emptySum = emptyList.fold(0, { acc, next -> acc + next })
+ assertEquals(0, emptySum)
+
+ //power of changing result type
+ val (even, odd) = numbers.fold(Pair(listOf(), listOf()), { acc, next ->
+ if (next % 2 == 0) Pair(acc.first + next, acc.second)
+ else Pair(acc.first, acc.second + next)
+ })
+
+ assertEquals(listOf(2), even)
+ assertEquals(listOf(1, 3), odd)
+ }
+
+ @Test
+ fun testVariationsOfFold() {
+ val numbers = listOf(1, 2, 3)
+ val reversed = numbers.foldRight(listOf(), { next, acc -> acc + next})
+ assertEquals(listOf(3,2,1), reversed)
+
+ val reversedIndexes = numbers.foldRightIndexed(listOf(), { i, _, acc -> acc + i })
+ assertEquals(listOf(2,1,0), reversedIndexes)
+ }
+
+
+}
\ No newline at end of file
diff --git a/jee-7/pom.xml b/jee-7/pom.xml
index 7352c6550a..9077aae1a6 100644
--- a/jee-7/pom.xml
+++ b/jee-7/pom.xml
@@ -256,10 +256,9 @@
- src/main/resources
-
- country.wsdl
-
+
+ http://localhost:8888/ws/country?wsdl
+
true
com.baeldung.soap.ws.client.generated
src/main/java
diff --git a/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java b/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java
index 09f4c29202..a6983938f5 100644
--- a/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java
+++ b/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java
@@ -12,11 +12,11 @@ import javax.xml.ws.WebServiceFeature;
/**
* This class was generated by the JAX-WS RI.
- * JAX-WS RI 2.3.2
+ * JAX-WS RI 2.2.9-b130926.1035
* Generated source version: 2.2
*
*/
-@WebServiceClient(name = "CountryServiceImplService", targetNamespace = "http://server.ws.soap.baeldung.com/", wsdlLocation = "file:src/main/resources/country.wsdl")
+@WebServiceClient(name = "CountryServiceImplService", targetNamespace = "http://server.ws.soap.baeldung.com/", wsdlLocation = "http://localhost:8888/ws/country?wsdl")
public class CountryServiceImplService extends Service {
private final static URL COUNTRYSERVICEIMPLSERVICE_WSDL_LOCATION;
@@ -27,7 +27,7 @@ public class CountryServiceImplService extends Service {
URL url = null;
WebServiceException e = null;
try {
- url = new URL("file:src/main/resources/country.wsdl");
+ url = new URL("http://localhost:8888/ws/country?wsdl");
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
diff --git a/jee-7/src/main/resources/country.wsdl b/jee-7/src/main/resources/country.wsdl
deleted file mode 100644
index 4d41fce322..0000000000
--- a/jee-7/src/main/resources/country.wsdl
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointUnitTest.java b/jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointUnitTest.java
index 744bdfc8f5..c607efeb24 100644
--- a/jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointUnitTest.java
+++ b/jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointUnitTest.java
@@ -1,20 +1,17 @@
package com.baeldung.batch.understanding;
-import static org.junit.jupiter.api.Assertions.*;
-import java.util.Map;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
import java.util.Properties;
+
import javax.batch.operations.JobOperator;
import javax.batch.runtime.BatchRuntime;
import javax.batch.runtime.BatchStatus;
import javax.batch.runtime.JobExecution;
-import javax.batch.runtime.Metric;
import javax.batch.runtime.StepExecution;
-import com.baeldung.batch.understanding.BatchTestHelper;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.Disabled;
-@Disabled("Should be fixed in BAEL-3812")
class CustomCheckPointUnitTest {
@Test
public void givenChunk_whenCustomCheckPoint_thenCommitCountIsThree() throws Exception {
diff --git a/jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceUnitTest.java b/jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceUnitTest.java
index 88b981df92..4b27e5f5ec 100644
--- a/jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceUnitTest.java
+++ b/jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceUnitTest.java
@@ -1,6 +1,8 @@
package com.baeldung.batch.understanding;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.ArrayList;
import java.util.List;
@@ -13,9 +15,7 @@ import javax.batch.runtime.JobExecution;
import javax.batch.runtime.StepExecution;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.Disabled;
-@Disabled("Should be fixed in BAEL-3812")
class JobSequenceUnitTest {
@Test
public void givenTwoSteps_thenBatch_CompleteWithSuccess() throws Exception {
diff --git a/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetUnitTest.java b/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetUnitTest.java
index 3babf9b5aa..788b75eb3e 100644
--- a/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetUnitTest.java
+++ b/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetUnitTest.java
@@ -1,17 +1,16 @@
package com.baeldung.batch.understanding;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Properties;
import javax.batch.operations.JobOperator;
import javax.batch.runtime.BatchRuntime;
import javax.batch.runtime.BatchStatus;
import javax.batch.runtime.JobExecution;
-import java.util.Properties;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Test;
-@Disabled("Should be fixed in BAEL-3812")
class SimpleBatchLetUnitTest {
@Test
public void givenBatchLet_thenBatch_CompleteWithSuccess() throws Exception {
diff --git a/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkUnitTest.java b/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkUnitTest.java
index 5871143fa3..9010c365a2 100644
--- a/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkUnitTest.java
+++ b/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkUnitTest.java
@@ -1,6 +1,7 @@
package com.baeldung.batch.understanding;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import java.util.Map;
@@ -14,9 +15,7 @@ import javax.batch.runtime.Metric;
import javax.batch.runtime.StepExecution;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.Disabled;
-@Disabled("Should be fixed in BAEL-3812")
class SimpleChunkUnitTest {
@Test
public void givenChunk_thenBatch_CompletesWithSucess() throws Exception {
diff --git a/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkUnitTest.java b/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkUnitTest.java
index c53561a0c0..bc410aec8d 100644
--- a/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkUnitTest.java
+++ b/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkUnitTest.java
@@ -1,19 +1,18 @@
package com.baeldung.batch.understanding;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import java.util.Properties;
import javax.batch.operations.JobOperator;
import javax.batch.runtime.BatchRuntime;
import javax.batch.runtime.BatchStatus;
import javax.batch.runtime.JobExecution;
import javax.batch.runtime.StepExecution;
-import java.util.List;
-import java.util.Properties;
-import static org.junit.Assert.assertEquals;
+import org.junit.jupiter.api.Test;
-@Disabled("Should be fixed in BAEL-3812")
class SimpleErrorChunkUnitTest {
@Test
diff --git a/jee-7/src/test/resources/jberet.properties b/jee-7/src/test/resources/jberet.properties
new file mode 100644
index 0000000000..e8b9907de5
--- /dev/null
+++ b/jee-7/src/test/resources/jberet.properties
@@ -0,0 +1 @@
+db-url=jdbc:h2:mem:jberet-repo;DB_CLOSE_DELAY=-1
\ No newline at end of file
diff --git a/jhipster/jhipster-uaa/gateway/pom.xml b/jhipster/jhipster-uaa/gateway/pom.xml
index 1b85877a9b..b417bd7b57 100644
--- a/jhipster/jhipster-uaa/gateway/pom.xml
+++ b/jhipster/jhipster-uaa/gateway/pom.xml
@@ -1013,7 +1013,7 @@
1.0.0
- 0.24.0-RC.0
+ 0.24.0
3.0.0
1.8
diff --git a/jhipster/jhipster-uaa/quotes/pom.xml b/jhipster/jhipster-uaa/quotes/pom.xml
index aacc6f8e36..f088ad2fd1 100644
--- a/jhipster/jhipster-uaa/quotes/pom.xml
+++ b/jhipster/jhipster-uaa/quotes/pom.xml
@@ -910,6 +910,6 @@
${project.basedir}/src/test/
- 0.24.0-RC.0
+ 0.24.0
diff --git a/jhipster/jhipster-uaa/uaa/pom.xml b/jhipster/jhipster-uaa/uaa/pom.xml
index 27a056820d..f9c1f226bb 100644
--- a/jhipster/jhipster-uaa/uaa/pom.xml
+++ b/jhipster/jhipster-uaa/uaa/pom.xml
@@ -835,7 +835,7 @@
1.0.0
- 0.24.0-RC.0
+ 0.24.0
3.0.0
1.8
diff --git a/maven-java-11/README.md b/maven-java-11/README.md
deleted file mode 100644
index b923518825..0000000000
--- a/maven-java-11/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-## Maven and Java 11
-
-This module contains articles about Maven with Java 11+.
-
-### Relevant Articles:
-
diff --git a/maven-java-11/multimodule-maven-project/daomodule/pom.xml b/maven-java-11/multimodule-maven-project/daomodule/pom.xml
deleted file mode 100644
index cbe0b4cb95..0000000000
--- a/maven-java-11/multimodule-maven-project/daomodule/pom.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- 4.0.0
- com.baeldung.daomodule
- daomodule
- 1.0
- daomodule
- jar
-
-
- com.baeldung.multimodule-maven-project
- multimodule-maven-project
- 1.0
-
-
-
diff --git a/maven-java-11/multimodule-maven-project/daomodule/src/main/java/com/baeldung/dao/Dao.java b/maven-java-11/multimodule-maven-project/daomodule/src/main/java/com/baeldung/dao/Dao.java
deleted file mode 100644
index f86ae8abb3..0000000000
--- a/maven-java-11/multimodule-maven-project/daomodule/src/main/java/com/baeldung/dao/Dao.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.baeldung.dao;
-
-import java.util.List;
-import java.util.Optional;
-
-public interface Dao {
-
- Optional findById(int id);
-
- List findAll();
-
-}
diff --git a/maven-java-11/multimodule-maven-project/daomodule/src/main/java/module-info.java b/maven-java-11/multimodule-maven-project/daomodule/src/main/java/module-info.java
deleted file mode 100644
index 072d7ad007..0000000000
--- a/maven-java-11/multimodule-maven-project/daomodule/src/main/java/module-info.java
+++ /dev/null
@@ -1,3 +0,0 @@
-module com.baeldung.dao {
- exports com.baeldung.dao;
-}
diff --git a/maven-java-11/multimodule-maven-project/entitiymodule/pom.xml b/maven-java-11/multimodule-maven-project/entitiymodule/pom.xml
deleted file mode 100644
index 228619ed74..0000000000
--- a/maven-java-11/multimodule-maven-project/entitiymodule/pom.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
- 4.0.0
- com.baeldung.entitymodule
- entitymodule
- 1.0
- entitymodule
- jar
-
-
- com.baeldung.multimodule-maven-project
- multimodule-maven-project
- 1.0
-
-
-
- 11
- 11
-
-
-
diff --git a/maven-java-11/multimodule-maven-project/entitiymodule/src/main/java/com/baeldung/entity/User.java b/maven-java-11/multimodule-maven-project/entitiymodule/src/main/java/com/baeldung/entity/User.java
deleted file mode 100644
index 22022a2e6d..0000000000
--- a/maven-java-11/multimodule-maven-project/entitiymodule/src/main/java/com/baeldung/entity/User.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.baeldung.entity;
-
-public class User {
-
- private final String name;
-
- public User(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- @Override
- public String toString() {
- return "User{" + "name=" + name + '}';
- }
-}
diff --git a/maven-java-11/multimodule-maven-project/entitiymodule/src/main/java/module-info.java b/maven-java-11/multimodule-maven-project/entitiymodule/src/main/java/module-info.java
deleted file mode 100644
index 67a3097352..0000000000
--- a/maven-java-11/multimodule-maven-project/entitiymodule/src/main/java/module-info.java
+++ /dev/null
@@ -1,3 +0,0 @@
-module com.baeldung.entity {
- exports com.baeldung.entity;
-}
diff --git a/maven-java-11/multimodule-maven-project/mainppmodule/pom.xml b/maven-java-11/multimodule-maven-project/mainppmodule/pom.xml
deleted file mode 100644
index a4a6575906..0000000000
--- a/maven-java-11/multimodule-maven-project/mainppmodule/pom.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
- 4.0.0
- com.baeldung.mainappmodule
- mainappmodule
- 1.0
- mainappmodule
- jar
-
-
- com.baeldung.multimodule-maven-project
- multimodule-maven-project
- 1.0
- 1.0
- 1.0
- 1.0
-
-
-
-
- com.baeldung.entitymodule
- entitymodule
- ${entitymodule.version}
-
-
- com.baeldung.daomodule
- daomodule
- ${daomodule.version}
-
-
- com.baeldung.userdaomodule
- userdaomodule
- ${userdaomodule.version}
-
-
-
-
diff --git a/maven-java-11/multimodule-maven-project/mainppmodule/src/main/java/com/baeldung/mainapp/Application.java b/maven-java-11/multimodule-maven-project/mainppmodule/src/main/java/com/baeldung/mainapp/Application.java
deleted file mode 100644
index 0c0df7461b..0000000000
--- a/maven-java-11/multimodule-maven-project/mainppmodule/src/main/java/com/baeldung/mainapp/Application.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.baeldung.mainapp;
-
-import com.baeldung.dao.Dao;
-import com.baeldung.entity.User;
-import com.baeldung.userdao.UserDao;
-import java.util.HashMap;
-import java.util.Map;
-
-public class Application {
-
- public static void main(String[] args) {
- Map users = new HashMap<>();
- users.put(1, new User("Julie"));
- users.put(2, new User("David"));
- Dao userDao = new UserDao(users);
- userDao.findAll().forEach(System.out::println);
- }
-
-}
diff --git a/maven-java-11/multimodule-maven-project/mainppmodule/src/main/java/module-info.java b/maven-java-11/multimodule-maven-project/mainppmodule/src/main/java/module-info.java
deleted file mode 100644
index c688fcf7de..0000000000
--- a/maven-java-11/multimodule-maven-project/mainppmodule/src/main/java/module-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-module com.baeldung.mainapp {
- requires com.baeldung.entity;
- requires com.baeldung.userdao;
- requires com.baeldung.dao;
- uses com.baeldung.dao.Dao;
-}
diff --git a/maven-java-11/multimodule-maven-project/pom.xml b/maven-java-11/multimodule-maven-project/pom.xml
deleted file mode 100644
index 65f5b7a814..0000000000
--- a/maven-java-11/multimodule-maven-project/pom.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
- 4.0.0
- com.baeldung.multimodule-maven-project
- multimodule-maven-project
- 1.0
- multimodule-maven-project
- pom
-
-
- com.baeldung.maven-java-11
- maven-java-11
- 1.0
-
-
-
- entitymodule
- daomodule
- userdaomodule
- mainappmodule
-
-
-
-
-
- junit
- junit
- ${junit.version}
- test
-
-
- org.assertj
- assertj-core
- ${assertj.version}
- test
-
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${compiler.plugin.version}
-
- ${source.version}
- ${target.version}
-
-
-
-
-
-
-
- UTF-8
- 4.12
- 3.12.2
- 3.8.0
- 11
- 11
-
-
-
diff --git a/maven-java-11/multimodule-maven-project/userdaomodule/pom.xml b/maven-java-11/multimodule-maven-project/userdaomodule/pom.xml
deleted file mode 100644
index cf6ea85cb5..0000000000
--- a/maven-java-11/multimodule-maven-project/userdaomodule/pom.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- 4.0.0
- com.baeldung.userdaomodule
- userdaomodule
- 1.0
- userdaomodule
- jar
-
-
- com.baeldung.multimodule-maven-project
- multimodule-maven-project
- 1.0
-
-
-
-
- com.baeldung.entitymodule
- entitymodule
- ${entitymodule.version}1.0
-
-
- com.baeldung.daomodule
- daomodule
- ${daomodule.version}
-
-
- junit
- junit
- test
-
-
-
-
- 1.0
- 1.0
-
-
-
diff --git a/maven-java-11/multimodule-maven-project/userdaomodule/src/main/java/com/baeldung/userdao/UserDao.java b/maven-java-11/multimodule-maven-project/userdaomodule/src/main/java/com/baeldung/userdao/UserDao.java
deleted file mode 100644
index 1f1ea38a60..0000000000
--- a/maven-java-11/multimodule-maven-project/userdaomodule/src/main/java/com/baeldung/userdao/UserDao.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.baeldung.userdao;
-
-import com.baeldung.dao.Dao;
-import com.baeldung.entity.User;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-public class UserDao implements Dao {
-
- private final Map users;
-
- public UserDao() {
- users = new HashMap<>();
- }
-
- public UserDao(Map users) {
- this.users = users;
- }
-
- @Override
- public List findAll() {
- return new ArrayList<>(users.values());
- }
-
- @Override
- public Optional findById(int id) {
- return Optional.ofNullable(users.get(id));
- }
-}
\ No newline at end of file
diff --git a/maven-java-11/multimodule-maven-project/userdaomodule/src/main/java/module-info.java b/maven-java-11/multimodule-maven-project/userdaomodule/src/main/java/module-info.java
deleted file mode 100644
index f1cb217e23..0000000000
--- a/maven-java-11/multimodule-maven-project/userdaomodule/src/main/java/module-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-module com.baeldung.userdao {
- requires com.baeldung.entity;
- requires com.baeldung.dao;
- provides com.baeldung.dao.Dao with com.baeldung.userdao.UserDao;
- exports com.baeldung.userdao;
-}
diff --git a/maven-java-11/multimodule-maven-project/userdaomodule/src/test/java/com/baeldung/userdao/test/UserDaoUnitTest.java b/maven-java-11/multimodule-maven-project/userdaomodule/src/test/java/com/baeldung/userdao/test/UserDaoUnitTest.java
deleted file mode 100644
index 191d17ff32..0000000000
--- a/maven-java-11/multimodule-maven-project/userdaomodule/src/test/java/com/baeldung/userdao/test/UserDaoUnitTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.baeldung.userdao.test;
-
-import com.baeldung.dao.Dao;
-import com.baeldung.entity.User;
-import com.baeldung.userdao.UserDao;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import static org.junit.Assert.*;
-import static org.hamcrest.CoreMatchers.*;
-import org.junit.Before;
-import org.junit.Test;
-
-public class UserDaoUnitTest {
-
- private Dao userDao;
-
- @Before
- public void setUpUserDaoInstance() {
- Map users = new HashMap<>();
- users.put(1, new User("Julie"));
- users.put(2, new User("David"));
- userDao = new UserDao(users);
- }
-
- @Test
- public void givenUserDaoIntance_whenCalledFindById_thenCorrect() {
- assertThat(userDao.findById(1), isA(Optional.class));
- }
-
- @Test
- public void givenUserDaoIntance_whenCalledFindAll_thenCorrect() {
- assertThat(userDao.findAll(), isA(List.class));
- }
-}
diff --git a/maven-java-11/pom.xml b/maven-java-11/pom.xml
deleted file mode 100644
index 10e80365c8..0000000000
--- a/maven-java-11/pom.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
- 4.0.0
- com.baeldung.maven-java-11
- maven-java-11
- 1.0
- maven-java-11
- pom
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
- multimodule-maven-project
-
-
-
- UTF-8
- 11
- 11
-
-
-
diff --git a/mybatis/src/main/java/com/baeldung/mybatis/mapper/AddressMapper.java b/mybatis/src/main/java/com/baeldung/mybatis/mapper/AddressMapper.java
index e96a4837db..c79ef667bd 100644
--- a/mybatis/src/main/java/com/baeldung/mybatis/mapper/AddressMapper.java
+++ b/mybatis/src/main/java/com/baeldung/mybatis/mapper/AddressMapper.java
@@ -14,8 +14,8 @@ public interface AddressMapper {
@Results(value = { @Result(property = "addressId", column = "addressId"),
@Result(property = "streetAddress", column = "streetAddress"),
@Result(property = "person", column = "personId", javaType = Person.class, one = @One(select = "getPerson")) })
- Address getAddresses(Integer addressID);
+ Address getAddresses(Integer addressId);
@Select("SELECT personId FROM address WHERE addressId = #{addressId})")
- Person getPerson(Integer personId);
+ Person getPerson(Integer addressId);
}
diff --git a/patterns/solid/src/main/java/com/baeldung/s/TextManipulator.java b/patterns/solid/src/main/java/com/baeldung/s/TextManipulator.java
new file mode 100644
index 0000000000..a6b32a0ff9
--- /dev/null
+++ b/patterns/solid/src/main/java/com/baeldung/s/TextManipulator.java
@@ -0,0 +1,35 @@
+package com.baeldung.s;
+
+public class TextManipulator {
+ private String text;
+
+ public TextManipulator(String text) {
+ this.text = text;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void appendText(String newText) {
+ text = text.concat(newText);
+ }
+
+ public void findWordAndReplace(String word, String replacementWord) {
+ if (text.contains(word)) {
+ text = text.replace(word, replacementWord);
+ } else System.out.println("Word you want to replace is not found in the text");
+ }
+
+ public void findWordAndDelete(String word) {
+ if (text.contains(word)) {
+ text = text.replace(word, "");
+ } else System.out.println("Word you want to delete is not found in the text");
+ }
+
+ /*
+ * Bad practice when implementing SRP principle, not in the scope of this class
+ public void printText() {
+ System.out.println(textManipulator.getText());
+ }*/
+}
diff --git a/patterns/solid/src/main/java/com/baeldung/s/TextPrinter.java b/patterns/solid/src/main/java/com/baeldung/s/TextPrinter.java
new file mode 100644
index 0000000000..d6a413e7ac
--- /dev/null
+++ b/patterns/solid/src/main/java/com/baeldung/s/TextPrinter.java
@@ -0,0 +1,23 @@
+package com.baeldung.s;
+
+import java.util.Arrays;
+
+public class TextPrinter {
+ TextManipulator textManipulator;
+
+ public TextPrinter(TextManipulator textManipulator) {
+ this.textManipulator = textManipulator;
+ }
+
+ public void printText() {
+ System.out.println(textManipulator.getText());
+ }
+
+ public void printOutEachWordOfText() {
+ System.out.println(Arrays.toString(textManipulator.getText().split(" ")));
+ }
+
+ public void printRangeOfCharacters(int startingIndex, int endIndex) {
+ System.out.println(textManipulator.getText().substring(startingIndex, endIndex));
+ }
+}
diff --git a/persistence-modules/java-jpa-2/pom.xml b/persistence-modules/java-jpa-2/pom.xml
index f79f6f1633..ab5bb39dfc 100644
--- a/persistence-modules/java-jpa-2/pom.xml
+++ b/persistence-modules/java-jpa-2/pom.xml
@@ -48,6 +48,17 @@
${postgres.version}
runtime
+
+ com.querydsl
+ querydsl-apt
+ ${querydsl.version}
+ provided
+
+
+ com.querydsl
+ querydsl-jpa
+ ${querydsl.version}
+
org.assertj
@@ -101,23 +112,41 @@
target/metamodel
+ ${project.build.directory}/generated-sources/java/
+
+ com.mysema.maven
+ apt-maven-plugin
+ 1.1.3
+
+
+
+ process
+
+
+ target/generated-sources/java
+ com.querydsl.apt.jpa.JPAAnnotationProcessor
+
+
+
+
- 5.4.0.Final
- 2.7.4-RC1
+ 5.4.14.Final
+ 2.7.4
42.2.5
2.2
3.11.1
3.5.1
3.3.3
3.0.0
+ 4.3.1
-
\ No newline at end of file
+
diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Cocktail.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Cocktail.java
new file mode 100644
index 0000000000..96310c1cc5
--- /dev/null
+++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Cocktail.java
@@ -0,0 +1,90 @@
+package com.baeldung.jpa.unrelated.entities;
+
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
+import org.hibernate.annotations.NotFound;
+import org.hibernate.annotations.NotFoundAction;
+
+import javax.persistence.*;
+import java.util.List;
+import java.util.Objects;
+
+@Entity
+@Table(name = "menu")
+public class Cocktail {
+ @Id
+ @Column(name = "cocktail_name")
+ private String name;
+
+ @Column
+ private double price;
+
+ @Column(name = "category")
+ private String category;
+
+ @OneToOne
+ @NotFound(action = NotFoundAction.IGNORE)
+ @JoinColumn(name = "cocktail_name",
+ referencedColumnName = "cocktail",
+ insertable = false, updatable = false,
+ foreignKey = @javax.persistence
+ .ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
+ private Recipe recipe;
+
+ @OneToMany(fetch = FetchType.LAZY)
+ @NotFound(action = NotFoundAction.IGNORE)
+ @JoinColumn(
+ name = "cocktail",
+ referencedColumnName = "cocktail_name",
+ insertable = false,
+ updatable = false,
+ foreignKey = @javax.persistence
+ .ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
+ private List recipeList;
+
+ public Cocktail() {
+ }
+
+ public Cocktail(String name, double price, String baseIngredient) {
+ this.name = name;
+ this.price = price;
+ this.category = baseIngredient;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public double getPrice() {
+ return price;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public Recipe getRecipe() {
+ return recipe;
+ }
+
+ public List getRecipeList() {
+ return recipeList;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ Cocktail cocktail = (Cocktail) o;
+ return Double.compare(cocktail.price, price) == 0 &&
+ Objects.equals(name, cocktail.name) &&
+ Objects.equals(category, cocktail.category);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, price, category);
+ }
+}
diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/MultipleRecipe.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/MultipleRecipe.java
new file mode 100644
index 0000000000..8664d6fd7f
--- /dev/null
+++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/MultipleRecipe.java
@@ -0,0 +1,71 @@
+package com.baeldung.jpa.unrelated.entities;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.Objects;
+
+@Entity
+@Table(name = "multiple_recipes")
+public class MultipleRecipe {
+ @Id
+ @Column(name = "id")
+ private Long id;
+
+ @Column(name = "cocktail")
+ private String cocktail;
+
+ @Column(name = "instructions")
+ private String instructions;
+
+ @Column(name = "base_ingredient")
+ private String baseIngredient;
+
+ public MultipleRecipe() {
+ }
+
+ public MultipleRecipe(Long id, String cocktail,
+ String instructions, String baseIngredient) {
+ this.id = id;
+ this.cocktail = cocktail;
+ this.instructions = instructions;
+ this.baseIngredient = baseIngredient;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getCocktail() {
+ return cocktail;
+ }
+
+ public String getInstructions() {
+ return instructions;
+ }
+
+ public String getBaseIngredient() {
+ return baseIngredient;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ MultipleRecipe that = (MultipleRecipe) o;
+
+ return Objects.equals(id, that.id) &&
+ Objects.equals(cocktail, that.cocktail) &&
+ Objects.equals(instructions, that.instructions) &&
+ Objects.equals(baseIngredient, that.baseIngredient);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, cocktail,
+ instructions, baseIngredient);
+ }
+}
diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Recipe.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Recipe.java
new file mode 100644
index 0000000000..4b3d200b60
--- /dev/null
+++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Recipe.java
@@ -0,0 +1,50 @@
+package com.baeldung.jpa.unrelated.entities;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.Objects;
+
+@Entity
+@Table(name="recipes")
+public class Recipe {
+ @Id
+ @Column(name = "cocktail")
+ private String cocktail;
+
+ @Column
+ private String instructions;
+
+ public Recipe() {
+ }
+
+ public Recipe(String cocktail, String instructions) {
+ this.cocktail = cocktail;
+ this.instructions = instructions;
+ }
+
+ public String getCocktail() {
+ return cocktail;
+ }
+
+ public String getInstructions() {
+ return instructions;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ Recipe recipe = (Recipe) o;
+ return Objects.equals(cocktail, recipe.cocktail)
+ && Objects.equals(instructions, recipe.instructions);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(cocktail, instructions);
+ }
+}
diff --git a/persistence-modules/java-jpa-2/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa-2/src/main/resources/META-INF/persistence.xml
index 11e007973f..eec7f7cf6e 100644
--- a/persistence-modules/java-jpa-2/src/main/resources/META-INF/persistence.xml
+++ b/persistence-modules/java-jpa-2/src/main/resources/META-INF/persistence.xml
@@ -162,5 +162,26 @@
value="false" />
-
-
\ No newline at end of file
+
+
+ org.hibernate.jpa.HibernatePersistenceProvider
+ com.baeldung.jpa.unrelated.entities.Cocktail
+ com.baeldung.jpa.unrelated.entities.Recipe
+ com.baeldung.jpa.unrelated.entities.MultipleRecipe
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/unrelated/entities/UnrelatedEntitiesUnitTest.java b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/unrelated/entities/UnrelatedEntitiesUnitTest.java
new file mode 100644
index 0000000000..044e59b16e
--- /dev/null
+++ b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/unrelated/entities/UnrelatedEntitiesUnitTest.java
@@ -0,0 +1,189 @@
+package com.baeldung.jpa.unrelated.entities;
+
+import javax.persistence.*;
+
+import com.querydsl.jpa.impl.JPAQuery;
+import org.junit.jupiter.api.*;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class UnrelatedEntitiesUnitTest {
+ private static EntityManagerFactory entityManagerFactory;
+ private static EntityManager entityManager;
+ private static Cocktail mojito;
+ private static Cocktail ginTonic;
+
+ @BeforeAll
+ public static void setup() {
+ entityManagerFactory = Persistence.createEntityManagerFactory("jpa-h2-unrelated-entities");
+ entityManager = entityManagerFactory.createEntityManager();
+ mojito = new Cocktail("Mojito", 11, "Rum");
+ ginTonic = new Cocktail("Gin tonic", 8.50, "Gin");
+ entityManager.getTransaction().begin();
+ entityManager.persist(mojito);
+ entityManager.persist(ginTonic);
+ entityManager.persist(new Recipe(mojito.getName(), "Some instructions"));
+ entityManager.persist(new MultipleRecipe(1L, mojito.getName(),
+ "some instructions", mojito.getCategory()));
+ entityManager.persist(new MultipleRecipe(2L, mojito.getName(),
+ "some other instructions", mojito.getCategory()));
+ entityManager.getTransaction().commit();
+ }
+
+ @AfterAll
+ public static void closeSession() {
+ entityManager.close();
+ }
+
+
+ @Test
+ public void givenCocktailsWithRecipe_whenQuerying_thenTheExpectedCocktailsReturned() {
+ // JPA
+ Cocktail cocktail = entityManager.createQuery("select c "
+ + "from Cocktail c join c.recipe", Cocktail.class)
+ .getSingleResult();
+ verifyResult(mojito, cocktail);
+
+ cocktail = entityManager.createQuery("select c "
+ + "from Cocktail c join Recipe r "
+ + "on c.name = r.cocktail", Cocktail.class)
+ .getSingleResult();
+ verifyResult(mojito, cocktail);
+
+ // QueryDSL
+ cocktail = new JPAQuery(entityManager).from(QCocktail.cocktail)
+ .join(QCocktail.cocktail.recipe)
+ .fetchOne();
+ verifyResult(mojito, cocktail);
+
+ cocktail = new JPAQuery(entityManager).from(QCocktail.cocktail)
+ .join(QRecipe.recipe)
+ .on(QCocktail.cocktail.name.eq(QRecipe.recipe.cocktail))
+ .fetchOne();
+ verifyResult(mojito, cocktail);
+ }
+
+ @Test
+ public void givenCocktailsWithoutRecipe_whenQuerying_thenTheExpectedCocktailsReturned() {
+ Cocktail cocktail = entityManager.createQuery("select c "
+ + "from Cocktail c left join c.recipe r "
+ + "where r is null", Cocktail.class)
+ .getSingleResult();
+ verifyResult(ginTonic, cocktail);
+
+ cocktail = entityManager.createQuery("select c "
+ + "from Cocktail c left join Recipe r "
+ + "on c.name = r.cocktail "
+ + "where r is null", Cocktail.class)
+ .getSingleResult();
+ verifyResult(ginTonic, cocktail);
+
+ QRecipe recipe = new QRecipe("alias");
+ cocktail = new JPAQuery(entityManager).from(QCocktail.cocktail)
+ .leftJoin(QCocktail.cocktail.recipe, recipe)
+ .where(recipe.isNull())
+ .fetchOne();
+ verifyResult(ginTonic, cocktail);
+
+ cocktail = new JPAQuery(entityManager).from(QCocktail.cocktail)
+ .leftJoin(QRecipe.recipe)
+ .on(QCocktail.cocktail.name.eq(QRecipe.recipe.cocktail))
+ .where(QRecipe.recipe.isNull())
+ .fetchOne();
+ verifyResult(ginTonic, cocktail);
+ }
+
+ @Test
+ public void givenCocktailsWithMultipleRecipes_whenQuerying_thenTheExpectedCocktailsReturned() {
+ // JPQL
+ Cocktail cocktail = entityManager.createQuery("select c "
+ + "from Cocktail c join c.recipeList", Cocktail.class)
+ .getSingleResult();
+ verifyResult(mojito, cocktail);
+
+ cocktail = entityManager.createQuery("select c "
+ + "from Cocktail c join MultipleRecipe mr "
+ + "on mr.cocktail = c.name", Cocktail.class)
+ .getSingleResult();
+ verifyResult(mojito, cocktail);
+
+ // QueryDSL
+ cocktail = new JPAQuery(entityManager).from(QCocktail.cocktail)
+ .join(QCocktail.cocktail.recipeList)
+ .fetchOne();
+ verifyResult(mojito, cocktail);
+
+ cocktail = new JPAQuery(entityManager).from(QCocktail.cocktail)
+ .join(QMultipleRecipe.multipleRecipe)
+ .on(QCocktail.cocktail.name.eq(QMultipleRecipe.multipleRecipe.cocktail))
+ .fetchOne();
+ verifyResult(mojito, cocktail);
+ }
+
+ @Test
+ public void givenCocktailsWithoutMultipleRecipes_whenQuerying_thenTheExpectedCocktailsReturned() {
+ // JPQL
+ Cocktail cocktail = entityManager.createQuery("select c "
+ + "from Cocktail c left join c.recipeList r "
+ + "where r is null", Cocktail.class)
+ .getSingleResult();
+ verifyResult(ginTonic, cocktail);
+
+ cocktail = entityManager.createQuery("select c "
+ + "from Cocktail c left join MultipleRecipe r "
+ + "on c.name = r.cocktail "
+ + "where r is null", Cocktail.class)
+ .getSingleResult();
+ verifyResult(ginTonic, cocktail);
+
+ // QueryDSL
+ QMultipleRecipe multipleRecipe = new QMultipleRecipe("alias");
+ cocktail = new JPAQuery(entityManager).from(QCocktail.cocktail)
+ .leftJoin(QCocktail.cocktail.recipeList, multipleRecipe)
+ .where(multipleRecipe.isNull())
+ .fetchOne();
+ verifyResult(ginTonic, cocktail);
+
+ cocktail = new JPAQuery(entityManager).from(QCocktail.cocktail)
+ .leftJoin(QMultipleRecipe.multipleRecipe)
+ .on(QCocktail.cocktail.name.eq(QMultipleRecipe.multipleRecipe.cocktail))
+ .where(QMultipleRecipe.multipleRecipe.isNull())
+ .fetchOne();
+ verifyResult(ginTonic, cocktail);
+ }
+
+ @Test
+ public void givenMultipleRecipesWithCocktails_whenQuerying_thenTheExpectedMultipleRecipesReturned() {
+ Consumer> verifyResult = recipes -> {
+ assertEquals(2, recipes.size());
+ recipes.forEach(r -> assertEquals(mojito.getName(), r.getCocktail()));
+ };
+
+ // JPQL
+ List recipes = entityManager.createQuery("select distinct r "
+ + "from MultipleRecipe r "
+ + "join Cocktail c "
+ + "on r.baseIngredient = c.category",
+ MultipleRecipe.class).getResultList();
+
+ verifyResult.accept(recipes);
+
+ // QueryDSL
+ QCocktail cocktail = QCocktail.cocktail;
+ QMultipleRecipe multipleRecipe = QMultipleRecipe.multipleRecipe;
+ recipes = new JPAQuery(entityManager).from(multipleRecipe)
+ .join(cocktail)
+ .on(multipleRecipe.baseIngredient.eq(cocktail.category))
+ .fetch();
+
+ verifyResult.accept(recipes);
+ }
+
+ private void verifyResult(Cocktail expectedCocktail, Cocktail queryResult) {
+ assertNotNull(queryResult);
+ assertEquals(expectedCocktail, queryResult);
+ }
+}
diff --git a/persistence-modules/java-jpa/pom.xml b/persistence-modules/java-jpa/pom.xml
index 762c541d96..3601721dac 100644
--- a/persistence-modules/java-jpa/pom.xml
+++ b/persistence-modules/java-jpa/pom.xml
@@ -106,7 +106,7 @@
5.4.0.Final
- 2.7.4-RC1
+ 2.7.4
42.2.5
2.2
3.3.3
diff --git a/persistence-modules/spring-data-mongodb/README.md b/persistence-modules/spring-data-mongodb/README.md
index c4f21dffc0..381bf83fa8 100644
--- a/persistence-modules/spring-data-mongodb/README.md
+++ b/persistence-modules/spring-data-mongodb/README.md
@@ -13,3 +13,12 @@
- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
- [Spring Data MongoDB Transactions](https://www.baeldung.com/spring-data-mongodb-transactions )
- [ZonedDateTime with Spring Data MongoDB](https://www.baeldung.com/spring-data-mongodb-zoneddatetime)
+
+
+## Spring Data MongoDB Live Testing
+
+
+There are 3 scripts to simplify running live tests:
+1. [`live-test-setup.sh`](src/live-test/resources/live-test-setup.sh) builds a docker image with the necessary setup and runs it. The environment is ready, when the log stops - it takes approximately 30 seconds.
+2. [`live-test.sh`](src/live-test/resources/live-test.sh) runs the live tests (but no other tests).
+3. [`live-test-teardown.sh`](src/live-test/resources/live-test-teardown.sh) stops and removes the docker image.
diff --git a/persistence-modules/spring-data-mongodb/src/live-test/resources/Dockerfile b/persistence-modules/spring-data-mongodb/src/live-test/resources/Dockerfile
new file mode 100644
index 0000000000..9e3634feb0
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb/src/live-test/resources/Dockerfile
@@ -0,0 +1,8 @@
+FROM mongo:4.2.1
+
+COPY init-session.js /docker-entrypoint-initdb.d/
+
+EXPOSE 27017
+
+HEALTHCHECK --interval=5s --timeout=3s --start-period=10s CMD mongo db.stats()
+CMD ["mongod", "--replSet", "rs0"]
diff --git a/persistence-modules/spring-data-mongodb/src/live-test/resources/init-session.js b/persistence-modules/spring-data-mongodb/src/live-test/resources/init-session.js
new file mode 100644
index 0000000000..2e968884cc
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb/src/live-test/resources/init-session.js
@@ -0,0 +1 @@
+rs.initiate();
diff --git a/persistence-modules/spring-data-mongodb/src/live-test/resources/live-test-setup.sh b/persistence-modules/spring-data-mongodb/src/live-test/resources/live-test-setup.sh
new file mode 100644
index 0000000000..78968d51aa
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb/src/live-test/resources/live-test-setup.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+docker image build -t spring-data-mongodb:live-test .
+
+docker run -p 27017:27017 --name spring-data-mongodb-live-test spring-data-mongodb:live-test
diff --git a/persistence-modules/spring-data-mongodb/src/live-test/resources/live-test-teardown.sh b/persistence-modules/spring-data-mongodb/src/live-test/resources/live-test-teardown.sh
new file mode 100644
index 0000000000..a29163bc7a
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb/src/live-test/resources/live-test-teardown.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+docker stop spring-data-mongodb-live-test
+docker rm spring-data-mongodb-live-test
diff --git a/persistence-modules/spring-data-mongodb/src/live-test/resources/live-test.sh b/persistence-modules/spring-data-mongodb/src/live-test/resources/live-test.sh
new file mode 100644
index 0000000000..307a68a3bd
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb/src/live-test/resources/live-test.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+mvn clean compile test -P live-all -f ../../../pom.xml
diff --git a/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionalLiveTest.java b/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionalLiveTest.java
index bafcd770ec..6cd9657006 100644
--- a/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionalLiveTest.java
+++ b/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionalLiveTest.java
@@ -62,24 +62,6 @@ public class MongoTransactionalLiveTest {
}
}
- @Test(expected = MongoCommandException.class)
- @Transactional
- public void whenCountDuringMongoTransaction_thenException() {
- userRepository.save(new User("John", 30));
- userRepository.save(new User("Ringo", 35));
- userRepository.count();
- }
-
- @Test
- @Transactional
- public void whenQueryDuringMongoTransaction_thenSuccess() {
- userRepository.save(new User("Jane", 20));
- userRepository.save(new User("Nick", 33));
- List users = mongoTemplate.find(new Query(), User.class);
-
- assertTrue(users.size() > 1);
- }
-
// ==== Using test instead of before and after due to @transactional doesn't allow list collection
@Test
diff --git a/pom.xml b/pom.xml
index 44a94095b3..2f4579c999 100644
--- a/pom.xml
+++ b/pom.xml
@@ -814,6 +814,7 @@
vaadin
vavr
+ vavr-2
@@ -1313,10 +1314,41 @@
vaadin
vavr
+ vavr-2
+
+ live-all
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ **/SpringContextTest.java
+ **/*UnitTest.java
+ **/*IntegrationTest.java
+ **/*IntTest.java
+ **/*LongRunningUnitTest.java
+ **/*ManualTest.java
+ **/*JdbcTest.java
+
+
+ **/*LiveTest.java
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-5-security/src/main/java/com/baeldung/manuallogout/BasicAuthController.java b/spring-5-security/src/main/java/com/baeldung/manuallogout/BasicAuthController.java
deleted file mode 100644
index 8f01940dce..0000000000
--- a/spring-5-security/src/main/java/com/baeldung/manuallogout/BasicAuthController.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.baeldung.manuallogout;
-
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-@Controller
-public class BasicAuthController {
-
- @RequestMapping(value = {"/basiclogout"}, method = RequestMethod.POST)
- public String logout(HttpServletRequest request, HttpServletResponse response) {
- HttpSession session;
- SecurityContextHolder.clearContext();
- session = request.getSession(false);
- if (session != null) {
- session.invalidate();
- }
- for (Cookie cookie : request.getCookies()) {
- String cookieName = cookie.getName();
- Cookie cookieToDelete = new Cookie(cookieName, null);
- cookieToDelete.setMaxAge(0);
- response.addCookie(cookieToDelete);
- }
- return "redirect:/login?logout";
- }
-}
diff --git a/spring-5-security/src/main/java/com/baeldung/manuallogout/ClearSiteDataController.java b/spring-5-security/src/main/java/com/baeldung/manuallogout/ClearSiteDataController.java
deleted file mode 100644
index 7eef397da3..0000000000
--- a/spring-5-security/src/main/java/com/baeldung/manuallogout/ClearSiteDataController.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.baeldung.manuallogout;
-
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.authentication.logout.HeaderWriterLogoutHandler;
-import org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter;
-import org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-@Controller
-public class ClearSiteDataController {
-
- Directive[] SOURCE = {Directive.COOKIES, Directive.STORAGE, Directive.EXECUTION_CONTEXTS, Directive.CACHE};
-
- @RequestMapping(value = {"/csdlogout"}, method = RequestMethod.POST)
- public String logout(HttpServletRequest request, HttpServletResponse response) {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- if (auth != null) {
- ClearSiteDataHeaderWriter csdHeaderWriter = new ClearSiteDataHeaderWriter(SOURCE);
- new HeaderWriterLogoutHandler(csdHeaderWriter).logout(request, response, auth);
- }
- return "redirect:/login?logout";
- }
-}
diff --git a/spring-5-security/src/main/java/com/baeldung/manuallogout/SimpleSecurityConfiguration.java b/spring-5-security/src/main/java/com/baeldung/manuallogout/SimpleSecurityConfiguration.java
index 6f14f6fca2..63394b64f2 100644
--- a/spring-5-security/src/main/java/com/baeldung/manuallogout/SimpleSecurityConfiguration.java
+++ b/spring-5-security/src/main/java/com/baeldung/manuallogout/SimpleSecurityConfiguration.java
@@ -1,39 +1,80 @@
package com.baeldung.manuallogout;
import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler;
+import org.springframework.security.web.authentication.logout.HeaderWriterLogoutHandler;
+import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
+import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices;
+import org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter;
+
+import javax.servlet.http.Cookie;
+
+import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.*;
@Configuration
@EnableWebSecurity
-public class SimpleSecurityConfiguration extends WebSecurityConfigurerAdapter {
+public class SimpleSecurityConfiguration {
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http.formLogin()
- .loginProcessingUrl("/login")
- .loginPage("/login")
- .usernameParameter("username")
- .passwordParameter("password")
- .defaultSuccessUrl("/")
- .failureUrl("/login?error");
+ @Order(3)
+ @Configuration
+ public static class DefaultLogoutConfiguration extends WebSecurityConfigurerAdapter {
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .antMatcher("/basic/**")
+ .authorizeRequests(authz -> authz.anyRequest().permitAll())
+ .logout(logout -> logout
+ .logoutUrl("/basic/basiclogout")
+ .addLogoutHandler(new SecurityContextLogoutHandler())
+ .addLogoutHandler(new CookieClearingLogoutHandler(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY))
+ );
+ }
}
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.inMemoryAuthentication()
- .withUser("user")
- .password("password")
- .roles("USER")
- .and()
- .withUser("manager")
- .password("password")
- .credentialsExpired(true)
- .accountExpired(true)
- .accountLocked(true)
- .authorities("WRITE_PRIVILEGES", "READ_PRIVILEGES")
- .roles("MANAGER");
+ @Order(2)
+ @Configuration
+ public static class AllCookieClearingLogoutConfiguration extends WebSecurityConfigurerAdapter {
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .antMatcher("/cookies/**")
+ .authorizeRequests(authz -> authz.anyRequest().permitAll())
+ .logout(logout -> logout
+ .logoutUrl("/cookies/cookielogout")
+ .addLogoutHandler(new SecurityContextLogoutHandler())
+ .addLogoutHandler((request, response, auth) -> {
+ for (Cookie cookie : request.getCookies()) {
+ String cookieName = cookie.getName();
+ Cookie cookieToDelete = new Cookie(cookieName, null);
+ cookieToDelete.setMaxAge(0);
+ response.addCookie(cookieToDelete);
+ }
+ }
+ ));
+ }
+ }
+
+ @Order(1)
+ @Configuration
+ public static class ClearSiteDataHeaderLogoutConfiguration extends WebSecurityConfigurerAdapter {
+
+ private static final ClearSiteDataHeaderWriter.Directive[] SOURCE =
+ { CACHE, COOKIES, STORAGE, EXECUTION_CONTEXTS };
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .antMatcher("/csd/**")
+ .authorizeRequests(authz -> authz.anyRequest().permitAll())
+ .logout(logout -> logout
+ .logoutUrl("/csd/csdlogout")
+ .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(SOURCE)))
+ );
+ }
}
}
diff --git a/spring-5-security/src/test/java/com/baeldung/manuallogout/ManualLogoutIntegrationTest.java b/spring-5-security/src/test/java/com/baeldung/manuallogout/ManualLogoutIntegrationTest.java
index a64cb82910..09e7daf877 100644
--- a/spring-5-security/src/test/java/com/baeldung/manuallogout/ManualLogoutIntegrationTest.java
+++ b/spring-5-security/src/test/java/com/baeldung/manuallogout/ManualLogoutIntegrationTest.java
@@ -7,6 +7,7 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
@@ -36,7 +37,22 @@ public class ManualLogoutIntegrationTest {
@WithMockUser(value = "spring")
@Test
- public void givenLoggedUserWhenUserLogoutThenSessionCleared() throws Exception {
+ public void givenLoggedUserWhenUserLogoutThenSessionClearedAndNecessaryCookieCleared() throws Exception {
+
+ MockHttpServletRequest requestStateAfterLogout = this.mockMvc.perform(post("/basic/basiclogout").secure(true).with(csrf()))
+ .andExpect(status().is3xxRedirection())
+ .andExpect(unauthenticated())
+ .andExpect(cookie().maxAge(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, 0))
+ .andReturn()
+ .getRequest();
+
+ HttpSession sessionStateAfterLogout = requestStateAfterLogout.getSession();
+ assertNull(sessionStateAfterLogout.getAttribute(ATTRIBUTE_NAME));
+ }
+
+ @WithMockUser(value = "spring")
+ @Test
+ public void givenLoggedUserWhenUserLogoutThenSessionClearedAndAllCookiesCleared() throws Exception {
MockHttpSession session = new MockHttpSession();
session.setAttribute(ATTRIBUTE_NAME, ATTRIBUTE_VALUE);
@@ -44,7 +60,7 @@ public class ManualLogoutIntegrationTest {
Cookie randomCookie = new Cookie(COOKIE_NAME, COOKIE_VALUE);
randomCookie.setMaxAge(EXPIRY); // 10 minutes
- MockHttpServletRequest requestStateAfterLogout = this.mockMvc.perform(post("/basiclogout").secure(true).with(csrf()).session(session).cookie(randomCookie))
+ MockHttpServletRequest requestStateAfterLogout = this.mockMvc.perform(post("/cookies/cookielogout").secure(true).with(csrf()).session(session).cookie(randomCookie))
.andExpect(status().is3xxRedirection())
.andExpect(unauthenticated())
.andExpect(cookie().maxAge(COOKIE_NAME, 0))
@@ -53,15 +69,13 @@ public class ManualLogoutIntegrationTest {
HttpSession sessionStateAfterLogout = requestStateAfterLogout.getSession();
assertNull(sessionStateAfterLogout.getAttribute(ATTRIBUTE_NAME));
-
-
}
@WithMockUser(value = "spring")
@Test
public void givenLoggedUserWhenUserLogoutThenClearDataSiteHeaderPresent() throws Exception {
- this.mockMvc.perform(post("/csdlogout").secure(true).with(csrf()))
+ this.mockMvc.perform(post("/csd/csdlogout").secure(true).with(csrf()))
.andDo(print())
.andExpect(status().is3xxRedirection())
.andExpect(header().exists(CLEAR_SITE_DATA_HEADER))
diff --git a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml
index 0bba2936a7..532f45cf3e 100644
--- a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml
+++ b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml
@@ -63,7 +63,7 @@
UTF-8
- 1.5.2.RELEASE
+ 2.2.6.RELEASE
0.0.1-SNAPSHOT
diff --git a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml
index ba2b4101e8..0e8fb4cbc9 100644
--- a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml
+++ b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml
@@ -51,7 +51,7 @@
UTF-8
0.0.1-SNAPSHOT
- 1.5.2.RELEASE
+ 2.2.6.RELEASE
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-property-exp/property-exp-custom-config/pom.xml b/spring-boot-modules/spring-boot-property-exp/property-exp-custom-config/pom.xml
index 8ea9c8366d..e38a2742d5 100644
--- a/spring-boot-modules/spring-boot-property-exp/property-exp-custom-config/pom.xml
+++ b/spring-boot-modules/spring-boot-property-exp/property-exp-custom-config/pom.xml
@@ -24,6 +24,12 @@
spring-boot-starter-test
${spring-boot.version}
test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
@@ -72,7 +78,7 @@
- 1.5.10.RELEASE
+ 2.2.6.RELEASE
Custom Property Value
2.7
1.6.0
diff --git a/spring-boot-modules/spring-boot-property-exp/property-exp-custom-config/src/test/java/org/baeldung/SpringContextTest.java b/spring-boot-modules/spring-boot-property-exp/property-exp-custom-config/src/test/java/com/baeldung/SpringContextTest.java
similarity index 100%
rename from spring-boot-modules/spring-boot-property-exp/property-exp-custom-config/src/test/java/org/baeldung/SpringContextTest.java
rename to spring-boot-modules/spring-boot-property-exp/property-exp-custom-config/src/test/java/com/baeldung/SpringContextTest.java
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 aa5b8ef34a..79e194a3b5 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,9 +9,9 @@
com.baeldung
- parent-boot-1
+ parent-boot-2
0.0.1-SNAPSHOT
- ../../../parent-boot-1
+ ../../../parent-boot-2
diff --git a/spring-boot-modules/spring-boot-property-exp/property-exp-default-config/src/test/java/org/baeldung/SpringContextTest.java b/spring-boot-modules/spring-boot-property-exp/property-exp-default-config/src/test/java/com/baeldung/SpringContextTest.java
similarity index 100%
rename from spring-boot-modules/spring-boot-property-exp/property-exp-default-config/src/test/java/org/baeldung/SpringContextTest.java
rename to spring-boot-modules/spring-boot-property-exp/property-exp-default-config/src/test/java/com/baeldung/SpringContextTest.java
diff --git a/spring-caching/pom.xml b/spring-caching/pom.xml
index f56d3cf328..80644f8a5f 100644
--- a/spring-caching/pom.xml
+++ b/spring-caching/pom.xml
@@ -2,66 +2,64 @@
- 4.0.0
- spring-caching
- 0.1-SNAPSHOT
- spring-caching
- war
+ 4.0.0
+ spring-caching
+ 0.1-SNAPSHOT
+ spring-caching
+ war
-
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../parent-boot-2
-
+
+ com.baeldung
+ parent-boot-2
+ 0.0.1-SNAPSHOT
+ ../parent-boot-2
+
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework
- spring-context
-
-
- org.springframework.boot
- spring-boot-starter-cache
-
-
- org.springframework
- spring-web
-
-
- org.springframework
- spring-webmvc
-
-
- org.ehcache
- ehcache
-
-
- org.springframework
- spring-test
- test
-
-
- com.github.ben-manes.caffeine
- caffeine
-
-
- com.h2database
- h2
- runtime
-
-
- org.springframework.boot
- spring-boot-starter-jdbc
-
-
-
-
- 3.5.2
-
-
-
\ No newline at end of file
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework
+ spring-context
+
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
+ org.springframework
+ spring-web
+
+
+ org.springframework
+ spring-webmvc
+
+
+ org.ehcache
+ ehcache
+
+
+ org.springframework
+ spring-test
+ test
+
+
+ com.github.ben-manes.caffeine
+ caffeine
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+
+
+
+ 3.5.2
+
+
diff --git a/spring-jenkins-pipeline/scripted-pipeline-unix-nonunix b/spring-jenkins-pipeline/scripted-pipeline-unix-nonunix
index b76bb8a81a..871fee4ccb 100644
--- a/spring-jenkins-pipeline/scripted-pipeline-unix-nonunix
+++ b/spring-jenkins-pipeline/scripted-pipeline-unix-nonunix
@@ -72,7 +72,7 @@ node {
if (isUnix()) {
sh 'nohup ./mvnw spring-boot:run -Dserver.port=8989 &'
} else {
- bat 'start ./mvnw.cmd spring-boot:run -Dserver.port=8989'
+ bat 'start mvnw.cmd spring-boot:run -Dserver.port=8989'
}
}
}
diff --git a/vavr-2/README.md b/vavr-2/README.md
new file mode 100644
index 0000000000..71814a08fd
--- /dev/null
+++ b/vavr-2/README.md
@@ -0,0 +1,8 @@
+## Vavr
+
+This module contains articles about Vavr.
+
+### Relevant Articles:
+- [Introduction to Vavr’s Either](https://www.baeldung.com/vavr-either)
+- [Interoperability Between Java and Vavr](https://www.baeldung.com/java-vavr)
+- [[<-- prev]](/vavr)
diff --git a/vavr-2/pom.xml b/vavr-2/pom.xml
new file mode 100644
index 0000000000..d20dd9afef
--- /dev/null
+++ b/vavr-2/pom.xml
@@ -0,0 +1,27 @@
+
+
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+
+ 4.0.0
+
+ vavr-2
+ vavr-2
+ jar
+
+
+
+ io.vavr
+ vavr-test
+ ${vavr.version}
+
+
+
+
+ 0.9.1
+
+
\ No newline at end of file
diff --git a/vavr/src/main/java/com/baeldung/vavr/either/EitherDemo.java b/vavr-2/src/main/java/com/baeldung/vavr/either/EitherDemo.java
similarity index 100%
rename from vavr/src/main/java/com/baeldung/vavr/either/EitherDemo.java
rename to vavr-2/src/main/java/com/baeldung/vavr/either/EitherDemo.java
diff --git a/vavr/src/test/java/com/baeldung/vavr/either/EitherUnitTest.java b/vavr-2/src/test/java/com/baeldung/vavr/either/EitherUnitTest.java
similarity index 100%
rename from vavr/src/test/java/com/baeldung/vavr/either/EitherUnitTest.java
rename to vavr-2/src/test/java/com/baeldung/vavr/either/EitherUnitTest.java
diff --git a/vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java b/vavr-2/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java
similarity index 100%
rename from vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java
rename to vavr-2/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java
diff --git a/vavr/README.md b/vavr/README.md
index 2b8bb25356..e04e02069f 100644
--- a/vavr/README.md
+++ b/vavr/README.md
@@ -13,5 +13,4 @@ This module contains articles about Vavr.
- [Guide to Collections API in Vavr](https://www.baeldung.com/vavr-collections)
- [Collection Factory Methods for Vavr](https://www.baeldung.com/vavr-collection-factory-methods)
- [Introduction to Future in Vavr](https://www.baeldung.com/vavr-future)
-- [Introduction to Vavr’s Either](https://www.baeldung.com/vavr-either)
-- [Interoperability Between Java and Vavr](https://www.baeldung.com/java-vavr)
+- [[next -->]](/vavr-2)