diff --git a/algorithms-modules/pom.xml b/algorithms-modules/pom.xml index 342662ce9c..fda8eea0e7 100644 --- a/algorithms-modules/pom.xml +++ b/algorithms-modules/pom.xml @@ -28,7 +28,7 @@ - 1.11 + 1.16.0 3.6.1 2.7 1.0.1 diff --git a/apache-httpclient/pom.xml b/apache-httpclient/pom.xml index 1b22d64799..3b178d4df8 100644 --- a/apache-httpclient/pom.xml +++ b/apache-httpclient/pom.xml @@ -58,11 +58,16 @@ - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test + + org.apache.httpcomponents + httpclient + ${httpclient.version} + @@ -77,11 +82,12 @@ 5.6.1 - 2.5.1 + 3.3.1 5.2 5.2 5.2 + 4.5.14 diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java index 92cb452dc8..1a4f4aebf3 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java @@ -8,7 +8,7 @@ import static org.mockserver.model.HttpResponse.response; import java.io.IOException; import java.net.ServerSocket; -import org.apache.http.HttpStatus; +import org.apache.hc.core5.http.HttpStatus; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.mockserver.client.MockServerClient; diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java index d421de1c7a..50cf1b7a64 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java @@ -38,8 +38,6 @@ import org.junit.jupiter.api.Test; class HttpAsyncClientLiveTest extends GetRequestMockServer { - - private static final String HOST = "http://www.google.com"; private static final String HOST_WITH_SSL = "https://mms.nw.ru/"; private static final String HOST_WITH_PROXY = "http://httpbin.org/"; private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://browserspy.dk/password-ok.php";// "http://localhost:8080/spring-security-rest-basic-auth/api/foos/1"; @@ -136,7 +134,7 @@ class HttpAsyncClientLiveTest extends GetRequestMockServer { client.start(); - final SimpleHttpRequest request = new SimpleHttpRequest("GET",HOST_WITH_SSL); + final SimpleHttpRequest request = new SimpleHttpRequest("GET", HOST_WITH_SSL); final Future future = client.execute(request, null); final HttpResponse response = future.get(); @@ -201,7 +199,7 @@ class HttpAsyncClientLiveTest extends GetRequestMockServer { @Override public void run() { try { - final Future future = client.execute(SimpleHttpRequest.copy(request), context, null); + final Future future = client.execute(SimpleRequestBuilder.copy(request).build(), context, null); final HttpResponse response = future.get(); assertThat(response.getCode(), equalTo(200)); } catch (final Exception ex) { diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java index e9ea08a723..537f501d93 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java @@ -1,10 +1,10 @@ package com.baeldung.httpclient; -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; - import java.io.IOException; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.core5.http.HttpEntity; + public final class ResponseUtil { private ResponseUtil() { } diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java index 3ac3ee88be..2a8665b624 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java @@ -103,7 +103,7 @@ class HttpClientAdvancedConfigurationIntegrationTest { void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException { //given proxyMock.stubFor(get(urlMatching(".*")) - .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); + .willReturn(aResponse().proxiedFrom("http://localhost:8089"))); serviceMock.stubFor(get(urlEqualTo("/private")) .willReturn(aResponse().withStatus(200))); @@ -129,7 +129,7 @@ class HttpClientAdvancedConfigurationIntegrationTest { public void givenServerThatIsBehindAuthorizationProxy_whenClientSendRequest_shouldAuthorizeProperly() throws IOException { //given proxyMock.stubFor(get(urlMatching("/private")) - .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); + .willReturn(aResponse().proxiedFrom("http://localhost:8089"))); serviceMock.stubFor(get(urlEqualTo("/private")) .willReturn(aResponse().withStatus(200))); diff --git a/apache-httpclient4/pom.xml b/apache-httpclient4/pom.xml index f4c213687e..90890ef7b9 100644 --- a/apache-httpclient4/pom.xml +++ b/apache-httpclient4/pom.xml @@ -158,7 +158,7 @@ ${mockserver.version} - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -234,10 +234,10 @@ - 1.10 + 1.16.0 4.1.5 - 2.5.1 + 3.3.1 4.4.16 4.5.14 5.11.2 diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java index 5ced756644..714c01192e 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java @@ -102,7 +102,7 @@ class HttpClientAdvancedConfigurationIntegrationTest { void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException { //given proxyMock.stubFor(get(urlMatching(".*")) - .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); + .willReturn(aResponse().proxiedFrom("http://localhost:8089"))); serviceMock.stubFor(get(urlEqualTo("/private")) .willReturn(aResponse().withStatus(200))); @@ -128,7 +128,7 @@ class HttpClientAdvancedConfigurationIntegrationTest { void givenServerThatIsBehindAuthorizationProxy_whenClientSendRequest_shouldAuthorizeProperly() throws IOException { //given proxyMock.stubFor(get(urlMatching("/private")) - .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); + .willReturn(aResponse().proxiedFrom("http://localhost:8089"))); serviceMock.stubFor(get(urlEqualTo("/private")) .willReturn(aResponse().withStatus(200))); diff --git a/apache-kafka-2/README.md b/apache-kafka-2/README.md index 40ee701be1..3aa8fcf4ad 100644 --- a/apache-kafka-2/README.md +++ b/apache-kafka-2/README.md @@ -14,3 +14,4 @@ You can build the project from the command line using: *mvn clean install*, or i - [Get Partition Count for a Topic in Kafka](https://www.baeldung.com/java-kafka-partition-count-topic) - [bootstrap-server in Kafka Configuration](https://www.baeldung.com/java-kafka-bootstrap-server) - [Introduction to Apache Kafka](https://www.baeldung.com/apache-kafka) +- [Ensuring Message Ordering in Kafka: Strategies and Configurations](https://www.baeldung.com/kafka-message-ordering) diff --git a/apache-libraries/pom.xml b/apache-libraries/pom.xml index c1def03bee..02e9f08a8d 100644 --- a/apache-libraries/pom.xml +++ b/apache-libraries/pom.xml @@ -191,7 +191,7 @@ 2.0.6 2.0.1.Final 1.2.15 - 3.10.0 + 4.12.0 1.2.15 1.2.15 1.2.15 diff --git a/aws-modules/aws-miscellaneous/pom.xml b/aws-modules/aws-miscellaneous/pom.xml index 5fdd7fa04d..b6326b6eb1 100644 --- a/aws-modules/aws-miscellaneous/pom.xml +++ b/aws-modules/aws-miscellaneous/pom.xml @@ -75,7 +75,7 @@ 2.10.1 1.21.1 - 1.10.L001 + 1.16.0 0.9.4.0006L 3.1.1 diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterFactory.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterFactory.java new file mode 100644 index 0000000000..25a855487e --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterFactory.java @@ -0,0 +1,47 @@ +package com.baeldung.deserializationfilters; + +import java.io.ObjectInputFilter; +import java.util.function.BinaryOperator; + +import com.baeldung.deserializationfilters.service.DeserializationService; +import com.baeldung.deserializationfilters.service.LimitedArrayService; +import com.baeldung.deserializationfilters.service.LowDepthService; +import com.baeldung.deserializationfilters.service.SmallObjectService; +import com.baeldung.deserializationfilters.utils.FilterUtils; + +public class ContextSpecificDeserializationFilterFactory implements BinaryOperator { + + @Override + public ObjectInputFilter apply(ObjectInputFilter current, ObjectInputFilter next) { + if (current == null) { + Class caller = findInStack(DeserializationService.class); + + if (caller == null) { + current = FilterUtils.fallbackFilter(); + } else if (caller.equals(SmallObjectService.class)) { + current = FilterUtils.safeSizeFilter(190); + } else if (caller.equals(LowDepthService.class)) { + current = FilterUtils.safeDepthFilter(2); + } else if (caller.equals(LimitedArrayService.class)) { + current = FilterUtils.safeArrayFilter(3); + } + } + + return ObjectInputFilter.merge(current, next); + } + + private static Class findInStack(Class superType) { + for (StackTraceElement element : Thread.currentThread() + .getStackTrace()) { + try { + Class subType = Class.forName(element.getClassName()); + if (superType.isAssignableFrom(subType)) { + return subType; + } + } catch (ClassNotFoundException e) { + return null; + } + } + return null; + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/ContextSpecific.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/ContextSpecific.java new file mode 100644 index 0000000000..add827d280 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/ContextSpecific.java @@ -0,0 +1,7 @@ +package com.baeldung.deserializationfilters.pojo; + +import java.io.Serializable; + +public interface ContextSpecific extends Serializable { + +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/NestedSample.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/NestedSample.java new file mode 100644 index 0000000000..a1d41744e6 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/NestedSample.java @@ -0,0 +1,19 @@ +package com.baeldung.deserializationfilters.pojo; + +public class NestedSample implements ContextSpecific { + private static final long serialVersionUID = 1L; + + private Sample optional; + + public NestedSample(Sample optional) { + this.optional = optional; + } + + public Sample getOptional() { + return optional; + } + + public void setOptional(Sample optional) { + this.optional = optional; + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/Sample.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/Sample.java new file mode 100644 index 0000000000..fed3639c64 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/Sample.java @@ -0,0 +1,61 @@ +package com.baeldung.deserializationfilters.pojo; + +public class Sample implements ContextSpecific, Comparable { + private static final long serialVersionUID = 1L; + + private int[] array; + private String name; + private NestedSample nested; + + public Sample(String name) { + this.name = name; + } + + public Sample(int[] array) { + this.array = array; + } + + public Sample(NestedSample nested) { + this.nested = nested; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int[] getArray() { + return array; + } + + public void setArray(int[] array) { + this.array = array; + } + + public NestedSample getNested() { + return nested; + } + + public void setNested(NestedSample nested) { + this.nested = nested; + } + + @Override + public String toString() { + return name; + } + + @Override + public int compareTo(Sample o) { + if (name == null) + return -1; + + if (o == null || o.getName() == null) + return 1; + + return getName().compareTo(o.getName()); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/SampleExploit.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/SampleExploit.java new file mode 100644 index 0000000000..24dce289c6 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/SampleExploit.java @@ -0,0 +1,25 @@ +package com.baeldung.deserializationfilters.pojo; + +public class SampleExploit extends Sample { + private static final long serialVersionUID = 1L; + + public SampleExploit() { + super("exploit"); + } + + public static void maliciousCode() { + System.out.println("exploit executed"); + } + + @Override + public String toString() { + maliciousCode(); + return "exploit"; + } + + @Override + public int compareTo(Sample o) { + maliciousCode(); + return super.compareTo(o); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/DeserializationService.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/DeserializationService.java new file mode 100644 index 0000000000..9a66cb0e91 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/DeserializationService.java @@ -0,0 +1,11 @@ +package com.baeldung.deserializationfilters.service; + +import java.io.InputStream; +import java.util.Set; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; + +public interface DeserializationService { + + Set process(InputStream... inputStreams); +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LimitedArrayService.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LimitedArrayService.java new file mode 100644 index 0000000000..3aadbe7111 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LimitedArrayService.java @@ -0,0 +1,15 @@ +package com.baeldung.deserializationfilters.service; + +import java.io.InputStream; +import java.util.Set; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; +import com.baeldung.deserializationfilters.utils.DeserializationUtils; + +public class LimitedArrayService implements DeserializationService { + + @Override + public Set process(InputStream... inputStreams) { + return DeserializationUtils.deserializeIntoSet(inputStreams); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LowDepthService.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LowDepthService.java new file mode 100644 index 0000000000..69350c1399 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LowDepthService.java @@ -0,0 +1,20 @@ +package com.baeldung.deserializationfilters.service; + +import java.io.InputStream; +import java.io.ObjectInputFilter; +import java.util.Set; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; +import com.baeldung.deserializationfilters.utils.DeserializationUtils; + +public class LowDepthService implements DeserializationService { + + public Set process(ObjectInputFilter filter, InputStream... inputStreams) { + return DeserializationUtils.deserializeIntoSet(filter, inputStreams); + } + + @Override + public Set process(InputStream... inputStreams) { + return process(null, inputStreams); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/SmallObjectService.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/SmallObjectService.java new file mode 100644 index 0000000000..a0690276b7 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/SmallObjectService.java @@ -0,0 +1,15 @@ +package com.baeldung.deserializationfilters.service; + +import java.io.InputStream; +import java.util.Set; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; +import com.baeldung.deserializationfilters.utils.DeserializationUtils; + +public class SmallObjectService implements DeserializationService { + + @Override + public Set process(InputStream... inputStreams) { + return DeserializationUtils.deserializeIntoSet(inputStreams); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/DeserializationUtils.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/DeserializationUtils.java new file mode 100644 index 0000000000..54db823102 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/DeserializationUtils.java @@ -0,0 +1,50 @@ +package com.baeldung.deserializationfilters.utils; + +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.ObjectInputFilter; +import java.io.ObjectInputStream; +import java.util.Set; +import java.util.TreeSet; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; + +public class DeserializationUtils { + private DeserializationUtils() { + } + + public static Object deserialize(InputStream inStream) { + return deserialize(inStream, null); + } + + public static Object deserialize(InputStream inStream, ObjectInputFilter filter) { + try (ObjectInputStream in = new ObjectInputStream(inStream)) { + if (filter != null) { + in.setObjectInputFilter(filter); + } + return in.readObject(); + } catch (InvalidClassException e) { + return null; + } catch (Throwable e) { + e.printStackTrace(); + return null; + } + } + + public static Set deserializeIntoSet(InputStream... inputStreams) { + return deserializeIntoSet(null, inputStreams); + } + + public static Set deserializeIntoSet(ObjectInputFilter filter, InputStream... inputStreams) { + Set set = new TreeSet<>(); + + for (InputStream inputStream : inputStreams) { + Object object = deserialize(inputStream, filter); + if (object != null) { + set.add((ContextSpecific) object); + } + } + + return set; + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/FilterUtils.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/FilterUtils.java new file mode 100644 index 0000000000..fac69a94b9 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/FilterUtils.java @@ -0,0 +1,32 @@ +package com.baeldung.deserializationfilters.utils; + +import java.io.ObjectInputFilter; + +public class FilterUtils { + + private static final String DEFAULT_PACKAGE_PATTERN = "java.base/*;!*"; + private static final String POJO_PACKAGE = "com.baeldung.deserializationfilters.pojo"; + + private FilterUtils() { + } + + private static ObjectInputFilter baseFilter(String parameter, int max) { + return ObjectInputFilter.Config.createFilter(String.format("%s=%d;%s.**;%s", parameter, max, POJO_PACKAGE, DEFAULT_PACKAGE_PATTERN)); + } + + public static ObjectInputFilter fallbackFilter() { + return ObjectInputFilter.Config.createFilter(String.format("%s", DEFAULT_PACKAGE_PATTERN)); + } + + public static ObjectInputFilter safeSizeFilter(int max) { + return baseFilter("maxbytes", max); + } + + public static ObjectInputFilter safeArrayFilter(int max) { + return baseFilter("maxarray", max); + } + + public static ObjectInputFilter safeDepthFilter(int max) { + return baseFilter("maxdepth", max); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/SerializationUtils.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/SerializationUtils.java new file mode 100644 index 0000000000..4f62e5d46b --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/SerializationUtils.java @@ -0,0 +1,17 @@ +package com.baeldung.deserializationfilters.utils; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +public class SerializationUtils { + + private SerializationUtils() { + } + + public static void serialize(Object object, OutputStream outStream) throws IOException { + try (ObjectOutputStream objStream = new ObjectOutputStream(outStream)) { + objStream.writeObject(object); + } + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterIntegrationTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterIntegrationTest.java new file mode 100644 index 0000000000..3e7de20070 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterIntegrationTest.java @@ -0,0 +1,119 @@ +package com.baeldung.deserializationfilters; + +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputFilter; +import java.util.Set; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; +import com.baeldung.deserializationfilters.pojo.NestedSample; +import com.baeldung.deserializationfilters.pojo.Sample; +import com.baeldung.deserializationfilters.pojo.SampleExploit; +import com.baeldung.deserializationfilters.service.LimitedArrayService; +import com.baeldung.deserializationfilters.service.LowDepthService; +import com.baeldung.deserializationfilters.service.SmallObjectService; +import com.baeldung.deserializationfilters.utils.DeserializationUtils; +import com.baeldung.deserializationfilters.utils.FilterUtils; +import com.baeldung.deserializationfilters.utils.SerializationUtils; + +public class ContextSpecificDeserializationFilterIntegrationTest { + + private static ByteArrayOutputStream serialSampleA = new ByteArrayOutputStream(); + private static ByteArrayOutputStream serialBigSampleA = new ByteArrayOutputStream(); + + private static ByteArrayOutputStream serialSampleB = new ByteArrayOutputStream(); + private static ByteArrayOutputStream serialBigSampleB = new ByteArrayOutputStream(); + + private static ByteArrayOutputStream serialSampleC = new ByteArrayOutputStream(); + private static ByteArrayOutputStream serialBigSampleC = new ByteArrayOutputStream(); + + private static ByteArrayInputStream bytes(ByteArrayOutputStream stream) { + return new ByteArrayInputStream(stream.toByteArray()); + } + + @BeforeAll + static void setup() throws IOException { + ObjectInputFilter.Config.setSerialFilterFactory(new ContextSpecificDeserializationFilterFactory()); + + SerializationUtils.serialize(new Sample("simple"), serialSampleA); + SerializationUtils.serialize(new SampleExploit(), serialBigSampleA); + + SerializationUtils.serialize(new Sample(new int[] { 1, 2, 3 }), serialSampleB); + SerializationUtils.serialize(new Sample(new int[] { 1, 2, 3, 4, 5, 6 }), serialBigSampleB); + + SerializationUtils.serialize(new Sample(new NestedSample(null)), serialSampleC); + SerializationUtils.serialize(new Sample(new NestedSample(new Sample("deep"))), serialBigSampleC); + } + + @Test + void whenSmallObjectContext_thenCorrectFilterApplied() { + Set result = new SmallObjectService().process( // + bytes(serialSampleA), // + bytes(serialBigSampleA)); + + assertEquals(1, result.size()); + assertEquals("simple", ((Sample) result.iterator() + .next()).getName()); + } + + @Test + void whenLimitedArrayContext_thenCorrectFilterApplied() { + Set result = new LimitedArrayService().process( // + bytes(serialSampleB), // + bytes(serialBigSampleB)); + + assertEquals(1, result.size()); + } + + @Test + void whenLowDepthContext_thenCorrectFilterApplied() { + Set result = new LowDepthService().process( // + bytes(serialSampleC), // + bytes(serialBigSampleC)); + + assertEquals(1, result.size()); + } + + @Test + void givenExtraFilter_whenCombinedContext_thenMergedFiltersApplied() { + Set result = new LowDepthService().process( // + FilterUtils.safeSizeFilter(190), // + bytes(serialSampleA), // + bytes(serialBigSampleA), // + bytes(serialSampleC), // + bytes(serialBigSampleC)); + + assertEquals(1, result.size()); + assertEquals("simple", ((Sample) result.iterator() + .next()).getName()); + } + + @Test + void givenFallbackContext_whenUsingBaseClasses_thenRestrictiveFilterApplied() throws IOException { + String a = new String("a"); + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + SerializationUtils.serialize(a, outStream); + + String deserializedA = (String) DeserializationUtils.deserialize(bytes(outStream)); + + assertEquals(a, deserializedA); + } + + @Test + void givenFallbackContext_whenUsingAppClasses_thenRejected() throws IOException { + Sample a = new Sample("a"); + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + SerializationUtils.serialize(a, outStream); + + Sample deserializedA = (Sample) DeserializationUtils.deserialize(bytes(outStream)); + + assertNull(deserializedA); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java index 73d8aad810..0c437affd8 100644 --- a/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java @@ -18,19 +18,19 @@ public class VehicleUnitTest { } @Test - public void givenCar_whenUsingReflectionAPI_thenSuperClassIsSealed() { + public void givenCar_whenUsingReflectionAPI_thenSuperClassIsSealed() throws ClassNotFoundException { Assertions.assertThat(car.getClass().isSealed()).isEqualTo(false); Assertions.assertThat(car.getClass().getSuperclass().isSealed()).isEqualTo(true); Assertions.assertThat(car.getClass().getSuperclass().getPermittedSubclasses()) - .contains(ClassDesc.of(car.getClass().getCanonicalName())); + .contains(Class.forName(car.getClass().getCanonicalName())); } @Test - public void givenTruck_whenUsingReflectionAPI_thenSuperClassIsSealed() { + public void givenTruck_whenUsingReflectionAPI_thenSuperClassIsSealed() throws ClassNotFoundException { Assertions.assertThat(truck.getClass().isSealed()).isEqualTo(false); Assertions.assertThat(truck.getClass().getSuperclass().isSealed()).isEqualTo(true); Assertions.assertThat(truck.getClass().getSuperclass().getPermittedSubclasses()) - .contains(ClassDesc.of(truck.getClass().getCanonicalName())); + .contains(Class.forName(truck.getClass().getCanonicalName())); } @Test diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java index ac8a8c953c..8dd150b5e7 100644 --- a/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java @@ -18,19 +18,19 @@ public class VehicleUnitTest { } @Test - public void givenCar_whenUsingReflectionAPI_thenInterfaceIsSealed() { + public void givenCar_whenUsingReflectionAPI_thenInterfaceIsSealed() throws ClassNotFoundException { Assertions.assertThat(car.getClass().isSealed()).isEqualTo(false); Assertions.assertThat(car.getClass().getInterfaces()[0].isSealed()).isEqualTo(true); - Assertions.assertThat(car.getClass().getInterfaces()[0].permittedSubclasses()) - .contains(ClassDesc.of(car.getClass().getCanonicalName())); + Assertions.assertThat(car.getClass().getInterfaces()[0].getPermittedSubclasses()) + .contains(Class.forName(car.getClass().getCanonicalName())); } @Test - public void givenTruck_whenUsingReflectionAPI_thenInterfaceIsSealed() { + public void givenTruck_whenUsingReflectionAPI_thenInterfaceIsSealed() throws ClassNotFoundException { Assertions.assertThat(truck.getClass().isSealed()).isEqualTo(false); Assertions.assertThat(truck.getClass().getInterfaces()[0].isSealed()).isEqualTo(true); - Assertions.assertThat(truck.getClass().getInterfaces()[0].permittedSubclasses()) - .contains(ClassDesc.of(truck.getClass().getCanonicalName())); + Assertions.assertThat(truck.getClass().getInterfaces()[0].getPermittedSubclasses()) + .contains(Class.forName(truck.getClass().getCanonicalName())); } @Test diff --git a/core-java-modules/core-java-8-datetime-2/README.md b/core-java-modules/core-java-8-datetime-2/README.md index 462a4be6f1..f7ada52da6 100644 --- a/core-java-modules/core-java-8-datetime-2/README.md +++ b/core-java-modules/core-java-8-datetime-2/README.md @@ -7,4 +7,5 @@ - [Difference Between Instant and LocalDateTime](https://www.baeldung.com/java-instant-vs-localdatetime) - [Add Minutes to a Time String in Java](https://www.baeldung.com/java-string-time-add-mins) - [Round the Date in Java](https://www.baeldung.com/java-round-the-date) +- [Representing Furthest Possible Date in Java](https://www.baeldung.com/java-date-represent-max) - [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) diff --git a/core-java-modules/core-java-collections-4/pom.xml b/core-java-modules/core-java-collections-4/pom.xml index 1a59411ecb..344ec6bc41 100644 --- a/core-java-modules/core-java-collections-4/pom.xml +++ b/core-java-modules/core-java-collections-4/pom.xml @@ -34,7 +34,6 @@ 2.2 - 3.12.0 \ No newline at end of file diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md index 4869158d2b..acee8154f7 100644 --- a/core-java-modules/core-java-collections-5/README.md +++ b/core-java-modules/core-java-collections-5/README.md @@ -9,4 +9,5 @@ - [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration) - [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue) - [Intro to Vector Class in Java](https://www.baeldung.com/java-vector-guide) +- [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-4) diff --git a/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityJMH.java b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityJMH.java new file mode 100644 index 0000000000..766a89f674 --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityJMH.java @@ -0,0 +1,60 @@ +package com.baeldung.collectionssortcomplexity; + +import org.openjdk.jmh.annotations.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Fork(value = 1, warmups = 1) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +public class CollectionsSortTimeComplexityJMH { + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + + } + + @Benchmark + public void measureCollectionsSortBestCase(BestCaseBenchmarkState state) { + List sortedList = new ArrayList<>(state.sortedList); + Collections.sort(sortedList); + } + + @Benchmark + public void measureCollectionsSortAverageWorstCase(AverageWorstCaseBenchmarkState state) { + List unsortedList = new ArrayList<>(state.unsortedList); + Collections.sort(unsortedList); + } + + @State(Scope.Benchmark) + public static class BestCaseBenchmarkState { + List sortedList; + + @Setup(Level.Trial) + public void setUp() { + sortedList = new ArrayList<>(); + for (int i = 1; i <= 1000000; i++) { + sortedList.add(i); + } + } + } + + @State(Scope.Benchmark) + public static class AverageWorstCaseBenchmarkState { + List unsortedList; + + @Setup(Level.Trial) + public void setUp() { + unsortedList = new ArrayList<>(); + for (int i = 1000000; i > 0; i--) { + unsortedList.add(i); + } + } + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityMain.java b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityMain.java new file mode 100644 index 0000000000..f273d3562a --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityMain.java @@ -0,0 +1,33 @@ +package com.baeldung.collectionssortcomplexity; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class CollectionsSortTimeComplexityMain { + // O(n log n) Time Complexity Example + public static void worstAndAverageCasesTimeComplexity() { + Integer[] sortedArray = {20, 21, 22, 23, 24, 25, 26, 17, 28, 29, 30, 31, 18, 19, 32, 33, 34, 27, 35}; + List list = Arrays.asList(sortedArray); + Collections.shuffle(list); + long startTime = System.nanoTime(); + Collections.sort(list); + long endTime = System.nanoTime(); + System.out.println("Execution Time for O(n log n): " + (endTime - startTime) + " nanoseconds"); + } + + // O(n) Time Complexity Example + public static void bestCaseTimeComplexity() { + Integer[] sortedArray = {19, 22, 19, 22, 24, 25, 17, 11, 22, 23, 28, 23, 0, 1, 12, 9, 13, 27, 15}; + List list = Arrays.asList(sortedArray); + long startTime = System.nanoTime(); + Collections.sort(list); + long endTime = System.nanoTime(); + System.out.println("Execution Time for O(n): " + (endTime - startTime) + " nanoseconds"); + } + + public static void main(String[] args) { + worstAndAverageCasesTimeComplexity(); + bestCaseTimeComplexity(); + } +} diff --git a/core-java-modules/core-java-collections-list-5/pom.xml b/core-java-modules/core-java-collections-list-5/pom.xml index 2b4b0041b3..b8832df357 100644 --- a/core-java-modules/core-java-collections-list-5/pom.xml +++ b/core-java-modules/core-java-collections-list-5/pom.xml @@ -66,7 +66,6 @@ 1.21 2.2 - 3.12.0 2.10.1 2.15.2 20230618 diff --git a/core-java-modules/core-java-collections-maps-7/pom.xml b/core-java-modules/core-java-collections-maps-7/pom.xml index a7acded9cf..a05b1b3528 100644 --- a/core-java-modules/core-java-collections-maps-7/pom.xml +++ b/core-java-modules/core-java-collections-maps-7/pom.xml @@ -33,6 +33,11 @@ commons-csv ${csv.version} + + com.google.guava + guava + 32.1.2-jre + diff --git a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java new file mode 100644 index 0000000000..eca028efe4 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java @@ -0,0 +1,70 @@ +package com.baeldung.map; + +import java.util.HashMap; +import java.util.Map; + +public class BenchmarkMapMethods { + public static void main(String[] args) { + BenchmarkMapMethods bmm = new BenchmarkMapMethods(); + Map map = new HashMap<>(); + map.put("Guava", bmm.benchMarkGuavaMap()); + map.put("ContainsKey", bmm.benchContainsKeyMap()); + map.put("MergeMethod", bmm.benchMarkMergeMethod()); + map.put("ComputeMethod", bmm.benchMarComputeMethod()); + map.put("GetOrDefault", bmm.benchMarkGetOrDefaultMethod()); + } + + private long benchMarkGuavaMap() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingAtomicMap(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private long benchContainsKeyMap() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingContainsKey(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private long benchMarComputeMethod() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingCompute(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private long benchMarkMergeMethod() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingMerge(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private long benchMarkGetOrDefaultMethod() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingGetOrDefault(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private String getString() { + return + "Once upon a time in a quaint village nestled between rolling hills and whispering forests, there lived a solitary storyteller named Elias. Elias was known for spinning tales that transported listeners to magical realms and awakened forgotten dreams.\n" + + "\n" + + "His favorite spot was beneath an ancient oak tree, its sprawling branches offering shade to those who sought refuge from the bustle of daily life. Villagers of all ages would gather around Elias, their faces illuminated by the warmth of his stories.\n" + + "\n" + "One evening, as dusk painted the sky in hues of orange and purple, a curious young girl named Lily approached Elias. Her eyes sparkled with wonder as she asked for a tale unlike any other.\n" + "\n" + + "Elias smiled, sensing her thirst for adventure, and began a story about a forgotten kingdom veiled by mist, guarded by mystical creatures and enchanted by ancient spells. With each word, the air grew thick with anticipation, and the listeners were transported into a world where magic danced on the edges of reality.\n" + + "\n" + "As Elias weaved the story, Lily's imagination took flight. She envisioned herself as a brave warrior, wielding a shimmering sword against dark forces, her heart fueled by courage and kindness.\n" + "\n" + + "The night wore on, but the spell of the tale held everyone captive. The villagers laughed, gasped, and held their breaths, journeying alongside the characters through trials and triumphs.\n" + "\n" + + "As the final words lingered in the air, a sense of enchantment settled upon the listeners. They thanked Elias for the gift of his storytelling, each carrying a piece of the magical kingdom within their hearts.\n" + "\n" + + "Lily, inspired by the story, vowed to cherish the spirit of adventure and kindness in her own life. With a newfound spark in her eyes, she bid Elias goodnight, already dreaming of the countless adventures awaiting her.\n" + "\n" + + "Under the star-studded sky, Elias remained beneath the ancient oak, his heart aglow with the joy of sharing tales that ignited imagination and inspired dreams. And as the night embraced the village, whispers of the enchanted kingdom lingered in the breeze, promising endless possibilities to those who dared to believe."; + } +} diff --git a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java new file mode 100644 index 0000000000..70b3c6c54d --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java @@ -0,0 +1,80 @@ +package com.baeldung.map; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import com.google.common.util.concurrent.AtomicLongMap; + +public class IncrementMapValueWays { + + public Map charFrequencyUsingContainsKey(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + int count = 0; + if (charMap.containsKey(sentence.charAt(c))) { + count = charMap.get(sentence.charAt(c)); + } + charMap.put(sentence.charAt(c), count + 1); + } + return charMap; + } + + public Map charFrequencyUsingGetOrDefault(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.put(sentence.charAt(c), charMap.getOrDefault(sentence.charAt(c), 0) + 1); + } + return charMap; + } + + public Map charFrequencyUsingMerge(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.merge(sentence.charAt(c), 1, Integer::sum); + } + return charMap; + } + + public Map charFrequencyUsingCompute(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.compute(sentence.charAt(c), (key, value) -> (value == null) ? 1 : value + 1); + } + return charMap; + } + + public Map charFrequencyUsingAtomicMap(String sentence) { + AtomicLongMap map = AtomicLongMap.create(); + for (int c = 0; c < sentence.length(); c++) { + map.getAndIncrement(sentence.charAt(c)); + } + return map.asMap(); + } + + public Map charFrequencyWithConcurrentMap(String sentence, Map charMap) { + for (int c = 0; c < sentence.length(); c++) { + charMap.compute(sentence.charAt(c), (key, value) -> (value == null) ? 1 : value + 1); + } + return charMap; + } + + public Map charFrequencyWithGetAndIncrement(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.putIfAbsent(sentence.charAt(c), new AtomicInteger(0)); + charMap.get(sentence.charAt(c)) + .incrementAndGet(); + } + return charMap; + } + + public Map charFrequencyWithGetAndIncrementComputeIfAbsent(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.computeIfAbsent(sentence.charAt(c), k -> new AtomicInteger(0)) + .incrementAndGet(); + } + return charMap; + } +} diff --git a/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java new file mode 100644 index 0000000000..df4f2b787e --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java @@ -0,0 +1,103 @@ +package com.baeldung.map; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Assert; +import org.junit.Test; + +public class IncrementMapValueUnitTest { + + @Test + public void givenString_whenUsingContainsKey_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingContainsKey(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, actualMap); + } + + @Test + public void givenString_whenUsingGetOrDefault_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingGetOrDefault(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, actualMap); + } + + @Test + public void givenString_whenUsingMapMerge_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingMerge(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, actualMap); + } + + @Test + public void givenString_whenUsingMapCompute_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingCompute(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, actualMap); + } + + @Test + public void givenString_whenUsingGuava_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingAtomicMap(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap.keySet(), actualMap.keySet()); + } + + @Test + public void givenString_whenUsingIncrementAndGet_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyWithGetAndIncrement(string); + Assert.assertEquals(getExpectedMap().keySet(), actualMap.keySet()); + } + + @Test + public void givenString_whenUsingIncrementAndGetAndComputeIfAbsent_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyWithGetAndIncrementComputeIfAbsent(string); + Assert.assertEquals(getExpectedMap().keySet(), actualMap.keySet()); + } + + @Test + public void givenString_whenUsingConcurrentMapCompute_thenReturnFreqMap() throws InterruptedException { + Map charMap = new ConcurrentHashMap<>(); + Thread thread1 = new Thread(() -> { + IncrementMapValueWays ic = new IncrementMapValueWays(); + ic.charFrequencyWithConcurrentMap("the quick brown", charMap); + }); + + Thread thread2 = new Thread(() -> { + IncrementMapValueWays ic = new IncrementMapValueWays(); + ic.charFrequencyWithConcurrentMap(" fox jumps over the lazy dog", charMap); + }); + + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, charMap); + } + + private Map getExpectedMap() { + return Stream.of( + new Object[][] { { ' ', 8 }, { 'a', 1 }, { 'b', 1 }, { 'c', 1 }, { 'd', 1 }, { 'e', 3 }, { 'f', 1 }, { 'g', 1 }, { 'h', 2 }, { 'i', 1 }, { 'j', 1 }, { 'k', 1 }, { 'l', 1 }, { 'm', 1 }, { 'n', 1 }, { 'o', 4 }, { 'p', 1 }, { 'q', 1 }, { 'r', 2 }, + { 's', 1 }, { 't', 2 }, { 'u', 2 }, { 'v', 1 }, { 'w', 1 }, { 'x', 1 }, { 'y', 1 }, { 'z', 1 } }) + .collect(Collectors.toMap(data -> (Character) data[0], data -> (Integer) data[1])); + } +} diff --git a/core-java-modules/core-java-concurrency-advanced-3/pom.xml b/core-java-modules/core-java-concurrency-advanced-3/pom.xml index 7fa859c2d5..e3b399782e 100644 --- a/core-java-modules/core-java-concurrency-advanced-3/pom.xml +++ b/core-java-modules/core-java-concurrency-advanced-3/pom.xml @@ -85,12 +85,12 @@ 1.8 1.8 0.22.6 - 1.9.5 + 1.9.20.1 0.43 1.2.3 0.14.1 - 1.9.1 - 1.9.1 + 1.9.20.1 + 1.9.20.1 \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-basic-3/README.md b/core-java-modules/core-java-concurrency-basic-3/README.md index 09d085a32b..1021544e11 100644 --- a/core-java-modules/core-java-concurrency-basic-3/README.md +++ b/core-java-modules/core-java-concurrency-basic-3/README.md @@ -12,4 +12,5 @@ This module contains articles about basic Java concurrency. - [CompletableFuture allOf().join() vs. CompletableFuture.join()](https://www.baeldung.com/java-completablefuture-allof-join) - [Retry Logic with CompletableFuture](https://www.baeldung.com/java-completablefuture-retry-logic) - [Convert From List of CompletableFuture to CompletableFuture List](https://www.baeldung.com/java-completablefuture-list-convert) +- [Synchronize a Static Variable Among Different Threads](https://www.baeldung.com/java-synchronize-static-variable-different-threads) - [[<-- Prev]](../core-java-concurrency-basic-2) diff --git a/core-java-modules/core-java-console/README.md b/core-java-modules/core-java-console/README.md index 180193d8c1..77ad16d015 100644 --- a/core-java-modules/core-java-console/README.md +++ b/core-java-modules/core-java-console/README.md @@ -7,3 +7,4 @@ - [ASCII Art in Java](http://www.baeldung.com/ascii-art-in-java) - [System.console() vs. System.out](https://www.baeldung.com/java-system-console-vs-system-out) - [How to Log to the Console in Color](https://www.baeldung.com/java-log-console-in-color) +- [Create Table Using ASCII in a Console in Java](https://www.baeldung.com/java-console-ascii-make-table) diff --git a/core-java-modules/core-java-date-operations-3/pom.xml b/core-java-modules/core-java-date-operations-3/pom.xml index 9b7be18b85..8e4740785c 100644 --- a/core-java-modules/core-java-date-operations-3/pom.xml +++ b/core-java-modules/core-java-date-operations-3/pom.xml @@ -28,7 +28,6 @@ 2.12.5 - 3.12.0 \ No newline at end of file diff --git a/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java b/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java index 2ebe30f4ff..25a8a57ba7 100644 --- a/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java +++ b/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java @@ -1,32 +1,31 @@ package com.baeldung.timestamptolong; -import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Date; public class TimestampToLong { - public void usingSimpleDateFormat() throws ParseException { + + public long usingSimpleDateFormat(String timestampString) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - String currentDateString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); - long actualTimestamp = sdf.parse(currentDateString).getTime(); + Date date = sdf.parse(timestampString); + String currentDateString = sdf.format(date); + return sdf.parse(currentDateString).getTime(); } - public void usingInstantClass() { - Instant instant = Instant.now(); - long actualTimestamp = instant.toEpochMilli(); + public long usingInstantClass(String timestampString) { + Instant instant = LocalDateTime.parse(timestampString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + .atZone(ZoneId.systemDefault()) + .toInstant(); + return instant.toEpochMilli(); } - public void usingTimestamp() { - Timestamp timestamp = new Timestamp(System.currentTimeMillis()); - long actualTimestamp = timestamp.getTime(); + public long usingJava8DateTime(String timestampString) { + LocalDateTime localDateTime = LocalDateTime.parse(timestampString.replace(" ", "T")); + return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); } - - public void usingJava8DateTime() { - LocalDateTime localDateTime = LocalDateTime.now(); - long actualTimestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); - } -} \ No newline at end of file +} diff --git a/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolocaldatetime/TimeToLocalDateTimeUnitTest.java b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolocaldatetime/TimeToLocalDateTimeUnitTest.java new file mode 100644 index 0000000000..e8fb821c75 --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolocaldatetime/TimeToLocalDateTimeUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.timestamptolocaldatetime; + +import org.joda.time.DateTimeZone; +import org.junit.Test; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; + +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; + +import static org.junit.Assert.assertEquals; + +public class TimeToLocalDateTimeUnitTest { + private static final long timestampInMillis = 1700010123000L; + private static final String expectedTimestampString = "2023-11-15 01:02:03"; + + @Test + public void givenTimestamp_whenConvertingToLocalDateTime_thenConvertSuccessfully() { + Instant instant = Instant.ofEpochMilli(timestampInMillis); + LocalDateTime localDateTime = + LocalDateTime.ofInstant(instant, ZoneId.of("UTC")); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + String formattedDateTime = localDateTime.format(formatter); + + assertEquals(expectedTimestampString, formattedDateTime); + } + + @Test + public void givenJodaTime_whenGettingTimestamp_thenConvertToLong() { + DateTime dateTime = new DateTime(timestampInMillis, DateTimeZone.UTC); + org.joda.time.LocalDateTime localDateTime = dateTime.toLocalDateTime(); + + org.joda.time.format.DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); + String actualTimestamp = formatter.print(localDateTime); + + assertEquals(expectedTimestampString, actualTimestamp); + } +} diff --git a/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java index ede8f7792d..868d019cf2 100644 --- a/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java +++ b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java @@ -2,51 +2,42 @@ package com.baeldung.timestamptolong; import org.junit.Test; -import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Date; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; public class TimestampToLongUnitTest { - - private static final long TOLERANCE = 1000; + private static final String timestampString = "2023-11-15 01:02:03"; @Test - public void givenSimpleDateFormat_whenFormattingDate_thenTConvertToLong() throws ParseException { + public void givenSimpleDateFormat_whenFormattingDate_thenConvertToLong() throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = sdf.parse(timestampString); - String currentDateString = sdf.format(new Date()); + String currentDateString = sdf.format(date); long actualTimestamp = sdf.parse(currentDateString).getTime(); - - assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + assertEquals(1700010123000L, actualTimestamp); } @Test - public void givenInstantClass_whenGettingTimestamp_thenTConvertToLong() { - Instant instant = Instant.now(); + public void givenInstantClass_whenGettingTimestamp_thenConvertToLong() { + Instant instant = LocalDateTime.parse(timestampString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + .atZone(ZoneId.systemDefault()) + .toInstant(); long actualTimestamp = instant.toEpochMilli(); - - assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + assertEquals(1700010123000L, actualTimestamp); } @Test - public void givenTimestamp_whenCreatingTimestamp_thenTConvertToLong() { - Timestamp timestamp = new Timestamp(System.currentTimeMillis()); - long actualTimestamp = timestamp.getTime(); - - assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); - } - - @Test - public void givenJava8DateTime_whenGettingTimestamp_thenTConvertToLong() { - LocalDateTime localDateTime = LocalDateTime.now(); + public void givenJava8DateTime_whenGettingTimestamp_thenConvertToLong() { + LocalDateTime localDateTime = LocalDateTime.parse(timestampString.replace(" ", "T")); long actualTimestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); - - assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + assertEquals(1700010123000L, actualTimestamp); } } diff --git a/core-java-modules/core-java-function/pom.xml b/core-java-modules/core-java-function/pom.xml index e8b538ad24..4110b8f6d9 100644 --- a/core-java-modules/core-java-function/pom.xml +++ b/core-java-modules/core-java-function/pom.xml @@ -51,7 +51,6 @@ 3.8.0 3.22.0 - 3.12.0 0.10.4 diff --git a/core-java-modules/core-java-functional/pom.xml b/core-java-modules/core-java-functional/pom.xml index 4b0bf9f730..3b21dd6e8a 100644 --- a/core-java-modules/core-java-functional/pom.xml +++ b/core-java-modules/core-java-functional/pom.xml @@ -35,7 +35,6 @@ 3.8.0 3.22.0 - 3.12.0 0.10.4 diff --git a/core-java-modules/core-java-hex/README.md b/core-java-modules/core-java-hex/README.md index 0ba4d1372f..2424137b32 100644 --- a/core-java-modules/core-java-hex/README.md +++ b/core-java-modules/core-java-hex/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Convert Hex to RGB Using Java](https://www.baeldung.com/java-convert-hex-to-rgb) +- [Convert a Hex String to an Integer in Java](https://www.baeldung.com/java-convert-hex-string-to-integer) diff --git a/core-java-modules/core-java-httpclient/pom.xml b/core-java-modules/core-java-httpclient/pom.xml index f3730d1b45..fc95366392 100644 --- a/core-java-modules/core-java-httpclient/pom.xml +++ b/core-java-modules/core-java-httpclient/pom.xml @@ -32,7 +32,7 @@ test - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -58,7 +58,7 @@ 11 3.22.0 5.11.2 - 2.27.2 + 3.3.1 \ No newline at end of file diff --git a/core-java-modules/core-java-io-2/pom.xml b/core-java-modules/core-java-io-2/pom.xml index 8f4f2518fe..8632748baa 100644 --- a/core-java-modules/core-java-io-2/pom.xml +++ b/core-java-modules/core-java-io-2/pom.xml @@ -31,9 +31,8 @@ log4j-over-slf4j ${org.slf4j.version} - - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -63,7 +62,7 @@ 3.0.0-M1 - 2.26.3 + 3.3.1 \ No newline at end of file diff --git a/core-java-modules/core-java-io-conversions-2/README.md b/core-java-modules/core-java-io-conversions-2/README.md index 4e179a84d2..bcc1db5f89 100644 --- a/core-java-modules/core-java-io-conversions-2/README.md +++ b/core-java-modules/core-java-io-conversions-2/README.md @@ -12,4 +12,5 @@ This module contains articles about core Java input/output(IO) conversions. - [How to Convert InputStream to Base64 String](https://www.baeldung.com/java-inputstream-to-base64-string) - [Convert an OutputStream to an InputStream](https://www.baeldung.com/java-convert-outputstream-to-inputstream) - [Java PrintStream to String](https://www.baeldung.com/java-printstream-to-string) +- [Convert File to Byte Array in Java](https://www.baeldung.com/java-convert-file-byte-array) - More articles: [[<-- prev]](/core-java-modules/core-java-io-conversions) diff --git a/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java b/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java index f409d05b06..184ae6d3e3 100644 --- a/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java +++ b/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java @@ -12,6 +12,10 @@ public class WriteCsvFileExample { } public String escapeSpecialCharacters(String data) { + if (data == null) { + throw new IllegalArgumentException("Input data cannot be null"); + } + String escapedData = data.replaceAll("\\R", " "); if (data.contains(",") || data.contains("\"") || data.contains("'")) { data = data.replace("\"", "\"\""); diff --git a/core-java-modules/core-java-lang-5/pom.xml b/core-java-modules/core-java-lang-5/pom.xml index 8e95fc4405..b65f061fc7 100644 --- a/core-java-modules/core-java-lang-5/pom.xml +++ b/core-java-modules/core-java-lang-5/pom.xml @@ -24,7 +24,6 @@ - 3.12.0 0.10.2 diff --git a/core-java-modules/core-java-lang-oop-methods/pom.xml b/core-java-modules/core-java-lang-oop-methods/pom.xml index 6f246d78ce..5e53004d62 100644 --- a/core-java-modules/core-java-lang-oop-methods/pom.xml +++ b/core-java-modules/core-java-lang-oop-methods/pom.xml @@ -35,7 +35,7 @@ 2.6 3.10.0 - 3.0.3 + 3.15.3 \ No newline at end of file diff --git a/core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/classcheck/CheckClassIsEnumUnitTest.java b/core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/classcheck/CheckClassIsEnumUnitTest.java new file mode 100644 index 0000000000..a69df8739f --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/classcheck/CheckClassIsEnumUnitTest.java @@ -0,0 +1,75 @@ +package com.baeldung.enums.classcheck; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +enum Device { + Keyboard, Monitor, Mouse, Printer +} + +enum Weekday { + Monday, Tuesday, Wednesday, Thursday, Friday, + Saturday { + @Override + boolean isWeekend() { + return true; + } + }, + Sunday { + @Override + boolean isWeekend() { + return true; + } + }; + + boolean isWeekend() { + return false; + } +} + +public class CheckClassIsEnumUnitTest { + + @Test + void whenUsingInstanceOf_thenGetExpectedResult() { + Object obj = Device.Keyboard; + assertTrue(obj instanceof Enum); + } + + @Test + void whenUsingisInstance_thenGetExpectedResult() { + Object obj = Device.Keyboard; + assertTrue(Enum.class.isInstance(obj)); + } + + @Test + void whenUsingEnumClassisAssignableFrom_thenGetExpectedResult() { + Object obj = Device.Keyboard; + assertTrue(Enum.class.isAssignableFrom(obj.getClass())); + } + + @Test + void whenUsingGetClassIsEnum_thenGetExpectedResult() { + assertTrue(Device.class.isEnum()); + + Object obj = Device.Keyboard; + assertTrue(obj.getClass().isEnum()); + } + + + @Test + void whenEnum_thenGetExpectedResult() { + Object monday = Weekday.Monday; + assertTrue(monday instanceof Enum); + assertTrue(Enum.class.isInstance(monday)); + assertTrue(Enum.class.isAssignableFrom(monday.getClass())); + assertTrue(monday.getClass().isEnum()); + + Object sunday = Weekday.Sunday; + assertTrue(sunday instanceof Enum); + assertTrue(Enum.class.isInstance(sunday)); + assertTrue(Enum.class.isAssignableFrom(sunday.getClass())); + assertFalse(sunday.getClass().isEnum()); // <-- isEnum() check failed when Enum values with body + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-networking-2/pom.xml b/core-java-modules/core-java-networking-2/pom.xml index 34f16a9938..388e439e37 100644 --- a/core-java-modules/core-java-networking-2/pom.xml +++ b/core-java-modules/core-java-networking-2/pom.xml @@ -56,7 +56,7 @@ 2.4.5 2.3.3 2.0.0-alpha-3 - 1.15 + 1.16.0 \ No newline at end of file diff --git a/core-java-modules/core-java-numbers-6/README.md b/core-java-modules/core-java-numbers-6/README.md index cf84e29710..3a2154efdd 100644 --- a/core-java-modules/core-java-numbers-6/README.md +++ b/core-java-modules/core-java-numbers-6/README.md @@ -7,4 +7,5 @@ - [Java Double vs. BigDecimal](https://www.baeldung.com/java-double-vs-bigdecimal) - [Finding the Square Root of a BigInteger in Java](https://www.baeldung.com/java-find-square-root-biginteger) - [Truncate a Double to Two Decimal Places in Java](https://www.baeldung.com/java-double-round-two-decimal-places) +- [Comparing the Values of Two Generic Numbers in Java](https://www.baeldung.com/java-generic-numbers-comparison-methods) - More articles: [[<-- prev]](../core-java-numbers-5) diff --git a/core-java-modules/core-java-numbers-6/pom.xml b/core-java-modules/core-java-numbers-6/pom.xml index 7a3b3d4426..34e53056a4 100644 --- a/core-java-modules/core-java-numbers-6/pom.xml +++ b/core-java-modules/core-java-numbers-6/pom.xml @@ -42,7 +42,6 @@ - 1.15 - 32.1.2-jre + 1.16.0 \ No newline at end of file diff --git a/core-java-modules/core-java-os/pom.xml b/core-java-modules/core-java-os/pom.xml index d4ee34b8b7..cd5b479974 100644 --- a/core-java-modules/core-java-os/pom.xml +++ b/core-java-modules/core-java-os/pom.xml @@ -75,7 +75,6 @@ 4.01 - 1.8.9 1.9 1.9 0.4 diff --git a/core-java-modules/core-java-reflection/pom.xml b/core-java-modules/core-java-reflection/pom.xml index a836ee4a22..f77c791936 100644 --- a/core-java-modules/core-java-reflection/pom.xml +++ b/core-java-modules/core-java-reflection/pom.xml @@ -52,7 +52,6 @@ 1.8 1.8 0.10.2 - 3.12.0 \ No newline at end of file diff --git a/core-java-modules/core-java-security-2/pom.xml b/core-java-modules/core-java-security-2/pom.xml index 0fc121c070..b54afc31d8 100644 --- a/core-java-modules/core-java-security-2/pom.xml +++ b/core-java-modules/core-java-security-2/pom.xml @@ -21,7 +21,7 @@ org.bouncycastle - bcprov-jdk15on + bcprov-jdk18on ${bouncycastle.version} @@ -33,8 +33,8 @@ - 1.60 - 1.11 + 1.76 + 1.16.0 2.3.1 diff --git a/core-java-modules/core-java-security-3/pom.xml b/core-java-modules/core-java-security-3/pom.xml index b979b56658..dae570e51d 100644 --- a/core-java-modules/core-java-security-3/pom.xml +++ b/core-java-modules/core-java-security-3/pom.xml @@ -21,7 +21,7 @@ org.bouncycastle - bcprov-jdk15on + bcprov-jdk18on ${bouncycastle.version} @@ -43,8 +43,8 @@ - 1.70 - 1.15 + 1.76 + 1.16.0 2.3.1 6.0.3 diff --git a/core-java-modules/core-java-security-4/pom.xml b/core-java-modules/core-java-security-4/pom.xml index 2b9809b749..a4700c34ba 100644 --- a/core-java-modules/core-java-security-4/pom.xml +++ b/core-java-modules/core-java-security-4/pom.xml @@ -16,7 +16,7 @@ org.bouncycastle - bcpkix-jdk15on + bcpkix-jdk18on ${bouncycastle.version} @@ -27,7 +27,7 @@ - 1.70 + 1.76 1.2.6 diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java new file mode 100644 index 0000000000..8f3ec35160 --- /dev/null +++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java @@ -0,0 +1,49 @@ +package com.baeldung.keystorealias; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.security.KeyStore; +import java.security.cert.X509Certificate; + +import org.junit.jupiter.api.Test; + +public class KeystoreCertificateNameAliasUnitTest { + private static final String KEYSTORE_FILE = "my-keystore.jks"; + private static final String KEYSTORE_PWD = "storepw@1"; + private static final String KEYSTORE_ALIAS = "baeldung"; + + private KeyStore readKeyStore() throws Exception { + KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); + keystore.load(getClass().getResourceAsStream(KEYSTORE_FILE), KEYSTORE_PWD.toCharArray()); + return keystore; + } + + @Test + void whenCheckingAliasAndName_thenMatchIsFound() throws Exception { + KeyStore keystore = readKeyStore(); + + assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); + + X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); + String ownerName = x509Certificate.getSubjectX500Principal().getName(); + assertThat(ownerName.contains("my-cn.localhost")).isTrue(); + } + + @Test + void whenCheckingAliasAndName_thenNameIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); + + assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); + + X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); + String ownerName = x509Certificate.getSubjectX500Principal().getName(); + assertThat(ownerName.contains("commonName1")).isFalse(); + } + + @Test + void whenCheckingAliasAndName_thenAliasIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); + + assertThat(keystore.containsAlias("alias1")).isFalse(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-security-4/src/test/resources/com/baeldung/keystorealias/my-keystore.jks b/core-java-modules/core-java-security-4/src/test/resources/com/baeldung/keystorealias/my-keystore.jks new file mode 100644 index 0000000000..8f7709ee96 Binary files /dev/null and b/core-java-modules/core-java-security-4/src/test/resources/com/baeldung/keystorealias/my-keystore.jks differ diff --git a/core-java-modules/core-java-streams-5/README.md b/core-java-modules/core-java-streams-5/README.md index 64bc4e6b7a..dfd5a649b5 100644 --- a/core-java-modules/core-java-streams-5/README.md +++ b/core-java-modules/core-java-streams-5/README.md @@ -7,3 +7,4 @@ - [Taking Every N-th Element from Finite and Infinite Streams in Java](https://www.baeldung.com/java-nth-element-finite-infinite-streams) - [Modifying Objects Within Stream While Iterating](https://www.baeldung.com/java-stream-modify-objects-during-iteration) - [Convert a Stream into a Map or Multimap in Java](https://www.baeldung.com/java-convert-stream-map-multimap) +- [How to Avoid NoSuchElementException in Stream API](https://www.baeldung.com/java-streams-api-avoid-nosuchelementexception) diff --git a/core-java-modules/core-java-streams-5/pom.xml b/core-java-modules/core-java-streams-5/pom.xml index d7baf84d30..e217271f4c 100644 --- a/core-java-modules/core-java-streams-5/pom.xml +++ b/core-java-modules/core-java-streams-5/pom.xml @@ -77,7 +77,6 @@ 12 12 0.10.2 - 32.1.2-jre \ No newline at end of file diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index 507e830e8a..548a3dc3f8 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -21,7 +21,7 @@ org.apache.commons commons-lang3 - ${apache-commons-lang3.version} + ${commons-lang3.version} com.vdurmont @@ -61,7 +61,6 @@ 11 11 1.7 - 3.12.0 5.1.1 1.10.0 diff --git a/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java b/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java index c498921d9a..c54bb1236e 100644 --- a/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java +++ b/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java @@ -1,12 +1,12 @@ package com.baeldung.bytebuffertostring; -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.Test; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; public class ByteArrayToStringUnitTest { private static Charset charset = StandardCharsets.UTF_8; @@ -37,8 +37,17 @@ public class ByteArrayToStringUnitTest { // Allocate a ByteBuffer ByteBuffer byteBuffer = ByteBuffer.wrap(content.getBytes()); String newContent = charset.decode(byteBuffer) - .toString(); + .toString(); assertEquals(content, newContent); } + @Test + public void convertStringToByteBuffer_thenOk() { + byte[] expectedBytes = content.getBytes(Charset.forName(charset.toString())); + ByteBuffer byteBuffer = ByteBuffer.wrap(expectedBytes); + + // Test the conversion from string to ByteBuffer + assertEquals(expectedBytes, byteBuffer.array()); + } + } diff --git a/core-java-modules/core-java-string-operations-2/pom.xml b/core-java-modules/core-java-string-operations-2/pom.xml index 383a3b4a40..27071e5427 100644 --- a/core-java-modules/core-java-string-operations-2/pom.xml +++ b/core-java-modules/core-java-string-operations-2/pom.xml @@ -87,7 +87,7 @@ 8.0.1.Final 5.0.0 - 1.14 + 1.16.0 5.3.0 diff --git a/core-java-modules/core-java-string-operations-3/pom.xml b/core-java-modules/core-java-string-operations-3/pom.xml index 39167271fa..0558e71a35 100644 --- a/core-java-modules/core-java-string-operations-3/pom.xml +++ b/core-java-modules/core-java-string-operations-3/pom.xml @@ -22,7 +22,7 @@ org.apache.commons commons-lang3 - ${apache-commons-lang3.version} + ${commons-lang3.version} org.apache.maven @@ -70,7 +70,6 @@ 11 11 5.3.9 - 3.12.0 3.6.3 6.1.1 2.11.1 diff --git a/core-java-modules/core-java-string-operations-4/pom.xml b/core-java-modules/core-java-string-operations-4/pom.xml index 27c2bf91bd..b9591763a0 100644 --- a/core-java-modules/core-java-string-operations-4/pom.xml +++ b/core-java-modules/core-java-string-operations-4/pom.xml @@ -27,12 +27,12 @@ org.apache.commons commons-lang3 - ${apache-commons-lang3.version} + ${commons-lang3.version} org.apache.commons commons-text - ${apache-commons-text.version} + ${commons-text.version} org.assertj @@ -60,8 +60,7 @@ 11 5.8 5.3.13 - 3.12.0 - 1.10.0 + 1.10.0 \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-6/README.md b/core-java-modules/core-java-string-operations-6/README.md index 9d92552dd1..506b548304 100644 --- a/core-java-modules/core-java-string-operations-6/README.md +++ b/core-java-modules/core-java-string-operations-6/README.md @@ -11,4 +11,3 @@ - [Check if a String Has All Unique Characters in Java](https://www.baeldung.com/java-check-string-all-unique-chars) - [Performance Comparison Between Different Java String Concatenation Methods](https://www.baeldung.com/java-string-concatenation-methods) - [Replacing Single Quote with \’ in Java String](https://www.baeldung.com/java-replacing-single-quote-string) -- [Check if a String Contains a Number Value in Java](https://www.baeldung.com/java-string-number-presence) diff --git a/core-java-modules/core-java-string-operations-7/README.md b/core-java-modules/core-java-string-operations-7/README.md index 28e2dccd39..2b9c4c25f3 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -3,3 +3,5 @@ - [How to Center Text Output in Java](https://www.baeldung.com/java-center-text-output) - [Capitalize the First Letter of Each Word in a String](https://www.baeldung.com/java-string-initial-capital-letter-every-word) - [Check if a String Contains Only Unicode Letters](https://www.baeldung.com/java-string-all-unicode-characters) +- [Create a Mutable String in Java](https://www.baeldung.com/java-mutable-string) +- [Check if a String Contains a Number Value in Java](https://www.baeldung.com/java-string-number-presence) diff --git a/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/isemptyvsisblank/StringIsEmptyVsIsBlankUnitTest.java b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/isemptyvsisblank/StringIsEmptyVsIsBlankUnitTest.java new file mode 100644 index 0000000000..f6950237c5 --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/isemptyvsisblank/StringIsEmptyVsIsBlankUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.isemptyvsisblank; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class StringIsEmptyVsIsBlankUnitTest { + + @Test + public void givenString_whenCallIsEmpty_thenReturnCorrectValues() { + assertFalse("Example text".isEmpty()); + assertTrue("".isEmpty()); + assertFalse(" ".isEmpty()); + assertFalse("\t\n\r\f".isEmpty()); + } + + @Test + public void givenString_whenCallStringIsBlank_thenReturnCorrectValues() { + assertFalse("Example text".isBlank()); + assertTrue("".isBlank()); + assertTrue(" ".isBlank()); + assertTrue("\t\n\r\f ".isBlank()); + } +} diff --git a/core-java-modules/core-java-sun/README.md b/core-java-modules/core-java-sun/README.md index 107035cbe8..82977bca6c 100644 --- a/core-java-modules/core-java-sun/README.md +++ b/core-java-modules/core-java-sun/README.md @@ -5,4 +5,6 @@ This module contains articles about the sun package ### Relevant Articles: - [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin) -- [Guide to sun.misc.Unsafe](http://www.baeldung.com/java-unsafe) \ No newline at end of file +- [Guide to sun.misc.Unsafe](http://www.baeldung.com/java-unsafe) +- [Why Is sun.misc.Unsafe.park Actually Unsafe?](https://www.baeldung.com/java-sun-misc-unsafe-park-reason) +- [Sharing Memory Between JVMs](https://www.baeldung.com/java-sharing-memory-between-jvms) diff --git a/core-java-modules/core-java-time-measurements/pom.xml b/core-java-modules/core-java-time-measurements/pom.xml index 7b2bc31ebb..2dd713efe8 100644 --- a/core-java-modules/core-java-time-measurements/pom.xml +++ b/core-java-modules/core-java-time-measurements/pom.xml @@ -33,7 +33,7 @@ org.aspectj aspectjrt - ${asspectj.version} + ${aspectj.version} org.mockito @@ -74,7 +74,7 @@ 3.6.1 2.10 - 1.8.9 + 1.9.20.1 1.44 4.1.0 diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index a237fe0ed6..27d84c742d 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -198,7 +198,8 @@ core-java-records core-java-9-jigsaw - + + core-java-collections-set core-java-date-operations-1 core-java-datetime-conversion diff --git a/di-modules/cdi/pom.xml b/di-modules/cdi/pom.xml index fd920c8ce1..09f69f3dc3 100644 --- a/di-modules/cdi/pom.xml +++ b/di-modules/cdi/pom.xml @@ -59,7 +59,7 @@ 2.0.SP1 3.1.6.Final - 1.9.19 + 1.9.20.1 \ No newline at end of file diff --git a/docker-modules/docker-caching/multi-module-caching/pom.xml b/docker-modules/docker-caching/multi-module-caching/pom.xml index 60f14a17e5..bebfb85e8a 100644 --- a/docker-modules/docker-caching/multi-module-caching/pom.xml +++ b/docker-modules/docker-caching/multi-module-caching/pom.xml @@ -27,7 +27,7 @@ UTF-8 1.8 - 32.1.2-jre + 32.1.3-jre \ No newline at end of file diff --git a/docker-modules/docker-caching/single-module-caching/pom.xml b/docker-modules/docker-caching/single-module-caching/pom.xml index 0e5174b7ca..bb44c21e10 100644 --- a/docker-modules/docker-caching/single-module-caching/pom.xml +++ b/docker-modules/docker-caching/single-module-caching/pom.xml @@ -49,7 +49,7 @@ 8 8 UTF-8 - 32.1.2-jre + 32.1.3-jre \ No newline at end of file diff --git a/gradle-modules/.gitignore b/gradle-modules/.gitignore new file mode 100644 index 0000000000..63b7142f43 --- /dev/null +++ b/gradle-modules/.gitignore @@ -0,0 +1 @@ +!gradle-wrapper.jar \ No newline at end of file diff --git a/gradle-modules/gradle-5/README.md b/gradle-modules/gradle-5/README.md index 7871c0e822..6d701ac43c 100644 --- a/gradle-modules/gradle-5/README.md +++ b/gradle-modules/gradle-5/README.md @@ -1,5 +1,7 @@ ### Relevant Articles: +This module is using gradle-8.3. + - [Run a Java main Method Using Gradle](https://www.baeldung.com/gradle-run-java-main) - [Finding Unused Gradle Dependencies](https://www.baeldung.com/gradle-finding-unused-dependencies) - [Intro to Gradle Lint Plugin](https://www.baeldung.com/java-gradle-lint-intro) diff --git a/gradle-modules/gradle-6/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-6/gradle/wrapper/gradle-wrapper.properties index 94920145f3..cd141cfc9d 100644 --- a/gradle-modules/gradle-6/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle-6/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists + diff --git a/gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..7f93135c49 Binary files /dev/null and b/gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..7f93135c49 Binary files /dev/null and b/gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..7f93135c49 Binary files /dev/null and b/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties index 774fae8767..878fe049c2 100644 --- a/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle/gradle/shipkit.gradle b/gradle-modules/gradle/gradle/shipkit.gradle deleted file mode 100644 index 144c01dc05..0000000000 --- a/gradle-modules/gradle/gradle/shipkit.gradle +++ /dev/null @@ -1,41 +0,0 @@ -//This default Shipkit configuration file was created automatically and is intended to be checked-in. -//Default configuration is sufficient for local testing and trying out Shipkit. -//To leverage Shipkit fully, please fix the TODO items, refer to our Getting Started Guide for help: -// -// https://github.com/mockito/shipkit/blob/master/docs/getting-started.md -// -shipkit { - //TODO is the repository correct? - gitHub.repository = "unspecified-user/unspecified-repo" - - //TODO generate and use your own read-only GitHub personal access token - gitHub.readOnlyAuthToken = "76826c9ec886612f504d12fd4268b16721c4f85d" - - //TODO generate GitHub write token, and ensure your Travis CI has this env variable exported - gitHub.writeAuthToken = System.getenv("GH_WRITE_TOKEN") -} - -allprojects { - plugins.withId("com.jfrog.bintray") { - - //Bintray configuration is handled by JFrog Bintray Gradle Plugin - //For reference see the official documentation: https://github.com/bintray/gradle-bintray-plugin - bintray { - - //TODO sign up for free open source account with https://bintray.com, then look up your API key on your profile page in Bintray - key = '7ea297848ca948adb7d3ee92a83292112d7ae989' - //TODO don't check in the key, remove above line and use env variable exported on CI: - //key = System.getenv("BINTRAY_API_KEY") - - pkg { - //TODO configure Bintray settings per your project (https://github.com/bintray/gradle-bintray-plugin) - repo = 'bootstrap' - user = 'shipkit-bootstrap-bot' - userOrg = 'shipkit-bootstrap' - name = 'maven' - licenses = ['MIT'] - labels = ['continuous delivery', 'release automation', 'shipkit'] - } - } - } -} diff --git a/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..7f93135c49 Binary files /dev/null and b/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.properties index ebf7ae9184..3fa8f862f7 100644 --- a/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ -#Thu Oct 12 16:43:02 BDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-bin.zip diff --git a/httpclient-simple/pom.xml b/httpclient-simple/pom.xml index a6049432ce..a0f2dd6514 100644 --- a/httpclient-simple/pom.xml +++ b/httpclient-simple/pom.xml @@ -99,7 +99,7 @@ ${commons-codec.version} - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -205,9 +205,9 @@ 17 - 1.10 + 1.16.0 - 2.5.1 + 3.3.1 5.2 5.2 diff --git a/java-spi/exchange-rate-impl/pom.xml b/java-spi/exchange-rate-impl/pom.xml index 254a8bb809..7ec10b1c04 100644 --- a/java-spi/exchange-rate-impl/pom.xml +++ b/java-spi/exchange-rate-impl/pom.xml @@ -65,7 +65,7 @@ 1.0.0-SNAPSHOT - 3.10.0 + 4.12.0 1.0 1.0.1 1.1.2 diff --git a/javaxval-2/pom.xml b/javaxval-2/pom.xml index f73f23bcb2..366fd9fdbf 100644 --- a/javaxval-2/pom.xml +++ b/javaxval-2/pom.xml @@ -9,26 +9,24 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + parent-boot-3 + 0.0.1-SNAPSHOT + ../parent-boot-3 org.springframework.boot spring-boot-starter-validation - ${spring.boot.version} org.springframework.boot spring-boot-starter-test - ${spring.boot.version} test com.fasterxml.jackson.core jackson-databind - ${jackson.databind.version} @@ -42,9 +40,16 @@ - - 3.0.4 - 2.14.0 - + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + \ No newline at end of file diff --git a/javaxval-2/src/test/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidationUnitTest.java b/javaxval-2/src/test/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidationUnitTest.java index 094236e963..8c3761ae09 100644 --- a/javaxval-2/src/test/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidationUnitTest.java +++ b/javaxval-2/src/test/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidationUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.javaxval; +package com.baeldung.javaxval.afterdeserialization; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/javaxval/pom.xml b/javaxval/pom.xml index c4a30f915d..e1a3dc350c 100644 --- a/javaxval/pom.xml +++ b/javaxval/pom.xml @@ -8,20 +8,19 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + parent-boot-3 + 0.0.1-SNAPSHOT + ../parent-boot-3 org.springframework.boot spring-boot-starter-validation - ${spring.boot.version} org.springframework.boot spring-boot-starter-test - ${spring.boot.version} test @@ -38,7 +37,6 @@ 8.0.1.Final - 3.0.4 \ No newline at end of file diff --git a/json-modules/json-conversion/pom.xml b/json-modules/json-conversion/pom.xml index 638216f4c5..9eebac16b4 100644 --- a/json-modules/json-conversion/pom.xml +++ b/json-modules/json-conversion/pom.xml @@ -38,7 +38,6 @@ 2.10.1 - 32.1.2-jre diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml index 8d45b95a7b..9923e46267 100644 --- a/libraries-3/pom.xml +++ b/libraries-3/pom.xml @@ -219,10 +219,10 @@ 2.7.2 1.2.3.Final 0.22.6 - 1.9.2 + 1.9.20.1 0.14.1 - 1.9.2 - 1.9.2 + 1.9.20.1 + 1.9.20.1 1.19 4.4.13 4.5.12 diff --git a/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java b/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java index 7cfe8984e7..6745b9be7f 100644 --- a/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java +++ b/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java @@ -74,7 +74,7 @@ public class OpenCsvIntegrationTest { assertThat(contents.split(NEW_LINE)) .containsExactly( - "'colA','colB','colC'", + "'COLA','COLB','COLC'", "'Test1','sample','data'", "'Test2','ipso','facto'" ); diff --git a/libraries-http-2/pom.xml b/libraries-http-2/pom.xml index c80c5729a7..b49e4b9387 100644 --- a/libraries-http-2/pom.xml +++ b/libraries-http-2/pom.xml @@ -109,7 +109,7 @@ - 4.9.1 + 4.12.0 2.10.1 4.9.1 1.0.3 diff --git a/libraries-http/pom.xml b/libraries-http/pom.xml index c726b56b5d..caf42639cc 100644 --- a/libraries-http/pom.xml +++ b/libraries-http/pom.xml @@ -105,7 +105,7 @@ 2.10.1 4.5.3 - 4.9.1 + 4.12.0 1.23.0 2.2.0 2.3.0 diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml index 62c476a82c..8a6dad6da2 100644 --- a/libraries-security/pom.xml +++ b/libraries-security/pom.xml @@ -122,7 +122,7 @@ 1.2.2 1.2.2 1.9.2 - 1.58 + 1.68 0.1.55 2.5.1 2.4.0.RELEASE diff --git a/osgi/pom.xml b/osgi/pom.xml index ecc8758ef9..16b1f5d106 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -91,7 +91,7 @@ - 3.9.0 + 4.12.0 1.1 6.0.0 3.3.0 diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index 3f6ad8ef8a..b79be81a66 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -36,6 +36,16 @@ pom import + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjweaver + ${aspectj.version} + @@ -95,7 +105,7 @@ 1.0.22.RELEASE 2.7.11 - 1.9.1 + 1.9.20.1 8.0.31 diff --git a/patterns-modules/design-patterns-singleton/README.md b/patterns-modules/design-patterns-singleton/README.md index edec116b93..a4915ebfaf 100644 --- a/patterns-modules/design-patterns-singleton/README.md +++ b/patterns-modules/design-patterns-singleton/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: - [How to Serialize a Singleton in Java](https://www.baeldung.com/java-serialize-singleton) +- [Bill Pugh Singleton Implementation](https://www.baeldung.com/java-bill-pugh-singleton-implementation) diff --git a/pdf-2/pom.xml b/pdf-2/pom.xml index ccbb5c9693..2079ff70e5 100644 --- a/pdf-2/pom.xml +++ b/pdf-2/pom.xml @@ -51,7 +51,7 @@ 5.5.13.3 7.2.3 3.0.1 - 3.0.0-RC1 + 3.0.0 \ No newline at end of file diff --git a/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoITextUnitTest.java b/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoITextUnitTest.java index 422858d659..f54405a533 100644 --- a/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoITextUnitTest.java +++ b/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoITextUnitTest.java @@ -1,29 +1,31 @@ package com.baeldung.pdfinfo; -import org.junit.Assert; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import java.io.IOException; import java.util.Map; -public class PdfInfoITextUnitTest { +import org.junit.jupiter.api.Test; + +class PdfInfoITextUnitTest { private static final String PDF_FILE = "src/test/resources/input.pdf"; @Test - public void givenPdf_whenGetNumberOfPages_thenOK() throws IOException { - Assert.assertEquals(4, PdfInfoIText.getNumberOfPages(PDF_FILE)); + void givenPdf_whenGetNumberOfPages_thenOK() throws IOException { + assertEquals(4, PdfInfoIText.getNumberOfPages(PDF_FILE)); } @Test - public void givenPdf_whenIsPasswordRequired_thenOK() throws IOException { - Assert.assertFalse(PdfInfoIText.isPasswordRequired(PDF_FILE)); + void givenPdf_whenIsPasswordRequired_thenOK() throws IOException { + assertFalse(PdfInfoIText.isPasswordRequired(PDF_FILE)); } @Test - public void givenPdf_whenGetInfo_thenOK() throws IOException { + void givenPdf_whenGetInfo_thenOK() throws IOException { Map info = PdfInfoIText.getInfo(PDF_FILE); - Assert.assertEquals("LibreOffice 4.2", info.get("Producer")); - Assert.assertEquals("Writer", info.get("Creator")); + assertEquals("LibreOffice 4.2", info.get("Producer")); + assertEquals("Writer", info.get("Creator")); } } diff --git a/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoPdfBoxUnitTest.java b/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoPdfBoxUnitTest.java index 0fcbc7ee3c..5c4e5fc30d 100644 --- a/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoPdfBoxUnitTest.java +++ b/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoPdfBoxUnitTest.java @@ -1,29 +1,31 @@ package com.baeldung.pdfinfo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + import org.apache.pdfbox.pdmodel.PDDocumentInformation; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.io.IOException; -public class PdfInfoPdfBoxUnitTest { +class PdfInfoPdfBoxUnitTest { private static final String PDF_FILE = "src/test/resources/input.pdf"; @Test - public void givenPdf_whenGetNumberOfPages_thenOK() throws IOException { - Assert.assertEquals(4, PdfInfoPdfBox.getNumberOfPages(PDF_FILE)); + void givenPdf_whenGetNumberOfPages_thenOK() throws IOException { + assertEquals(4, PdfInfoPdfBox.getNumberOfPages(PDF_FILE)); } @Test - public void givenPdf_whenIsPasswordRequired_thenOK() throws IOException { - Assert.assertFalse(PdfInfoPdfBox.isPasswordRequired(PDF_FILE)); + void givenPdf_whenIsPasswordRequired_thenOK() throws IOException { + assertFalse(PdfInfoPdfBox.isPasswordRequired(PDF_FILE)); } @Test - public void givenPdf_whenGetInfo_thenOK() throws IOException { + void givenPdf_whenGetInfo_thenOK() throws IOException { PDDocumentInformation info = PdfInfoPdfBox.getInfo(PDF_FILE); - Assert.assertEquals("LibreOffice 4.2", info.getProducer()); - Assert.assertEquals("Writer", info.getCreator()); + assertEquals("LibreOffice 4.2", info.getProducer()); + assertEquals("Writer", info.getCreator()); } } diff --git a/pdf/pom.xml b/pdf/pom.xml index cead1b2ded..0fe90b6eb5 100644 --- a/pdf/pom.xml +++ b/pdf/pom.xml @@ -104,7 +104,7 @@ - 2.0.25 + 3.0.0 2.0.1 5.5.13.3 5.5.10 diff --git a/persistence-modules/core-java-persistence-3/README.md b/persistence-modules/core-java-persistence-3/README.md new file mode 100644 index 0000000000..6ca158560b --- /dev/null +++ b/persistence-modules/core-java-persistence-3/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Convert ResultSet Into Map](https://www.baeldung.com/java-resultset-map) diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/README.md b/persistence-modules/spring-boot-persistence-mongodb-3/README.md index ee6a96397a..e234c2b3a1 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/README.md +++ b/persistence-modules/spring-boot-persistence-mongodb-3/README.md @@ -1,4 +1,5 @@ # Relevant Articles - [How to Insert a HashMap Into MongoDB With Java?](https://www.baeldung.com/java-mongodb-insert-hashmap) - [MongoDB – Field Level Encryption](https://www.baeldung.com/mongodb-field-level-encryption) +- [MongoDB Atlas Search Using the Java Driver and Spring Data](https://www.baeldung.com/mongodb-spring-data-atlas-search) - More articles: [[<--prev]](../spring-boot-persistence-mongodb-2) diff --git a/pom.xml b/pom.xml index 47c566023d..7099dd8cbc 100644 --- a/pom.xml +++ b/pom.xml @@ -1236,7 +1236,7 @@ 3.21.0 1.18.28 2.1.214 - 32.1.2-jre + 32.1.3-jre 3.3.0 diff --git a/security-modules/oauth2-framework-impl/oauth2-authorization-server/pom.xml b/security-modules/oauth2-framework-impl/oauth2-authorization-server/pom.xml index 7f13e5acea..1ebbb5e10f 100644 --- a/security-modules/oauth2-framework-impl/oauth2-authorization-server/pom.xml +++ b/security-modules/oauth2-framework-impl/oauth2-authorization-server/pom.xml @@ -21,13 +21,13 @@ org.bouncycastle - bcprov-jdk15on - ${bcprov-jdk15on.version} + bcprov-jdk18on + ${bouncycastle.version} org.bouncycastle - bcpkix-jdk15on - ${bcpkix-jdk15on.version} + bcpkix-jdk18on + ${bouncycastle.version} @@ -69,8 +69,7 @@ 9080 9443 7.3 - 1.62 - 1.62 + 1.76 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-annotations/pom.xml b/spring-boot-modules/spring-boot-annotations/pom.xml index 91f2614de8..13a28cbd4e 100644 --- a/spring-boot-modules/spring-boot-annotations/pom.xml +++ b/spring-boot-modules/spring-boot-annotations/pom.xml @@ -17,7 +17,6 @@ org.aspectj aspectjweaver - ${aspectjweaver.version} org.springframework.boot diff --git a/spring-boot-modules/spring-boot-mvc/pom.xml b/spring-boot-modules/spring-boot-mvc/pom.xml index a251c5049b..963cda61b9 100644 --- a/spring-boot-modules/spring-boot-mvc/pom.xml +++ b/spring-boot-modules/spring-boot-mvc/pom.xml @@ -84,12 +84,10 @@ org.aspectj aspectjrt - ${aspectjweaver.version} org.aspectj aspectjweaver - ${aspectjweaver.version} org.projectlombok @@ -114,6 +112,7 @@ 1.10.0 2.3.7 + 1.9.20.1 com.baeldung.springbootmvc.SpringBootMvcApplication diff --git a/spring-boot-modules/spring-boot-testing-2/README.md b/spring-boot-modules/spring-boot-testing-2/README.md index 1baf83bf34..fbf708381b 100644 --- a/spring-boot-modules/spring-boot-testing-2/README.md +++ b/spring-boot-modules/spring-boot-testing-2/README.md @@ -14,4 +14,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring Boot – Testing Redis With Testcontainers](https://www.baeldung.com/spring-boot-redis-testcontainers) - [Spring Boot – Keycloak Integration Testing with Testcontainers](https://www.baeldung.com/spring-boot-keycloak-integration-testing) - [Difference Between @Spy and @SpyBean](https://www.baeldung.com/spring-spy-vs-spybean) +- [Overriding Spring Beans in Integration Test](https://www.baeldung.com/overriding-spring-beans-in-integration-test) - More articles: [[<-- prev]](../spring-boot-testing) diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Config.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Config.java new file mode 100644 index 0000000000..f0892338f8 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Config.java @@ -0,0 +1,13 @@ +package com.baeldung.overridebean; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class Config { + + @Bean + public Service helloWorld() { + return new ServiceImpl(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Endpoint.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Endpoint.java new file mode 100644 index 0000000000..e199d1f25b --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Endpoint.java @@ -0,0 +1,19 @@ +package com.baeldung.overridebean; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class Endpoint { + + private final Service service; + + public Endpoint(Service service) { + this.service = service; + } + + @GetMapping("/hello") + public String helloWorldEndpoint() { + return service.helloWorld(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Service.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Service.java new file mode 100644 index 0000000000..0872fcc372 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Service.java @@ -0,0 +1,5 @@ +package com.baeldung.overridebean; + +public interface Service { + String helloWorld(); +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/ServiceImpl.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/ServiceImpl.java new file mode 100644 index 0000000000..4d4b5582e6 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/ServiceImpl.java @@ -0,0 +1,8 @@ +package com.baeldung.overridebean; + +public class ServiceImpl implements Service { + + public String helloWorld() { + return "hello world"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/boot/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/boot/Application.java new file mode 100644 index 0000000000..1eb0012493 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/boot/Application.java @@ -0,0 +1,14 @@ +package com.baeldung.overridebean.boot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; + +@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class }) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/ConditionalConfig.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/ConditionalConfig.java new file mode 100644 index 0000000000..e18689e042 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/ConditionalConfig.java @@ -0,0 +1,18 @@ +package com.baeldung.overridebean.conditional; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.ServiceImpl; + +@Configuration +public class ConditionalConfig { + + @Bean + @ConditionalOnProperty(name = "service.stub", havingValue = "false") + public Service helloWorld() { + return new ServiceImpl(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/ProfileConfig.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/ProfileConfig.java new file mode 100644 index 0000000000..64cdfff8a5 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/ProfileConfig.java @@ -0,0 +1,18 @@ +package com.baeldung.overridebean.profile; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.ServiceImpl; + +@Configuration +@Profile("prod") +public class ProfileConfig { + + @Bean + public Service helloWorld() { + return new ServiceImpl(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-testing-2/src/main/resources/application.properties index b628a708bd..0982b7bac0 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-testing-2/src/main/resources/application.properties @@ -1,2 +1,3 @@ keycloak.enabled=true spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8180/auth/realms/baeldung-api +service.stub=false \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java new file mode 100644 index 0000000000..b3a5164ff5 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java @@ -0,0 +1,30 @@ +package com.baeldung.overridebean.conditional; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.boot.Application; + +@SpringBootTest(classes = { Application.class, ConditionalConfig.class, Endpoint.class, ConditionalTestConfig.class }, properties = "service.stub=true") +@AutoConfigureMockMvc +class ConditionIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void givenConditionalConfig_whenServiceStubIsTrue_thenStubOk() throws Exception { + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello conditional stub"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalStub.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalStub.java new file mode 100644 index 0000000000..6b3e447108 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalStub.java @@ -0,0 +1,10 @@ +package com.baeldung.overridebean.conditional; + +import com.baeldung.overridebean.Service; + +public class ConditionalStub implements Service { + + public String helloWorld() { + return "hello conditional stub"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java new file mode 100644 index 0000000000..ce82b43df0 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java @@ -0,0 +1,17 @@ +package com.baeldung.overridebean.conditional; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; + +import com.baeldung.overridebean.Service; + +@TestConfiguration +public class ConditionalTestConfig { + + @Bean + @ConditionalOnProperty(name = "service.stub", havingValue = "true") + public Service helloWorld() { + return new ConditionalStub(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java new file mode 100644 index 0000000000..9a63ad4113 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java @@ -0,0 +1,37 @@ +package com.baeldung.overridebean.mockbean; + +import static org.hamcrest.Matchers.containsString; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.boot.Application; + +@SpringBootTest(classes = { Application.class, Endpoint.class }) +@AutoConfigureMockMvc +class MockBeanIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private Service service; + + @Test + void givenServiceMockBean_whenGetHelloEndpoint_thenMockOk() throws Exception { + when(service.helloWorld()).thenReturn("hello mock bean"); + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello mock bean"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java new file mode 100644 index 0000000000..a8dba58b79 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java @@ -0,0 +1,31 @@ +package com.baeldung.overridebean.overridebeandefinition; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Config; +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.boot.Application; + +@SpringBootTest(classes = { Application.class, Config.class, Endpoint.class, OverrideBeanDefinitionTestConfig.class }, properties = "spring.main.allow-bean-definition-overriding=true") +@AutoConfigureMockMvc +class OverrideBeanDefinitionIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void givenNoProfile_whenAllowBeanDefinitionOverriding_thenStubOk() throws Exception { + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello no profile stub"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionServiceStub.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionServiceStub.java new file mode 100644 index 0000000000..d06b43cf24 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionServiceStub.java @@ -0,0 +1,10 @@ +package com.baeldung.overridebean.overridebeandefinition; + +import com.baeldung.overridebean.Service; + +public class OverrideBeanDefinitionServiceStub implements Service { + + public String helloWorld() { + return "hello no profile stub"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionTestConfig.java new file mode 100644 index 0000000000..5c35304296 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionTestConfig.java @@ -0,0 +1,15 @@ +package com.baeldung.overridebean.overridebeandefinition; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; + +import com.baeldung.overridebean.Service; + +@TestConfiguration +public class OverrideBeanDefinitionTestConfig { + + @Bean + public Service helloWorld() { + return new OverrideBeanDefinitionServiceStub(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java new file mode 100644 index 0000000000..b6061c86d5 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java @@ -0,0 +1,31 @@ +package com.baeldung.overridebean.primary; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Config; +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.boot.Application; + +@SpringBootTest(classes = { Application.class, Config.class, Endpoint.class, PrimaryTestConfig.class }) +@AutoConfigureMockMvc +class PrimaryIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void givenTestConfiguration_whenPrimaryBeanIsDefined_thenStubOk() throws Exception { + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello primary stub"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryServiceStub.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryServiceStub.java new file mode 100644 index 0000000000..1d3d887f99 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryServiceStub.java @@ -0,0 +1,10 @@ +package com.baeldung.overridebean.primary; + +import com.baeldung.overridebean.Service; + +public class PrimaryServiceStub implements Service { + + public String helloWorld() { + return "hello primary stub"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryTestConfig.java new file mode 100644 index 0000000000..3765377b41 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryTestConfig.java @@ -0,0 +1,17 @@ +package com.baeldung.overridebean.primary; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; + +import com.baeldung.overridebean.Service; + +@TestConfiguration +public class PrimaryTestConfig { + + @Primary + @Bean("service.stub") + public Service helloWorld() { + return new PrimaryServiceStub(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileMockIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileMockIntegrationTest.java new file mode 100644 index 0000000000..2fac6d954a --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileMockIntegrationTest.java @@ -0,0 +1,38 @@ +package com.baeldung.overridebean.profile; + +import static org.hamcrest.Matchers.containsString; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.boot.Application; + +@SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) +@AutoConfigureMockMvc +@ActiveProfiles("mock") +class ProfileMockIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private Service service; + + @Test + void givenConfigurationWithProfile_whenTestProfileIsActive_thenMockOk() throws Exception { + when(service.helloWorld()).thenReturn("hello profile mock"); + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello profile mock"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileServiceStub.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileServiceStub.java new file mode 100644 index 0000000000..ef1f2e7a22 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileServiceStub.java @@ -0,0 +1,10 @@ +package com.baeldung.overridebean.profile; + +import com.baeldung.overridebean.Service; + +public class ProfileServiceStub implements Service { + + public String helloWorld() { + return "hello profile stub"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileStubIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileStubIntegrationTest.java new file mode 100644 index 0000000000..2d6eb06d32 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileStubIntegrationTest.java @@ -0,0 +1,32 @@ +package com.baeldung.overridebean.profile; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.boot.Application; + +@SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) +@AutoConfigureMockMvc +@ActiveProfiles("stub") +class ProfileStubIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void givenConfigurationWithProfile_whenTestProfileIsActive_thenStubOk() throws Exception { + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello profile stub"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java new file mode 100644 index 0000000000..7e1de309d3 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java @@ -0,0 +1,25 @@ +package com.baeldung.overridebean.profile; + +import static org.mockito.Mockito.mock; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Profile; + +import com.baeldung.overridebean.Service; + +@TestConfiguration +public class ProfileTestConfig { + + @Bean + @Profile("stub") + public Service helloWorldStub() { + return new ProfileServiceStub(); + } + + @Bean + @Profile("mock") + public Service helloWorldMock() { + return mock(Service.class); + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/MainComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/MainComponent.java new file mode 100644 index 0000000000..9f97b108da --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/MainComponent.java @@ -0,0 +1,21 @@ +package com.baeldung.nullablebean; + +import org.springframework.stereotype.Component; + +@Component +public class MainComponent { + + private SubComponent subComponent; + + public MainComponent(final SubComponent subComponent) { + this.subComponent = subComponent; + } + + public SubComponent getSubComponent() { + return subComponent; + } + + public void setSubComponent(final SubComponent subComponent) { + this.subComponent = subComponent; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/SubComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/SubComponent.java new file mode 100644 index 0000000000..b171d28db4 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/SubComponent.java @@ -0,0 +1,8 @@ +package com.baeldung.nullablebean; + +import org.springframework.stereotype.Component; + +@Component +public class SubComponent { + +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredConfiguration.java new file mode 100644 index 0000000000..d34479a565 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredConfiguration.java @@ -0,0 +1,8 @@ +package com.baeldung.nullablebean.nonrequired; + +import org.springframework.context.annotation.ComponentScan; + +@ComponentScan +public class NonRequiredConfiguration { + +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredMainComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredMainComponent.java new file mode 100644 index 0000000000..f181d2068d --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredMainComponent.java @@ -0,0 +1,19 @@ +package com.baeldung.nullablebean.nonrequired; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class NonRequiredMainComponent { + + @Autowired(required = false) + private NonRequiredSubComponent subComponent; + + public NonRequiredSubComponent getSubComponent() { + return subComponent; + } + + public void setSubComponent(final NonRequiredSubComponent subComponent) { + this.subComponent = subComponent; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredSubComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredSubComponent.java new file mode 100644 index 0000000000..6678880a24 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredSubComponent.java @@ -0,0 +1,5 @@ +package com.baeldung.nullablebean.nonrequired; + +public class NonRequiredSubComponent { + +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableJavaConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableJavaConfiguration.java new file mode 100644 index 0000000000..c13dbe3363 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableJavaConfiguration.java @@ -0,0 +1,9 @@ +package com.baeldung.nullablebean.nullablejava; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan +public class NullableJavaConfiguration { +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableMainComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableMainComponent.java new file mode 100644 index 0000000000..f35ead7477 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableMainComponent.java @@ -0,0 +1,22 @@ +package com.baeldung.nullablebean.nullablejava; + +import jakarta.annotation.Nullable; +import org.springframework.stereotype.Component; + +@Component +public class NullableMainComponent { + + private NullableSubComponent subComponent; + + public NullableMainComponent(final @Nullable NullableSubComponent subComponent) { + this.subComponent = subComponent; + } + + public NullableSubComponent getSubComponent() { + return subComponent; + } + + public void setSubComponent(final NullableSubComponent subComponent) { + this.subComponent = subComponent; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableSubComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableSubComponent.java new file mode 100644 index 0000000000..c3cbd78c43 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableSubComponent.java @@ -0,0 +1,5 @@ +package com.baeldung.nullablebean.nullablejava; + +public class NullableSubComponent { + +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableConfiguration.java new file mode 100644 index 0000000000..17942d31cd --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableConfiguration.java @@ -0,0 +1,20 @@ +package com.baeldung.nullablebean.nullablespring; + +import com.baeldung.nullablebean.MainComponent; +import com.baeldung.nullablebean.SubComponent; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class NullableConfiguration { + + @Bean + public MainComponent mainComponent(SubComponent subComponent) { + return new MainComponent(subComponent); + } + + @Bean + public SubComponent subComponent() { + return null; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableSupplierConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableSupplierConfiguration.java new file mode 100644 index 0000000000..debaa60fa9 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableSupplierConfiguration.java @@ -0,0 +1,21 @@ +package com.baeldung.nullablebean.nullablespring; + +import com.baeldung.nullablebean.MainComponent; +import com.baeldung.nullablebean.SubComponent; +import java.util.function.Supplier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class NullableSupplierConfiguration { + + @Bean + public MainComponent mainComponent(Supplier subComponentSupplier) { + return new MainComponent(subComponentSupplier.get()); + } + + @Bean + public Supplier subComponentSupplier() { + return () -> null; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/optionable/OptionableConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/optionable/OptionableConfiguration.java new file mode 100644 index 0000000000..fd54553e8c --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/optionable/OptionableConfiguration.java @@ -0,0 +1,17 @@ +package com.baeldung.nullablebean.optionable; + +import com.baeldung.nullablebean.MainComponent; +import com.baeldung.nullablebean.SubComponent; +import java.util.Optional; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class OptionableConfiguration { + + @Bean + public MainComponent mainComponent(Optional optionalSubComponent) { + return new MainComponent(optionalSubComponent.orElse(null)); + } + +} diff --git a/spring-di-4/src/test/java/com/baeldung/nullablebean/NullableXMLComponentUnitTest.java b/spring-di-4/src/test/java/com/baeldung/nullablebean/NullableXMLComponentUnitTest.java new file mode 100644 index 0000000000..2997da478c --- /dev/null +++ b/spring-di-4/src/test/java/com/baeldung/nullablebean/NullableXMLComponentUnitTest.java @@ -0,0 +1,95 @@ +package com.baeldung.nullablebean; + +import static org.junit.jupiter.api.Assertions.*; + +import com.baeldung.nullablebean.nonrequired.NonRequiredConfiguration; +import com.baeldung.nullablebean.nonrequired.NonRequiredMainComponent; +import com.baeldung.nullablebean.nullablejava.NullableJavaConfiguration; +import com.baeldung.nullablebean.nullablejava.NullableMainComponent; +import com.baeldung.nullablebean.nullablespring.NullableConfiguration; +import com.baeldung.nullablebean.nullablespring.NullableSupplierConfiguration; +import com.baeldung.nullablebean.optionable.OptionableConfiguration; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.UnsatisfiedDependencyException; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +class NullableXMLComponentUnitTest { + + @Test + void givenContextWhenCreatingNullableMainComponentThenSubComponentIsNull() { + final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + NullableJavaConfiguration.class); + final NullableMainComponent bean = context.getBean(NullableMainComponent.class); + assertNull(bean.getSubComponent()); + } + @Test + void givenNonRequiredContextWhenCreatingMainComponentThenSubComponentIsNull() { + final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + NonRequiredConfiguration.class); + final NonRequiredMainComponent bean = context.getBean(NonRequiredMainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenOptionableContextWhenCreatingMainComponentThenSubComponentIsNull() { + final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + OptionableConfiguration.class); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableSupplierContextWhenCreatingMainComponentThenSubComponentIsNull() { + final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + NullableSupplierConfiguration.class); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableContextWhenCreatingMainComponentThenSubComponentIsNull() { + assertThrows(UnsatisfiedDependencyException.class, () -> new AnnotationConfigApplicationContext( + NullableConfiguration.class)); + } + + @Test + void givenNullableXMLContextWhenCreatingMainComponentThenSubComponentIsNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "nullable-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableSpELXMLContextWhenCreatingMainComponentThenSubComponentIsNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "nullable-spel-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableSpELXMLContextWithNullablePropertiesWhenCreatingMainComponentThenSubComponentIsNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "nullable-configurable-spel-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableSpELXMLContextWithNonNullablePropertiesWhenCreatingMainComponentThenSubComponentIsNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "non-nullable-configurable-spel-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNotNull(bean.getSubComponent()); + } + + @Test + void givenXMLContextWhenCreatingMainComponentThenSubComponentNotNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "non-nullable-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNotNull(bean.getSubComponent()); + } +} \ No newline at end of file diff --git a/spring-di-4/src/test/resources/non-nullable-application-context.xml b/spring-di-4/src/test/resources/non-nullable-application-context.xml new file mode 100644 index 0000000000..07a8115bac --- /dev/null +++ b/spring-di-4/src/test/resources/non-nullable-application-context.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/non-nullable-configurable-spel-application-context.xml b/spring-di-4/src/test/resources/non-nullable-configurable-spel-application-context.xml new file mode 100644 index 0000000000..8a7b107ee4 --- /dev/null +++ b/spring-di-4/src/test/resources/non-nullable-configurable-spel-application-context.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/non-nullable.properties b/spring-di-4/src/test/resources/non-nullable.properties new file mode 100644 index 0000000000..76b127a2e5 --- /dev/null +++ b/spring-di-4/src/test/resources/non-nullable.properties @@ -0,0 +1 @@ +nullableBean = subComponent \ No newline at end of file diff --git a/spring-di-4/src/test/resources/nullable-application-context.xml b/spring-di-4/src/test/resources/nullable-application-context.xml new file mode 100644 index 0000000000..9794dbbfff --- /dev/null +++ b/spring-di-4/src/test/resources/nullable-application-context.xml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/nullable-configurable-spel-application-context.xml b/spring-di-4/src/test/resources/nullable-configurable-spel-application-context.xml new file mode 100644 index 0000000000..f6f04a6289 --- /dev/null +++ b/spring-di-4/src/test/resources/nullable-configurable-spel-application-context.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/nullable-spel-application-context.xml b/spring-di-4/src/test/resources/nullable-spel-application-context.xml new file mode 100644 index 0000000000..c0a14b4cbb --- /dev/null +++ b/spring-di-4/src/test/resources/nullable-spel-application-context.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/nullable.properties b/spring-di-4/src/test/resources/nullable.properties new file mode 100644 index 0000000000..315f9b0d03 --- /dev/null +++ b/spring-di-4/src/test/resources/nullable.properties @@ -0,0 +1 @@ +nullableBean = null \ No newline at end of file diff --git a/spring-di/pom.xml b/spring-di/pom.xml index bae7263ef9..d073f5359d 100644 --- a/spring-di/pom.xml +++ b/spring-di/pom.xml @@ -134,7 +134,7 @@ org.baeldung.org.baeldung.sample.App 3.1.2 - 1.9.5 + 1.9.20.1 \ No newline at end of file diff --git a/spring-jersey/pom.xml b/spring-jersey/pom.xml index 32f75aa676..9ea5f62778 100644 --- a/spring-jersey/pom.xml +++ b/spring-jersey/pom.xml @@ -85,7 +85,7 @@ ${jersey.version} - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -219,7 +219,7 @@ 1.6.1 4.4.9 4.5.5 - 2.27.2 + 3.3.1 1.5.10.RELEASE diff --git a/spring-kafka-2/README.md b/spring-kafka-2/README.md index 318312ace6..43b2f59147 100644 --- a/spring-kafka-2/README.md +++ b/spring-kafka-2/README.md @@ -8,3 +8,4 @@ This module contains articles about Spring with Kafka - [Spring Kafka: Configure Multiple Listeners on Same Topic](https://www.baeldung.com/spring-kafka-multiple-listeners-same-topic) - [Understanding Kafka Topics and Partitions](https://www.baeldung.com/kafka-topics-partitions) - [How to Subscribe a Kafka Consumer to Multiple Topics](https://www.baeldung.com/kafka-subscribe-consumer-multiple-topics) +- [Splitting Streams in Kafka](https://www.baeldung.com/kafka-splitting-streams) diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaConsumerConfiguration.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaConsumerConfiguration.java new file mode 100644 index 0000000000..04025bf484 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaConsumerConfiguration.java @@ -0,0 +1,37 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.common.serialization.DoubleDeserializer; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class KafkaConsumerConfiguration { + + @Value(value = "${spring.kafka.bootstrap-servers}") + private String bootstrapAddress; + + @Bean + public ConsumerFactory kafkaConsumer() { + Map props = new HashMap<>(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, DoubleDeserializer.class); + return new DefaultKafkaConsumerFactory<>(props); + } + + @Bean + public ConcurrentKafkaListenerContainerFactory kafkaConsumerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(kafkaConsumer()); + return factory; + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaProducerConfiguration.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaProducerConfiguration.java new file mode 100644 index 0000000000..b5b10e8301 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaProducerConfiguration.java @@ -0,0 +1,35 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.DoubleSerializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class KafkaProducerConfiguration { + + @Value(value = "${spring.kafka.bootstrap-servers}") + private String bootstrapAddress; + + @Bean + public ProducerFactory kafkaProducer() { + Map configProps = new HashMap<>(); + configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); + configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, DoubleSerializer.class); + return new DefaultKafkaProducerFactory<>(configProps); + } + + @Bean + public KafkaTemplate kafkaProducerTemplate() { + return new KafkaTemplate<>(kafkaProducer()); + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaTopicConfiguration.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaTopicConfiguration.java new file mode 100644 index 0000000000..1535f0c358 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaTopicConfiguration.java @@ -0,0 +1,30 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.kafka.clients.admin.AdminClientConfig; +import org.apache.kafka.clients.admin.NewTopic; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.TopicBuilder; +import org.springframework.kafka.core.KafkaAdmin; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class KafkaTopicConfiguration { + + @Value(value = "${spring.kafka.bootstrap-servers}") + private String bootstrapAddress; + + public KafkaAdmin kafkaAdmin() { + Map configs = new HashMap<>(); + configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); + return new KafkaAdmin(configs); + } + + public NewTopic celciusTopic() { + return TopicBuilder.name("topic-1") + .partitions(2) + .build(); + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsApplicationKafkaApp.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsApplicationKafkaApp.java new file mode 100644 index 0000000000..c5c990ff9d --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsApplicationKafkaApp.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Import; + +@SpringBootApplication +@Import(value = {KafkaConsumerConfiguration.class, KafkaProducerConfiguration.class, KafkaTopicConfiguration.class}) +public class ManagingConsumerGroupsApplicationKafkaApp { + public static void main(String[] args) { + SpringApplication.run(ManagingConsumerGroupsApplicationKafkaApp.class, args); + } +} \ No newline at end of file diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/MessageConsumerService.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/MessageConsumerService.java new file mode 100644 index 0000000000..d010b19a80 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/MessageConsumerService.java @@ -0,0 +1,34 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Service; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +@Service +public class MessageConsumerService { + + Map> consumedPartitions = new ConcurrentHashMap<>(); + + @KafkaListener(topics = "topic-1", groupId = "group-1") + public void consumer0(ConsumerRecord consumerRecord) { + trackConsumedPartitions("consumer-0", consumerRecord); + } + + @KafkaListener(topics = "topic-1", groupId = "group-1") + public void consumer1(ConsumerRecord consumerRecord) { + trackConsumedPartitions("consumer-1", consumerRecord); + } + + private void trackConsumedPartitions(String key, ConsumerRecord record) { + consumedPartitions.computeIfAbsent(key, k -> new HashSet<>()); + consumedPartitions.computeIfPresent(key, (k, v) -> { + v.add(record.partition()); + return v; + }); + } +} diff --git a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsIntegrationTest.java b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsIntegrationTest.java new file mode 100644 index 0000000000..1620add9ca --- /dev/null +++ b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsIntegrationTest.java @@ -0,0 +1,57 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.commons.lang3.RandomUtils; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.config.KafkaListenerEndpointRegistry; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.listener.MessageListenerContainer; +import org.springframework.kafka.test.context.EmbeddedKafka; + +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest(classes = ManagingConsumerGroupsApplicationKafkaApp.class) +@EmbeddedKafka(partitions = 2, brokerProperties = {"listeners=PLAINTEXT://localhost:9092", "port=9092"}) +public class ManagingConsumerGroupsIntegrationTest { + + private static final String CONSUMER_1_IDENTIFIER = "org.springframework.kafka.KafkaListenerEndpointContainer#1"; + private static final int TOTAL_PRODUCED_MESSAGES = 50000; + private static final int MESSAGE_WHERE_CONSUMER_1_LEAVES_GROUP = 10000; + + @Autowired + KafkaTemplate kafkaTemplate; + + @Autowired + KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry; + + @Autowired + MessageConsumerService consumerService; + + @Test + public void givenContinuousMessageFlow_whenAConsumerLeavesTheGroup_thenKafkaTriggersPartitionRebalance() throws InterruptedException { + int currentMessage = 0; + + do { + kafkaTemplate.send("topic-1", RandomUtils.nextDouble(10.0, 20.0)); + currentMessage++; + + if (currentMessage == MESSAGE_WHERE_CONSUMER_1_LEAVES_GROUP) { + String containerId = kafkaListenerEndpointRegistry.getListenerContainerIds() + .stream() + .filter(a -> a.equals(CONSUMER_1_IDENTIFIER)) + .findFirst() + .orElse(""); + MessageListenerContainer container = kafkaListenerEndpointRegistry.getListenerContainer(containerId); + Thread.sleep(2000); + Objects.requireNonNull(container).stop(); + kafkaListenerEndpointRegistry.unregisterListenerContainer(containerId); + } + } while (currentMessage != TOTAL_PRODUCED_MESSAGES); + Thread.sleep(2000); + assertEquals(1, consumerService.consumedPartitions.get("consumer-1").size()); + assertEquals(2, consumerService.consumedPartitions.get("consumer-0").size()); + } +} diff --git a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java index 345e84b65b..570670cdf9 100644 --- a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java +++ b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java @@ -21,7 +21,7 @@ import org.springframework.kafka.test.context.EmbeddedKafka; import org.springframework.kafka.test.utils.ContainerTestUtils; @SpringBootTest(classes = KafkaMultipleTopicsApplication.class) -@EmbeddedKafka(partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9092", "port=9092" }) +@EmbeddedKafka(partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9099", "port=9099" }) public class KafkaMultipleTopicsIntegrationTest { private static final String CARD_PAYMENTS_TOPIC = "card-payments"; private static final String BANK_TRANSFERS_TOPIC = "bank-transfers"; diff --git a/spring-reactive-modules/spring-reactive-client/pom.xml b/spring-reactive-modules/spring-reactive-client/pom.xml index 94134e5271..5736ce497f 100644 --- a/spring-reactive-modules/spring-reactive-client/pom.xml +++ b/spring-reactive-modules/spring-reactive-client/pom.xml @@ -179,7 +179,7 @@ 1.0.1.RELEASE 1.0 1.1.6 - 4.0.1 + 4.12.0 3.5.3 2.26.0 3.1.4 diff --git a/spring-static-resources/pom.xml b/spring-static-resources/pom.xml index 875b8de31b..2bf865ddbe 100644 --- a/spring-static-resources/pom.xml +++ b/spring-static-resources/pom.xml @@ -88,7 +88,7 @@ org.aspectj aspectjrt - ${org.aspectj-version} + ${aspectj.version} javax.inject @@ -186,7 +186,7 @@ - 1.8.9 + 1.9.20.1 8.0.1.Final 4.1.0 diff --git a/spring-web-modules/spring-mvc-velocity/pom.xml b/spring-web-modules/spring-mvc-velocity/pom.xml index 676fa09dac..cc92e8c6a5 100644 --- a/spring-web-modules/spring-mvc-velocity/pom.xml +++ b/spring-web-modules/spring-mvc-velocity/pom.xml @@ -64,7 +64,7 @@ org.powermock - powermock-api-mockito + powermock-api-mockito2 ${powermock.version} test @@ -106,7 +106,7 @@ - 1.6.6 + 2.0.9 4.4.5 4.5.2 1.7 diff --git a/spring-web-modules/spring-mvc-xml/pom.xml b/spring-web-modules/spring-mvc-xml/pom.xml index bf0dc52b68..12f0a1a68a 100644 --- a/spring-web-modules/spring-mvc-xml/pom.xml +++ b/spring-web-modules/spring-mvc-xml/pom.xml @@ -142,7 +142,7 @@ 4.4.5 4.5.2 - 6.0.10.Final + 8.0.1.Final 3.0.1-b08 2.8.0 diff --git a/spring-web-modules/spring-rest-http-2/pom.xml b/spring-web-modules/spring-rest-http-2/pom.xml index 88294c7811..bcacdbbdb1 100644 --- a/spring-web-modules/spring-rest-http-2/pom.xml +++ b/spring-web-modules/spring-rest-http-2/pom.xml @@ -53,7 +53,6 @@ 2.9.2 1.6.1 1.7.0 - 31.0.1-jre \ No newline at end of file diff --git a/spring-web-modules/spring-rest-simple/pom.xml b/spring-web-modules/spring-rest-simple/pom.xml index 2764ac8393..089c5e411f 100644 --- a/spring-web-modules/spring-rest-simple/pom.xml +++ b/spring-web-modules/spring-rest-simple/pom.xml @@ -292,7 +292,7 @@ 1.6.0 3.0.4 - 3.4.1 + 4.12.0 2.2.0 diff --git a/spring-web-modules/spring-resttemplate/pom.xml b/spring-web-modules/spring-resttemplate/pom.xml index 4abaac5628..5cf1476f87 100644 --- a/spring-web-modules/spring-resttemplate/pom.xml +++ b/spring-web-modules/spring-resttemplate/pom.xml @@ -274,7 +274,7 @@ 1.6.1 3.0.4 - 3.4.1 + 4.12.0 3.6.3 1.8 1.8 diff --git a/spring-web-modules/spring-thymeleaf-5/pom.xml b/spring-web-modules/spring-thymeleaf-5/pom.xml index 0717e41bac..2d178bd933 100644 --- a/spring-web-modules/spring-thymeleaf-5/pom.xml +++ b/spring-web-modules/spring-thymeleaf-5/pom.xml @@ -139,7 +139,7 @@ 3.0.4.RELEASE 2.4.1 2.0.1.Final - 6.0.11.Final + 8.0.1.Final 1.6.1 diff --git a/spring-web-modules/spring-thymeleaf/pom.xml b/spring-web-modules/spring-thymeleaf/pom.xml index 94ae05ca11..ce0c0a7e21 100644 --- a/spring-web-modules/spring-thymeleaf/pom.xml +++ b/spring-web-modules/spring-thymeleaf/pom.xml @@ -140,7 +140,7 @@ 3.0.4.RELEASE 2.4.1 2.0.1.Final - 6.0.11.Final + 8.0.1.Final 1.9.9 diff --git a/testing-modules/rest-testing/pom.xml b/testing-modules/rest-testing/pom.xml index f8005092ae..975b6fb647 100644 --- a/testing-modules/rest-testing/pom.xml +++ b/testing-modules/rest-testing/pom.xml @@ -34,7 +34,7 @@ - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -135,7 +135,7 @@ 2.9.0 6.8.0 - 2.21.0 + 3.3.1 1.3.1 4.1 diff --git a/testing-modules/selenium-2/README.md b/testing-modules/selenium-2/README.md index 5403fb9f06..a1d180814d 100644 --- a/testing-modules/selenium-2/README.md +++ b/testing-modules/selenium-2/README.md @@ -2,6 +2,7 @@ - [Running Selenium Scripts with JMeter](https://www.baeldung.com/selenium-jmeter) - [Fixing Selenium WebDriver Executable Path Error](https://www.baeldung.com/java-selenium-webdriver-path-error) - [Implicit Wait vs Explicit Wait in Selenium Webdriver](https://www.baeldung.com/selenium-implicit-explicit-wait) +- [Switching Between Frames Using Selenium WebDriver in Java](https://www.baeldung.com/java-selenium-change-frames) #### Notes: - to run the live tests for the article *Fixing Selenium WebDriver Executable Path Error*, follow the manual setup described diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java new file mode 100644 index 0000000000..7c48a5eb4a --- /dev/null +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java @@ -0,0 +1,92 @@ +package com.baeldung.assertnestedmap; + + +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static com.baeldung.assertnestedmap.matchers.NestedMapMatcher.hasNestedMapEntry; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; +import static org.junit.jupiter.api.Assertions.*; + +public class AssertNestedMapUnitTest { + @Test + void givenNestedMap_whenUseJupiterAssertTrueWithoutCasting_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); + + assertTrue(outerMap.containsKey("address") && outerMap.get("address").get("city").equals("Chicago")); + } + + @Test + void givenNestedMap_whenUseJupiterAssertAllAndAssertTrue_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); + + assertAll( + () -> assertTrue(outerMap.containsKey("address")), + () -> assertEquals(outerMap.get("address").get("city"), "Chicago") + ); + } + + @Test + void givenNestedMap_whenUseJupiterAssertTrueWithCasting_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map outerMap = Map.of("address", innerMap); + + assertTrue(outerMap.containsKey("address") + && ((Map)outerMap.get("address")).get("city").equals("Chicago")); + } + + @Test + void givenNestedMap_whenUseHamcrestAssertThat_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); + assertAll( + () -> assertThat(outerMap, hasKey("address")), + () -> assertThat(outerMap.get("address"), hasEntry("city", "Chicago")) + ); + } + + @Test + void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThat_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); + + assertThat(outerMap, hasEntry(equalTo("address"), hasEntry("city", "Chicago"))); + } + + @Test + void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { + Map innerMap = Map.of + ( + "city", "Chicago", + "zip", "10005" + ); + Map> outerMap = Map.of("address", innerMap); + + assertThat(outerMap, hasNestedMapEntry("address", innerMap)); + } + + @Test + void givenOuterMapOfStringAndObjectAndInnerMap_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { + Map innerMap = Map.of + ( + "city", "Chicago", + "zip", "10005" + ); + Map outerMap = Map.of("address", innerMap); + + assertThat(outerMap, hasNestedMapEntry("address", innerMap)); + } + + @Test + void givenNestedMap_whenUseHamcrestAssertThatWithCasting_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map outerMap = Map.of("address", innerMap); + + assertThat((Map)outerMap.get("address"), hasEntry("city", "Chicago")); + } + +} diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/matchers/NestedMapMatcher.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/matchers/NestedMapMatcher.java new file mode 100644 index 0000000000..961130bb20 --- /dev/null +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/matchers/NestedMapMatcher.java @@ -0,0 +1,38 @@ +package com.baeldung.assertnestedmap.matchers; + + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; + +import java.util.Map; + +public class NestedMapMatcher extends TypeSafeMatcher> { + private K key; + private V subMapValue; + + public NestedMapMatcher(K key, V subMapValue) { + this.key = key; + this.subMapValue = subMapValue; + } + + @Override + protected boolean matchesSafely(Map item) { + if (item.containsKey(key)) { + Object actualValue = item.get(key); + return subMapValue.equals(actualValue); + } + return false; + } + + @Override + public void describeTo(Description description) { + description.appendText("a map containing key ").appendValue(key) + .appendText(" with value ").appendValue(subMapValue); + } + + public static Matcher hasNestedMapEntry(K key, V expectedValue) { + return new NestedMapMatcher(key, expectedValue); + } +} + diff --git a/web-modules/jooby/pom.xml b/web-modules/jooby/pom.xml index 238f17571f..998ceaef4e 100644 --- a/web-modules/jooby/pom.xml +++ b/web-modules/jooby/pom.xml @@ -77,7 +77,7 @@ com.baeldung.jooby.App 3.2.4 3.8.1 - 4.9.1 + 4.12.0 \ No newline at end of file diff --git a/web-modules/vraptor/pom.xml b/web-modules/vraptor/pom.xml index ecc6fe3313..25f8b5d5e5 100644 --- a/web-modules/vraptor/pom.xml +++ b/web-modules/vraptor/pom.xml @@ -49,7 +49,7 @@ provided - org.hibernate + org.hibernate.validator hibernate-validator-cdi ${hibernate-validator.version} @@ -115,7 +115,7 @@ 4.2.0.Final 2.1.2.Final 2.2 - 5.1.1.Final + 8.0.1.Final 4.1.0-RC3 4.0.4 8.0.8-dmr diff --git a/xml-2/pom.xml b/xml-2/pom.xml index 0f94588ba0..ccb84e1687 100644 --- a/xml-2/pom.xml +++ b/xml-2/pom.xml @@ -46,6 +46,16 @@ underscore ${underscore.version} + + com.thoughtworks.xstream + xstream + ${xstream.version} + + + com.sun.xml.bind + jaxb-impl + ${jaxb.version} + org.apache.xmlbeans xmlbeans @@ -82,6 +92,8 @@ 2.1.3 20230227 1.89 + 1.4.18 + 2.3.3 diff --git a/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java new file mode 100644 index 0000000000..c9c40e743a --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java @@ -0,0 +1,31 @@ +package com.baeldung.xml.tohashmap; + +public class Employee { + private String id; + private String firstName; + private String lastName; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java new file mode 100644 index 0000000000..d2f2276e5c --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java @@ -0,0 +1,21 @@ +package com.baeldung.xml.tohashmap; + +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "employees") +public class Employees { + + private List employeeList; + + @XmlElement(name = "employee") + public List getEmployeeList() { + return employeeList; + } + + public void setEmployeeList(List employeeList) { + this.employeeList = employeeList; + } +} \ No newline at end of file diff --git a/xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java b/xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java new file mode 100644 index 0000000000..ec651486ac --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java @@ -0,0 +1,124 @@ +package com.baeldung.xml.tohashmap; + +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import com.github.underscore.U; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.security.AnyTypePermission; + +public class XmlToHashMap { + + public Map xmlToHashMapUsingXstream(String xml) { + XStream xStream = new XStream(); + xStream.alias("employees", List.class); + xStream.alias("employee", Employee.class); + xStream.addPermission(AnyTypePermission.ANY); + List employees = (List) xStream.fromXML(xml); + return employees.stream() + .collect(Collectors.toMap(Employee::getId, Function.identity())); + } + + public Map xmlToHashMapUsingUnderscore(String xml) { + Map employeeMap = new HashMap<>(); + Map employeeList = (Map) U.fromXmlMap(xml) + .get("employees"); + List> list = (List>) employeeList.get("employee"); + parseXmlToMap(employeeMap, list); + return employeeMap; + } + + public Map xmlToHashMapUsingJackson(String xml) throws JsonProcessingException { + XmlMapper xmlMapper = new XmlMapper(); + Map employeeMap = new HashMap<>(); + Map map = xmlMapper.readValue(xml, Map.class); + List> list = (List>) map.get("employee"); + parseXmlToMap(employeeMap, list); + return employeeMap; + } + + public Map xmlToHashMapUsingJAXB(String xmlData) throws JAXBException { + JAXBContext context = JAXBContext.newInstance(Employees.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + Employees employees = (Employees) unmarshaller.unmarshal(new StringReader(xmlData)); + return employees.getEmployeeList() + .stream() + .collect(Collectors.toMap(Employee::getId, Function.identity())); + } + + public Map xmlToHashMapUsingDOMParserXpath(String xmlData) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(new InputSource(new StringReader(xmlData))); + + XPathFactory xPathfactory = XPathFactory.newInstance(); + XPath xpath = xPathfactory.newXPath(); + XPathExpression xPathExpr = xpath.compile("/employees/employee"); + NodeList nodes = (NodeList) xPathExpr.evaluate(doc, XPathConstants.NODESET); + + HashMap map = new HashMap<>(); + for (int i = 0; i < nodes.getLength(); i++) { + Element node = (Element) nodes.item(i); + Employee employee = new Employee(); + employee.setId(node.getElementsByTagName("id") + .item(0) + .getTextContent()); + employee.setFirstName(node.getElementsByTagName("firstName") + .item(0) + .getTextContent()); + employee.setLastName(node.getElementsByTagName("lastName") + .item(0) + .getTextContent()); + map.put(employee.getId(), employee); + } + return map; + } + + private static void parseXmlToMap(Map employeeMap, List> list) { + list.forEach(empMap -> { + Employee employee = new Employee(); + for (Map.Entry key : empMap.entrySet()) { + switch (key.getKey()) { + case "id": + employee.setId(key.getValue()); + break; + case "firstName": + employee.setFirstName(key.getValue()); + break; + case "lastName": + employee.setLastName(key.getValue()); + break; + default: + break; + } + } + employeeMap.put(employee.getId(), employee); + }); + } +} diff --git a/xml-2/src/main/resources/xml/xmltohashmap/test.xml b/xml-2/src/main/resources/xml/xmltohashmap/test.xml new file mode 100644 index 0000000000..ef0d12e2af --- /dev/null +++ b/xml-2/src/main/resources/xml/xmltohashmap/test.xml @@ -0,0 +1,12 @@ + + + 654 + John + Doe + + + 776 + Steve + Smith + + \ No newline at end of file diff --git a/xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java b/xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java new file mode 100644 index 0000000000..5e05dd3ccb --- /dev/null +++ b/xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java @@ -0,0 +1,71 @@ +package com.baeldung.xml.tohashmap; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Map; + +import javax.xml.bind.JAXBException; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class XmlToHashMapUnitTest { + + private XmlToHashMap xmlToHashMap; + private static final String TEST_XML_PATH = "src/main/resources/xml/xmltohashmap/test.xml"; + + @BeforeEach + void setUp() { + xmlToHashMap = new XmlToHashMap(); + } + + @Test + void whenUsingXstream_thenHashMapShouldBeCreated() throws IOException { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingXstream(getXml()); + verify(employeeMap); + } + + @Test + void whenUsingUnderscore_thenHashMapShouldBeCreated() throws IOException { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingUnderscore(getXml()); + verify(employeeMap); + } + + @Test + void whenUsingJackson_thenHashMapShouldBeCreated() throws IOException { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingJackson(getXml()); + verify(employeeMap); + } + + @Test + void whenUsingJAXB_thenHashMapShouldBeCreated() throws IOException, JAXBException { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingJAXB(getXml()); + verify(employeeMap); + } + + @Test + void whenUsingDOMXpath_thenHashMapShouldBeCreated() throws Exception { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingDOMParserXpath(getXml()); + verify(employeeMap); + } + + private void verify(Map employeeMap) { + Employee employee1 = employeeMap.get("654"); + Employee employee2 = employeeMap.get("776"); + Assertions.assertEquals("John", employee1 + .getFirstName()); + Assertions.assertEquals("Doe", employee1 + .getLastName()); + Assertions.assertEquals("Steve", employee2 + .getFirstName()); + Assertions.assertEquals("Smith", employee2 + .getLastName()); + } + + private String getXml() throws IOException { + return new String(Files.readAllBytes(Paths.get(TEST_XML_PATH))); + } +}