diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java new file mode 100644 index 0000000000..b10bd95a19 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java @@ -0,0 +1,129 @@ +package com.baeldung.algorithms.connect4; + +import java.util.ArrayList; +import java.util.List; + +public class GameBoard { + private final List> columns; + + private final int rows; + + public GameBoard(int columns, int rows) { + this.rows = rows; + this.columns = new ArrayList<>(); + + for (int i = 0; i < columns; ++i) { + this.columns.add(new ArrayList<>()); + } + } + + public int getRows() { + return rows; + } + + public int getColumns() { + return columns.size(); + } + + public Piece getCell(int x, int y) { + assert(x >= 0 && x < getColumns()); + assert(y >= 0 && y < getRows()); + + List column = columns.get(x); + + if (column.size() > y) { + return column.get(y); + } else { + return null; + } + } + + public boolean move(int x, Piece player) { + assert(x >= 0 && x < getColumns()); + + List column = columns.get(x); + + if (column.size() >= this.rows) { + throw new IllegalArgumentException("That column is full"); + } + + column.add(player); + + return checkWin(x, column.size() - 1, player); + } + + private boolean checkWin(int x, int y, Piece player) { + // Vertical line + if (checkLine(x, y, 0, -1, player)) { + return true; + } + + for (int offset = 0; offset < 4; ++offset) { + // Horizontal line + if (checkLine(x - 3 + offset, y, 1, 0, player)) { + return true; + } + + // Leading diagonal + if (checkLine(x - 3 + offset, y + 3 - offset, 1, -1, player)) { + return true; + } + + // Trailing diagonal + if (checkLine(x - 3 + offset, y - 3 + offset, 1, 1, player)) { + return true; + } + } + + return false; + } + + private boolean checkLine(int x1, int y1, int xDiff, int yDiff, Piece player) { + for (int i = 0; i < 4; ++i) { + int x = x1 + (xDiff * i); + int y = y1 + (yDiff * i); + + if (x < 0 || x > columns.size() - 1) { + return false; + } + + if (y < 0 || y > rows - 1) { + return false; + } + + if (player != getCell(x, y)) { + return false; + } + } + + return true; + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + + for (int y = getRows() - 1; y >= 0; --y) { + for (int x = 0; x < getColumns(); ++x) { + Piece piece = getCell(x, y); + + result.append("|"); + if (piece == null) { + result.append(" "); + } else if (piece == Piece.PLAYER_1) { + result.append("X"); + } else if (piece == Piece.PLAYER_2) { + result.append("O"); + } + } + + result.append("|\n"); + for (int i = 0; i < getColumns(); ++i) { + result.append("+-"); + } + result.append("+\n"); + } + + return result.toString(); + } +} diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java new file mode 100644 index 0000000000..f340644950 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.algorithms.connect4; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class GameUnitTest { + @Test + public void blankGame() { + GameBoard gameBoard = new GameBoard(8, 6); + + System.out.println(gameBoard); + } + + @Test + public void playedGame() { + GameBoard gameBoard = new GameBoard(8, 6); + + assertFalse(gameBoard.move(3, Piece.PLAYER_1)); + assertFalse(gameBoard.move(2, Piece.PLAYER_2)); + + assertFalse(gameBoard.move(4, Piece.PLAYER_1)); + assertFalse(gameBoard.move(3, Piece.PLAYER_2)); + + assertFalse(gameBoard.move(5, Piece.PLAYER_1)); + assertFalse(gameBoard.move(6, Piece.PLAYER_2)); + + assertFalse(gameBoard.move(5, Piece.PLAYER_1)); + assertFalse(gameBoard.move(4, Piece.PLAYER_2)); + + assertFalse(gameBoard.move(5, Piece.PLAYER_1)); + assertFalse(gameBoard.move(5, Piece.PLAYER_2)); + + assertFalse(gameBoard.move(6, Piece.PLAYER_1)); + assertTrue(gameBoard.move(4, Piece.PLAYER_2)); + + System.out.println(gameBoard); + } +} diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/Piece.java b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/Piece.java new file mode 100644 index 0000000000..5a8724c09b --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/Piece.java @@ -0,0 +1,6 @@ +package com.baeldung.algorithms.connect4; + +public enum Piece { + PLAYER_1, + PLAYER_2 +} diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md new file mode 100644 index 0000000000..55bc2abec5 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Implement Connect 4 Game with Java](https://www.baeldung.com/java-connect-4-game) diff --git a/apache-kafka-2/log4j.properties b/apache-kafka-2/log4j.properties deleted file mode 100644 index 2173c5d96f..0000000000 --- a/apache-kafka-2/log4j.properties +++ /dev/null @@ -1 +0,0 @@ -log4j.rootLogger=INFO, stdout diff --git a/apache-kafka-2/pom.xml b/apache-kafka-2/pom.xml index 067dedef8a..d1f74e8aae 100644 --- a/apache-kafka-2/pom.xml +++ b/apache-kafka-2/pom.xml @@ -23,11 +23,6 @@ slf4j-api ${org.slf4j.version} - - org.slf4j - slf4j-log4j12 - ${org.slf4j.version} - com.google.guava guava @@ -57,6 +52,11 @@ ${lombok.version} provided + + com.fasterxml.jackson.core + jackson-databind + ${jackson.databind.version} + @@ -64,6 +64,7 @@ 2.8.0 1.15.3 1.15.3 + 2.15.2 \ No newline at end of file diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java new file mode 100644 index 0000000000..7fae8403b5 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java @@ -0,0 +1,11 @@ +package com.baeldung.kafka.message.ordering; + +public class Config { + public static final String CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS = "value.deserializer.serializedClass"; + public static final String MULTI_PARTITION_TOPIC = "multi_partition_topic"; + public static final String SINGLE_PARTITION_TOPIC = "single_partition_topic"; + + public static final int MULTIPLE_PARTITIONS = 5; + public static final int SINGLE_PARTITION = 1; + public static final short REPLICATION_FACTOR = 1; +} diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java new file mode 100644 index 0000000000..99e0cc6c7e --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java @@ -0,0 +1,61 @@ +package com.baeldung.kafka.message.ordering.payload; + +import java.util.Objects; + +public class UserEvent implements Comparable { + private String userEventId; + private long eventNanoTime; + private long globalSequenceNumber; + + @SuppressWarnings("unused") + public UserEvent() { + // Required for Jackson Serialization and Deserialization + } + + public UserEvent(String userEventId) { + this.userEventId = userEventId; + } + + public String getUserEventId() { + return userEventId; + } + + public long getEventNanoTime() { + return eventNanoTime; + } + + public void setEventNanoTime(long eventNanoTime) { + this.eventNanoTime = eventNanoTime; + } + + public long getGlobalSequenceNumber() { + return globalSequenceNumber; + } + + public void setGlobalSequenceNumber(long globalSequenceNumber) { + this.globalSequenceNumber = globalSequenceNumber; + } + + @Override + public int compareTo(UserEvent other) { + return Long.compare(this.globalSequenceNumber, other.globalSequenceNumber); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof UserEvent)) { + return false; + } + UserEvent userEvent = (UserEvent) obj; + return this.globalSequenceNumber == userEvent.globalSequenceNumber; + } + + @Override + public int hashCode() { + return Objects.hash(globalSequenceNumber); + } +} + diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java new file mode 100644 index 0000000000..cf72ab12df --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java @@ -0,0 +1,34 @@ +package com.baeldung.kafka.message.ordering.serialization; + +import com.baeldung.kafka.message.ordering.Config; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.apache.kafka.common.serialization.Deserializer; + +import java.util.Map; + +/** + * Configured via {@link org.apache.kafka.clients.consumer.ConsumerConfig#VALUE_DESERIALIZER_CLASS_CONFIG} + */ +public class JacksonDeserializer implements Deserializer { + private final ObjectMapper objectMapper = new ObjectMapper(); + private Class type; + + @Override + public void configure(Map configs, boolean isKey) { + this.type = (Class) configs.get(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS); + } + + @Override + public T deserialize(String topic, byte[] bytes) { + if (bytes == null) { + return null; + } + try { + return objectMapper.readValue(bytes, type); + } catch (Exception e) { + throw new RuntimeException("Error deserializing value", e); + } + } +} + diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java new file mode 100644 index 0000000000..b2ace3b8ed --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java @@ -0,0 +1,24 @@ +package com.baeldung.kafka.message.ordering.serialization; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.apache.kafka.common.serialization.Serializer; + +/** + * Configured via {@link org.apache.kafka.clients.producer.ProducerConfig#VALUE_SERIALIZER_CLASS_CONFIG} + */ +public class JacksonSerializer implements Serializer { + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Override + public byte[] serialize(String topic, T data) { + if (data == null) { + return null; + } + try { + return objectMapper.writeValueAsBytes(data); + } catch (Exception e) { + throw new RuntimeException("Error serializing value", e); + } + } +} diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowLiveTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowLiveTest.java new file mode 100644 index 0000000000..f36c6ebd63 --- /dev/null +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowLiveTest.java @@ -0,0 +1,126 @@ +package com.baeldung.kafka.message.ordering; + +import com.baeldung.kafka.message.ordering.payload.UserEvent; +import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; +import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; + +import org.apache.kafka.clients.admin.*; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.apache.kafka.common.serialization.LongDeserializer; +import org.apache.kafka.common.serialization.LongSerializer; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import java.time.Duration; +import java.util.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import com.google.common.collect.ImmutableList; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +@Testcontainers +public class ExternalSequenceWithTimeWindowLiveTest { + + private static Admin admin; + private static KafkaProducer producer; + private static KafkaConsumer consumer; + private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); + private static final long BUFFER_PERIOD_NS = Duration.ofSeconds(5) + .toNanos(); + private static Logger logger = LoggerFactory.getLogger(ExternalSequenceWithTimeWindowLiveTest.class); + + @Container + private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + + @BeforeAll + static void setup() throws ExecutionException, InterruptedException { + KAFKA_CONTAINER.addExposedPort(9092); + + Properties adminProperties = new Properties(); + adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + + Properties producerProperties = new Properties(); + producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); + producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); + + Properties consumerProperties = new Properties(); + consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); + consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); + admin = Admin.create(adminProperties); + producer = new KafkaProducer<>(producerProperties); + consumer = new KafkaConsumer<>(consumerProperties); + admin.createTopics(ImmutableList.of(new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR))) + .all() + .get(); + } + + @AfterAll + static void destroy() { + KAFKA_CONTAINER.stop(); + } + + @Test + void givenMultiplePartitions_whenPublishedToKafkaAndConsumedWithExtSeqNumberAndTimeWindow_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { + List sentUserEventList = new ArrayList<>(); + List receivedUserEventList = new ArrayList<>(); + for (long sequenceNumber = 1; sequenceNumber <= 10; sequenceNumber++) { + UserEvent userEvent = new UserEvent(UUID.randomUUID() + .toString()); + userEvent.setEventNanoTime(System.nanoTime()); + userEvent.setGlobalSequenceNumber(sequenceNumber); + Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, sequenceNumber, userEvent)); + sentUserEventList.add(userEvent); + RecordMetadata metadata = future.get(); + logger.info("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); + } + + consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); + List buffer = new ArrayList<>(); + long lastProcessedTime = System.nanoTime(); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + records.forEach(record -> { + buffer.add(record.value()); + }); + while (!buffer.isEmpty()) { + if (System.nanoTime() - lastProcessedTime > BUFFER_PERIOD_NS) { + processBuffer(buffer, receivedUserEventList); + lastProcessedTime = System.nanoTime(); + } + records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + records.forEach(record -> { + buffer.add(record.value()); + }); + } + assertThat(receivedUserEventList).isEqualTo(sentUserEventList) + .containsExactlyElementsOf(sentUserEventList); + } + + private static void processBuffer(List buffer, List receivedUserEventList) { + Collections.sort(buffer); + buffer.forEach(userEvent -> { + receivedUserEventList.add(userEvent); + logger.info("Processing message with Global Sequence number: " + userEvent.getGlobalSequenceNumber() + ", User Event Id: " + userEvent.getUserEventId()); + }); + buffer.clear(); + } +} diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionLiveTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionLiveTest.java new file mode 100644 index 0000000000..407b4d52a9 --- /dev/null +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionLiveTest.java @@ -0,0 +1,105 @@ +package com.baeldung.kafka.message.ordering; + +import com.baeldung.kafka.message.ordering.payload.UserEvent; +import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; +import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; + +import org.apache.kafka.clients.admin.*; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.apache.kafka.common.serialization.LongDeserializer; +import org.apache.kafka.common.serialization.LongSerializer; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import java.time.Duration; +import java.util.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import com.google.common.collect.ImmutableList; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +@Testcontainers +public class MultiplePartitionLiveTest { + + private static Admin admin; + private static KafkaProducer producer; + private static KafkaConsumer consumer; + private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); + + private static Logger logger = LoggerFactory.getLogger(MultiplePartitionLiveTest.class); + @Container + private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + + @BeforeAll + static void setup() throws ExecutionException, InterruptedException { + KAFKA_CONTAINER.addExposedPort(9092); + + Properties adminProperties = new Properties(); + adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + + Properties producerProperties = new Properties(); + producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); + producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); + + Properties consumerProperties = new Properties(); + consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); + consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); + admin = Admin.create(adminProperties); + producer = new KafkaProducer<>(producerProperties); + consumer = new KafkaConsumer<>(consumerProperties); + admin.createTopics(ImmutableList.of(new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR))) + .all() + .get(); + } + + @AfterAll + static void destroy() { + KAFKA_CONTAINER.stop(); + } + + @Test + void givenMultiplePartitions_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { + List sentUserEventList = new ArrayList<>(); + List receivedUserEventList = new ArrayList<>(); + for (long sequenceNumber = 1; sequenceNumber <= 10; sequenceNumber++) { + UserEvent userEvent = new UserEvent(UUID.randomUUID() + .toString()); + userEvent.setGlobalSequenceNumber(sequenceNumber); + userEvent.setEventNanoTime(System.nanoTime()); + Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, sequenceNumber, userEvent)); + sentUserEventList.add(userEvent); + RecordMetadata metadata = future.get(); + logger.info("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); + } + + consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + records.forEach(record -> { + UserEvent userEvent = record.value(); + receivedUserEventList.add(userEvent); + logger.info("User Event ID: " + userEvent.getUserEventId()); + }); + assertThat(receivedUserEventList).isNotEqualTo(sentUserEventList) + .containsExactlyInAnyOrderElementsOf(sentUserEventList); + } +} diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionLiveTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionLiveTest.java new file mode 100644 index 0000000000..9c6a15ebeb --- /dev/null +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionLiveTest.java @@ -0,0 +1,109 @@ +package com.baeldung.kafka.message.ordering; + +import com.baeldung.kafka.message.ordering.payload.UserEvent; +import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; +import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; + +import org.apache.kafka.clients.admin.Admin; +import org.apache.kafka.clients.admin.AdminClientConfig; +import org.apache.kafka.clients.admin.NewTopic; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.apache.kafka.common.serialization.LongDeserializer; +import org.apache.kafka.common.serialization.LongSerializer; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import java.time.Duration; +import java.util.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import com.google.common.collect.ImmutableList; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +@Testcontainers +public class SinglePartitionLiveTest { + + private static Admin admin; + private static KafkaProducer producer; + private static KafkaConsumer consumer; + + private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); + + private static Logger logger = LoggerFactory.getLogger(SinglePartitionLiveTest.class); + @Container + private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + + @BeforeAll + static void setup() throws ExecutionException, InterruptedException { + KAFKA_CONTAINER.addExposedPort(9092); + + Properties adminProperties = new Properties(); + adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + + Properties producerProperties = new Properties(); + producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); + producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); + + Properties consumerProperties = new Properties(); + consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); + consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); + admin = Admin.create(adminProperties); + producer = new KafkaProducer<>(producerProperties); + consumer = new KafkaConsumer<>(consumerProperties); + admin.createTopics(ImmutableList.of(new NewTopic(Config.SINGLE_PARTITION_TOPIC, Config.SINGLE_PARTITION, Config.REPLICATION_FACTOR))) + .all() + .get(); + } + + @AfterAll + static void destroy() { + KAFKA_CONTAINER.stop(); + } + + @Test + void givenASinglePartition_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { + List sentUserEventList = new ArrayList<>(); + List receivedUserEventList = new ArrayList<>(); + for (long sequenceNumber = 1; sequenceNumber <= 10; sequenceNumber++) { + UserEvent userEvent = new UserEvent(UUID.randomUUID() + .toString()); + userEvent.setGlobalSequenceNumber(sequenceNumber); + userEvent.setEventNanoTime(System.nanoTime()); + ProducerRecord producerRecord = new ProducerRecord<>(Config.SINGLE_PARTITION_TOPIC, userEvent); + Future future = producer.send(producerRecord); + sentUserEventList.add(userEvent); + RecordMetadata metadata = future.get(); + logger.info("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); + } + + consumer.subscribe(Collections.singletonList(Config.SINGLE_PARTITION_TOPIC)); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + records.forEach(record -> { + UserEvent userEvent = record.value(); + receivedUserEventList.add(userEvent); + logger.info("User Event ID: " + userEvent.getUserEventId()); + }); + assertThat(receivedUserEventList).isEqualTo(sentUserEventList) + .containsExactlyElementsOf(sentUserEventList); + } +} diff --git a/apache-kafka-2/src/test/resources/logback.xml b/apache-kafka-2/src/test/resources/logback.xml new file mode 100644 index 0000000000..6156c2188e --- /dev/null +++ b/apache-kafka-2/src/test/resources/logback.xml @@ -0,0 +1,11 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/atomikos/pom.xml b/atomikos/pom.xml index cd798825d1..2cbc106268 100644 --- a/atomikos/pom.xml +++ b/atomikos/pom.xml @@ -82,26 +82,11 @@ geronimo-jta_1.0.1B_spec ${geronimo.version} - - javax.validation - validation-api - ${validation-api.version} - org.hibernate.validator hibernate-validator ${hibernate-validator.version} - - javax.el - javax.el-api - ${javax.el-api.version} - - - org.glassfish.web - javax.el - ${javax.el.version} - @@ -113,10 +98,7 @@ 10.8.1.2 1.1 1.0 - 2.0.1.Final - 6.1.2.Final - 3.0.0 - 2.2.4 + 8.0.1.Final \ No newline at end of file diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/Application.java b/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/Application.java index cf1fef2cd8..ad828bd2ca 100644 --- a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/Application.java +++ b/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/Application.java @@ -3,10 +3,10 @@ package com.baeldung.atomikos.spring.jpa; import java.util.Set; import java.util.UUID; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/Order.java b/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/Order.java index 4b9ae2dd1d..3a580e6448 100644 --- a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/Order.java +++ b/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/Order.java @@ -3,7 +3,7 @@ package com.baeldung.atomikos.spring.jpa.order; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; -import javax.validation.constraints.Max; +import jakarta.validation.constraints.Max; @Entity @Table(name = "ORDERS") diff --git a/aws-modules/aws-dynamodb/pom.xml b/aws-modules/aws-dynamodb/pom.xml index 37b88327f4..adce036733 100644 --- a/aws-modules/aws-dynamodb/pom.xml +++ b/aws-modules/aws-dynamodb/pom.xml @@ -79,7 +79,7 @@ - 2.8.0 + 2.10.1 1.21.1 3.1.1 diff --git a/aws-modules/aws-miscellaneous/pom.xml b/aws-modules/aws-miscellaneous/pom.xml index 4126256fb9..5fdd7fa04d 100644 --- a/aws-modules/aws-miscellaneous/pom.xml +++ b/aws-modules/aws-miscellaneous/pom.xml @@ -73,7 +73,7 @@ - 2.8.0 + 2.10.1 1.21.1 1.10.L001 0.9.4.0006L 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 ac1e1ca81f..462a4be6f1 100644 --- a/core-java-modules/core-java-8-datetime-2/README.md +++ b/core-java-modules/core-java-8-datetime-2/README.md @@ -6,4 +6,5 @@ - [How Many Days Are There in a Particular Month of a Given Year?](https://www.baeldung.com/days-particular-month-given-year) - [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) - [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) diff --git a/core-java-modules/core-java-8-datetime-2/pom.xml b/core-java-modules/core-java-8-datetime-2/pom.xml index ce349d9dc3..02af06dc9d 100644 --- a/core-java-modules/core-java-8-datetime-2/pom.xml +++ b/core-java-modules/core-java-8-datetime-2/pom.xml @@ -55,7 +55,7 @@ 1.8 1.8 - 2.10 + 2.12.5 \ No newline at end of file diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/DateComparison.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/DateComparison.java new file mode 100644 index 0000000000..d6450670a2 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/DateComparison.java @@ -0,0 +1,18 @@ +package com.baeldung.maxdate; + +import java.util.Date; + +public class DateComparison { + public int compareTodayWithMaxDate() { + Date today = new Date(); + Date maxDate = new Date(Long.MAX_VALUE); + + int comparisonResult = today.compareTo(maxDate); + return comparisonResult; + } + + public static void main(String[] args) { + DateComparison comparator = new DateComparison(); + System.out.println(comparator.compareTodayWithMaxDate()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/MaxDateDisplay.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/MaxDateDisplay.java new file mode 100644 index 0000000000..b79b5f4422 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/MaxDateDisplay.java @@ -0,0 +1,18 @@ +package com.baeldung.maxdate; + +import java.util.Date; +import java.text.SimpleDateFormat; + +public class MaxDateDisplay { + public String getMaxDateValue() { + Date maxDate = new Date(Long.MAX_VALUE); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + return "The maximum date value in Java is: " + sdf.format(maxDate); + } + + public static void main(String[] args) { + MaxDateDisplay display = new MaxDateDisplay(); + System.out.println(display.getMaxDateValue()); + } +} + diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleParseDate.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleParseDate.java index cb024eea53..ba4f14ec5f 100644 --- a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleParseDate.java +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleParseDate.java @@ -7,7 +7,7 @@ import java.util.List; public class SimpleParseDate { - public Date parseDate(String dateString, List formatStrings) { + public static Date parseDate(String dateString, List formatStrings) { for (String formatString : formatStrings) { try { return new SimpleDateFormat(formatString).parse(dateString); diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/rounddate/RoundDate.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/rounddate/RoundDate.java new file mode 100644 index 0000000000..6fb7cf87b7 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/rounddate/RoundDate.java @@ -0,0 +1,113 @@ +package com.baeldung.rounddate; + +import java.time.DayOfWeek; +import java.time.temporal.ChronoField; +import java.time.temporal.TemporalAdjusters; +import java.util.Calendar; +import java.util.Date; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; + +public class RoundDate { + public static Date getDate(int year, int month, int day, int hour, int minute) { + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.YEAR, year); + calendar.set(Calendar.MONTH, month); + calendar.set(Calendar.DAY_OF_MONTH, day); + calendar.set(Calendar.HOUR_OF_DAY, hour); + calendar.set(Calendar.MINUTE, minute); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + return calendar.getTime(); + } + + public static Date roundToDay(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTime(); + } + + public static Date roundToNearestUnit(Date date, int unit) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + switch (unit) { + case Calendar.HOUR: + int minute = calendar.get(Calendar.MINUTE); + if (minute >= 0 && minute < 15) { + calendar.set(Calendar.MINUTE, 0); + } else if (minute >= 15 && minute < 45) { + calendar.set(Calendar.MINUTE, 30); + } else { + calendar.set(Calendar.MINUTE, 0); + calendar.add(Calendar.HOUR_OF_DAY, 1); + } + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + break; + + case Calendar.DAY_OF_MONTH: + int hour = calendar.get(Calendar.HOUR_OF_DAY); + if (hour >= 12) { + calendar.add(Calendar.DAY_OF_MONTH, 1); + } + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + break; + + case Calendar.MONTH: + int day = calendar.get(Calendar.DAY_OF_MONTH); + if (day >= 15) { + calendar.add(Calendar.MONTH, 1); + } + calendar.set(Calendar.DAY_OF_MONTH, 1); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + break; + } + + return calendar.getTime(); + } + + public static LocalDateTime roundToStartOfMonthUsingLocalDateTime(LocalDateTime dateTime) { + return dateTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0); + } + + public static LocalDateTime roundToEndOfWeekUsingLocalDateTime(LocalDateTime dateTime) { + return dateTime.with(TemporalAdjusters.next(DayOfWeek.SATURDAY)) + .withHour(23) + .withMinute(59) + .withSecond(59) + .withNano(999); + } + + public static ZonedDateTime roundToStartOfMonthUsingZonedDateTime(ZonedDateTime dateTime) { + return dateTime.withDayOfMonth(1) + .withHour(0) + .withMinute(0) + .withSecond(0) + .with(ChronoField.MILLI_OF_SECOND, 0) + .with(ChronoField.MICRO_OF_SECOND, 0) + .with(ChronoField.NANO_OF_SECOND, 0); + } + + public static ZonedDateTime roundToEndOfWeekUsingZonedDateTime(ZonedDateTime dateTime) { + return dateTime.with(TemporalAdjusters.next(DayOfWeek.SATURDAY)) + .withHour(23) + .withMinute(59) + .withSecond(59) + .with(ChronoField.MILLI_OF_SECOND, 999) + .with(ChronoField.MICRO_OF_SECOND, 999) + .with(ChronoField.NANO_OF_SECOND, 999); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/DateComparisonUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/DateComparisonUnitTest.java new file mode 100644 index 0000000000..70aef126da --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/DateComparisonUnitTest.java @@ -0,0 +1,16 @@ +package com.baeldung.maxdate; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class DateComparisonUnitTest { + + @Test + void whenCompareTodayWithMaxDate_thenCorrectResult() { + DateComparison comparator = new DateComparison(); + int result = comparator.compareTodayWithMaxDate(); + + assertTrue(result < 0); + } +} diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/MaxDateDisplayUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/MaxDateDisplayUnitTest.java new file mode 100644 index 0000000000..dd7000bd29 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/MaxDateDisplayUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.maxdate; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class MaxDateDisplayUnitTest { + + @Test + void whenGetMaxDate_thenCorrectResult() { + MaxDateDisplay display = new MaxDateDisplay(); + String result = display.getMaxDateValue(); + assertEquals( + "The maximum date value in Java is: 292278994-08-17 07:12:55.807", + result + ); + } +} diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/parsingDates/SimpleParseDateUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/parsingDates/SimpleParseDateUnitTest.java index d7cbb6a834..ed8607fd96 100644 --- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/parsingDates/SimpleParseDateUnitTest.java +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/parsingDates/SimpleParseDateUnitTest.java @@ -1,43 +1,41 @@ package com.baeldung.parsingDates; -import com.baeldung.parsingDates.SimpleDateTimeFormat; -import com.baeldung.parsingDates.SimpleDateTimeFormater; -import com.baeldung.parsingDates.SimpleDateUtils; -import com.baeldung.parsingDates.SimpleParseDate; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + import java.time.format.DateTimeParseException; import java.util.Arrays; -import org.junit.*; -import static org.junit.Assert.*; + import org.joda.time.LocalDate; +import org.junit.jupiter.api.Test; -public class SimpleParseDateUnitTest { +class SimpleParseDateUnitTest { @Test - public void whenInvalidInput_thenGettingUnexpectedResult() { - SimpleParseDate simpleParseDate = new SimpleParseDate(); + void whenInvalidInput_thenGettingUnexpectedResult() { String date = "2022-40-40"; - assertEquals("Sat May 10 00:00:00 UTC 2025", simpleParseDate.parseDate(date, Arrays.asList("MM/dd/yyyy", "dd.MM.yyyy", "yyyy-MM-dd")).toString()); + assertEquals("Sat May 10 00:00:00 UTC 2025", SimpleParseDate.parseDate(date, Arrays.asList("MM/dd/yyyy", "dd.MM.yyyy", "yyyy-MM-dd")) + .toString()); } @Test - public void whenInvalidDate_thenAssertThrows() { - SimpleDateTimeFormater simpleDateTimeFormater = new SimpleDateTimeFormater(); - assertEquals(java.time.LocalDate.parse("2022-12-04"), simpleDateTimeFormater.parseDate("2022-12-04")); - assertThrows(DateTimeParseException.class, () -> simpleDateTimeFormater.parseDate("2022-13-04")); + void whenInvalidDate_thenAssertThrows() { + assertEquals(java.time.LocalDate.parse("2022-12-04"), SimpleDateTimeFormater.parseDate("2022-12-04")); + assertThrows(DateTimeParseException.class, () -> SimpleDateTimeFormater.parseDate("2022-13-04")); } @Test - public void whenDateIsCorrect_thenParseCorrect() { - SimpleDateUtils simpleDateUtils = new SimpleDateUtils(); - assertNull(simpleDateUtils.parseDate("53/10/2014")); - assertEquals("Wed Sep 10 00:00:00 UTC 2014", simpleDateUtils.parseDate("10/09/2014").toString()); + void whenDateIsCorrect_thenParseCorrect() { + assertNull(SimpleDateUtils.parseDate("53/10/2014")); + assertEquals("Wed Sep 10 00:00:00 UTC 2014", SimpleDateUtils.parseDate("10/09/2014") + .toString()); } @Test - public void whenDateIsCorrect_thenResultCorrect() { - SimpleDateTimeFormat simpleDateTimeFormat = new SimpleDateTimeFormat(); - assertNull(simpleDateTimeFormat.parseDate("53/10/2014")); - assertEquals(LocalDate.parse("2014-10-10"), simpleDateTimeFormat.parseDate("2014-10-10")); + void whenDateIsCorrect_thenResultCorrect() { + assertNull(SimpleDateTimeFormat.parseDate("53/10/2014")); + assertEquals(LocalDate.parse("2014-10-10"), SimpleDateTimeFormat.parseDate("2014-10-10")); } } diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/rounddate/DateRoundingUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/rounddate/DateRoundingUnitTest.java new file mode 100644 index 0000000000..bbe49d8340 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/rounddate/DateRoundingUnitTest.java @@ -0,0 +1,63 @@ +package com.baeldung.rounddate; + +import org.junit.Test; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Date; + +import static org.junit.Assert.assertEquals; + +public class DateRoundingUnitTest { + + @Test + public void givenDate_whenRoundToDay_thenBeginningOfDay() { + Date date = RoundDate.getDate(2023, Calendar.JANUARY, 27, 14, 30); + Date result = RoundDate.roundToDay(date); + assertEquals(RoundDate.getDate(2023, Calendar.JANUARY, 27, 0, 0), result); + } + + @Test + public void givenDate_whenRoundToNearestUnit_thenNearestUnit() { + Date date = RoundDate.getDate(2023, Calendar.JANUARY, 27, 14, 12); + Date result = RoundDate.roundToNearestUnit(date, Calendar.DAY_OF_MONTH); + Date expected = RoundDate.getDate(2023, Calendar.JANUARY, 28, 0, 0); + assertEquals(expected, result); + } + + @Test + public void givenLocalDateTime_whenRoundToStartOfMonth_thenStartOfMonth() { + LocalDateTime dateTime = LocalDateTime.of(2023, 1, 27, 14, 12); + LocalDateTime result = RoundDate.roundToStartOfMonthUsingLocalDateTime(dateTime); + LocalDateTime expected = LocalDateTime.of(2023, 1, 1, 0, 0, 0); + assertEquals(expected, result); + } + + + @Test + public void givenZonedDateTime_whenRoundToStartOfMonth_thenStartOfMonth() { + ZonedDateTime dateTime = ZonedDateTime.of(2023, 1, 27, 14, 12, 0, 0, ZoneId.systemDefault()); + ZonedDateTime result = RoundDate.roundToStartOfMonthUsingZonedDateTime(dateTime); + ZonedDateTime expected = ZonedDateTime.of(2023, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()); + assertEquals(expected, result); + } + + @Test + public void givenLocalDateTime_whenRoundToEndOfWeek_thenEndOfWeek() { + LocalDateTime dateTime = LocalDateTime.of(2023, 1, 27, 14, 12); + LocalDateTime result = RoundDate.roundToEndOfWeekUsingLocalDateTime(dateTime); + LocalDateTime expected = LocalDateTime.of(2023, 1, 28, 23, 59, 59, 999); + assertEquals(expected, result); + } + + @Test + public void givenZonedDateTime_whenRoundToEndOfWeek_thenEndOfWeek() { + ZonedDateTime dateTime = ZonedDateTime.of(2023, 1, 27, 14, 12, 0, 0, ZoneId.systemDefault()); + ZonedDateTime result = RoundDate.roundToEndOfWeekUsingZonedDateTime(dateTime); + ZonedDateTime expected = ZonedDateTime.of(2023, 1, 28, 23, 59, 59, 999, ZoneId.systemDefault()); + assertEquals(expected, result); + } + +} diff --git a/core-java-modules/core-java-8-datetime/pom.xml b/core-java-modules/core-java-8-datetime/pom.xml index 481b1a6a69..06ecc3d017 100644 --- a/core-java-modules/core-java-8-datetime/pom.xml +++ b/core-java-modules/core-java-8-datetime/pom.xml @@ -56,7 +56,7 @@ 1.8 1.8 - 2.10 + 2.12.5 \ No newline at end of file diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/spliterator/CustomSpliterator.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/spliterator/CustomSpliterator.java new file mode 100644 index 0000000000..2f806cccda --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/baeldung/spliterator/CustomSpliterator.java @@ -0,0 +1,48 @@ +package com.baeldung.spliterator; + +import java.util.List; +import java.util.Spliterator; +import java.util.function.Consumer; + +public class CustomSpliterator implements Spliterator { + private final List elements; + private int currentIndex; + + public CustomSpliterator(List elements) { + this.elements = elements; + this.currentIndex = 0; + } + + @Override + public boolean tryAdvance(Consumer action) { + if (currentIndex < elements.size()) { + action.accept(elements.get(currentIndex)); + currentIndex++; + return true; + } + return false; + } + + @Override + public Spliterator trySplit() { + int currentSize = elements.size() - currentIndex; + if (currentSize < 2) { + return null; + } + + int splitIndex = currentIndex + currentSize / 2; + CustomSpliterator newSpliterator = new CustomSpliterator(elements.subList(currentIndex, splitIndex)); + currentIndex = splitIndex; + return newSpliterator; + } + + @Override + public long estimateSize() { + return elements.size() - currentIndex; + } + + @Override + public int characteristics() { + return ORDERED | SIZED | SUBSIZED | NONNULL; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/spliterator/Executor.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/spliterator/Executor.java deleted file mode 100644 index 3dc2fa06bb..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/spliterator/Executor.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.spliterator; - -import java.util.stream.Stream; - -public class Executor { - - public static int countAutors(Stream stream) { - RelatedAuthorCounter wordCounter = stream.reduce(new RelatedAuthorCounter(0, true), - RelatedAuthorCounter::accumulate, RelatedAuthorCounter::combine); - return wordCounter.getCounter(); - } -} \ No newline at end of file diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/spliterator/RelatedAuthorCounter.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/spliterator/RelatedAuthorCounter.java deleted file mode 100644 index 8800eac55b..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/spliterator/RelatedAuthorCounter.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.baeldung.spliterator; - -public class RelatedAuthorCounter { - private final int counter; - private final boolean isRelated; - - public RelatedAuthorCounter(int counter, boolean isRelated) { - this.counter = counter; - this.isRelated = isRelated; - } - - public RelatedAuthorCounter accumulate(Author author) { - if (author.getRelatedArticleId() == 0) { - return isRelated ? this : new RelatedAuthorCounter(counter, true); - } else { - return isRelated ? new RelatedAuthorCounter(counter + 1, false) : this; - } - } - - public RelatedAuthorCounter combine(RelatedAuthorCounter RelatedAuthorCounter) { - return new RelatedAuthorCounter(counter + RelatedAuthorCounter.counter, RelatedAuthorCounter.isRelated); - } - - public int getCounter() { - return counter; - } -} diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/spliterator/RelatedAuthorSpliterator.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/spliterator/RelatedAuthorSpliterator.java deleted file mode 100644 index 93c83b8127..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/spliterator/RelatedAuthorSpliterator.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.baeldung.spliterator; - -import java.util.List; -import java.util.Spliterator; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; - -public class RelatedAuthorSpliterator implements Spliterator { - private final List list; - AtomicInteger current = new AtomicInteger(); - - public RelatedAuthorSpliterator(List list) { - this.list = list; - } - - @Override - public boolean tryAdvance(Consumer action) { - - action.accept(list.get(current.getAndIncrement())); - return current.get() < list.size(); - } - - @Override - public Spliterator trySplit() { - int currentSize = list.size() - current.get(); - if (currentSize < 10) { - return null; - } - for (int splitPos = currentSize / 2 + current.intValue(); splitPos < list.size(); splitPos++) { - if (list.get(splitPos).getRelatedArticleId() == 0) { - Spliterator spliterator = new RelatedAuthorSpliterator(list.subList(current.get(), splitPos)); - current.set(splitPos); - return spliterator; - } - } - return null; - } - - @Override - public long estimateSize() { - return list.size() - current.get(); - } - - @Override - public int characteristics() { - return CONCURRENT; - } - -} diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/application/Application.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/application/Application.java deleted file mode 100644 index 00fc45ccae..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/application/Application.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.baeldung.streamreduce.application; - -import com.baeldung.streamreduce.entities.User; -import com.baeldung.streamreduce.utilities.NumberUtils; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class Application { - - public static void main(String[] args) { - List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); - int result1 = numbers.stream().reduce(0, (a, b) -> a + b); - System.out.println(result1); - - int result2 = numbers.stream().reduce(0, Integer::sum); - System.out.println(result2); - - List letters = Arrays.asList("a", "b", "c", "d", "e"); - String result3 = letters.stream().reduce("", (a, b) -> a + b); - System.out.println(result3); - - String result4 = letters.stream().reduce("", String::concat); - System.out.println(result4); - - String result5 = letters.stream().reduce("", (a, b) -> a.toUpperCase() + b.toUpperCase()); - System.out.println(result5); - - List users = Arrays.asList(new User("John", 30), new User("Julie", 35)); - int result6 = users.stream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); - System.out.println(result6); - - String result7 = letters.parallelStream().reduce("", String::concat); - System.out.println(result7); - - int result8 = users.parallelStream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); - System.out.println(result8); - - List userList = new ArrayList<>(); - for (int i = 0; i <= 1000000; i++) { - userList.add(new User("John" + i, i)); - } - - long t1 = System.currentTimeMillis(); - int result9 = userList.stream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); - long t2 = System.currentTimeMillis(); - System.out.println(result9); - System.out.println("Sequential stream time: " + (t2 - t1) + "ms"); - - long t3 = System.currentTimeMillis(); - int result10 = userList.parallelStream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); - long t4 = System.currentTimeMillis(); - System.out.println(result10); - System.out.println("Parallel stream time: " + (t4 - t3) + "ms"); - - int result11 = NumberUtils.divideListElements(numbers, 1); - System.out.println(result11); - - int result12 = NumberUtils.divideListElementsWithExtractedTryCatchBlock(numbers, 0); - System.out.println(result12); - } -} diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Rating.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Rating.java deleted file mode 100644 index c4d0276256..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Rating.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.baeldung.streamreduce.entities; - -import java.util.ArrayList; -import java.util.List; - -public class Rating { - - double points; - List reviews = new ArrayList<>(); - - public Rating() {} - - public void add(Review review) { - reviews.add(review); - computeRating(); - } - - private double computeRating() { - double totalPoints = reviews.stream().map(Review::getPoints).reduce(0, Integer::sum); - this.points = totalPoints / reviews.size(); - return this.points; - } - - public static Rating average(Rating r1, Rating r2) { - Rating combined = new Rating(); - combined.reviews = new ArrayList<>(r1.reviews); - combined.reviews.addAll(r2.reviews); - combined.computeRating(); - return combined; - } - - public double getPoints() { - return points; - } - - public List getReviews() { - return reviews; - } -} diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Review.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Review.java deleted file mode 100644 index 03cde8a9c8..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Review.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.baeldung.streamreduce.entities; - -public class Review { - - int points; - String review; - - public Review(int points, String review) { - this.points = points; - this.review = review; - } - - public int getPoints() { - return points; - } - - public void setPoints(int points) { - this.points = points; - } - - public String getReview() { - return review; - } - - public void setReview(String review) { - this.review = review; - } -} diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/User.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/User.java deleted file mode 100644 index 20c12d7920..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/User.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.baeldung.streamreduce.entities; - -public class User { - - private final String name; - private final int age; - private final Rating rating = new Rating(); - - public User(String name, int age) { - this.name = name; - this.age = age; - } - - public String getName() { - return name; - } - - public int getAge() { - return age; - } - - public Rating getRating() { - return rating; - } - - @Override - public String toString() { - return "User{" + "name=" + name + ", age=" + age + '}'; - } -} diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/utilities/NumberUtils.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/utilities/NumberUtils.java deleted file mode 100644 index a2325cc701..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/utilities/NumberUtils.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.baeldung.streamreduce.utilities; - -import java.util.List; -import java.util.function.BiFunction; -import java.util.logging.Level; -import java.util.logging.Logger; - -public abstract class NumberUtils { - - private static final Logger LOGGER = Logger.getLogger(NumberUtils.class.getName()); - - public static int divideListElements(List values, Integer divider) { - return values.stream() - .reduce(0, (a, b) -> { - try { - return a / divider + b / divider; - } catch (ArithmeticException e) { - LOGGER.log(Level.INFO, "Arithmetic Exception: Division by Zero"); - } - return 0; - }); - } - - public static int divideListElementsWithExtractedTryCatchBlock(List values, int divider) { - return values.stream().reduce(0, (a, b) -> divide(a, divider) + divide(b, divider)); - } - - public static int divideListElementsWithApplyFunctionMethod(List values, int divider) { - BiFunction division = (a, b) -> a / b; - return values.stream().reduce(0, (a, b) -> applyFunction(division, a, divider) + applyFunction(division, b, divider)); - } - - private static int divide(int value, int factor) { - int result = 0; - try { - result = value / factor; - } catch (ArithmeticException e) { - LOGGER.log(Level.INFO, "Arithmetic Exception: Division by Zero"); - } - return result; - } - - private static int applyFunction(BiFunction function, int a, int b) { - try { - return function.apply(a, b); - } - catch(Exception e) { - LOGGER.log(Level.INFO, "Exception occurred!"); - } - return 0; - } -} diff --git a/core-java-modules/core-java-8/src/test/java/com/baeldung/spliterator/ExecutorUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/baeldung/spliterator/ExecutorUnitTest.java index 4628f95481..30760ddf6f 100644 --- a/core-java-modules/core-java-8/src/test/java/com/baeldung/spliterator/ExecutorUnitTest.java +++ b/core-java-modules/core-java-8/src/test/java/com/baeldung/spliterator/ExecutorUnitTest.java @@ -6,10 +6,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Spliterator; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import java.util.stream.Stream; -import java.util.stream.StreamSupport; - import org.junit.Before; import org.junit.Test; @@ -18,22 +18,50 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class ExecutorUnitTest { Article article; - Stream stream; - Spliterator spliterator; @Before public void init() { article = new Article(Arrays.asList(new Author("Ahmad", 0), new Author("Eugen", 0), new Author("Alice", 1), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Michał", 0), new Author("Loredana", 1)), 0); - - spliterator = new RelatedAuthorSpliterator(article.getListOfAuthors()); } @Test - public void givenAstreamOfAuthors_whenProcessedInParallelWithCustomSpliterator_coubtProducessRightOutput() { - Stream stream2 = StreamSupport.stream(spliterator, true); - assertThat(Executor.countAutors(stream2.parallel())).isEqualTo(9); + public void givenAStreamOfIntegers_whenProcessedSequentialCustomSpliterator_countProducesRightOutput() { + List numbers = new ArrayList<>(); + numbers.add(1); + numbers.add(2); + numbers.add(3); + numbers.add(4); + numbers.add(5); + + CustomSpliterator customSpliterator = new CustomSpliterator(numbers); + + AtomicInteger sum = new AtomicInteger(); + + customSpliterator.forEachRemaining(sum::addAndGet); + assertThat(sum.get()).isEqualTo(15); + } + + @Test + public void givenAStreamOfIntegers_whenProcessedInParallelWithCustomSpliterator_countProducesRightOutput() { + List numbers = new ArrayList<>(); + numbers.add(1); + numbers.add(2); + numbers.add(3); + numbers.add(4); + numbers.add(5); + + CustomSpliterator customSpliterator = new CustomSpliterator(numbers); + + // Create a ForkJoinPool for parallel processing + ForkJoinPool forkJoinPool = ForkJoinPool.commonPool(); + + AtomicInteger sum = new AtomicInteger(0); + + // Process elements in parallel using parallelStream + forkJoinPool.submit(() -> customSpliterator.forEachRemaining(sum::addAndGet)).join(); + assertThat(sum.get()).isEqualTo(15); } @Test @@ -43,9 +71,7 @@ public class ExecutorUnitTest { .collect(Collectors.toList()); Spliterator
spliterator = articles.spliterator(); - while (spliterator.tryAdvance(article -> article.setName(article.getName() - .concat("- published by Baeldung")))) - ; + while(spliterator.tryAdvance(article -> article.setName(article.getName().concat("- published by Baeldung")))); articles.forEach(article -> assertThat(article.getName()).isEqualTo("Java- published by Baeldung")); } diff --git a/core-java-modules/core-java-arrays-operations-advanced/pom.xml b/core-java-modules/core-java-arrays-operations-advanced/pom.xml index cbcd6ae440..52787cc0c9 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/pom.xml +++ b/core-java-modules/core-java-arrays-operations-advanced/pom.xml @@ -57,5 +57,9 @@ + + + 11 + \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/test/java/com/baeldung/arraycompare/ArraysCompareUnitTest.java b/core-java-modules/core-java-arrays-operations-advanced/src/test/java/com/baeldung/arraycompare/ArraysCompareUnitTest.java new file mode 100644 index 0000000000..828560d71c --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-advanced/src/test/java/com/baeldung/arraycompare/ArraysCompareUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.arraycompare; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +class ArraysCompareUnitTest { + + @Test + void givenSameContents_whenCompare_thenCorrect() { + String[] array1 = new String[] { "A", "B", "C" }; + String[] array2 = new String[] { "A", "B", "C" }; + + assertThat(Arrays.compare(array1, array2)).isEqualTo(0); + } + + @Test + void givenDifferentContents_whenCompare_thenDifferent() { + String[] array1 = new String[] { "A", "B", "C" }; + String[] array2 = new String[] { "A", "C", "B", "D" }; + + assertThat(Arrays.compare(array1, array2)).isLessThan(0); + assertThat(Arrays.compare(array2, array1)).isGreaterThan(0); + assertThat(Arrays.compare(array1, null)).isGreaterThan(0); + } + +} diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md index 1939e5ca3f..4869158d2b 100644 --- a/core-java-modules/core-java-collections-5/README.md +++ b/core-java-modules/core-java-collections-5/README.md @@ -8,4 +8,5 @@ - [Difference Between Arrays.sort() and Collections.sort()](https://www.baeldung.com/java-arrays-collections-sort-methods) - [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) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-4) diff --git a/core-java-modules/core-java-collections-5/src/test/java/com/baeldung/vectors/VectorOperationsUnitTest.java b/core-java-modules/core-java-collections-5/src/test/java/com/baeldung/vectors/VectorOperationsUnitTest.java new file mode 100644 index 0000000000..c948ce2481 --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/test/java/com/baeldung/vectors/VectorOperationsUnitTest.java @@ -0,0 +1,87 @@ +package com.baeldung.vectors; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Vector; + +import org.junit.Test; + +public class VectorOperationsUnitTest { + + private static Vector getVector() { + Vector vector = new Vector(); + vector.add("Today"); + vector.add("is"); + vector.add("a"); + vector.add("great"); + vector.add("day!"); + + return vector; + } + + @Test + public void givenAVector_whenAddElementsUsingAddMethod_thenElementsGetAddedAtEnd() { + Vector vector = getVector(); + vector.add("Hello"); + assertEquals(6, vector.size()); + } + + @Test + public void givenAVector_whenUpdateElementAtIndex_thenElementAtIndexGetsUpdated() { + Vector vector = getVector(); + assertEquals(5, vector.size()); + assertEquals("great", vector.get(3)); + vector.set(3, "good"); + assertEquals("good", vector.get(3)); + } + + @Test + public void givenAVector_whenRemoveAnElement_thenElementGetsRemovedFromTheVector() { + Vector vector = getVector(); + assertEquals(5, vector.size()); + + // remove a specific element + vector.remove("a"); + assertEquals(4, vector.size()); + + // remove at specific index + vector.remove(2); + assertEquals("day!", vector.get(2)); + assertEquals(3, vector.size()); + + assertEquals(false, vector.remove("SomethingThatDoesn'tExist")); + } + + @Test(expected = ArrayIndexOutOfBoundsException.class) + public void givenAVector_whenIndexIsBeyondRange_thenRemoveMethodThrowsArrayIndexOutOfBoundsException() { + Vector vector = getVector(); + assertEquals(5, vector.size()); + vector.remove(10); + } + + @Test + public void givenAVector_whenGetElementWithinARange_thenGetMethodGetsAnElementFromTheVector() { + Vector vector = getVector(); + String fourthElement = vector.get(3); + assertEquals("great", fourthElement); + } + + @Test(expected = ArrayIndexOutOfBoundsException.class) + public void givenAVector_whenGetElementBeyondARange_thenGetMethodThrowsArrayIndexOutOfBoundsException() { + Vector vector = getVector(); + assertEquals(5, vector.size()); + vector.get(10); + } + + @Test + public void givenAVector_whenAddElementFromACollection_thenAllElementsGetAdeddToTheVector() { + Vector vector = getVector(); + assertEquals(5, vector.size()); + ArrayList words = new ArrayList<>(Arrays.asList("Baeldung", "is", "cool!")); + vector.addAll(words); + assertEquals(8, vector.size()); + assertEquals("cool!", vector.get(7)); + } +} diff --git a/core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java b/core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java new file mode 100644 index 0000000000..420c1d25e6 --- /dev/null +++ b/core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.toarraymethod; + +import org.junit.Test; + +import java.util.HashSet; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class ConvertingHashSetToArrayUnitTest { + + @Test + public void givenStringHashSet_whenConvertedToArray_thenArrayContainsStringElements() { + HashSet stringSet = new HashSet<>(); + stringSet.add("Apple"); + stringSet.add("Banana"); + stringSet.add("Cherry"); + + // Convert the HashSet of Strings to an array of Strings + String[] stringArray = stringSet.toArray(new String[0]); + + // Test that the array is of the correct length + assertEquals(3, stringArray.length); + + for (String str : stringArray) { + assertTrue(stringSet.contains(str)); + } + } + + @Test + public void givenIntegerHashSet_whenConvertedToArray_thenArrayContainsIntegerElements() { + HashSet integerSet = new HashSet<>(); + integerSet.add(5); + integerSet.add(10); + integerSet.add(15); + + // Convert the HashSet of Integers to an array of Integers + Integer[] integerArray = integerSet.toArray(new Integer[0]); + + // Test that the array is of the correct length + assertEquals(3, integerArray.length); + + for (Integer num : integerArray) { + assertTrue(integerSet.contains(num)); + } + + assertTrue(integerSet.contains(5)); + assertTrue(integerSet.contains(10)); + assertTrue(integerSet.contains(15)); + } +} diff --git a/core-java-modules/core-java-collections-conversions-2/pom.xml b/core-java-modules/core-java-collections-conversions-2/pom.xml index 7b7533fc39..da6b6a564a 100644 --- a/core-java-modules/core-java-collections-conversions-2/pom.xml +++ b/core-java-modules/core-java-collections-conversions-2/pom.xml @@ -44,6 +44,6 @@ 0.10.3 11 - 3.1.1 + 3.2.0 \ No newline at end of file diff --git a/core-java-modules/core-java-collections-conversions-2/src/test/java/com/baeldung/modelmapper/UsersListMappingUnitTest.java b/core-java-modules/core-java-collections-conversions-2/src/test/java/com/baeldung/modelmapper/UsersListMappingUnitTest.java index a8a72b12f7..c71f655044 100644 --- a/core-java-modules/core-java-collections-conversions-2/src/test/java/com/baeldung/modelmapper/UsersListMappingUnitTest.java +++ b/core-java-modules/core-java-collections-conversions-2/src/test/java/com/baeldung/modelmapper/UsersListMappingUnitTest.java @@ -1,8 +1,9 @@ package com.baeldung.modelmapper; import org.hamcrest.Matchers; -import org.junit.Before; -import org.junit.Test; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.modelmapper.ModelMapper; import org.modelmapper.TypeMap; import org.modelmapper.TypeToken; @@ -10,11 +11,10 @@ import org.modelmapper.TypeToken; import java.util.ArrayList; import java.util.List; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasProperty; -import static org.junit.Assert.assertThat; - /** * This class has test methods of mapping Integer to Character list, @@ -22,12 +22,12 @@ import static org.junit.Assert.assertThat; * * @author Sasa Milenkovic */ -public class UsersListMappingUnitTest { +class UsersListMappingUnitTest { private ModelMapper modelMapper; private List users; - @Before + @BeforeEach public void init() { modelMapper = new ModelMapper(); @@ -35,18 +35,16 @@ public class UsersListMappingUnitTest { TypeMap typeMap = modelMapper.createTypeMap(UserList.class, UserListDTO.class); typeMap.addMappings(mapper -> mapper.using(new UsersListConverter()) - .map(UserList::getUsers, UserListDTO::setUsernames)); + .map(UserList::getUsers, UserListDTO::setUsernames)); - users = new ArrayList(); + users = new ArrayList<>(); users.add(new User("b100", "user1", "user1@baeldung.com", "111-222", "USER")); users.add(new User("b101", "user2", "user2@baeldung.com", "111-333", "USER")); users.add(new User("b102", "user3", "user3@baeldung.com", "111-444", "ADMIN")); - } @Test - public void whenInteger_thenMapToCharacter() { - + void whenInteger_thenMapToCharacter() { List integers = new ArrayList(); integers.add(1); @@ -57,36 +55,27 @@ public class UsersListMappingUnitTest { }.getType()); assertThat(characters, hasItems('1', '2', '3')); - } @Test - public void givenUsersList_whenUseGenericType_thenMapToUserDTO() { - + void givenUsersList_whenUseGenericType_thenMapToUserDTO() { // Mapping lists using custom (generic) type mapping - List userDtoList = MapperUtil.mapList(users, UserDTO.class); - assertThat(userDtoList, Matchers.hasItem( - Matchers.both(hasProperty("userId", equalTo("b100"))) - .and(hasProperty("email", equalTo("user1@baeldung.com"))) - .and(hasProperty("username", equalTo("user1"))))); - - + assertThat(userDtoList, Matchers. hasItem(Matchers.both(hasProperty("userId", equalTo("b100"))) + .and(hasProperty("email", equalTo("user1@baeldung.com"))) + .and(hasProperty("username", equalTo("user1"))))); } @Test - public void givenUsersList_whenUseConverter_thenMapToUsernames() { - + void givenUsersList_whenUseConverter_thenMapToUsernames() { // Mapping lists using property mapping and converter - UserList userList = new UserList(); userList.setUsers(users); UserListDTO dtos = new UserListDTO(); modelMapper.map(userList, dtos); assertThat(dtos.getUsernames(), hasItems("user1", "user2", "user3")); - } } \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-7/README.md b/core-java-modules/core-java-collections-maps-7/README.md index 5599187cd8..a62bdda7af 100644 --- a/core-java-modules/core-java-collections-maps-7/README.md +++ b/core-java-modules/core-java-collections-maps-7/README.md @@ -1,3 +1,7 @@ -## Relevant Articles +## Relevant Articles: - [Difference Between putIfAbsent() and computeIfAbsent() in Java’s Map](https://www.baeldung.com/java-map-putifabsent-computeifabsent) +- [How to Write and Read a File with a Java HashMap](https://www.baeldung.com/how-to-write-and-read-a-file-with-a-java-hashmap/) - [How to Write Hashmap to CSV File](https://www.baeldung.com/java-write-hashmap-csv) +- [How to Get First or Last Entry From a LinkedHashMap in Java](https://www.baeldung.com/java-linkedhashmap-first-last-key-value-pair) +- [How to Write and Read a File with a Java HashMap](https://www.baeldung.com/java-hashmap-write-read-file) +- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-6) \ No newline at end of file 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 bcc0915073..a7acded9cf 100644 --- a/core-java-modules/core-java-collections-maps-7/pom.xml +++ b/core-java-modules/core-java-collections-maps-7/pom.xml @@ -1,11 +1,15 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-maps-7 core-java-collections-maps-7 jar + + 2.10.1 + 1.5 + core-java-modules @@ -13,71 +17,35 @@ 0.0.1-SNAPSHOT - - 5.2.5.RELEASE - com.fasterxml.jackson.core jackson-databind - 2.12.4 - - - org.openjdk.jmh - jmh-core - 1.36 + ${jackson.version} com.google.code.gson gson - 2.8.9 - - - org.json - json - 20230227 - - - junit - junit - 4.13.1 - test - - - org.junit.jupiter - junit-jupiter - 5.8.1 - test - - - org.junit.jupiter - junit-jupiter - 5.8.1 - test - - - junit - junit - 4.13.1 - test - - - org.junit.jupiter - junit-jupiter - 5.8.1 - test - - - junit - junit - 4.13.1 - test + ${gson.version} org.apache.commons commons-csv - 1.5 + ${csv.version} + + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.util=ALL-UNNAMED + + + + + diff --git a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/readandwritefile/Student.java b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/readandwritefile/Student.java new file mode 100644 index 0000000000..b981de6300 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/readandwritefile/Student.java @@ -0,0 +1,51 @@ +package com.baeldung.map.readandwritefile; + +import java.io.Serializable; +import java.util.Objects; + +public class Student implements Serializable { + private static final long serialVersionUID = 1L; + private String firstName; + private String lastName; + + /** Default constructor for JSON serialization */ + public Student() { + + } + + public Student(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Student student = (Student) o; + return Objects.equals(firstName, student.firstName) && Objects.equals(lastName, student.lastName); + } + + @Override + public int hashCode() { + return super.hashCode(); + } +} diff --git a/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/linkedhashmapfirstandlastentry/GetFirstAndLastEntryFromLinkedHashMapUnitTest.java b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/linkedhashmapfirstandlastentry/GetFirstAndLastEntryFromLinkedHashMapUnitTest.java new file mode 100644 index 0000000000..b872e8bdda --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/linkedhashmapfirstandlastentry/GetFirstAndLastEntryFromLinkedHashMapUnitTest.java @@ -0,0 +1,85 @@ +package com.baeldung.map.linkedhashmapfirstandlastentry; + +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map.Entry; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class GetFirstAndLastEntryFromLinkedHashMapUnitTest { + private static final LinkedHashMap THE_MAP = new LinkedHashMap<>(); + + static { + THE_MAP.put("key one", "a1 b1 c1"); + THE_MAP.put("key two", "a2 b2 c2"); + THE_MAP.put("key three", "a3 b3 c3"); + THE_MAP.put("key four", "a4 b4 c4"); + } + + @Test + void whenIteratingEntrySet_thenGetExpectedResult() { + Entry firstEntry = THE_MAP.entrySet().iterator().next(); + assertEquals("key one", firstEntry.getKey()); + assertEquals("a1 b1 c1", firstEntry.getValue()); + + Entry lastEntry = null; + Iterator> it = THE_MAP.entrySet().iterator(); + while (it.hasNext()) { + lastEntry = it.next(); + } + + assertNotNull(lastEntry); + assertEquals("key four", lastEntry.getKey()); + assertEquals("a4 b4 c4", lastEntry.getValue()); + + } + + @Test + void whenConvertingEntriesToArray_thenGetExpectedResult() { + + Entry[] theArray = new Entry[THE_MAP.size()]; + THE_MAP.entrySet().toArray(theArray); + + Entry firstEntry = theArray[0]; + assertEquals("key one", firstEntry.getKey()); + assertEquals("a1 b1 c1", firstEntry.getValue()); + + Entry lastEntry = theArray[THE_MAP.size() - 1]; + assertEquals("key four", lastEntry.getKey()); + assertEquals("a4 b4 c4", lastEntry.getValue()); + } + + @Test + void whenUsingStreamAPI_thenGetExpectedResult() { + Entry firstEntry = THE_MAP.entrySet().stream().findFirst().get(); + assertEquals("key one", firstEntry.getKey()); + assertEquals("a1 b1 c1", firstEntry.getValue()); + + Entry lastEntry = THE_MAP.entrySet().stream().skip(THE_MAP.size() - 1).findFirst().get(); + + assertNotNull(lastEntry); + assertEquals("key four", lastEntry.getKey()); + assertEquals("a4 b4 c4", lastEntry.getValue()); + } + + @Test + void whenUsingReflection_thenGetExpectedResult() throws NoSuchFieldException, IllegalAccessException { + Field head = THE_MAP.getClass().getDeclaredField("head"); + head.setAccessible(true); + Entry firstEntry = (Entry) head.get(THE_MAP); + assertEquals("key one", firstEntry.getKey()); + assertEquals("a1 b1 c1", firstEntry.getValue()); + + Field tail = THE_MAP.getClass().getDeclaredField("tail"); + tail.setAccessible(true); + Entry lastEntry = (Entry) tail.get(THE_MAP); + assertEquals("key four", lastEntry.getKey()); + assertEquals("a4 b4 c4", lastEntry.getValue()); + } + + +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/readandwritefile/ReadAndWriteFileWithHashMapUnitTest.java b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/readandwritefile/ReadAndWriteFileWithHashMapUnitTest.java new file mode 100644 index 0000000000..56867d3885 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/readandwritefile/ReadAndWriteFileWithHashMapUnitTest.java @@ -0,0 +1,135 @@ +package com.baeldung.map.readandwritefile; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.lang.reflect.Type; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import org.junit.After; +import org.junit.Test; +import org.junit.Before; + +public class ReadAndWriteFileWithHashMapUnitTest { + + private static final Map STUDENT_DATA = new HashMap<>(); + + static { + STUDENT_DATA.put(1234, new Student("Henry", "Winter")); + STUDENT_DATA.put(5678, new Student("Richard", "Papen")); + } + + private File file; + + @Before + public void createFile() throws IOException { + file = File.createTempFile("student", ".data"); + } + + @After + public void deleteFile() { + file.delete(); + } + + @Test + public void givenHashMap_whenWrittenAsPropertiesFile_thenReloadedMapIsIdentical() throws IOException { + // Given a map containing student data + Map studentData = new HashMap<>(); + studentData.put("student.firstName", "Henry"); + studentData.put("student.lastName", "Winter"); + + // When converting to a Properties object and writing to a file + Properties props = new Properties(); + props.putAll(studentData); + try (OutputStream output = Files.newOutputStream(file.toPath())) { + props.store(output, null); + } + + // Then the map resulting from loading the Properties file is identical + Properties propsFromFile = new Properties(); + try (InputStream input = Files.newInputStream(file.toPath())) { + propsFromFile.load(input); + } + + Map studentDataFromProps = propsFromFile.stringPropertyNames() + .stream() + .collect(Collectors.toMap(key -> key, props::getProperty)); + assertThat(studentDataFromProps).isEqualTo(studentData); + } + + @Test + public void givenHashMap_whenSerializedToFile_thenDeserializedMapIsIdentical() throws IOException, ClassNotFoundException { + // Given a map containing student data (STUDENT_DATA) + + // When serializing the map to a file + try (FileOutputStream fileOutput = new FileOutputStream(file); ObjectOutputStream objectStream = new ObjectOutputStream(fileOutput)) { + objectStream.writeObject(STUDENT_DATA); + } + + // Then read the file back into a map and check the contents + Map studentsFromFile; + try (FileInputStream fileReader = new FileInputStream(file); ObjectInputStream objectStream = new ObjectInputStream(fileReader)) { + studentsFromFile = (HashMap) objectStream.readObject(); + } + assertThat(studentsFromFile).isEqualTo(STUDENT_DATA); + } + + @Test + public void givenHashMap_whenSerializedToFileWithJackson_thenDeserializedMapIsIdentical() throws IOException { + // Given a map containing student data (STUDENT_DATA) + + // When converting to JSON with Jackson and writing to a file + ObjectMapper mapper = new ObjectMapper(); + try (FileOutputStream fileOutput = new FileOutputStream(file)) { + mapper.writeValue(fileOutput, STUDENT_DATA); + } + + // Then deserialize the file back into a map and check that it's identical + Map mapFromFile; + try (FileInputStream fileInput = new FileInputStream(file)) { + // Create a TypeReference so we can deserialize the parameterized type + TypeReference> mapType = new TypeReference>() { + }; + mapFromFile = mapper.readValue(fileInput, mapType); + } + assertThat(mapFromFile).isEqualTo(STUDENT_DATA); + } + + @Test + public void givenHashMap_whenSerializedToFileWithGson_thenDeserializedMapIsIdentical() throws IOException { + // Given a map containing student data (STUDENT_DATA) + + // When converting to JSON using Gson and writing to a file + Gson gson = new Gson(); + try (FileWriter writer = new FileWriter(file)) { + gson.toJson(STUDENT_DATA, writer); + } + + // Then deserialize the file back into a map and check that it's identical + Map studentsFromFile; + try (FileReader reader = new FileReader(file)) { + Type mapType = new TypeToken>() { + }.getType(); + studentsFromFile = gson.fromJson(reader, mapType); + } + assertThat(studentsFromFile).isEqualTo(STUDENT_DATA); + } +} diff --git a/core-java-modules/core-java-concurrency-advanced-5/src/test/java/com/baeldung/exceptions_completablefuture/CompletableFutureExceptionsHandlingUnitTest.java b/core-java-modules/core-java-concurrency-advanced-5/src/test/java/com/baeldung/exceptions_completablefuture/CompletableFutureExceptionsHandlingUnitTest.java new file mode 100644 index 0000000000..afb31f7617 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-5/src/test/java/com/baeldung/exceptions_completablefuture/CompletableFutureExceptionsHandlingUnitTest.java @@ -0,0 +1,126 @@ +package com.baeldung.exceptions_completablefuture; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.stream.Stream; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class CompletableFutureExceptionsHandlingUnitTest { + + @ParameterizedTest + @MethodSource("parametersSource_handle") + void whenCompletableFutureIsScheduled_thenHandleStageIsAlwaysInvoked(int radius, long expected) + throws ExecutionException, InterruptedException { + long actual = CompletableFuture + .supplyAsync(() -> { + if (radius <= 0) { + throw new IllegalArgumentException("Supplied with non-positive radius '%d'"); + } + return Math.round(Math.pow(radius, 2) * Math.PI); + }) + .handle((result, ex) -> { + if (ex == null) { + return result; + } else { + return -1L; + } + }) + .get(); + + Assertions.assertThat(actual).isEqualTo(expected); + } + + @ParameterizedTest + @MethodSource("parametersSource_exceptionally") + void whenCompletableFutureIsScheduled_thenExceptionallyExecutedOnlyOnFailure(int a, int b, int c, long expected) + throws ExecutionException, InterruptedException { + long actual = CompletableFuture + .supplyAsync(() -> { + if (a <= 0 || b <= 0 || c <= 0) { + throw new IllegalArgumentException(String.format("Supplied with incorrect edge length [%s]", List.of(a, b, c))); + } + return a * b * c; + }) + .exceptionally((ex) -> -1) + .get(); + + Assertions.assertThat(actual).isEqualTo(expected); + } + + @ParameterizedTest + @MethodSource("parametersSource_exceptionally") + void givenCompletableFutureIsScheduled_whenHandleIsAlreadyPresent_thenExceptionallyIsNotExecuted(int a, int b, int c, long expected) + throws ExecutionException, InterruptedException { + long actual = CompletableFuture + .supplyAsync(() -> { + if (a <= 0 || b <= 0 || c <= 0) { + throw new IllegalArgumentException(String.format("Supplied with incorrect edge length [%s]", List.of(a, b, c))); + } + return a * b * c; + }) + .handle((result, throwable) -> { + if (throwable != null) { + return -1; + } + return result; + }) + .exceptionally((ex) -> { + System.exit(1); + return 0; + }) + .get(); + + Assertions.assertThat(actual).isEqualTo(expected); + } + + @ParameterizedTest + @MethodSource("parametersSource_whenComplete") + void whenCompletableFutureIsScheduled_thenWhenCompletedExecutedAlways(Double a, long expected, Class ifAny) { + try { + CountDownLatch countDownLatch = new CountDownLatch(1); + + long actual = CompletableFuture + .supplyAsync(() -> { + if (a.isNaN()) { + throw new IllegalArgumentException("Supplied value is NaN"); + } + return Math.round(Math.pow(a, 2)); + }) + .whenComplete((result, exception) -> countDownLatch.countDown()) + .get(); + + Assertions.assertThat(countDownLatch.await(20L, java.util.concurrent.TimeUnit.SECONDS)); + Assertions.assertThat(actual).isEqualTo(expected); + } catch (Exception e) { + Assertions.assertThat(e.getClass()).isSameAs(ExecutionException.class); + Assertions.assertThat(e.getCause().getClass()).isSameAs(ifAny); + } + } + + static Stream parametersSource_handle() { + return Stream.of( + Arguments.of(1, 3), + Arguments.of(-1, -1) + ); + } + + static Stream parametersSource_exceptionally() { + return Stream.of( + Arguments.of(1, 5, 5, 25), + Arguments.of(-1, 10, 15, -1) + ); + } + + static Stream parametersSource_whenComplete() { + return Stream.of( + Arguments.of(2d, 4, null), + Arguments.of(Double.NaN, 1, IllegalArgumentException.class) + ); + } +} 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 179a69495c..09d085a32b 100644 --- a/core-java-modules/core-java-concurrency-basic-3/README.md +++ b/core-java-modules/core-java-concurrency-basic-3/README.md @@ -11,4 +11,5 @@ This module contains articles about basic Java concurrency. - [CompletableFuture and ThreadPool in Java](https://www.baeldung.com/java-completablefuture-threadpool) - [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) - [[<-- Prev]](../core-java-concurrency-basic-2) diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java new file mode 100644 index 0000000000..bb7c1c6b4c --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java @@ -0,0 +1,30 @@ +package com.baeldung.concurrent.synchronizestatic.atomicinteger; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Synchronizing static variable with AtomicInteger. + */ +public class Employee { + + private static final AtomicInteger count = new AtomicInteger(0); + + int id; + String name; + String title; + + public Employee(int id, String name, String title) { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static void incrementCount() { + count.incrementAndGet(); + } + + public static int getCount() { + return count.get(); + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/none/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/none/Employee.java new file mode 100644 index 0000000000..ba722e15e9 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/none/Employee.java @@ -0,0 +1,27 @@ +package com.baeldung.concurrent.synchronizestatic.none; + +/** + * No synchronization. + */ +public class Employee { + + static int count; + int id; + String name; + String title; + + public Employee(int id, String name, String title) { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static void incrementCount() { + System.out.println("Count = " + ++count); + } + + public static Integer getCount() { + return count; + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/reentrantlock/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/reentrantlock/Employee.java new file mode 100644 index 0000000000..e74013ad0e --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/reentrantlock/Employee.java @@ -0,0 +1,43 @@ +package com.baeldung.concurrent.synchronizestatic.reentrantlock; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * Synchronizing static variable with a Reenatrant Lock. + */ +public class Employee { + + private static final ReentrantLock lock = new ReentrantLock(); + + static int count; + int id; + String name; + String title; + + public Employee(int id, String name, String title) { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static void incrementCount() { + lock.lock(); + try { + System.out.println("Count = " + ++count); + } + finally { + lock.unlock(); + } + } + + public static int getCount() { + lock.lock(); + try { + return count; + } + finally { + lock.unlock(); + } + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedblock/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedblock/Employee.java new file mode 100644 index 0000000000..4cf04e5b06 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedblock/Employee.java @@ -0,0 +1,33 @@ +package com.baeldung.concurrent.synchronizestatic.synchronizedblock; + +/** + * Synchronizing static variable with a synchronized block. + */ +public class Employee { + + private static final Object lock = new Object(); + + static int count; + int id; + String name; + String title; + + public Employee(int id, String name, String title) { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static void incrementCount() { + synchronized(lock) { + System.out.println("Count = " + ++count); + } + } + + public static int getCount() { + synchronized(lock) { + return count; + } + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedclass/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedclass/Employee.java new file mode 100644 index 0000000000..627040e88c --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedclass/Employee.java @@ -0,0 +1,31 @@ +package com.baeldung.concurrent.synchronizestatic.synchronizedclass; + +/** + * Synchronizing static variable with a synchronized block. + */ +public class Employee +{ + static int count; + int id; + String name; + String title; + + public Employee(int id, String name, String title) { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static void incrementCount() { + synchronized(Employee.class) { + System.out.println("Count = " + ++count); + } + } + + public static int getCount() { + synchronized(Employee.class) { + return count; + } + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedmethod/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedmethod/Employee.java new file mode 100644 index 0000000000..f0a785c427 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedmethod/Employee.java @@ -0,0 +1,27 @@ +package com.baeldung.concurrent.synchronizestatic.synchronizedmethod; + +/** + * Synchronizing static variable with a synchronized method. + */ +public class Employee { + static int count; + int id; + String name; + String title; + + public Employee(int id, String name, String title) + { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static synchronized void incrementCount() { + System.out.println("Count = " + ++count); + } + + public static synchronized int getCount() { + return count; + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java new file mode 100644 index 0000000000..b4e03673a1 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java @@ -0,0 +1,90 @@ +package com.baeldung.concurrent.synchronizestatic; + +import org.junit.Test; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +/** + * The tests in this class show the output of creating multiple + * types of Employee classes in the synchronizedstatic + * package. When not synchronized the out will not be sequential; + * when it is synchronized the output will be in sequential. + */ +public class SychronizeStaticDataUnitTest { + private final Executor pool = Executors.newFixedThreadPool(4); + + private final int numberToTest = 100; + + @Test + public void whenNotSynchronized_thenDataOutOfOrder() { + + System.out.println("No synchronization"); + + for(int i = 0; i < numberToTest; i++) { + int finalI = i; + pool.execute(() -> { + new com.baeldung.concurrent.synchronizestatic.none.Employee(finalI, "John", "Smith"); + }); + } + } + + @Test + public void whenSynchronizedMethod_thenDataInOrder() { + + System.out.println("Synchronization with synchronized method"); + + for(int i = 0; i < numberToTest; i++) { + int finalI = i; + pool.execute(() -> { + new com.baeldung.concurrent.synchronizestatic.synchronizedmethod.Employee(finalI, "John", "Smith"); + }); + } + } + + @Test + public void whenSynchronizedClass_thenDataInOrder() { + + System.out.println("Synchronization with synchronized block on class"); + + for(int i = 0; i < numberToTest; i++) { + int finalI = i; + pool.execute(() -> { + new com.baeldung.concurrent.synchronizestatic.synchronizedclass.Employee(finalI, "John", "Smith"); + }); + } + } + + @Test + public void whenSynchronizedBlock_thenDataInOrder() { + + System.out.println("Synchronization with synchronized block on a private object"); + + for(int i = 0; i < numberToTest; i++) { + int finalI = i; + pool.execute(() -> { + new com.baeldung.concurrent.synchronizestatic.synchronizedblock.Employee(finalI, "John", "Smith"); + }); + } + } + + @Test + public void whenAtomicInteger_thenDataInOrder() { + // Not straight forward to test this because we cannot log/print + // and increment values in a synchronized fashion like other + // tests + } + + @Test + public void whenReentrantLock_thenDataInOrder() { + + System.out.println("Synchronization with ReentrantLock"); + + for(int i = 0; i < numberToTest; i++) { + int finalI = i; + pool.execute(() -> { + new com.baeldung.concurrent.synchronizestatic.reentrantlock.Employee(finalI, "John", "Smith"); + }); + } + } +} diff --git a/core-java-modules/core-java-concurrency-simple/pom.xml b/core-java-modules/core-java-concurrency-simple/pom.xml index a16df4fc97..720ab5a0ed 100644 --- a/core-java-modules/core-java-concurrency-simple/pom.xml +++ b/core-java-modules/core-java-concurrency-simple/pom.xml @@ -12,6 +12,15 @@ 0.0.1-SNAPSHOT + + + org.wiremock + wiremock + 3.1.0 + test + + + core-java-concurrency-simple diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java new file mode 100644 index 0000000000..d04865026b --- /dev/null +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -0,0 +1,182 @@ +package com.baeldung.concurrent.completablefuture; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.client.WireMock; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.concurrent.*; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class CompletableFutureTimeoutUnitTest { + private WireMockServer wireMockServer; + private ScheduledExecutorService executorService; + private static final int DEFAULT_TIMEOUT = 1000; //1 seconds + private static final String DEFAULT_PRODUCT = """ + { + "products": [ + { + "id": 2, + "title": "iPhone X", + "description": "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...", + "price": 899, + "discountPercentage": 0.0, + "rating": 4.44, + "stock": 34, + "brand": "Apple", + "category": "smartphones" + }, + { + "id": 3, + "title": "Samsung Universe 9", + "description": "Samsung's new variant which goes beyond Galaxy to the Universe", + "price": 1249, + "discountPercentage": 0.0, + "rating": 4.09, + "stock": 36, + "brand": "Samsung", + "category": "smartphones" + } + ], + "total": 2 + }"""; + private static final String PRODUCT_OFFERS = """ + { + "products": [ + { + "id": 1, + "title": "iPhone 9", + "description": "An apple mobile which is nothing like apple", + "price": 549, + "discountPercentage": 12.96, + "rating": 4.69, + "stock": 94, + "brand": "Apple", + "category": "smartphones" + }, + { + "id": 2, + "title": "iPhone X", + "description": "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...", + "price": 899, + "discountPercentage": 17.94, + "rating": 4.44, + "stock": 34, + "brand": "Apple", + "category": "smartphones" + }, + { + "id": 3, + "title": "Samsung Universe 9", + "description": "Samsung's new variant which goes beyond Galaxy to the Universe", + "price": 1249, + "discountPercentage": 15.46, + "rating": 4.09, + "stock": 36, + "brand": "Samsung", + "category": "smartphones" + }, + { + "id": 4, + "title": "OPPOF19", + "description": "OPPO F19 is officially announced on April 2021.", + "price": 280, + "discountPercentage": 17.91, + "rating": 4.3, + "stock": 123, + "brand": "OPPO", + "category": "smartphones" + }, + { + "id": 5, + "title": "Huawei P30", + "description": "Huawei’s re-badged P30 Pro New Edition was officially unveiled yesterday in Germany and now the device has made its way to the UK.", + "price": 499, + "discountPercentage": 10.58, + "rating": 4.09, + "stock": 32, + "brand": "Huawei", + "category": "smartphones" + } + ], + "total": 5 + }"""; + + @BeforeAll + void setUp() { + wireMockServer = new WireMockServer(8080); + wireMockServer.start(); + WireMock.configureFor("localhost", 8080); + + stubFor(get(urlEqualTo("/api/dummy")) + .willReturn(aResponse() + .withFixedDelay(5000) // must be > DEFAULT_TIMEOUT for a timeout to occur. + .withBody(PRODUCT_OFFERS))); + + executorService = Executors.newScheduledThreadPool(1); + } + + @AfterAll + void tearDown() { + executorService.shutdown(); + wireMockServer.stop(); + } + + private CompletableFuture fetchProductData() { + return CompletableFuture.supplyAsync(() -> { + try { + URL url = new URL("http://localhost:8080/api/dummy"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + + try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + String inputLine; + StringBuffer response = new StringBuffer(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + + return response.toString(); + } finally { + connection.disconnect(); + } + } catch (IOException e) { + return ""; + } + }); + } + + + @Test + void whenorTimeout_thenGetThrow() { + CompletableFuture productDataFuture = fetchProductData(); + productDataFuture.orTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); + assertThrows(ExecutionException.class, productDataFuture::get); + } + + @Test + void whencompleteOnTimeout_thenReturnValue() throws ExecutionException, InterruptedException { + CompletableFuture productDataFuture = fetchProductData(); + productDataFuture.completeOnTimeout(DEFAULT_PRODUCT, DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); + assertEquals(DEFAULT_PRODUCT, productDataFuture.get()); + } + + @Test + void whencompleteExceptionally_thenGetThrow() { + CompletableFuture productDataFuture = fetchProductData(); + executorService.schedule(() -> productDataFuture + .completeExceptionally(new TimeoutException("Timeout occurred")), DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); + assertThrows(ExecutionException.class, productDataFuture::get); + } +} diff --git a/core-java-modules/core-java-conditionals/pom.xml b/core-java-modules/core-java-conditionals/pom.xml index 811f183e99..f2ad7df749 100644 --- a/core-java-modules/core-java-conditionals/pom.xml +++ b/core-java-modules/core-java-conditionals/pom.xml @@ -5,7 +5,7 @@ 4.0.0 core-java-conditionals 0.1.0-SNAPSHOT - core-java-compiler + core-java-conditionals jar diff --git a/core-java-modules/core-java-console/pom.xml b/core-java-modules/core-java-console/pom.xml index 1b56f1f27c..8677b672ea 100644 --- a/core-java-modules/core-java-console/pom.xml +++ b/core-java-modules/core-java-console/pom.xml @@ -29,6 +29,11 @@ + + de.vandermeer + asciitable + ${ascii.version} + @@ -157,6 +162,7 @@ 3.0.0-M1 1.8 1.8 + 0.3.2 \ No newline at end of file diff --git a/core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndex.java b/core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndex.java new file mode 100644 index 0000000000..96cede7020 --- /dev/null +++ b/core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndex.java @@ -0,0 +1,44 @@ +package com.baeldung.consoletableoutput; + +public class BodyMassIndex { + + private String name; + private double height; + private double weight; + + public BodyMassIndex(String name, double height, double weight) { + this.name = name; + this.height = height; + this.weight = weight; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getHeight() { + return height; + } + + public void setHeight(double height) { + this.height = height; + } + + public double getWeight() { + return weight; + } + + public void setWeight(double weight) { + this.weight = weight; + } + + public double calculate() { + double bmi = weight / (height * height); + String formattedBmi = String.format("%.2f", bmi); + return Double.parseDouble(formattedBmi); + } +} diff --git a/core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndexApplication.java b/core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndexApplication.java new file mode 100644 index 0000000000..cb340256aa --- /dev/null +++ b/core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndexApplication.java @@ -0,0 +1,62 @@ +package com.baeldung.consoletableoutput; + +import java.util.ArrayList; +import java.util.List; + +import de.vandermeer.asciitable.AsciiTable; +import de.vandermeer.skb.interfaces.transformers.textformat.TextAlignment; + +public class BodyMassIndexApplication { + + public static void main(String[] args) { + stringFormat(); + asciiTable(); + + } + + public static void stringFormat() { + List bodyMassIndices = new ArrayList<>(); + bodyMassIndices.add(new BodyMassIndex("Tom", 1.8, 80)); + bodyMassIndices.add(new BodyMassIndex("Elton", 1.9, 90)); + bodyMassIndices.add(new BodyMassIndex("Harry", 1.9, 90)); + bodyMassIndices.add(new BodyMassIndex("Hannah", 1.9, 90)); + + String leftAlignment = "| %-7s | %-7.2f | %-7.2f | %-5.2f |%n"; + + System.out.format("+---------+---------+---------+-------+%n"); + System.out.format("| Name | Height | Weight | BMI |%n"); + System.out.format("+---------+---------+---------+-------+%n"); + + for (BodyMassIndex bodyMassIndex : bodyMassIndices) { + System.out.format(leftAlignment, bodyMassIndex.getName(), bodyMassIndex.getHeight(), bodyMassIndex.getWeight(), bodyMassIndex.calculate()); + System.out.format("+---------+---------+---------+-------+%n"); + } + + } + + public static void asciiTable() { + List bodyMassIndices = new ArrayList<>(); + bodyMassIndices.add(new BodyMassIndex("Tom", 1.8, 80)); + bodyMassIndices.add(new BodyMassIndex("Elton", 1.9, 90)); + bodyMassIndices.add(new BodyMassIndex("Harry", 1.9, 90)); + bodyMassIndices.add(new BodyMassIndex("Hannah", 1.9, 90)); + + AsciiTable asciiTable = new AsciiTable(); + asciiTable.addRule(); + asciiTable.addRow("Name", "Height", "Weight", "BMI"); + asciiTable.addRule(); + + for (BodyMassIndex bodyMassIndex : bodyMassIndices) { + + asciiTable.addRow(bodyMassIndex.getName(), bodyMassIndex.getHeight(), bodyMassIndex.getWeight(), bodyMassIndex.calculate()); + asciiTable.addRule(); + + } + + asciiTable.setTextAlignment(TextAlignment.CENTER); + String render = asciiTable.render(); + System.out.println(render); + + } + +} diff --git a/core-java-modules/core-java-date-operations-1/pom.xml b/core-java-modules/core-java-date-operations-1/pom.xml index 5bfbb5bab0..3d7335c86e 100644 --- a/core-java-modules/core-java-date-operations-1/pom.xml +++ b/core-java-modules/core-java-date-operations-1/pom.xml @@ -54,7 +54,7 @@ - 2.10 + 2.12.5 RELEASE 1.9 1.9 diff --git a/core-java-modules/core-java-date-operations-2/pom.xml b/core-java-modules/core-java-date-operations-2/pom.xml index c6a22a4166..86fbbf614e 100644 --- a/core-java-modules/core-java-date-operations-2/pom.xml +++ b/core-java-modules/core-java-date-operations-2/pom.xml @@ -47,7 +47,7 @@ - 2.10 + 2.12.5 1.5.1 3.2.7.Final 5.9 diff --git a/core-java-modules/core-java-date-operations-3/README.md b/core-java-modules/core-java-date-operations-3/README.md index 9d16d1f71c..d8c321deab 100644 --- a/core-java-modules/core-java-date-operations-3/README.md +++ b/core-java-modules/core-java-date-operations-3/README.md @@ -11,4 +11,6 @@ This module contains articles about date operations in Java. - [Getting Yesterday’s Date in Java](https://www.baeldung.com/java-find-yesterdays-date) - [How to Get the Start and End Dates of a Year Using Java](https://www.baeldung.com/java-date-year-start-end) - [Convert Between Java LocalDate and Epoch](https://www.baeldung.com/java-localdate-epoch) +- [Get First Date of Current Month in Java](https://www.baeldung.com/java-current-month-start-date) +- [Time Conversions Using TimeUnit](https://www.baeldung.com/java-timeunit-conversion) - [[<-- Prev]](/core-java-modules/core-java-date-operations-2) diff --git a/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/firstdaymonth/FirstDayOfMonthUnitTest.java b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/firstdaymonth/FirstDayOfMonthUnitTest.java new file mode 100644 index 0000000000..9edc3e4a8d --- /dev/null +++ b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/firstdaymonth/FirstDayOfMonthUnitTest.java @@ -0,0 +1,61 @@ +package com.baeldung.firstdaymonth; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.time.LocalDate; +import java.time.YearMonth; +import java.time.temporal.TemporalAdjusters; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import org.junit.jupiter.api.Test; + +public class FirstDayOfMonthUnitTest { + + @Test + void givenMonth_whenUsingCalendar_thenReturnFirstDay() { + Date currentDate = new GregorianCalendar(2023, Calendar.NOVEMBER, 23).getTime(); + Date expectedDate = new GregorianCalendar(2023, Calendar.NOVEMBER, 1).getTime(); + + Calendar cal = Calendar.getInstance(); + cal.setTime(currentDate); + cal.set(Calendar.DAY_OF_MONTH, 1); + + assertEquals(expectedDate, cal.getTime()); + } + + @Test + void givenMonth_whenUsingLocalDate_thenReturnFirstDay() { + LocalDate currentDate = LocalDate.of(2023, 9, 6); + LocalDate expectedDate = LocalDate.of(2023, 9, 1); + + assertEquals(expectedDate, currentDate.withDayOfMonth(1)); + } + + @Test + void givenMonth_whenUsingTemporalAdjusters_thenReturnFirstDay() { + LocalDate currentDate = LocalDate.of(2023, 7, 19); + LocalDate expectedDate = LocalDate.of(2023, 7, 1); + + assertEquals(expectedDate, currentDate.with(TemporalAdjusters.firstDayOfMonth())); + } + + @Test + void givenMonth_whenUsingYearMonth_thenReturnFirstDay() { + YearMonth currentDate = YearMonth.of(2023, 4); + LocalDate expectedDate = LocalDate.of(2023, 4, 1); + + assertEquals(expectedDate, currentDate.atDay(1)); + } + + @Test + void givenMonth_whenUsingJodaTime_thenReturnFirstDay() { + org.joda.time.LocalDate currentDate = org.joda.time.LocalDate.parse("2023-5-10"); + org.joda.time.LocalDate expectedDate = org.joda.time.LocalDate.parse("2023-5-1"); + + assertEquals(expectedDate, currentDate.dayOfMonth() + .withMinimumValue()); + } + +} diff --git a/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/timeunitconversions/TimeUnitConversionsUnitTest.java b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/timeunitconversions/TimeUnitConversionsUnitTest.java new file mode 100644 index 0000000000..cbcbcd566b --- /dev/null +++ b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/timeunitconversions/TimeUnitConversionsUnitTest.java @@ -0,0 +1,105 @@ +package com.baeldung.timeunitconversions; + +import org.junit.jupiter.api.Test; + +import java.util.concurrent.TimeUnit; + +import static org.assertj.core.api.Assertions.assertThat; + +class TimeUnitConversionsUnitTest { + + + @Test + void givenSeconds_whenConvertToMinutes_thenCorrect() { + int input = 60; + + long minutes = TimeUnit.MINUTES.convert(input, TimeUnit.SECONDS); + + assertThat(minutes).isEqualTo(1); + } + + @Test + void givenMinutes_whenConvertToSeconds_thenCorrect() { + int input = 1; + + long seconds = TimeUnit.SECONDS.convert(input, TimeUnit.MINUTES); + + assertThat(seconds).isEqualTo(60); + } + + @Test + void givenSeconds_whenToMinutes_thenCorrect() { + int input = 60; + + long minutes = TimeUnit.SECONDS.toMinutes(input); + + assertThat(minutes).isEqualTo(1); + } + + @Test + void givenMinutes_whenToSeconds_thenCorrect() { + int input = 1; + + long seconds = TimeUnit.MINUTES.toSeconds(input); + + assertThat(seconds).isEqualTo(60); + } + + @Test + void givenNegativeInput_whenToMinutes_thenCorrect() { + int input = -60; + + long minutes = TimeUnit.SECONDS.toMinutes(input); + assertThat(minutes).isEqualTo(-1); + } + + @Test + void givenNonTotalInput_whenToMinutes_thenCorrectTotalResultWithDecimalTruncate() { + long positiveUnder = TimeUnit.SECONDS.toMinutes(59); + long positiveAbove = TimeUnit.SECONDS.toMinutes(61); + + assertThat(positiveUnder).isEqualTo(0); + assertThat(positiveAbove).isEqualTo(1); + } + + @Test + void givenNonTotalNegativeInput_whenToMinutes_thenCorrectTotalResultWithDecimalTruncate() { + long negativeUnder = TimeUnit.SECONDS.toMinutes(-59); + long negativeAbove = TimeUnit.SECONDS.toMinutes(-61); + + assertThat(negativeUnder).isEqualTo(0); + assertThat(negativeAbove).isEqualTo(-1); + } + + @Test + void givenOverflowInput_whenToMillis_thenTruncatedToLimit() { + long maxMillis = TimeUnit.DAYS.toMillis(Long.MAX_VALUE); + long minMillis = TimeUnit.DAYS.toMillis(Long.MIN_VALUE); + + assertThat(maxMillis).isEqualTo(Long.MAX_VALUE); + assertThat(minMillis).isEqualTo(Long.MIN_VALUE); + } + + @Test + void givenInput_whenExtractFineTimeUnits_thenCorrect() { + long inputSeconds = 3672; + + long hours = TimeUnit.SECONDS.toHours(inputSeconds); + + long secondsRemainingAfterHours = inputSeconds - TimeUnit.HOURS.toSeconds(hours); + long minutes = TimeUnit.SECONDS.toMinutes(secondsRemainingAfterHours); + + long seconds = secondsRemainingAfterHours - TimeUnit.MINUTES.toSeconds(minutes); + + + assertThat(hours).isEqualTo(1); + assertThat(minutes).isEqualTo(1); + assertThat(seconds).isEqualTo(12); + + assertThat(inputSeconds).isEqualTo( + (hours * 60 * 60) + + (minutes * 60) + + (seconds) + ); + } +} diff --git a/core-java-modules/core-java-datetime-conversion/pom.xml b/core-java-modules/core-java-datetime-conversion/pom.xml index 3ff26323df..8e148edaad 100644 --- a/core-java-modules/core-java-datetime-conversion/pom.xml +++ b/core-java-modules/core-java-datetime-conversion/pom.xml @@ -54,7 +54,7 @@ - 2.10 + 2.12.5 1.9 1.9 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 new file mode 100644 index 0000000000..2ebe30f4ff --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java @@ -0,0 +1,32 @@ +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.util.Date; + +public class TimestampToLong { + public void usingSimpleDateFormat() 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(); + } + + public void usingInstantClass() { + Instant instant = Instant.now(); + long actualTimestamp = instant.toEpochMilli(); + } + + public void usingTimestamp() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + long actualTimestamp = timestamp.getTime(); + } + + 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/timestamptolong/TimestampToLongUnitTest.java b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java new file mode 100644 index 0000000000..ede8f7792d --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java @@ -0,0 +1,52 @@ +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.util.Date; + +import static org.junit.Assert.assertTrue; + +public class TimestampToLongUnitTest { + + private static final long TOLERANCE = 1000; + + @Test + public void givenSimpleDateFormat_whenFormattingDate_thenTConvertToLong() throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + String currentDateString = sdf.format(new Date()); + long actualTimestamp = sdf.parse(currentDateString).getTime(); + + assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + } + + @Test + public void givenInstantClass_whenGettingTimestamp_thenTConvertToLong() { + Instant instant = Instant.now(); + long actualTimestamp = instant.toEpochMilli(); + + assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + } + + @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(); + long actualTimestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + + assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + } +} diff --git a/core-java-modules/core-java-datetime-string/pom.xml b/core-java-modules/core-java-datetime-string/pom.xml index a33114852c..292a38a5af 100644 --- a/core-java-modules/core-java-datetime-string/pom.xml +++ b/core-java-modules/core-java-datetime-string/pom.xml @@ -64,7 +64,7 @@ - 1.6 + 1.7 2.12.5 RELEASE 1.9 diff --git a/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/formatinstant/FormatInstantUnitTest.java b/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/formatinstant/FormatInstantUnitTest.java index ef273e4b81..1466fece46 100644 --- a/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/formatinstant/FormatInstantUnitTest.java +++ b/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/formatinstant/FormatInstantUnitTest.java @@ -6,6 +6,7 @@ import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.temporal.UnsupportedTemporalTypeException; +import java.util.TimeZone; import org.joda.time.format.DateTimeFormat; import org.junit.Test; @@ -17,7 +18,7 @@ public class FormatInstantUnitTest { @Test public void givenInstant_whenUsingDateTimeFormatter_thenFormat() { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN_FORMAT) - .withZone(ZoneId.systemDefault()); + .withZone(TimeZone.getTimeZone("UTC").toZoneId()); Instant instant = Instant.parse("2022-02-15T18:35:24.00Z"); String formattedInstant = formatter.format(instant); diff --git a/core-java-modules/core-java-documentation/README.md b/core-java-modules/core-java-documentation/README.md index 972e76c165..9fa48dc09e 100644 --- a/core-java-modules/core-java-documentation/README.md +++ b/core-java-modules/core-java-documentation/README.md @@ -4,3 +4,4 @@ - [Introduction to Javadoc](http://www.baeldung.com/javadoc) - [Code Snippets in Java API Documentation](https://www.baeldung.com/java-doc-code-snippets) +- [How to Document Generic Type Parameters in Javadoc](https://www.baeldung.com/java-javadoc-generic-type-parameters) diff --git a/core-java-modules/core-java-documentation/src/main/java/com/baeldung/generictype/Pair.java b/core-java-modules/core-java-documentation/src/main/java/com/baeldung/generictype/Pair.java new file mode 100644 index 0000000000..f85adcfdab --- /dev/null +++ b/core-java-modules/core-java-documentation/src/main/java/com/baeldung/generictype/Pair.java @@ -0,0 +1,23 @@ +package com.baeldung.generictype; + +/** + * @param The type of the first value in the {@code Pair}. + * @param The type of the second value in the {@code Pair}. + */ + +public class Pair { + public T first; + public S second; + + /** + * Constructs a new Pair object with the specified values. + * + * @param a The first value. + * @param b The second value. + */ + + public Pair(T a, S b) { + first = a; + second = b; + } +} diff --git a/core-java-modules/core-java-hex/test/java/com/baeldung/hextoint/HexToIntConversionUnitTest.java b/core-java-modules/core-java-hex/test/java/com/baeldung/hextoint/HexToIntConversionUnitTest.java new file mode 100644 index 0000000000..c236f0a818 --- /dev/null +++ b/core-java-modules/core-java-hex/test/java/com/baeldung/hextoint/HexToIntConversionUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.hextoint; + +import org.junit.Test; + +import java.math.BigInteger; + +import static org.junit.Assert.assertEquals; + +public class HexToIntConversionUnitTest { + + @Test + public void givenValidHexString_whenUsingParseInt_thenExpectCorrectDecimalValue() { + String hexString = "0x00FF00"; + int expectedDecimalValue = 65280; + + int decimalValue = Integer.parseInt(hexString.substring(2), 16); + + assertEquals(expectedDecimalValue, decimalValue); + } + + @Test + public void givenValidHexString_whenUsingIntegerDecode_thenExpectCorrectDecimalValue() { + String hexString = "0x00FF00"; + int expectedDecimalValue = 65280; + + int decimalValue = Integer.decode(hexString); + + assertEquals(expectedDecimalValue, decimalValue); + } + + @Test + public void givenValidHexString_whenUsingBigInteger_thenExpectCorrectDecimalValue() { + String hexString = "0x00FF00"; + int expectedDecimalValue = 65280; + + BigInteger bigIntegerValue = new BigInteger(hexString.substring(2), 16); + int decimalValue = bigIntegerValue.intValue(); + assertEquals(expectedDecimalValue, decimalValue); + } + + +} diff --git a/core-java-modules/core-java-io-5/README.md b/core-java-modules/core-java-io-5/README.md index 3cc514e087..4578cf3777 100644 --- a/core-java-modules/core-java-io-5/README.md +++ b/core-java-modules/core-java-io-5/README.md @@ -5,5 +5,6 @@ This module contains articles about core Java input and output (IO) ### Relevant Articles: - [Get File Extension From MIME Type in Java](https://www.baeldung.com/java-mime-type-file-extension) - [How to Remove Line Breaks From a File in Java](https://www.baeldung.com/java-file-remove-line-breaks) +- [Difference Between ZipFile and ZipInputStream in Java](https://www.baeldung.com/java-zipfile-vs-zipinputstream) - [[<-- Prev]](/core-java-modules/core-java-io-4) diff --git a/core-java-modules/core-java-io-apis-2/README.md b/core-java-modules/core-java-io-apis-2/README.md index 3ec3220424..043e0c1ee3 100644 --- a/core-java-modules/core-java-io-apis-2/README.md +++ b/core-java-modules/core-java-io-apis-2/README.md @@ -8,3 +8,4 @@ This module contains articles about core Java input/output(IO) APIs. - [Check if a File Is Empty in Java](https://www.baeldung.com/java-check-file-empty) - [Converting Relative to Absolute Paths in Java](https://www.baeldung.com/java-from-relative-to-absolute-paths) - [Detect EOF in Java](https://www.baeldung.com/java-file-detect-end-of-file) +- [PrintWriter vs. FileWriter in Java](https://www.baeldung.com/java-printwriter-filewriter-difference) diff --git a/core-java-modules/core-java-io-conversions-2/pom.xml b/core-java-modules/core-java-io-conversions-2/pom.xml index 2c49bbfd81..9be165eaff 100644 --- a/core-java-modules/core-java-io-conversions-2/pom.xml +++ b/core-java-modules/core-java-io-conversions-2/pom.xml @@ -56,7 +56,7 @@ 11 11 20200518 - 4.1 + 5.8 \ No newline at end of file diff --git a/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/filetofrombytearray/FileToByteArrayUnitTest.java b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/filetofrombytearray/FileToByteArrayUnitTest.java new file mode 100644 index 0000000000..1bbd958583 --- /dev/null +++ b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/filetofrombytearray/FileToByteArrayUnitTest.java @@ -0,0 +1,63 @@ +package com.baeldung.filetofrombytearray; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; + +class FileToByteArrayUnitTest { + + private static final String FILE_NAME = "src" + File.separator + "test" + File.separator + "resources" + File.separator + "sample.txt"; + private final byte[] expectedByteArray = { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 }; + + @Test + void givenFile_whenUsingFileInputStreamClass_thenConvert() throws IOException { + File myFile = new File(FILE_NAME); + byte[] byteArray = new byte[(int) myFile.length()]; + try (FileInputStream inputStream = new FileInputStream(myFile)) { + inputStream.read(byteArray); + } + + assertArrayEquals(expectedByteArray, byteArray); + } + + @Test + void givenFile_whenUsingNioApiFilesClass_thenConvert() throws IOException { + byte[] byteArray = Files.readAllBytes(Paths.get(FILE_NAME)); + + assertArrayEquals(expectedByteArray, byteArray); + } + + @Test + void givenFile_whenUsingApacheCommonsIOUtilsClass_thenConvert() throws IOException { + File myFile = new File(FILE_NAME); + byte[] byteArray = new byte[(int) myFile.length()]; + try (FileInputStream inputStream = new FileInputStream(myFile)) { + byteArray = IOUtils.toByteArray(inputStream); + } + + assertArrayEquals(expectedByteArray, byteArray); + } + + @Test + void givenFile_whenUsingApacheCommonsFileUtilsClass_thenConvert() throws IOException { + byte[] byteArray = FileUtils.readFileToByteArray(new File(FILE_NAME)); + + assertArrayEquals(expectedByteArray, byteArray); + } + + @Test + void givenFile_whenUsingGuavaFilesClass_thenConvert() throws IOException { + byte[] byteArray = com.google.common.io.Files.toByteArray(new File(FILE_NAME)); + + assertArrayEquals(expectedByteArray, byteArray); + } + +} diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/size/FileSizeUtils.java b/core-java-modules/core-java-io/src/main/java/com/baeldung/size/FileSizeUtils.java new file mode 100644 index 0000000000..18c8687043 --- /dev/null +++ b/core-java-modules/core-java-io/src/main/java/com/baeldung/size/FileSizeUtils.java @@ -0,0 +1,28 @@ +package com.baeldung.size; + +import java.io.File; + +public class FileSizeUtils { + public static long getFileSizeInBytes(File file) { + if (file.exists()) { + return file.length(); + } else { + throw new IllegalArgumentException("File not found."); + } + } + + public static double getFileSizeInKilobytes(File file) { + long bytes = getFileSizeInBytes(file); + return (double) bytes / 1024; + } + + public static double getFileSizeInMegabytes(File file) { + double kilobytes = getFileSizeInKilobytes(file); + return kilobytes / 1024; + } + + public static double getFileSizeInGigabytes(File file) { + double megabytes = getFileSizeInMegabytes(file); + return megabytes / 1024; + } +} diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/size/JavaFileSizeUnitTest.java b/core-java-modules/core-java-io/src/test/java/com/baeldung/size/JavaFileSizeUnitTest.java index d015f2602e..d8f4361260 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/size/JavaFileSizeUnitTest.java +++ b/core-java-modules/core-java-io/src/test/java/com/baeldung/size/JavaFileSizeUnitTest.java @@ -1,6 +1,8 @@ package com.baeldung.size; -import static org.junit.Assert.assertEquals; +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.Test; import java.io.File; import java.io.FileInputStream; @@ -10,9 +12,9 @@ import java.net.URL; import java.nio.channels.FileChannel; import java.nio.file.Path; import java.nio.file.Paths; -import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; public class JavaFileSizeUnitTest { private static final long EXPECTED_FILE_SIZE_IN_BYTES = 11; @@ -85,4 +87,23 @@ public class JavaFileSizeUnitTest { assertEquals(EXPECTED_FILE_SIZE_IN_BYTES, stream.available()); } } -} \ No newline at end of file + + @Test + public void whenGetFileSizeInDifferentUnits_thenCorrect(){ + filePath = String.join(File.separator, new String[] { "src", "test", "resources", "size", "sample_file_1.in" }); + File file = new File(filePath); + if (file.exists()) { + long expectedBytes = file.length(); + double expectedKilobytes = (double) expectedBytes / 1024; + double expectedMegabytes = expectedKilobytes / 1024; + double expectedGigabytes = expectedMegabytes / 1024; + + assertEquals(expectedBytes, FileSizeUtils.getFileSizeInBytes(file)); + assertEquals(expectedKilobytes, FileSizeUtils.getFileSizeInKilobytes(file), 0.01); + assertEquals(expectedMegabytes, FileSizeUtils.getFileSizeInMegabytes(file), 0.01); + assertEquals(expectedGigabytes, FileSizeUtils.getFileSizeInGigabytes(file), 0.01); + } else { + fail("File not found."); + } + } +} diff --git a/core-java-modules/core-java-jndi/README.md b/core-java-modules/core-java-jndi/README.md index 9c6f489841..cdb1b34ca9 100644 --- a/core-java-modules/core-java-jndi/README.md +++ b/core-java-modules/core-java-jndi/README.md @@ -4,3 +4,4 @@ - [Java Naming and Directory Interface Overview](https://www.baeldung.com/jndi) - [LDAP Authentication Using Pure Java](https://www.baeldung.com/java-ldap-auth) - [Testing LDAP Connections With Java](https://www.baeldung.com/java-test-ldap-connections) +- [JNDI – What Is java:comp/env?](https://www.baeldung.com/java-jndi-comp-env) diff --git a/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/JndiNamingUnitTest.java b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/JndiNamingUnitTest.java new file mode 100644 index 0000000000..66d8d57d4e --- /dev/null +++ b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/JndiNamingUnitTest.java @@ -0,0 +1,72 @@ +package com.baeldung.jndi; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.jndi.JndiTemplate; +import org.springframework.mock.jndi.SimpleNamingContextBuilder; + +import javax.naming.*; +import javax.sql.DataSource; + +import java.util.Enumeration; + +import static org.junit.jupiter.api.Assertions.*; + +class JndiNamingUnitTest { + + private static InitialContext context; + private static DriverManagerDataSource dataSource; + + @BeforeAll + static void setUp() throws Exception { + SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); + dataSource = new DriverManagerDataSource("jdbc:h2:mem:mydb"); + builder.activate(); + + JndiTemplate jndiTemplate = new JndiTemplate(); + context = (InitialContext) jndiTemplate.getContext(); + + dataSource.setDriverClassName("org.h2.Driver"); + context.bind("java:comp/env/jdbc/datasource", dataSource); + } + + @Test + void givenACompositeName_whenAddingAnElement_thenNameIsAdded() throws Exception { + Name objectName = new CompositeName("java:comp/env/jdbc"); + + Enumeration items = objectName.getAll(); + while(items.hasMoreElements()) { + System.out.println(items.nextElement()); + } + + objectName.add("New Name"); + + assertEquals("env", objectName.get(1)); + assertEquals("New Name", objectName.get(objectName.size() - 1)); + } + + @Test + void givenContext_whenLookupByName_thenReturnsValidObject() throws Exception { + DataSource ds = (DataSource) context.lookup("java:comp/env/jdbc/datasource"); + + assertNotNull(ds); + assertNotNull(ds.getConnection()); + } + + @Test + void givenSubContext_whenLookupByName_thenReturnsValidObject() throws Exception { + Context subContext = (Context) context.lookup("java:comp/env"); + DataSource ds = (DataSource) subContext.lookup("jdbc/datasource"); + + assertNotNull(ds); + assertNotNull(ds.getConnection()); + } + + @AfterAll + static void tearDown() throws Exception { + context.close(); + } + +} diff --git a/core-java-modules/core-java-lang-6/pom.xml b/core-java-modules/core-java-lang-6/pom.xml index 6561c4fdcc..54035c1eb0 100644 --- a/core-java-modules/core-java-lang-6/pom.xml +++ b/core-java-modules/core-java-lang-6/pom.xml @@ -29,7 +29,6 @@ org.apache.maven.plugins maven-compiler-plugin - 3.5.1 17 17 @@ -50,7 +49,7 @@ 17 17 UTF-8 - 1.5.5.Final + 1.6.0.Beta1 \ No newline at end of file diff --git a/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/compressbytes/CompressByteArrayUtil.java b/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/compressbytes/CompressByteArrayUtil.java new file mode 100644 index 0000000000..88e2283985 --- /dev/null +++ b/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/compressbytes/CompressByteArrayUtil.java @@ -0,0 +1,58 @@ +package com.baeldung.compressbytes; + +import java.io.ByteArrayOutputStream; +import java.util.zip.DataFormatException; +import java.util.zip.Deflater; +import java.util.zip.Inflater; + +public class CompressByteArrayUtil { + + public static byte[] compress(byte[] input) { + Deflater deflater = new Deflater(); + deflater.setInput(input); + deflater.finish(); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + + while (!deflater.finished()) { + int compressedSize = deflater.deflate(buffer); + outputStream.write(buffer, 0, compressedSize); + } + + return outputStream.toByteArray(); + } + + public static byte[] decompress(byte[] input) throws DataFormatException { + Inflater inflater = new Inflater(); + inflater.setInput(input); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + + while (!inflater.finished()) { + int decompressedSize = inflater.inflate(buffer); + outputStream.write(buffer, 0, decompressedSize); + } + + return outputStream.toByteArray(); + } + + public static void main(String[] args) throws Exception { + String inputString = "Baeldung helps developers explore the Java ecosystem and simply be better engineers. " + + "We publish to-the-point guides and courses, with a strong focus on building web applications, Spring, " + + "Spring Security, and RESTful APIs"; + byte[] input = inputString.getBytes(); + + // Compression + byte[] compressedData = compress(input); + + // Decompression + byte[] decompressedData = decompress(compressedData); + + System.out.println("Original: " + input.length + " bytes"); + System.out.println("Compressed: " + compressedData.length + " bytes"); + System.out.println("Decompressed: " + decompressedData.length + " bytes"); + } + +} diff --git a/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/InterruptThread.java b/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/InterruptThread.java index 7964ad9f52..7fcb6185cc 100644 --- a/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/InterruptThread.java +++ b/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/InterruptThread.java @@ -4,9 +4,7 @@ public class InterruptThread extends Thread { @Override public void run() { while (!isInterrupted()) { - if (isInterrupted()) { - break; - } + break; // business logic } } diff --git a/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/genericnumberscomparator/GenericNumbersComparatorUnitTest.java b/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/genericnumberscomparator/GenericNumbersComparatorUnitTest.java new file mode 100644 index 0000000000..0b0295c2db --- /dev/null +++ b/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/genericnumberscomparator/GenericNumbersComparatorUnitTest.java @@ -0,0 +1,90 @@ +package com.baeldung.genericnumberscomparator; + +import static org.assertj.core.api.Assertions.entry; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Comparator; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.BiPredicate; +import java.util.function.Function; + +import org.junit.jupiter.api.Test; + +class GenericNumbersComparatorUnitTest { + + public int compareDouble(Number num1, Number num2) { + return Double.compare(num1.doubleValue(), num2.doubleValue()); + } + + @Test + void givenNumbers_whenUseCompareDouble_thenWillExecuteComparison() { + assertEquals(0, compareDouble(5, 5.0)); + } + + // we create a method that compares Integer, but this could also be done for other types e.g. Double, BigInteger + public int compareTo(Integer int1, Integer int2) { + return int1.compareTo(int2); + } + + @Test + void givenNumbers_whenUseCompareTo_thenWillExecuteComparison() { + assertEquals(-1, compareTo(5, 7)); + } + + // for this example, we create a function that compares Integer, but this could also be done for other types e.g. Double, BigInteger + Map, BiFunction> comparisonMap = Map.ofEntries(entry(Integer.class, (num1, num2) -> ((Integer) num1).compareTo((Integer) num2))); + + public int compareUsingMap(Number num1, Number num2) { + return comparisonMap.get(num1.getClass()) + .apply(num1, num2); + } + + @Test + void givenNumbers_whenUseCompareUsingMap_thenWillExecuteComparison() { + assertEquals(-1, compareUsingMap(5, 7)); + } + + public interface NumberComparator { + int compare(Number num1, Number num2); + } + + @Test + void givenNumbers_whenUseProxy_thenWillExecuteComparison() { + NumberComparator proxy = (NumberComparator) Proxy.newProxyInstance(NumberComparator.class.getClassLoader(), new Class[] { NumberComparator.class }, + (p, method, args) -> Double.compare(((Number) args[0]).doubleValue(), ((Number) args[1]).doubleValue())); + assertEquals(0, proxy.compare(5, 5.0)); + } + + public int compareUsingReflection(Number num1, Number num2) throws Exception { + Method method = num1.getClass() + .getMethod("compareTo", num1.getClass()); + return (int) method.invoke(num1, num2); + } + + @Test + void givenNumbers_whenUseCompareUsingReflection_thenWillExecuteComparison() throws Exception { + assertEquals(-1, compareUsingReflection(5, 7)); + } + + Function toDouble = Number::doubleValue; + BiPredicate isEqual = (num1, num2) -> toDouble.apply(num1) + .equals(toDouble.apply(num2)); + + @Test + void givenNumbers_whenUseIsEqual_thenWillExecuteComparison() { + assertEquals(true, isEqual.test(5, 5.0)); + } + + private boolean someCondition; + Function dynamicFunction = someCondition ? Number::doubleValue : Number::intValue; + Comparator dynamicComparator = (num1, num2) -> ((Comparable) dynamicFunction.apply(num1)).compareTo(dynamicFunction.apply(num2)); + + @Test + void givenNumbers_whenUseDynamicComparator_thenWillExecuteComparison() { + assertEquals(0, dynamicComparator.compare(5, 5.0)); + } + +} diff --git a/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/FloatDoubleConversionsTest.java b/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/FloatDoubleConversionsUnitTest.java similarity index 95% rename from core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/FloatDoubleConversionsTest.java rename to core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/FloatDoubleConversionsUnitTest.java index 9da50276a9..2bddb6d8cd 100644 --- a/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/FloatDoubleConversionsTest.java +++ b/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/FloatDoubleConversionsUnitTest.java @@ -3,7 +3,7 @@ package com.baeldung.floatdoubleconversions; import org.junit.Assert; import org.junit.Test; -public class FloatDoubleConversionsTest { +public class FloatDoubleConversionsUnitTest { @Test public void whenDoubleType_thenFloatTypeSuccess(){ diff --git a/core-java-modules/core-java-optional/pom.xml b/core-java-modules/core-java-optional/pom.xml index eeefed867e..68800f67fc 100644 --- a/core-java-modules/core-java-optional/pom.xml +++ b/core-java-modules/core-java-optional/pom.xml @@ -47,14 +47,14 @@ io.rest-assured json-path - ${rest-assured.version} + ${json-path.version} test 5.4.0.Final - 3.1.1 + 5.3.2 \ No newline at end of file diff --git a/core-java-modules/core-java-optional/src/test/java/com/baeldung/java9additions/Java9OptionalUnitTest.java b/core-java-modules/core-java-optional/src/test/java/com/baeldung/java9additions/Java9OptionalUnitTest.java index ee04432e44..e7daac4b8c 100644 --- a/core-java-modules/core-java-optional/src/test/java/com/baeldung/java9additions/Java9OptionalUnitTest.java +++ b/core-java-modules/core-java-optional/src/test/java/com/baeldung/java9additions/Java9OptionalUnitTest.java @@ -8,88 +8,88 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; -// Uncomment code when code base is compatible with Java 9 -//public class Java9OptionalUnitTest { -// -// @Test -// public void givenOptionalOfSome_whenToStream_thenShouldTreatItAsOneElementStream() { -// //given -// Optional value = Optional.of("a"); -// -// //when -// List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); -// -// //then -// assertThat(collect).hasSameElementsAs(List.of("A")); -// } -// -// @Test -// public void givenOptionalOfNone_whenToStream_thenShouldTreatItAsZeroElementStream() { -// //given -// Optional value = Optional.empty(); -// -// //when -// List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); -// -// //then -// assertThat(collect).isEmpty(); -// } -// -// @Test -// public void givenOptional_whenPresent_thenShouldExecuteProperCallback() { -// //given -// Optional value = Optional.of("properValue"); -// AtomicInteger successCounter = new AtomicInteger(0); -// AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); -// -// //when -// value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); -// -// //then -// assertThat(successCounter.get()).isEqualTo(1); -// assertThat(onEmptyOptionalCounter.get()).isEqualTo(0); -// } -// -// @Test -// public void givenOptional_whenNotPresent_thenShouldExecuteProperCallback() { -// //given -// Optional value = Optional.empty(); -// AtomicInteger successCounter = new AtomicInteger(0); -// AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); -// -// //when -// value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); -// -// //then -// assertThat(successCounter.get()).isEqualTo(0); -// assertThat(onEmptyOptionalCounter.get()).isEqualTo(1); -// } -// -// @Test -// public void givenOptional_whenPresent_thenShouldTakeAValueFromIt() { -// //given -// String expected = "properValue"; -// Optional value = Optional.of(expected); -// Optional defaultValue = Optional.of("default"); -// -// //when -// Optional result = value.or(() -> defaultValue); -// -// //then -// assertThat(result.get()).isEqualTo(expected); -// } -// -// @Test -// public void givenOptional_whenEmpty_thenShouldTakeAValueFromOr() { -// //given -// String defaultString = "default"; -// Optional value = Optional.empty(); -// Optional defaultValue = Optional.of(defaultString); -// -// //when -// Optional result = value.or(() -> defaultValue); -// -// //then -// assertThat(result.get()).isEqualTo(defaultString); -// } -//} \ No newline at end of file + +public class Java9OptionalUnitTest { + + @Test + public void givenOptionalOfSome_whenToStream_thenShouldTreatItAsOneElementStream() { + //given + Optional value = Optional.of("a"); + + //when + List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); + + //then + assertThat(collect).hasSameElementsAs(List.of("A")); + } + + @Test + public void givenOptionalOfNone_whenToStream_thenShouldTreatItAsZeroElementStream() { + //given + Optional value = Optional.empty(); + + //when + List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); + + //then + assertThat(collect).isEmpty(); + } + + @Test + public void givenOptional_whenPresent_thenShouldExecuteProperCallback() { + //given + Optional value = Optional.of("properValue"); + AtomicInteger successCounter = new AtomicInteger(0); + AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); + + //when + value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); + + //then + assertThat(successCounter.get()).isEqualTo(1); + assertThat(onEmptyOptionalCounter.get()).isEqualTo(0); + } + + @Test + public void givenOptional_whenNotPresent_thenShouldExecuteProperCallback() { + //given + Optional value = Optional.empty(); + AtomicInteger successCounter = new AtomicInteger(0); + AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); + + //when + value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); + + //then + assertThat(successCounter.get()).isEqualTo(0); + assertThat(onEmptyOptionalCounter.get()).isEqualTo(1); + } + + @Test + public void givenOptional_whenPresent_thenShouldTakeAValueFromIt() { + //given + String expected = "properValue"; + Optional value = Optional.of(expected); + Optional defaultValue = Optional.of("default"); + + //when + Optional result = value.or(() -> defaultValue); + + //then + assertThat(result.get()).isEqualTo(expected); + } + + @Test + public void givenOptional_whenEmpty_thenShouldTakeAValueFromOr() { + //given + String defaultString = "default"; + Optional value = Optional.empty(); + Optional defaultValue = Optional.of(defaultString); + + //when + Optional result = value.or(() -> defaultValue); + + //then + assertThat(result.get()).isEqualTo(defaultString); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-os-2/pom.xml b/core-java-modules/core-java-os-2/pom.xml index 53fdafa7d4..11b0585ae7 100644 --- a/core-java-modules/core-java-os-2/pom.xml +++ b/core-java-modules/core-java-os-2/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - core-java-os - core-java-os + core-java-os-2 + core-java-os-2 jar diff --git a/core-java-modules/core-java-records/README.md b/core-java-modules/core-java-records/README.md index 86d3579c76..7b4df6f15c 100644 --- a/core-java-modules/core-java-records/README.md +++ b/core-java-modules/core-java-records/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Overriding hashCode() And equals() For Records](https://www.baeldung.com/java-override-hashcode-equals-records) +- [Optional as a Record Parameter in Java](https://www.baeldung.com/java-record-optional-param) diff --git a/core-java-modules/core-java-records/src/main/java/com/baeldung/optionalsasparameterrecords/Product.java b/core-java-modules/core-java-records/src/main/java/com/baeldung/optionalsasparameterrecords/Product.java new file mode 100644 index 0000000000..8ede001ee1 --- /dev/null +++ b/core-java-modules/core-java-records/src/main/java/com/baeldung/optionalsasparameterrecords/Product.java @@ -0,0 +1,6 @@ +package com.baeldung.optionalsasparameterrecords; + +import java.util.Optional; + +public record Product(String name, double price, Optional description) { +} diff --git a/core-java-modules/core-java-records/src/test/java/com/baeldung/optionalsasparameterrecords/OptionalAsRecordParameterUnitTest.java b/core-java-modules/core-java-records/src/test/java/com/baeldung/optionalsasparameterrecords/OptionalAsRecordParameterUnitTest.java new file mode 100644 index 0000000000..554fb2eac3 --- /dev/null +++ b/core-java-modules/core-java-records/src/test/java/com/baeldung/optionalsasparameterrecords/OptionalAsRecordParameterUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.optionalsasparameterrecords; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Optional; + +public class OptionalAsRecordParameterUnitTest { + + @Test + public void givenRecordCreationWithOptional_thenCreateItProperly() { + var emptyDescriptionProduct = new Product("television", 1699.99, Optional.empty()); + Assertions.assertEquals("television", emptyDescriptionProduct.name()); + Assertions.assertEquals(1699.99, emptyDescriptionProduct.price()); + Assertions.assertNull(emptyDescriptionProduct.description().orElse(null)); + } +} diff --git a/core-java-modules/core-java-regex-2/src/main/java/com/baeldung/alphanumeric/AlphanumericPerformanceBenchmark.java b/core-java-modules/core-java-regex-2/src/main/java/com/baeldung/alphanumeric/AlphanumericPerformanceBenchmark.java index 4b2ecc4c4d..0525153ed9 100644 --- a/core-java-modules/core-java-regex-2/src/main/java/com/baeldung/alphanumeric/AlphanumericPerformanceBenchmark.java +++ b/core-java-modules/core-java-regex-2/src/main/java/com/baeldung/alphanumeric/AlphanumericPerformanceBenchmark.java @@ -85,7 +85,7 @@ public class AlphanumericPerformanceBenchmark { public boolean isAlphanumeric(final int codePoint) { return (codePoint >= 65 && codePoint <= 90) || - (codePoint >= 97 && codePoint <= 172) || + (codePoint >= 97 && codePoint <= 122) || (codePoint >= 48 && codePoint <= 57); } } diff --git a/core-java-modules/core-java-streams-5/README.md b/core-java-modules/core-java-streams-5/README.md index 629d52f0a9..64bc4e6b7a 100644 --- a/core-java-modules/core-java-streams-5/README.md +++ b/core-java-modules/core-java-streams-5/README.md @@ -5,3 +5,5 @@ - [Streams vs. Loops in Java](https://www.baeldung.com/java-streams-vs-loops) - [Partition a Stream in Java](https://www.baeldung.com/java-partition-stream) - [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) diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/ImmutablePerson.java b/core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/ImmutablePerson.java new file mode 100644 index 0000000000..bb7f3b8eb3 --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/ImmutablePerson.java @@ -0,0 +1,25 @@ +package com.baledung.modifystream.entity; + +public class ImmutablePerson { + + private String name; + private String email; + + public ImmutablePerson(String name, String email) { + this.name = name; + this.email = email; + } + + public ImmutablePerson withEmail(String email) { + + return new ImmutablePerson(this.name, email); + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } +} diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/Person.java b/core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/Person.java new file mode 100644 index 0000000000..c82c159059 --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/Person.java @@ -0,0 +1,27 @@ +package com.baledung.modifystream.entity; + +public class Person { + private String name; + private String email; + + public Person(String name, String email) { + this.name = name; + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java new file mode 100644 index 0000000000..9da3beb40e --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java @@ -0,0 +1,132 @@ +package com.baeldung.modifystream; + +import com.baledung.modifystream.entity.ImmutablePerson; +import com.baledung.modifystream.entity.Person; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.ConcurrentModificationException; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class ModifyStreamUnitTest { + Logger logger = LoggerFactory.getLogger(ModifyStreamUnitTest.class); + List personList = new ArrayList(); + List immutablePersonList = new ArrayList(); + + @BeforeEach + void prepare() { + Person person1 = new Person("John", "john@gmail.com"); + Person person2 = new Person("Peter", "peter@gmail.com"); + Person person3 = new Person("Mary", "mary@gmail.com"); + Person person4 = new Person("William", "william@gmail.com"); + + personList.add(person1); + personList.add(person2); + personList.add(person3); + personList.add(person4); + } + + @BeforeEach + void prepareImmutablePerson() { + ImmutablePerson immutablePerson1 = new ImmutablePerson("John", "john@gmail.com"); + ImmutablePerson immutablePerson2 = new ImmutablePerson("Peter", "peter@gmail.com"); + ImmutablePerson immutablePerson3 = new ImmutablePerson("Mary", "mary@gmail.com"); + ImmutablePerson immutablePerson4 = new ImmutablePerson("William", "william@gmail.com"); + + immutablePersonList.add(immutablePerson1); + immutablePersonList.add(immutablePerson2); + immutablePersonList.add(immutablePerson3); + immutablePersonList.add(immutablePerson4); + } + + @Test + void givenPersonList_whenRemoveWhileIterating_thenThrowException() { + assertThrows(NullPointerException.class, () -> { + personList.stream().forEach(e -> { + if(e.getName().equals("John")) { + personList.remove(e); + } + }); + }); + } + + @Test + void givenPersonList_whenRemoveWhileIteratingWithForEach_thenThrowException() { + assertThrows(ConcurrentModificationException.class, () -> { + personList.forEach(e -> { + if(e.getName().equals("John")) { + personList.remove(e); + } + }); + }); + } + + @Test + void givenPersonList_whenRemoveWhileIterating_thenPersonRemoved() { + assertEquals(4, personList.size()); + + CopyOnWriteArrayList cps = new CopyOnWriteArrayList<>(personList); + cps.stream().forEach(e -> { + if(e.getName().equals("John")) { + cps.remove(e); + } + }); + + assertEquals(3, cps.size()); + } + + + @Test + void givenPersonList_whenRemovePersonWithFilter_thenPersonRemoved() { + assertEquals(4, personList.size()); + + List newPersonList = personList.stream() + .filter(e -> !e.getName().equals("John")) + .collect(Collectors.toList()); + + assertEquals(3, newPersonList.size()); + } + + @Test + void givenPersonList_whenUpdatePersonEmailByInterferingWithForEach_thenPersonEmailUpdated() { + personList.stream().forEach(e -> e.setEmail(e.getEmail().toUpperCase())); + + personList.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); + } + + @Test + void givenPersonList_whenUpdatePersonEmailWithMapMethod_thenPersonEmailUpdated() { + List newPersonList = personList.stream() + .map(e -> new Person(e.getName(), e.getEmail().toUpperCase())) + .collect(Collectors.toList()); + + newPersonList.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); + } + + @Test + void givenPersonList_whenUpdateImmutablePersonEmailWithMapMethod_thenPersonEmailUpdated() { + List newImmutablePersonList = immutablePersonList.stream() + .map(e -> e.withEmail(e.getEmail().toUpperCase())) + .collect(Collectors.toList()); + + newImmutablePersonList.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); + } + + @Test + void givenPersonList_whenUpdatePersonEmailByInterferingWithPeek_thenPersonEmailUpdated() { + personList.stream() + .peek(e -> e.setEmail(e.getEmail().toUpperCase())) + .collect(Collectors.toList()); + + personList.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); + } + +} diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/nosuchelementexception/NoSuchElementExceptionStreamUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/nosuchelementexception/NoSuchElementExceptionStreamUnitTest.java new file mode 100644 index 0000000000..bef834c1af --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/nosuchelementexception/NoSuchElementExceptionStreamUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.nosuchelementexception; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; + +import org.junit.Test; + +public class NoSuchElementExceptionStreamUnitTest { + + @Test(expected = NoSuchElementException.class) + public void givenEmptyOptional_whenCallingGetMethod_thenThrowNoSuchElementException() { + List names = List.of("William", "Amelia", "Albert", "Philip"); + Optional emptyOptional = names.stream() + .filter(name -> name.equals("Emma")) + .findFirst(); + + emptyOptional.get(); + } + + @Test + public void givenEmptyOptional_whenUsingIsPresentMethod_thenReturnDefault() { + List names = List.of("Tyler", "Amelia", "James", "Emma"); + Optional emptyOptional = names.stream() + .filter(name -> name.equals("Lucas")) + .findFirst(); + + String name = "unknown"; + if (emptyOptional.isPresent()) { + name = emptyOptional.get(); + } + + assertEquals("unknown", name); + } + + @Test + public void givenEmptyOptional_whenUsingOrElseMethod_thenReturnDefault() { + List names = List.of("Nicholas", "Justin", "James"); + Optional emptyOptional = names.stream() + .filter(name -> name.equals("Lucas")) + .findFirst(); + + String name = emptyOptional.orElse("unknown"); + + assertEquals("unknown", name); + } + + @Test + public void givenEmptyOptional_whenUsingOrElseGetMethod_thenReturnDefault() { + List names = List.of("Thomas", "Catherine", "David", "Olivia"); + Optional emptyOptional = names.stream() + .filter(name -> name.equals("Liam")) + .findFirst(); + + String name = emptyOptional.orElseGet(() -> "unknown"); + + assertEquals("unknown", name); + } + +} diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamtomapandmultimap/StreamToMapAndMultiMapUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamtomapandmultimap/StreamToMapAndMultiMapUnitTest.java new file mode 100644 index 0000000000..f5da353551 --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamtomapandmultimap/StreamToMapAndMultiMapUnitTest.java @@ -0,0 +1,101 @@ +package com.baeldung.streamtomapandmultimap; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; +import org.junit.Test; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; + +public class StreamToMapAndMultiMapUnitTest { + @Test + public void givenStringStream_whenConvertingToMapWithMerge_thenExpectedMapIsGenerated() { + Stream stringStream = Stream.of("one", "two", "three", "two"); + + Map mergedMap = stringStream.collect( + Collectors.toMap(s -> s, s -> s, (s1, s2) -> s1 + ", " + s2) + ); + + // Define the expected map + Map expectedMap = Map.of( + "one", "one", + "two", "two, two", + "three", "three" + ); + + assertEquals(expectedMap, mergedMap); + } + + @Test + public void givenStringStream_whenConvertingToMultimap_thenExpectedMultimapIsGenerated() { + Stream stringStream = Stream.of("one", "two", "three", "two"); + + ListMultimap multimap = stringStream.collect( + ArrayListMultimap::create, + (map, element) -> map.put(element, element), + ArrayListMultimap::putAll + ); + + ListMultimap expectedMultimap = ArrayListMultimap.create(); + expectedMultimap.put("one", "one"); + expectedMultimap.put("two", "two"); + expectedMultimap.put("two", "two"); + expectedMultimap.put("three", "three"); + + assertEquals(expectedMultimap, multimap); + } + + @Test + public void givenStringStream_whenConvertingToMultimapWithStreamReduce_thenExpectedMultimapIsGenerated() { + Stream stringStream = Stream.of("one", "two", "three", "two"); + + Map> multimap = stringStream.reduce( + new HashMap<>(), + (map, element) -> { + map.computeIfAbsent(element, k -> new ArrayList<>()).add(element); + return map; + }, + (map1, map2) -> { + map2.forEach((key, value) -> map1.merge(key, value, (list1, list2) -> { + list1.addAll(list2); + return list1; + })); + return map1; + } + ); + + Map> expectedMultimap = new HashMap<>(); + expectedMultimap.put("one", Collections.singletonList("one")); + expectedMultimap.put("two", Arrays.asList("two", "two")); + expectedMultimap.put("three", Collections.singletonList("three")); + + assertEquals(expectedMultimap, multimap); + } + + @Test + public void givenStringStream_whenConvertingToMapWithStreamReduce_thenExpectedMapIsGenerated() { + Stream stringStream = Stream.of("one", "two", "three", "two"); + + Map resultMap = stringStream.reduce( + new HashMap<>(), + (map, element) -> { + map.put(element, element); + return map; + }, + (map1, map2) -> { + map1.putAll(map2); + return map1; + } + ); + + Map expectedMap = new HashMap<>(); + expectedMap.put("one", "one"); + expectedMap.put("two", "two"); + expectedMap.put("three", "three"); + + assertEquals(expectedMap, resultMap); + } +} diff --git a/core-java-modules/core-java-streams-simple/src/main/java/com/baeldung/streams/reduce/entities/User.java b/core-java-modules/core-java-streams-simple/src/main/java/com/baeldung/streams/reduce/entities/User.java index 610bd93b22..07c627005a 100644 --- a/core-java-modules/core-java-streams-simple/src/main/java/com/baeldung/streams/reduce/entities/User.java +++ b/core-java-modules/core-java-streams-simple/src/main/java/com/baeldung/streams/reduce/entities/User.java @@ -4,6 +4,7 @@ public class User { private final String name; private final int age; + private final Rating rating = new Rating(); public User(String name, int age) { this.name = name; @@ -17,7 +18,11 @@ public class User { public int getAge() { return age; } - + + public Rating getRating() { + return rating; + } + @Override public String toString() { return "User{" + "name=" + name + ", age=" + age + '}'; diff --git a/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/Java8StreamsUnitTest.java b/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/Java8StreamsUnitTest.java index f46fa79b08..6f1cac1903 100644 --- a/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/Java8StreamsUnitTest.java +++ b/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/Java8StreamsUnitTest.java @@ -1,7 +1,11 @@ package com.baeldung.streams; -import org.junit.Before; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import java.nio.file.Path; import java.nio.file.Paths; @@ -11,14 +15,12 @@ import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.junit.Assert.*; +class Java8StreamsUnitTest { -public class Java8StreamsUnitTest { + private static List list; - private List list; - - @Before - public void init() { + @BeforeAll + public static void init() { list = new ArrayList<>(); list.add("One"); list.add("OneAndOnly"); @@ -42,60 +44,73 @@ public class Java8StreamsUnitTest { Stream streamOf = Stream.of("a", "b", "c"); assertEquals(streamOf.count(), 3); - long count = list.stream().distinct().count(); + long count = list.stream() + .distinct() + .count(); assertEquals(count, 9); } @Test - public void checkStreamCount_whenOperationFilter_thanCorrect() { - Stream streamFilter = list.stream().filter(element -> element.isEmpty()); + void checkStreamCount_whenOperationFilter_thanCorrect() { + Stream streamFilter = list.stream() + .filter(element -> element.isEmpty()); assertEquals(streamFilter.count(), 2); } @Test - public void checkStreamCount_whenOperationMap_thanCorrect() { + void checkStreamCount_whenOperationMap_thanCorrect() { List uris = new ArrayList<>(); uris.add("C:\\My.txt"); - Stream streamMap = uris.stream().map(uri -> Paths.get(uri)); + Stream streamMap = uris.stream() + .map(uri -> Paths.get(uri)); assertEquals(streamMap.count(), 1); List details = new ArrayList<>(); details.add(new Detail()); details.add(new Detail()); - Stream streamFlatMap = details.stream().flatMap(detail -> detail.getParts().stream()); + Stream streamFlatMap = details.stream() + .flatMap(detail -> detail.getParts() + .stream()); assertEquals(streamFlatMap.count(), 4); } @Test - public void checkStreamCount_whenOperationMatch_thenCorrect() { - boolean isValid = list.stream().anyMatch(element -> element.contains("h")); - boolean isValidOne = list.stream().allMatch(element -> element.contains("h")); - boolean isValidTwo = list.stream().noneMatch(element -> element.contains("h")); + void checkStreamCount_whenOperationMatch_thenCorrect() { + boolean isValid = list.stream() + .anyMatch(element -> element.contains("h")); + boolean isValidOne = list.stream() + .allMatch(element -> element.contains("h")); + boolean isValidTwo = list.stream() + .noneMatch(element -> element.contains("h")); assertTrue(isValid); assertFalse(isValidOne); assertFalse(isValidTwo); } @Test - public void checkStreamReducedValue_whenOperationReduce_thenCorrect() { + void checkStreamReducedValue_whenOperationReduce_thenCorrect() { List integers = new ArrayList<>(); integers.add(1); integers.add(1); integers.add(1); - Integer reduced = integers.stream().reduce(23, (a, b) -> a + b); + Integer reduced = integers.stream() + .reduce(23, (a, b) -> a + b); assertTrue(reduced == 26); } @Test - public void checkStreamContains_whenOperationCollect_thenCorrect() { - List resultList = list.stream().map(element -> element.toUpperCase()).collect(Collectors.toList()); + void checkStreamContains_whenOperationCollect_thenCorrect() { + List resultList = list.stream() + .map(element -> element.toUpperCase()) + .collect(Collectors.toList()); assertEquals(resultList.size(), list.size()); assertTrue(resultList.contains("")); } @Test public void checkParallelStream_whenDoWork() { - list.parallelStream().forEach(element -> doWork(element)); + list.parallelStream() + .forEach(element -> doWork(element)); } private void doWork(String string) { diff --git a/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/collectors/Java8CollectorsUnitTest.java b/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/collectors/Java8CollectorsUnitTest.java index 085c1b5d7f..1faada9d23 100644 --- a/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/collectors/Java8CollectorsUnitTest.java +++ b/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/collectors/Java8CollectorsUnitTest.java @@ -3,6 +3,7 @@ package com.baeldung.streams.collectors; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; + import org.junit.Test; import java.util.*; @@ -23,142 +24,159 @@ public class Java8CollectorsUnitTest { private final List listWithDuplicates = Arrays.asList("a", "bb", "c", "d", "bb"); @Test - public void whenCollectingToList_shouldCollectToList() throws Exception { - final List result = givenList.stream().collect(toList()); + public void whenCollectingToList_shouldCollectToList() { + final List result = givenList.stream() + .collect(toList()); assertThat(result).containsAll(givenList); } @Test public void whenCollectingToUnmodifiableList_shouldCollectToUnmodifiableList() { - final List result = givenList.stream().collect(toUnmodifiableList()); + final List result = givenList.stream() + .collect(toUnmodifiableList()); - assertThatThrownBy(() -> result.add("foo")) - .isInstanceOf(UnsupportedOperationException.class); + assertThatThrownBy(() -> result.add("foo")).isInstanceOf(UnsupportedOperationException.class); } @Test - public void whenCollectingToSet_shouldCollectToSet() throws Exception { - final Set result = givenList.stream().collect(toSet()); + public void whenCollectingToSet_shouldCollectToSet() { + final Set result = givenList.stream() + .collect(toSet()); assertThat(result).containsAll(givenList); } @Test public void whenCollectingToUnmodifiableSet_shouldCollectToUnmodifiableSet() { - final Set result = givenList.stream().collect(toUnmodifiableSet()); + final Set result = givenList.stream() + .collect(toUnmodifiableSet()); - assertThatThrownBy(() -> result.add("foo")) - .isInstanceOf(UnsupportedOperationException.class); + assertThatThrownBy(() -> result.add("foo")).isInstanceOf(UnsupportedOperationException.class); } @Test public void givenContainsDuplicateElements_whenCollectingToSet_shouldAddDuplicateElementsOnlyOnce() throws Exception { - final Set result = listWithDuplicates.stream().collect(toSet()); + final Set result = listWithDuplicates.stream() + .collect(toSet()); assertThat(result).hasSize(4); } @Test - public void whenCollectingToCollection_shouldCollectToCollection() throws Exception { - final List result = givenList.stream().collect(toCollection(LinkedList::new)); + public void whenCollectingToCollection_shouldCollectToCollection() { + final List result = givenList.stream() + .collect(toCollection(LinkedList::new)); - assertThat(result).containsAll(givenList).isInstanceOf(LinkedList.class); + assertThat(result).containsAll(givenList) + .isInstanceOf(LinkedList.class); } @Test - public void whenCollectingToImmutableCollection_shouldThrowException() throws Exception { + public void whenCollectingToImmutableCollection_shouldThrowException() { assertThatThrownBy(() -> { - givenList.stream().collect(toCollection(ImmutableList::of)); + givenList.stream() + .collect(toCollection(ImmutableList::of)); }).isInstanceOf(UnsupportedOperationException.class); } @Test - public void whenCollectingToMap_shouldCollectToMap() throws Exception { - final Map result = givenList.stream().collect(toMap(Function.identity(), String::length)); + public void whenCollectingToMap_shouldCollectToMap() { + final Map result = givenList.stream() + .collect(toMap(Function.identity(), String::length)); - assertThat(result).containsEntry("a", 1).containsEntry("bb", 2).containsEntry("ccc", 3).containsEntry("dd", 2); + assertThat(result).containsEntry("a", 1) + .containsEntry("bb", 2) + .containsEntry("ccc", 3) + .containsEntry("dd", 2); } @Test public void whenCollectingToUnmodifiableMap_shouldCollectToUnmodifiableMap() { final Map result = givenList.stream() - .collect(toUnmodifiableMap(Function.identity(), String::length)); + .collect(toUnmodifiableMap(Function.identity(), String::length)); - assertThatThrownBy(() -> result.put("foo", 3)) - .isInstanceOf(UnsupportedOperationException.class); + assertThatThrownBy(() -> result.put("foo", 3)).isInstanceOf(UnsupportedOperationException.class); } @Test public void whenCollectingToMapwWithDuplicates_shouldCollectToMapMergingTheIdenticalItems() throws Exception { - final Map result = listWithDuplicates.stream().collect( - toMap( - Function.identity(), - String::length, - (item, identicalItem) -> item - ) - ); + final Map result = listWithDuplicates.stream() + .collect(toMap(Function.identity(), String::length, (item, identicalItem) -> item)); - assertThat(result).containsEntry("a", 1).containsEntry("bb", 2).containsEntry("c", 1).containsEntry("d", 1); + assertThat(result).containsEntry("a", 1) + .containsEntry("bb", 2) + .containsEntry("c", 1) + .containsEntry("d", 1); } @Test - public void givenContainsDuplicateElements_whenCollectingToMap_shouldThrowException() throws Exception { + public void givenContainsDuplicateElements_whenCollectingToMap_shouldThrowException() { assertThatThrownBy(() -> { - listWithDuplicates.stream().collect(toMap(Function.identity(), String::length)); + listWithDuplicates.stream() + .collect(toMap(Function.identity(), String::length)); }).isInstanceOf(IllegalStateException.class); } @Test - public void whenCollectingAndThen_shouldCollect() throws Exception { - final List result = givenList.stream().collect(collectingAndThen(toList(), ImmutableList::copyOf)); + public void whenCollectingAndThen_shouldCollect() { + final List result = givenList.stream() + .collect(collectingAndThen(toList(), ImmutableList::copyOf)); - assertThat(result).containsAll(givenList).isInstanceOf(ImmutableList.class); + assertThat(result).containsAll(givenList) + .isInstanceOf(ImmutableList.class); } @Test - public void whenJoining_shouldJoin() throws Exception { - final String result = givenList.stream().collect(joining()); + public void whenJoining_shouldJoin() { + final String result = givenList.stream() + .collect(joining()); assertThat(result).isEqualTo("abbcccdd"); } @Test - public void whenJoiningWithSeparator_shouldJoinWithSeparator() throws Exception { - final String result = givenList.stream().collect(joining(" ")); + public void whenJoiningWithSeparator_shouldJoinWithSeparator() { + final String result = givenList.stream() + .collect(joining(" ")); assertThat(result).isEqualTo("a bb ccc dd"); } @Test - public void whenJoiningWithSeparatorAndPrefixAndPostfix_shouldJoinWithSeparatorPrePost() throws Exception { - final String result = givenList.stream().collect(joining(" ", "PRE-", "-POST")); + public void whenJoiningWithSeparatorAndPrefixAndPostfix_shouldJoinWithSeparatorPrePost() { + final String result = givenList.stream() + .collect(joining(" ", "PRE-", "-POST")); assertThat(result).isEqualTo("PRE-a bb ccc dd-POST"); } @Test - public void whenPartitioningBy_shouldPartition() throws Exception { - final Map> result = givenList.stream().collect(partitioningBy(s -> s.length() > 2)); + public void whenPartitioningBy_shouldPartition() { + final Map> result = givenList.stream() + .collect(partitioningBy(s -> s.length() > 2)); - assertThat(result).containsKeys(true, false).satisfies(booleanListMap -> { - assertThat(booleanListMap.get(true)).contains("ccc"); + assertThat(result).containsKeys(true, false) + .satisfies(booleanListMap -> { + assertThat(booleanListMap.get(true)).contains("ccc"); - assertThat(booleanListMap.get(false)).contains("a", "bb", "dd"); - }); + assertThat(booleanListMap.get(false)).contains("a", "bb", "dd"); + }); } @Test - public void whenCounting_shouldCount() throws Exception { - final Long result = givenList.stream().collect(counting()); + public void whenCounting_shouldCount() { + final Long result = givenList.stream() + .collect(counting()); assertThat(result).isEqualTo(4); } @Test - public void whenSummarizing_shouldSummarize() throws Exception { - final DoubleSummaryStatistics result = givenList.stream().collect(summarizingDouble(String::length)); + public void whenSummarizing_shouldSummarize() { + final DoubleSummaryStatistics result = givenList.stream() + .collect(summarizingDouble(String::length)); assertThat(result.getAverage()).isEqualTo(2); assertThat(result.getCount()).isEqualTo(4); @@ -168,38 +186,47 @@ public class Java8CollectorsUnitTest { } @Test - public void whenAveraging_shouldAverage() throws Exception { - final Double result = givenList.stream().collect(averagingDouble(String::length)); + public void whenAveraging_shouldAverage() { + final Double result = givenList.stream() + .collect(averagingDouble(String::length)); assertThat(result).isEqualTo(2); } @Test - public void whenSumming_shouldSum() throws Exception { - final Double result = givenList.stream().filter(i -> true).collect(summingDouble(String::length)); + public void whenSumming_shouldSum() { + final Double result = givenList.stream() + .collect(summingDouble(String::length)); assertThat(result).isEqualTo(8); } @Test - public void whenMaxingBy_shouldMaxBy() throws Exception { - final Optional result = givenList.stream().collect(maxBy(Comparator.naturalOrder())); + public void whenMaxingBy_shouldMaxBy() { + final Optional result = givenList.stream() + .collect(maxBy(Comparator.naturalOrder())); - assertThat(result).isPresent().hasValue("dd"); + assertThat(result).isPresent() + .hasValue("dd"); } @Test - public void whenGroupingBy_shouldGroupBy() throws Exception { - final Map> result = givenList.stream().collect(groupingBy(String::length, toSet())); + public void whenGroupingBy_shouldGroupBy() { + final Map> result = givenList.stream() + .collect(groupingBy(String::length, toSet())); - assertThat(result).containsEntry(1, newHashSet("a")).containsEntry(2, newHashSet("bb", "dd")).containsEntry(3, newHashSet("ccc")); + assertThat(result).containsEntry(1, newHashSet("a")) + .containsEntry(2, newHashSet("bb", "dd")) + .containsEntry(3, newHashSet("ccc")); } @Test - public void whenCreatingCustomCollector_shouldCollect() throws Exception { - final ImmutableSet result = givenList.stream().collect(toImmutableSet()); + public void whenCreatingCustomCollector_shouldCollect() { + final ImmutableSet result = givenList.stream() + .collect(toImmutableSet()); - assertThat(result).isInstanceOf(ImmutableSet.class).contains("a", "bb", "ccc", "dd"); + assertThat(result).isInstanceOf(ImmutableSet.class) + .contains("a", "bb", "ccc", "dd"); } diff --git a/core-java-modules/core-java-8/src/test/java/com/baeldung/streamreduce/tests/StreamReduceManualTest.java b/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/reduce/StreamReduceManualTest.java similarity index 95% rename from core-java-modules/core-java-8/src/test/java/com/baeldung/streamreduce/tests/StreamReduceManualTest.java rename to core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/reduce/StreamReduceManualTest.java index 602bdd069e..2931384c94 100644 --- a/core-java-modules/core-java-8/src/test/java/com/baeldung/streamreduce/tests/StreamReduceManualTest.java +++ b/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/reduce/StreamReduceManualTest.java @@ -1,15 +1,18 @@ -package com.baeldung.streamreduce.tests; +package com.baeldung.streams.reduce; + +import static org.assertj.core.api.Assertions.assertThat; -import com.baeldung.streamreduce.entities.Rating; -import com.baeldung.streamreduce.entities.Review; -import com.baeldung.streamreduce.entities.User; -import com.baeldung.streamreduce.utilities.NumberUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.assertj.core.api.Assertions.assertThat; + import org.junit.Test; +import com.baeldung.streams.reduce.entities.Rating; +import com.baeldung.streams.reduce.entities.Review; +import com.baeldung.streams.reduce.entities.User; +import com.baeldung.streams.reduce.utilities.NumberUtils; + public class StreamReduceManualTest { @Test diff --git a/core-java-modules/core-java-string-apis-2/README.md b/core-java-modules/core-java-string-apis-2/README.md index 38bfb70ef1..c0b313d3b3 100644 --- a/core-java-modules/core-java-string-apis-2/README.md +++ b/core-java-modules/core-java-string-apis-2/README.md @@ -6,4 +6,6 @@ This module contains articles about string APIs. - [Retain Only Digits and Decimal Separator in String](https://www.baeldung.com/java-string-retain-digits-decimal) - [Difference Between null and Empty String in Java](https://www.baeldung.com/java-string-null-vs-empty) - [Guide to Java String Pool](https://www.baeldung.com/java-string-pool) -- [Java Localization – Formatting Messages](https://www.baeldung.com/java-localization-messages-formatting) \ No newline at end of file +- [Java Localization – Formatting Messages](https://www.baeldung.com/java-localization-messages-formatting) +- [Compare StringBuilder Objects in Java](https://www.baeldung.com/java-stringbuilder-objects-comparison) +- [Finding the N-th Occurrence of a Substring in a String in Java](https://www.baeldung.com/java-locate-nth-match-substring) diff --git a/core-java-modules/core-java-string-apis-2/pom.xml b/core-java-modules/core-java-string-apis-2/pom.xml index 814d301532..0289a18e85 100644 --- a/core-java-modules/core-java-string-apis-2/pom.xml +++ b/core-java-modules/core-java-string-apis-2/pom.xml @@ -33,6 +33,16 @@ core-java-string-apis-2 + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + src/main/resources diff --git a/core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/diffstringstringbuffer/MemoryAddress.java b/core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/diffstringstringbuffer/MemoryAddress.java new file mode 100644 index 0000000000..42a4d9d4b4 --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/diffstringstringbuffer/MemoryAddress.java @@ -0,0 +1,33 @@ +package com.baeldung.diffstringstringbuffer; + +import java.lang.reflect.Field; + +import sun.misc.Unsafe; + +public class MemoryAddress { + public long getMemoryAddress(Object object) { + Object[] arrayOfObject = new Object[]{object}; + Unsafe unsafe = null; + try { + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + unsafe = (Unsafe) field.get(null); + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + assert unsafe != null; + long arrayBaseOffset = unsafe.arrayBaseOffset(Object[].class); + int addressSize = unsafe.addressSize(); + long objectAddress; + if (addressSize == 4) { + objectAddress = unsafe.getInt(arrayOfObject, arrayBaseOffset); + } else { + if (addressSize == 8) { + objectAddress = unsafe.getLong(arrayOfObject, arrayBaseOffset); + } else { + throw new Error("Error: Size not supported: " + addressSize); + } + } + return objectAddress; + } +} diff --git a/core-java-modules/core-java-string-apis-2/src/main/java/stringbuildercomparison/StringBuilderCompare.java b/core-java-modules/core-java-string-apis-2/src/main/java/stringbuildercomparison/StringBuilderCompare.java new file mode 100644 index 0000000000..2d2dc04b83 --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/main/java/stringbuildercomparison/StringBuilderCompare.java @@ -0,0 +1,17 @@ +package stringbuildercomparison; + +public class StringBuilderCompare { + + public static boolean compare(StringBuilder one, StringBuilder two){ + if(one.length() != two.length()){ + return false; + } + for(int i = 0; i < one.length(); i++){ + if(one.charAt(i) != two.charAt(i)){ + return false; + } + } + return true; + } + +} diff --git a/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringBufferUnitTest.java b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringBufferUnitTest.java new file mode 100644 index 0000000000..adbe69b65e --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringBufferUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.diffstringstringbuffer; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class StringBufferUnitTest { + @Test + void whenStringBufferVariableIsReassigned_thenVariableRetainsOriginalMemoryAddress() { + MemoryAddress memoryAddress = new MemoryAddress(); + StringBuffer stringBuffer = new StringBuffer("DownTown"); + long address1 = memoryAddress.getMemoryAddress(stringBuffer); + stringBuffer.insert(0, "Coder"); + assertEquals(stringBuffer.toString(), "CoderDownTown"); + long address2 = memoryAddress.getMemoryAddress(stringBuffer); + assertEquals(address1, address2); + } +} diff --git a/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringUnitTest.java b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringUnitTest.java new file mode 100644 index 0000000000..bf1fcfeaf1 --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.diffstringstringbuffer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.jupiter.api.Test; + +public class StringUnitTest { + @Test + void whenStringVariableIsReassigned_thenVariableGetsNewMemoryAddress() { + MemoryAddress memoryAddress = new MemoryAddress(); + String s1 = "DownTown"; + long address1 = memoryAddress.getMemoryAddress(s1); + s1 = "Coder"; + long address2 = memoryAddress.getMemoryAddress(s1); + assertNotEquals(address1, address2); + } + + @Test + void whenStringsAreIncludedInAStringBuffer_thenThoseStringsRemainImmutable() { + String s1 = "TopCat"; + StringBuffer stringBuffer = new StringBuffer("DownTown"); + stringBuffer.append(s1); + stringBuffer.reverse(); + assertNotEquals(s1, "taCpoT"); + stringBuffer.delete(0, 3); + assertEquals(s1, "TopCat"); + } +} diff --git a/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/nthsubstring/FindNthSubstringIndexUnitTest.java b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/nthsubstring/FindNthSubstringIndexUnitTest.java new file mode 100644 index 0000000000..779585ffb0 --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/nthsubstring/FindNthSubstringIndexUnitTest.java @@ -0,0 +1,106 @@ +package com.baeldung.nthsubstring; + +import org.junit.jupiter.api.Test; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class FindNthSubstringIndexUnitTest { + // "0 8 16 24 " + private final static String INPUT = "a word, a word, a word, a word"; + + @Test + void whenCallingIndexOfTwice_thenGetTheSecondSubstringIndex() { + int firstIdx = INPUT.indexOf("a"); + int result = INPUT.indexOf("a", firstIdx + "a".length()); + assertEquals(8, result); + } + + // the recursive approach + static int nthIndexOf(String input, String substring, int nth) { + if (nth == 1) { + return input.indexOf(substring); + } else { + return input.indexOf(substring, nthIndexOf(input, substring, nth - 1) + substring.length()); + } + } + + @Test + void whenCallingRecursiveMethod_thenGetTheExpectedResult() { + int result1 = nthIndexOf(INPUT, "a", 1); + assertEquals(0, result1); + + int result2 = nthIndexOf(INPUT, "a", 2); + assertEquals(8, result2); + + int result3 = nthIndexOf(INPUT, "a", 3); + assertEquals(16, result3); + + int result4 = nthIndexOf(INPUT, "a", 4); + assertEquals(24, result4); + + int result5 = nthIndexOf(INPUT, "a", 5); + assertEquals(-1, result5); + } + + // loop-based approach + static int nthIndexOf2(String input, String substring, int nth) { + int index = -1; + while (nth > 0) { + index = input.indexOf(substring, index + substring.length()); + if (index == -1) { + return -1; + } + nth--; + } + return index; + } + + @Test + void whenCallingLoopBasedMethod_thenGetTheExpectedResult() { + int result1 = nthIndexOf2(INPUT, "a", 1); + assertEquals(0, result1); + + int result2 = nthIndexOf2(INPUT, "a", 2); + assertEquals(8, result2); + + int result3 = nthIndexOf2(INPUT, "a", 3); + assertEquals(16, result3); + + int result4 = nthIndexOf2(INPUT, "a", 4); + assertEquals(24, result4); + + int result5 = nthIndexOf2(INPUT, "a", 5); + assertEquals(-1, result5); + } + + static int nthOccurrenceIndex(String input, String regexPattern, int nth) { + Matcher matcher = Pattern.compile(regexPattern).matcher(INPUT); + for (int i = 0; i < nth; i++) { + if (!matcher.find()) { + return -1; + } + } + return matcher.start(); + } + + @Test + void whenCallingRegexBasedMethod_thenGetTheExpectedResult() { + int result1 = nthOccurrenceIndex(INPUT, "a", 1); + assertEquals(0, result1); + + int result2 = nthOccurrenceIndex(INPUT, "a", 2); + assertEquals(8, result2); + + int result3 = nthOccurrenceIndex(INPUT, "a", 3); + assertEquals(16, result3); + + int result4 = nthOccurrenceIndex(INPUT, "a", 4); + assertEquals(24, result4); + + int result5 = nthOccurrenceIndex(INPUT, "a", 5); + assertEquals(-1, result5); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/stringbuildercomparison/StringBuilderComparisonUnitTest.java b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/stringbuildercomparison/StringBuilderComparisonUnitTest.java new file mode 100644 index 0000000000..b1a5a83770 --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/stringbuildercomparison/StringBuilderComparisonUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.stringbuildercomparison; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertNotSame; + +import org.junit.Test; + +import stringbuildercomparison.StringBuilderCompare; + +public class StringBuilderComparisonUnitTest { + + @Test + public void whenUsingJavaEight_givenTwoIdenticalStringBuilders_thenCorrectlyMatch(){ + StringBuilder one = new StringBuilder("Hello"); + StringBuilder two = new StringBuilder("Hello"); + boolean result = StringBuilderCompare.compare(one, two); + assertEquals(true, result); + } + + @Test + public void whenUsingJavaEight_givenTwoDifferentStringBuilders_thenCorrectlyIdentifyDifference(){ + StringBuilder one = new StringBuilder("Hello"); + StringBuilder two = new StringBuilder("World"); + boolean result = StringBuilderCompare.compare(one, two); + assertEquals(false, result); + } + + @Test + public void whenUsingJavaEleven_givenTwoIdenticalStringBuilders_thenCorrectlyMatch(){ + StringBuilder one = new StringBuilder("Hello"); + StringBuilder two = new StringBuilder("Hello"); + assertEquals(0, one.compareTo(two)); + } + + @Test + public void whenUsingJavaEleven_givenTwoDifferentStringBuilders_thenCorrectlyIdentifyDifference(){ + StringBuilder one = new StringBuilder("Hello"); + StringBuilder two = new StringBuilder("World"); + assertNotSame(0, one.compareTo(two)); + } + + +} 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 c6debc4f71..383a3b4a40 100644 --- a/core-java-modules/core-java-string-operations-2/pom.xml +++ b/core-java-modules/core-java-string-operations-2/pom.xml @@ -14,11 +14,6 @@ - - javax.validation - validation-api - ${validation-api.version} - org.apache.commons commons-lang3 @@ -30,14 +25,9 @@ ${hibernate-validator.version} - javax.el - javax.el-api - ${javax.el-api.version} - - - org.glassfish.web - javax.el - ${javax.el.version} + org.glassfish.expressly + expressly + ${expressly.version} org.openjdk.jmh @@ -54,6 +44,11 @@ commons-codec ${commons-codec.version} + + org.springframework + spring-core + ${spring-core.version} + @@ -90,11 +85,10 @@ - 2.0.0.Final - 6.0.2.Final - 3.0.0 - 2.2.6 + 8.0.1.Final + 5.0.0 1.14 + 5.3.0 \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-2/src/main/java/com/baeldung/emptystrings/SomeClassWithValidations.java b/core-java-modules/core-java-string-operations-2/src/main/java/com/baeldung/emptystrings/SomeClassWithValidations.java index 058d53ba82..abe311938a 100644 --- a/core-java-modules/core-java-string-operations-2/src/main/java/com/baeldung/emptystrings/SomeClassWithValidations.java +++ b/core-java-modules/core-java-string-operations-2/src/main/java/com/baeldung/emptystrings/SomeClassWithValidations.java @@ -1,6 +1,6 @@ package com.baeldung.emptystrings; -import javax.validation.constraints.Pattern; +import jakarta.validation.constraints.Pattern; class SomeClassWithValidations { diff --git a/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/emptystrings/EmptyStringsUnitTest.java b/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/emptystrings/EmptyStringsUnitTest.java index d772c38341..c756953c70 100644 --- a/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/emptystrings/EmptyStringsUnitTest.java +++ b/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/emptystrings/EmptyStringsUnitTest.java @@ -3,11 +3,12 @@ package com.baeldung.emptystrings; import com.google.common.base.Strings; import org.apache.commons.lang3.StringUtils; import org.junit.Test; +import org.springframework.util.ObjectUtils; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import java.util.Set; import static org.hamcrest.Matchers.iterableWithSize; @@ -109,6 +110,24 @@ public class EmptyStringsUnitTest { assertFalse(Strings.isNullOrEmpty(blankString)); } + /* + * Spring Core ObjectUtils + */ + @Test + public void givenSomeEmptyString_thenObjectUtilsIsEmptyReturnsTrue() { + assertTrue(ObjectUtils.isEmpty(emptyString)); + } + + @Test + public void givenSomeNonEmptyString_thenObjectUtilsIsEmptyReturnsFalse() { + assertFalse(ObjectUtils.isEmpty(nonEmptyString)); + } + + @Test + public void givenSomeBlankString_thenObjectUtilsIsEmptyReturnsFalse() { + assertFalse(ObjectUtils.isEmpty(blankString)); + } + /* * Bean Validation */ 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 5cd1bd3c56..27c2bf91bd 100644 --- a/core-java-modules/core-java-string-operations-4/pom.xml +++ b/core-java-modules/core-java-string-operations-4/pom.xml @@ -58,7 +58,7 @@ 11 11 - 4.1 + 5.8 5.3.13 3.12.0 1.10.0 diff --git a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedString.java b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedString.java index c3bbdb4dfb..f2ae96128c 100644 --- a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedString.java +++ b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedString.java @@ -12,6 +12,7 @@ import com.opencsv.CSVParser; import com.opencsv.CSVParserBuilder; import com.opencsv.CSVReader; import com.opencsv.CSVReaderBuilder; +import com.opencsv.exceptions.CsvException; public class SplitCommaSeparatedString { @@ -50,7 +51,7 @@ public class SplitCommaSeparatedString { return splitter.splitToList(input); } - public static List splitMultiLineWithOpenCSV(String input) throws IOException { + public static List splitMultiLineWithOpenCSV(String input) throws IOException, CsvException { CSVParser parser = new CSVParserBuilder().withSeparator(',') .build(); diff --git a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedStringUnitTest.java b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedStringUnitTest.java index ca34430099..953acc6c78 100644 --- a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedStringUnitTest.java +++ b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedStringUnitTest.java @@ -14,6 +14,8 @@ import java.util.List; import org.junit.Test; +import com.opencsv.exceptions.CsvException; + public class SplitCommaSeparatedStringUnitTest { @Test @@ -27,7 +29,7 @@ public class SplitCommaSeparatedStringUnitTest { } @Test - public void givenMultiLineInput_whenParsing_shouldIgnoreCommasInsideDoubleQuotes() throws IOException { + public void givenMultiLineInput_whenParsing_shouldIgnoreCommasInsideDoubleQuotes() throws IOException, CsvException { String input = "baeldung,tutorial,splitting,text,\"ignoring this comma,\"" + System.lineSeparator() + "splitting,a,regular,line,no double quotes"; 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 6c4fab384b..28e2dccd39 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -2,3 +2,4 @@ ### Relevant Articles: - [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) diff --git a/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/mutablestrings/CharsetUsageExample.java b/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/mutablestrings/CharsetUsageExample.java new file mode 100644 index 0000000000..5ef8783ac8 --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/mutablestrings/CharsetUsageExample.java @@ -0,0 +1,34 @@ +package com.baeldung.mutablestrings; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; + +public class CharsetUsageExample { + + public ByteBuffer encodeString(String inputString) { + Charset charset = Charset.forName("UTF-8"); + CharsetEncoder encoder = charset.newEncoder(); + + CharBuffer charBuffer = CharBuffer.wrap(inputString); + ByteBuffer byteBuffer = ByteBuffer.allocate(50); + + encoder.encode(charBuffer, byteBuffer, true); // true indicates the end of input + byteBuffer.flip(); + return byteBuffer; + } + + public String decodeString(ByteBuffer byteBuffer) { + Charset charset = Charset.forName("UTF-8"); + CharsetDecoder decoder = charset.newDecoder(); + CharBuffer decodedCharBuffer = CharBuffer.allocate(50); + decoder.decode(byteBuffer, decodedCharBuffer, true); + decodedCharBuffer.flip(); + + return decodedCharBuffer.toString(); + } +} diff --git a/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/mutablestrings/MutableStringUsingCharset.java b/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/mutablestrings/MutableStringUsingCharset.java new file mode 100644 index 0000000000..3e4285c9d0 --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/mutablestrings/MutableStringUsingCharset.java @@ -0,0 +1,65 @@ +package com.baeldung.mutablestrings; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.util.concurrent.atomic.AtomicReference; + +public class MutableStringUsingCharset { + + private final AtomicReference cbRef = new AtomicReference<>(); + private final Charset myCharset = new Charset("mycharset", null) { + @Override + public boolean contains(Charset cs) { + return false; + } + + @Override + public CharsetDecoder newDecoder() { + return new CharsetDecoder(this, 1.0f, 1.0f) { + @Override + protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) { + cbRef.set(out); + while (in.remaining() > 0) { + out.append((char) in.get()); + } + return CoderResult.UNDERFLOW; + } + }; + } + + @Override + public CharsetEncoder newEncoder() { + CharsetEncoder cd = new CharsetEncoder(this, 1.0f, 1.0f) { + @Override + protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) { + while (in.hasRemaining()) { + if (!out.hasRemaining()) { + return CoderResult.OVERFLOW; + } + char currentChar = in.get(); + if (currentChar > 127) { + return CoderResult.unmappableForLength(1); + } + out.put((byte) currentChar); + } + return CoderResult.UNDERFLOW; + } + }; + return cd; + } + }; + + public String createModifiableString(String s) { + return new String(s.getBytes(), myCharset); + } + + public void modifyString() { + CharBuffer cb = cbRef.get(); + cb.position(0); + cb.put("xyz"); + } +} diff --git a/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/mutablestrings/MutableStrings.java b/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/mutablestrings/MutableStrings.java new file mode 100644 index 0000000000..99994498b9 --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/mutablestrings/MutableStrings.java @@ -0,0 +1,24 @@ +package com.baeldung.mutablestrings; + +import java.lang.reflect.Field; +import java.nio.charset.Charset; + +import com.google.errorprone.annotations.DoNotCall; + +public class MutableStrings { + + /** + * This involves using Reflection to change String fields and it is not encouraged to use this in programs. + * @throws NoSuchFieldException + * @throws IllegalAccessException + */ + @DoNotCall + public void mutableUsingReflection() throws NoSuchFieldException, IllegalAccessException { + String myString = "Hello World"; + String otherString = new String("Hello World"); + Field f = String.class.getDeclaredField("value"); + f.setAccessible(true); + f.set(myString, "Hi World".toCharArray()); + System.out.println(otherString); + } +} diff --git a/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/unicode/UnicodeLetterChecker.java b/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/unicode/UnicodeLetterChecker.java new file mode 100644 index 0000000000..8ac8671586 --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/main/java/com/baeldung/unicode/UnicodeLetterChecker.java @@ -0,0 +1,30 @@ +package com.baeldung.unicode; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.commons.lang3.StringUtils; + +public class UnicodeLetterChecker { + public boolean characterClassCheck(String input) { + for (char c : input.toCharArray()) { + if (!Character.isLetter(c)) { + return false; + } + } + return true; + } + + public boolean regexCheck(String input) { + Pattern pattern = Pattern.compile("^\\p{L}+$"); + Matcher matcher = pattern.matcher(input); + return matcher.matches(); + } + + public boolean isAlphaCheck(String input) { + return StringUtils.isAlpha(input); + } + + public boolean StreamsCheck(String input) { + return input.codePoints().allMatch(Character::isLetter); + } +} diff --git a/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/mutablestring/CharsetUsageUnitTest.java b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/mutablestring/CharsetUsageUnitTest.java new file mode 100644 index 0000000000..f009b0242f --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/mutablestring/CharsetUsageUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.mutablestring; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import com.baeldung.mutablestrings.CharsetUsageExample; + +public class CharsetUsageUnitTest { + + @Test + public void givenCharset_whenStringIsEncodedAndDecoded_thenGivesCorrectResult() { + CharsetUsageExample ch = new CharsetUsageExample(); + String inputString = "hello दुनिया"; + String result = ch.decodeString(ch.encodeString(inputString)); + Assertions.assertEquals(inputString, result); + } +} diff --git a/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/mutablestring/MutableStringUsingCharsetUnitTest.java b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/mutablestring/MutableStringUsingCharsetUnitTest.java new file mode 100644 index 0000000000..81a92038d5 --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/mutablestring/MutableStringUsingCharsetUnitTest.java @@ -0,0 +1,24 @@ +package com.baeldung.mutablestring; + +import org.junit.Assert; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import com.baeldung.mutablestrings.MutableStringUsingCharset; + +public class MutableStringUsingCharsetUnitTest { + @Test + @Disabled + /** + * This test is disabled as it works well for Java 8 and below + */ + public void givenCustomCharSet_whenStringUpdated_StringGetsMutated() throws Exception { + MutableStringUsingCharset ms = new MutableStringUsingCharset(); + String s = ms.createModifiableString("Hello"); + Assert.assertEquals("Hello", s); + ms.modifyString(); + Assert.assertEquals("something", s); + } + +} + diff --git a/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/unicode/UnicodeLetterCheckerUnitTest.java b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/unicode/UnicodeLetterCheckerUnitTest.java new file mode 100644 index 0000000000..a7ed9e5db9 --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/unicode/UnicodeLetterCheckerUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.unicode; + +import org.junit.Test; +import static org.junit.Assert.assertTrue; + +public class UnicodeLetterCheckerUnitTest { + @Test + public void givenString_whenUsingIsLetter_thenReturnTrue() { + UnicodeLetterChecker checker = new UnicodeLetterChecker(); + + boolean isUnicodeLetter = checker.characterClassCheck("HelloWorld"); + assertTrue(isUnicodeLetter); + } + + @Test + public void givenString_whenUsingRegex_thenReturnTrue() { + UnicodeLetterChecker checker = new UnicodeLetterChecker(); + + boolean isUnicodeLetter = checker.regexCheck("HelloWorld"); + assertTrue(isUnicodeLetter); + } + + @Test + public void givenString_whenUsingIsAlpha_thenReturnTrue() { + UnicodeLetterChecker checker = new UnicodeLetterChecker(); + + boolean isUnicodeLetter = checker.isAlphaCheck("HelloWorld"); + assertTrue(isUnicodeLetter); + } + + @Test + public void givenString_whenUsingStreams_thenReturnTrue() { + UnicodeLetterChecker checker = new UnicodeLetterChecker(); + + boolean isUnicodeLetter = checker.StreamsCheck("HelloWorld"); + assertTrue(isUnicodeLetter); + } +} diff --git a/core-java-modules/core-java-strings/README.md b/core-java-modules/core-java-strings/README.md index 03e980e5a5..e782793fea 100644 --- a/core-java-modules/core-java-strings/README.md +++ b/core-java-modules/core-java-strings/README.md @@ -14,3 +14,5 @@ Listed here there are only those articles that does not fit into other core-java - [Java String Interview Questions and Answers](https://www.baeldung.com/java-string-interview-questions) - [Java Multi-line String](https://www.baeldung.com/java-multiline-string) - [Reuse StringBuilder for Efficiency](https://www.baeldung.com/java-reuse-stringbuilder-for-efficiency) +- [How to Iterate Over the String Characters in Java](https://www.baeldung.com/java-iterate-string-characters) +- [Passing Strings by Reference in Java](https://www.baeldung.com/java-method-pass-string-reference) diff --git a/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringIterator/StringIterator.java b/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringIterator/StringIterator.java new file mode 100644 index 0000000000..0e46c7eedd --- /dev/null +++ b/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringIterator/StringIterator.java @@ -0,0 +1,42 @@ +package com.baeldung.stringIterator; + +import java.text.*; +import java.util.*; + +public class StringIterator { + + public static String javaCharArray(String str){ + StringBuilder result = new StringBuilder(); + for (char c : str.toCharArray()) { + result.append(c); + } + return result.toString(); + } + + public static String javaforLoop(String str) { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + result.append(c); + } + return result.toString(); + } + + public static String java8forEach(String str){ + StringBuilder result = new StringBuilder(); + str.chars().forEach(name -> { + result.append((char) name); + }); + return result.toString(); + } + + public static String javaCharacterIterator(String str){ + StringBuilder result = new StringBuilder(); + CharacterIterator it = new StringCharacterIterator(str); + while (it.current() != CharacterIterator.DONE) { + result.append(it.current()); + it.next(); + } + return result.toString(); + } +} diff --git a/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringIterator/StringIteratorTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringIterator/StringIteratorTest.java new file mode 100644 index 0000000000..585d65d4be --- /dev/null +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringIterator/StringIteratorTest.java @@ -0,0 +1,39 @@ +package com.baeldung.stringIterator; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class StringIteratorTest { + + @Test + public void whenUseCharArrayMethod_thenIterate() { + String input = "Hello, Baeldung!"; + String expectedOutput = "Hello, Baeldung!"; + String result = StringIterator.javaCharArray(input); + assertEquals(expectedOutput, result); + } + + @Test + public void whenUseJavaForLoop_thenIterate() { + String input = "Hello, Baeldung!"; + String expectedOutput = "Hello, Baeldung!"; + String result = StringIterator.javaForLoop(input); + assertEquals(expectedOutput, result); + } + + @Test + public void whenUseForEachMethod_thenIterate() { + String input = "Hello, Baeldung!"; + String expectedOutput = "Hello, Baeldung!"; + String result = StringIterator.java8ForEach(input); + assertEquals(expectedOutput, result); + } + + @Test + public void whenUseCharacterIterator_thenIterate() { + String input = "Hello, Baeldung!"; + String expectedOutput = "Hello, Baeldung!"; + String result = StringIterator.javaCharacterIterator(input); + assertEquals(expectedOutput, result); + } +} diff --git a/core-java-modules/core-java-sun/shared-mem-test1.bat b/core-java-modules/core-java-sun/shared-mem-test1.bat new file mode 100644 index 0000000000..148c51eb36 --- /dev/null +++ b/core-java-modules/core-java-sun/shared-mem-test1.bat @@ -0,0 +1,8 @@ +@rem This bat file starts the consumer and producer (more or less) at the same time +cd target\classes +rem start java --add-opens java.base/java.nio=ALL-UNNAMED com.baeldung.sharedmem.ProducerApp c:\lixo\sharedmem.bin 65536 +rem start java --add-opens java.base/java.nio=ALL-UNNAMED com.baeldung.sharedmem.ConsumerApp c:\lixo\sharedmem.bin 65536 +start %JAVA_HOME%\bin\java com.baeldung.sharedmem.ProducerApp c:\lixo\sharedmem.bin 65536 +start %JAVA_HOME%\bin\java com.baeldung.sharedmem.ConsumerApp c:\lixo\sharedmem.bin 65536 +cd .. +cd .. diff --git a/core-java-modules/core-java-sun/shared-mem-test2.bat b/core-java-modules/core-java-sun/shared-mem-test2.bat new file mode 100644 index 0000000000..7a7f8f7caa --- /dev/null +++ b/core-java-modules/core-java-sun/shared-mem-test2.bat @@ -0,0 +1,10 @@ +@rem This bat file starts the consumer and producer (more or less) at the same time +del target\sharedmem.bin +echo "" > target\sharedmem.bin +cd target\classes +rem start java --add-opens java.base/java.nio=ALL-UNNAMED com.baeldung.sharedmem.ProducerAppWithSpinLock ..\sharedmem.bin 65536 +rem start java --add-opens java.base/java.nio=ALL-UNNAMED com.baeldung.sharedmem.ConsumerAppWithSpinLock ..\sharedmem.bin 65536 +start %JAVA_HOME%\bin\java com.baeldung.sharedmem.ProducerAppWithSpinLock ..\sharedmem.bin 65536 +start %JAVA_HOME%\bin\java com.baeldung.sharedmem.ConsumerAppWithSpinLock ..\sharedmem.bin 65536 +cd .. +cd .. diff --git a/core-java-modules/core-java-sun/src/main/java/com/baeldung/park/ThreadMonitorInfo.java b/core-java-modules/core-java-sun/src/main/java/com/baeldung/park/ThreadMonitorInfo.java new file mode 100644 index 0000000000..948fb48fcb --- /dev/null +++ b/core-java-modules/core-java-sun/src/main/java/com/baeldung/park/ThreadMonitorInfo.java @@ -0,0 +1,26 @@ +package com.baeldung.park; + +import java.util.concurrent.locks.LockSupport; + +public class ThreadMonitorInfo { + private static final Object MONITOR = new Object(); + public static void main(String[] args) throws InterruptedException { + final Thread waitingThread = new Thread(() -> { + try { + synchronized (MONITOR) { + MONITOR.wait(); + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }, "Waiting Thread"); + + final Thread parkedThread = new Thread(LockSupport::park, "Parked Thread"); + + waitingThread.start(); + parkedThread.start(); + + waitingThread.join(); + parkedThread.join(); + } +} diff --git a/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerApp.java b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerApp.java new file mode 100644 index 0000000000..1fbc02bee9 --- /dev/null +++ b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerApp.java @@ -0,0 +1,94 @@ +package com.baeldung.sharedmem; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.security.MessageDigest; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Random; + +public class ConsumerApp { + + public static void main(String[] args) throws Exception { + + MessageDigest digest = MessageDigest.getInstance("SHA1"); + digest.digest(new byte[256]); + byte[] dummy = digest.digest(); + int hashLen = dummy.length; + + System.out.println("Starting consumer iterations..."); + + long size = Long.parseLong(args[1]); + MappedByteBuffer shm = createSharedMemory(args[0], size + hashLen); + long start = System.currentTimeMillis(); + long iterations = 0; + int capacity = shm.capacity(); + + long matchCount = 0; + long mismatchCount = 0; + byte[] expectedHash = new byte[hashLen]; + + while (System.currentTimeMillis() - start < 30_000) { + + for (int i = 0; i < capacity - hashLen; i++) { + byte value = shm.get(i); + digest.update(value); + } + + byte[] hash = digest.digest(); + shm.position(capacity-hashLen); + shm.get(expectedHash); + + if (Arrays.equals(hash, expectedHash)) { + matchCount++; + } else { + mismatchCount++; + } + + iterations++; + } + + System.out.printf("%d iterations run. matches=%d, mismatches=%d\n", iterations, matchCount, mismatchCount); + System.out.println("Press to exit"); + System.console() + .readLine(); + } + + private static MappedByteBuffer createSharedMemory(String path, long size) { + + try (FileChannel fc = (FileChannel) Files.newByteChannel( + new File(path).toPath(), + EnumSet.of( + StandardOpenOption.CREATE, + StandardOpenOption.SPARSE, + StandardOpenOption.WRITE, + StandardOpenOption.READ))) { + return fc.map(FileChannel.MapMode.READ_WRITE, 0, size); + + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + + private static long getBufferAddress(MappedByteBuffer shm) { + try { + Class cls = shm.getClass(); + Method maddr = cls.getMethod("address"); + maddr.setAccessible(true); + Long addr = (Long) maddr.invoke(shm); + if (addr == null) { + throw new RuntimeException("Unable to retrieve buffer's address"); + } + return addr; + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerAppWithSpinLock.java b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerAppWithSpinLock.java new file mode 100644 index 0000000000..fa91edda40 --- /dev/null +++ b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerAppWithSpinLock.java @@ -0,0 +1,119 @@ +package com.baeldung.sharedmem; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.security.MessageDigest; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Random; + +public class ConsumerAppWithSpinLock { + + public static void main(String[] args) { + try { + // Small wait to ensure the Producer gets the first round. Otherwise the hash will be invalid + Thread.sleep(1000); + run(args); + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + System.console() + .printf("Press to continue"); + System.console() + .readLine(); + } + } + + private static void run(String args[]) throws Exception { + + MessageDigest digest = MessageDigest.getInstance("SHA1"); + digest.digest(new byte[256]); + byte[] dummy = digest.digest(); + int hashLen = dummy.length; + + long size = Long.parseLong(args[1]); + MappedByteBuffer shm = createSharedMemory(args[0], size + hashLen); + long addr = getBufferAddress(shm); + + System.out.printf("Buffer address: 0x%08x\n", addr); + + Random rnd = new Random(); + + long start = System.currentTimeMillis(); + long iterations = 0; + int capacity = shm.capacity(); + System.out.println("Starting consumer iterations..."); + + long matchCount = 0; + long mismatchCount = 0; + byte[] expectedHash = new byte[hashLen]; + SpinLock lock = new SpinLock(addr); + + while (System.currentTimeMillis() - start < 30_000) { + + if (!lock.tryLock(5_000)) { + throw new RuntimeException("Unable to acquire lock"); + } + + try { + for (int i = 4; i < capacity - hashLen; i++) { + byte value = shm.get(i); + digest.update(value); + } + + byte[] hash = digest.digest(); + shm.position(capacity-hashLen); + shm.get(expectedHash); + + if (Arrays.equals(hash, expectedHash)) { + matchCount++; + } else { + mismatchCount++; + } + + iterations++; + } finally { + lock.unlock(); + } + } + + System.out.printf("%d iteractions run. matches=%d, mismatches=%d\n", iterations, matchCount, mismatchCount); + } + + private static MappedByteBuffer createSharedMemory(String path, long size) { + + try (FileChannel fc = (FileChannel) Files.newByteChannel( + new File(path).toPath(), + EnumSet.of( + StandardOpenOption.CREATE, + StandardOpenOption.SPARSE, + StandardOpenOption.WRITE, + StandardOpenOption.READ))) { + return fc.map(FileChannel.MapMode.READ_WRITE, 0, size); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + + private static long getBufferAddress(MappedByteBuffer shm) { + try { + Class cls = shm.getClass(); + Method maddr = cls.getMethod("address"); + maddr.setAccessible(true); + Long addr = (Long) maddr.invoke(shm); + if (addr == null) { + throw new RuntimeException("Unable to retrieve buffer's address"); + } + return addr; + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerApp.java b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerApp.java new file mode 100644 index 0000000000..ab7ca4d859 --- /dev/null +++ b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerApp.java @@ -0,0 +1,89 @@ +package com.baeldung.sharedmem; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.security.MessageDigest; +import java.util.EnumSet; +import java.util.Random; + +public class ProducerApp { + + + public static void main(String[] args) throws Exception { + + MessageDigest digest = MessageDigest.getInstance("SHA1"); + digest.digest(new byte[256]); + byte[] dummy = digest.digest(); + int hashLen = dummy.length; + + + long size = Long.parseLong(args[1]); + MappedByteBuffer shm = createSharedMemory(args[0], size + hashLen); + + System.out.println("Starting producer iterations..."); + + long start = System.currentTimeMillis(); + long iterations = 0; + int capacity = shm.capacity(); + Random rnd = new Random(); + + while(System.currentTimeMillis() - start < 30000) { + + for (int i = 0; i < capacity - hashLen; i++) { + byte value = (byte) (rnd.nextInt(256) & 0x00ff); + digest.update(value); + shm.put(i, value); + } + + // Write hash at the end + byte[] hash = digest.digest(); + shm.position(capacity - hashLen); + shm.put(hash); + iterations++; + } + + System.out.printf("%d iterations run\n", iterations); + System.out.println("Press to exit"); + System.console().readLine(); + + } + + private static long getBufferAddress(MappedByteBuffer shm) { + try { + Class cls = shm.getClass(); + Method maddr = cls.getMethod("address"); + maddr.setAccessible(true); + Long addr = (Long) maddr.invoke(shm); + if ( addr == null ) { + throw new RuntimeException("Unable to retrieve buffer's address"); + } + return addr; + } + catch( NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + + private static MappedByteBuffer createSharedMemory(String path, long size) { + + try (FileChannel fc = (FileChannel)Files.newByteChannel(new File(path).toPath(), + EnumSet.of( + StandardOpenOption.CREATE, + StandardOpenOption.SPARSE, + StandardOpenOption.WRITE, + StandardOpenOption.READ))) { + + return fc.map(FileChannel.MapMode.READ_WRITE, 0, size); + } + catch( IOException ioe) { + throw new RuntimeException(ioe); + } + } + +} diff --git a/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerAppWithSpinLock.java b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerAppWithSpinLock.java new file mode 100644 index 0000000000..619955eb2d --- /dev/null +++ b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerAppWithSpinLock.java @@ -0,0 +1,117 @@ +package com.baeldung.sharedmem; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.security.MessageDigest; +import java.util.EnumSet; +import java.util.Random; + +public class ProducerAppWithSpinLock { + + public static void main(String[] args) { + try { + run(args); + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + System.console() + .printf("Press to continue"); + System.console() + .readLine(); + } + } + + + public static void run(String[] args) throws Exception { + + MessageDigest digest = MessageDigest.getInstance("SHA1"); + digest.digest(new byte[256]); + byte[] dummy = digest.digest(); + int hashLen = dummy.length; + + + long size = Long.parseLong(args[1]); + MappedByteBuffer shm = createSharedMemory(args[0], size + hashLen); + + // Cleanup lock area + shm.putInt(0,0); + + long addr = getBufferAddress(shm); + System.out.printf("Buffer address: 0x%08x\n",addr); + Random rnd = new Random(); + + long start = System.currentTimeMillis(); + long iterations = 0; + int capacity = shm.capacity(); + System.out.println("Starting producer iterations..."); + SpinLock lock = new SpinLock(addr); + while(System.currentTimeMillis() - start < 30000) { + + if(!lock.tryLock(5000)) { + throw new RuntimeException("Unable to acquire lock"); + } + + try { + // Skip the first 4 bytes, as they're used by the lock + for (int i = 4; i < capacity - hashLen; i++) { + byte value = (byte) (rnd.nextInt(256) & 0x00ff); + digest.update(value); + shm.put(i, value); + } + + // Write hash at the end + byte[] hash = digest.digest(); + shm.position(capacity-hashLen); + shm.put(hash); + iterations++; + } + finally { + lock.unlock(); + } + } + + System.out.printf("%d iterations run\n", iterations); + + } + + private static long getBufferAddress(MappedByteBuffer shm) { + try { + Class cls = shm.getClass(); + Method maddr = cls.getMethod("address"); + maddr.setAccessible(true); + Long addr = (Long) maddr.invoke(shm); + if ( addr == null ) { + throw new RuntimeException("Unable to retrieve buffer's address"); + } + return addr; + } + catch( NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + + private static MappedByteBuffer createSharedMemory(String path, long size) { + + try (FileChannel fc = (FileChannel)Files.newByteChannel(new File(path).toPath(), + EnumSet.of( + StandardOpenOption.CREATE, + StandardOpenOption.SPARSE, + StandardOpenOption.WRITE, + StandardOpenOption.READ))) { + + return fc.map(FileChannel.MapMode.READ_WRITE, 0, size); + + } + catch( IOException ioe) { + throw new RuntimeException(ioe); + } + + } + +} diff --git a/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/SpinLock.java b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/SpinLock.java new file mode 100644 index 0000000000..145ac1e121 --- /dev/null +++ b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/SpinLock.java @@ -0,0 +1,43 @@ +package com.baeldung.sharedmem; + +//import sun.misc.Unsafe; + +import java.lang.reflect.Field; + +import sun.misc.Unsafe; + +public class SpinLock { + private static final Unsafe unsafe; + + static { + try { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + unsafe = (Unsafe) f.get(null); + } + catch(NoSuchFieldException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + + private final long addr; + + public SpinLock(long addr) { + this.addr = addr; + } + + public boolean tryLock(long maxWait) { + long deadline = System.currentTimeMillis() + maxWait; + while(System.currentTimeMillis() < deadline ) { + if ( unsafe.compareAndSwapInt(null,addr,0,1)) { + return true; + } + } + return false; + } + + public void unlock() { + unsafe.putInt(addr,0); + } + +} diff --git a/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/PreemptivePermitsBehaviorUnitTest.java b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/PreemptivePermitsBehaviorUnitTest.java new file mode 100644 index 0000000000..05bfa4ba0b --- /dev/null +++ b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/PreemptivePermitsBehaviorUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.park; + +import static org.junit.jupiter.api.Assertions.*; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.concurrent.locks.LockSupport; +import org.junit.jupiter.api.Test; + +class PreemptivePermitsBehaviorUnitTest { + + private final Thread parkedThread = new Thread() { + @Override + public void run() { + LockSupport.unpark(this); + LockSupport.park(); + } + }; + + @Test + void givenThreadWhenPreemptivePermitShouldNotPark() { + assertTimeoutPreemptively(Duration.of(1, ChronoUnit.SECONDS), () -> { + parkedThread.start(); + parkedThread.join(); + }); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/RepeatedPreemptivePermitsBehaviorUnitTest.java b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/RepeatedPreemptivePermitsBehaviorUnitTest.java new file mode 100644 index 0000000000..98be58e9d3 --- /dev/null +++ b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/RepeatedPreemptivePermitsBehaviorUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.park; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.LockSupport; +import org.junit.jupiter.api.Test; + +class RepeatedPreemptivePermitsBehaviorUnitTest { + + private final Thread parkedThread = new Thread() { + @Override + public void run() { + LockSupport.unpark(this); + LockSupport.unpark(this); + LockSupport.park(); + LockSupport.park(); + } + }; + + @Test + void givenThreadWhenRepeatedPreemptivePermitShouldPark() { + Callable callable = () -> { + parkedThread.start(); + parkedThread.join(); + return true; + }; + + boolean result = false; + final Future future = Executors.newSingleThreadExecutor().submit(callable); + try { + result = future.get(1, TimeUnit.SECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + // Expected the thread to be parked + } + assertFalse(result, "The thread should be parked"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/ThreadInterruptedBehaviorUnitTest.java b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/ThreadInterruptedBehaviorUnitTest.java new file mode 100644 index 0000000000..da7b6ffbc9 --- /dev/null +++ b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/ThreadInterruptedBehaviorUnitTest.java @@ -0,0 +1,56 @@ +package com.baeldung.park; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.LockSupport; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +class ThreadInterruptedBehaviorUnitTest { + + @Test + @Timeout(3) + void givenParkedThreadWhenInterruptedShouldNotResetInterruptedFlag() throws InterruptedException { + final Thread thread = new Thread(LockSupport::park); + thread.start(); + thread.interrupt(); + assertTrue(thread.isInterrupted(), "The thread should have the interrupted flag"); + thread.join(); + } + + @Test + @Timeout(3) + void givenParkedThreadWhenNotInterruptedShouldNotHaveInterruptedFlag() throws InterruptedException { + final Thread thread = new Thread(LockSupport::park); + thread.start(); + Thread.sleep(TimeUnit.SECONDS.toMillis(1)); + LockSupport.unpark(thread); + assertFalse(thread.isInterrupted(), "The thread shouldn't have the interrupted flag"); + thread.join(); + } + + @Test + @Timeout(3) + void givenWaitingThreadWhenNotInterruptedShouldNotHaveInterruptedFlag() throws InterruptedException { + + final Thread thread = new Thread() { + @Override + public void run() { + synchronized (this) { + try { + this.wait(); + } catch (InterruptedException e) { + // The thread was interrupted + } + } + } + }; + + thread.start(); + Thread.sleep(TimeUnit.SECONDS.toMillis(1)); + thread.interrupt(); + thread.join(); + assertFalse(thread.isInterrupted(), "The thread shouldn't have the interrupted flag"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/TreadMonitorsBehaviorUnitTest.java b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/TreadMonitorsBehaviorUnitTest.java new file mode 100644 index 0000000000..b14b674a19 --- /dev/null +++ b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/TreadMonitorsBehaviorUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.park; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.LockSupport; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + + +class TreadMonitorsBehaviorUnitTest { + + @Test + @Timeout(3) + void giveThreadWhenNotifyWithoutAcquiringMonitorThrowsException() { + final Thread thread = new Thread() { + @Override + public void run() { + synchronized (this) { + try { + this.wait(); + } catch (InterruptedException e) { + // The thread was interrupted + } + } + } + }; + + assertThrows(IllegalMonitorStateException.class, () -> { + thread.start(); + Thread.sleep(TimeUnit.SECONDS.toMillis(1)); + thread.notify(); + thread.join(); + }); + } + + @Test + @Timeout(3) + void giveThreadWhenUnparkWithoutAcquiringMonitor() { + final Thread thread = new Thread(LockSupport::park); + assertTimeoutPreemptively(Duration.of(2, ChronoUnit.SECONDS), () -> { + thread.start(); + LockSupport.unpark(thread); + }); + } +} diff --git a/java-native/README.md b/core-java-modules/java-native/README.md similarity index 100% rename from java-native/README.md rename to core-java-modules/java-native/README.md diff --git a/java-native/pom.xml b/core-java-modules/java-native/pom.xml similarity index 88% rename from java-native/pom.xml rename to core-java-modules/java-native/pom.xml index 95cb24bd98..2c4a8ea4ee 100644 --- a/java-native/pom.xml +++ b/core-java-modules/java-native/pom.xml @@ -7,9 +7,9 @@ java-native - com.baeldung - parent-modules - 1.0.0-SNAPSHOT + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT diff --git a/java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp diff --git a/java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h diff --git a/java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp diff --git a/java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h diff --git a/java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp diff --git a/java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h diff --git a/java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.cpp b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.cpp similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.cpp rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.cpp diff --git a/java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.h b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.h similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.h rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.h diff --git a/java-native/src/main/cpp/generateNativeLib.bat b/core-java-modules/java-native/src/main/cpp/generateNativeLib.bat similarity index 100% rename from java-native/src/main/cpp/generateNativeLib.bat rename to core-java-modules/java-native/src/main/cpp/generateNativeLib.bat diff --git a/java-native/src/main/cpp/generateNativeLib.sh b/core-java-modules/java-native/src/main/cpp/generateNativeLib.sh similarity index 100% rename from java-native/src/main/cpp/generateNativeLib.sh rename to core-java-modules/java-native/src/main/cpp/generateNativeLib.sh diff --git a/java-native/src/main/cpp/generateNativeLibMac.sh b/core-java-modules/java-native/src/main/cpp/generateNativeLibMac.sh old mode 100755 new mode 100644 similarity index 100% rename from java-native/src/main/cpp/generateNativeLibMac.sh rename to core-java-modules/java-native/src/main/cpp/generateNativeLibMac.sh diff --git a/java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.cpp b/core-java-modules/java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.cpp similarity index 100% rename from java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.cpp rename to core-java-modules/java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.cpp diff --git a/java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.h b/core-java-modules/java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.h similarity index 100% rename from java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.h rename to core-java-modules/java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.h diff --git a/java-native/src/main/cpp/unsatisfiedlink/generateNativeLib.sh b/core-java-modules/java-native/src/main/cpp/unsatisfiedlink/generateNativeLib.sh old mode 100755 new mode 100644 similarity index 100% rename from java-native/src/main/cpp/unsatisfiedlink/generateNativeLib.sh rename to core-java-modules/java-native/src/main/cpp/unsatisfiedlink/generateNativeLib.sh diff --git a/java-native/src/main/java/com/baeldung/jna/CMath.java b/core-java-modules/java-native/src/main/java/com/baeldung/jna/CMath.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jna/CMath.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jna/CMath.java diff --git a/java-native/src/main/java/com/baeldung/jna/Main.java b/core-java-modules/java-native/src/main/java/com/baeldung/jna/Main.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jna/Main.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jna/Main.java diff --git a/java-native/src/main/java/com/baeldung/jna/NativeFS.java b/core-java-modules/java-native/src/main/java/com/baeldung/jna/NativeFS.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jna/NativeFS.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jna/NativeFS.java diff --git a/java-native/src/main/java/com/baeldung/jna/StdC.java b/core-java-modules/java-native/src/main/java/com/baeldung/jna/StdC.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jna/StdC.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jna/StdC.java diff --git a/java-native/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java b/core-java-modules/java-native/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java diff --git a/java-native/src/main/java/com/baeldung/jni/ExampleParametersJNI.java b/core-java-modules/java-native/src/main/java/com/baeldung/jni/ExampleParametersJNI.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jni/ExampleParametersJNI.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jni/ExampleParametersJNI.java diff --git a/java-native/src/main/java/com/baeldung/jni/HelloWorldJNI.java b/core-java-modules/java-native/src/main/java/com/baeldung/jni/HelloWorldJNI.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jni/HelloWorldJNI.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jni/HelloWorldJNI.java diff --git a/java-native/src/main/java/com/baeldung/jni/RegisterNativesHelloWorldJNI.java b/core-java-modules/java-native/src/main/java/com/baeldung/jni/RegisterNativesHelloWorldJNI.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jni/RegisterNativesHelloWorldJNI.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jni/RegisterNativesHelloWorldJNI.java diff --git a/java-native/src/main/java/com/baeldung/jni/UserData.java b/core-java-modules/java-native/src/main/java/com/baeldung/jni/UserData.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jni/UserData.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jni/UserData.java diff --git a/java-native/src/main/java/com/baeldung/jvmbitversion/JVMBitVersion.java b/core-java-modules/java-native/src/main/java/com/baeldung/jvmbitversion/JVMBitVersion.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jvmbitversion/JVMBitVersion.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jvmbitversion/JVMBitVersion.java diff --git a/java-native/src/main/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLink.java b/core-java-modules/java-native/src/main/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLink.java similarity index 100% rename from java-native/src/main/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLink.java rename to core-java-modules/java-native/src/main/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLink.java diff --git a/java-native/src/main/resources/logback.xml b/core-java-modules/java-native/src/main/resources/logback.xml similarity index 100% rename from java-native/src/main/resources/logback.xml rename to core-java-modules/java-native/src/main/resources/logback.xml diff --git a/java-native/src/main/resources/unsatisfiedlink/jni.policy b/core-java-modules/java-native/src/main/resources/unsatisfiedlink/jni.policy similarity index 100% rename from java-native/src/main/resources/unsatisfiedlink/jni.policy rename to core-java-modules/java-native/src/main/resources/unsatisfiedlink/jni.policy diff --git a/java-native/src/test/java/com/baeldung/jna/CMathUnitTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/jna/CMathUnitTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/jna/CMathUnitTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/jna/CMathUnitTest.java diff --git a/java-native/src/test/java/com/baeldung/jna/NativeFSUnitTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/jna/NativeFSUnitTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/jna/NativeFSUnitTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/jna/NativeFSUnitTest.java diff --git a/java-native/src/test/java/com/baeldung/jna/StdCUnitTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/jna/StdCUnitTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/jna/StdCUnitTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/jna/StdCUnitTest.java diff --git a/java-native/src/test/java/com/baeldung/jni/JNINativeManualTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/jni/JNINativeManualTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/jni/JNINativeManualTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/jni/JNINativeManualTest.java diff --git a/java-native/src/test/java/com/baeldung/jni/registernatives/JNIRegisterNativesManualTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/jni/registernatives/JNIRegisterNativesManualTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/jni/registernatives/JNIRegisterNativesManualTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/jni/registernatives/JNIRegisterNativesManualTest.java diff --git a/java-native/src/test/java/com/baeldung/jvmbitversion/JVMBitVersionUnitTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/jvmbitversion/JVMBitVersionUnitTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/jvmbitversion/JVMBitVersionUnitTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/jvmbitversion/JVMBitVersionUnitTest.java diff --git a/java-native/src/test/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLinkManualTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLinkManualTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLinkManualTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLinkManualTest.java diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index bf5b90cd32..a237fe0ed6 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -21,7 +21,9 @@ - + core-java-collections-conversions-2 + core-java-collections-conversions-3 + core-java-concurrency-advanced-5 @@ -32,6 +34,7 @@ + core-java-numbers-conversions core-java-9-improvements core-java-9-streams core-java-9 @@ -195,10 +198,12 @@ core-java-records core-java-9-jigsaw + core-java-collections-set core-java-date-operations-1 - + core-java-datetime-conversion core-java-httpclient + java-native diff --git a/data-structures/src/main/java/com/baeldung/avltree/AVLTree.java b/data-structures/src/main/java/com/baeldung/avltree/AVLTree.java index ca0cfce7b4..117a35e028 100644 --- a/data-structures/src/main/java/com/baeldung/avltree/AVLTree.java +++ b/data-structures/src/main/java/com/baeldung/avltree/AVLTree.java @@ -42,17 +42,17 @@ public class AVLTree { return root == null ? -1 : root.height; } - private Node insert(Node node, int key) { - if (node == null) { + private Node insert(Node root, int key) { + if (root == null) { return new Node(key); - } else if (node.key > key) { - node.left = insert(node.left, key); - } else if (node.key < key) { - node.right = insert(node.right, key); + } else if (root.key > key) { + root.left = insert(root.left, key); + } else if (root.key < key) { + root.right = insert(root.right, key); } else { throw new RuntimeException("duplicate Key!"); } - return rebalance(node); + return rebalance(root); } private Node delete(Node node, int key) { diff --git a/di-modules/avaje/pom.xml b/di-modules/avaje/pom.xml index 49162c518e..03d3902d5f 100644 --- a/di-modules/avaje/pom.xml +++ b/di-modules/avaje/pom.xml @@ -3,14 +3,11 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung - inject-intro + avaje 0.0.1-SNAPSHOT - avaje-inject-intro - - 11 - 11 - 9.5 - + avaje + Avaje Inject Intro + io.avaje @@ -34,4 +31,10 @@ true + + + 11 + 11 + 9.5 + \ No newline at end of file diff --git a/di-modules/pom.xml b/di-modules/pom.xml index e6c86d48e6..984180cb28 100644 --- a/di-modules/pom.xml +++ b/di-modules/pom.xml @@ -18,6 +18,7 @@ dagger flyway-cdi-extension guice + avaje \ No newline at end of file diff --git a/ethereum/pom.xml b/ethereum/pom.xml index 8dc25427d9..a94f74c115 100644 --- a/ethereum/pom.xml +++ b/ethereum/pom.xml @@ -192,7 +192,7 @@ 1.5.0-RELEASE 3.3.1 1.5.6.RELEASE - 2.4.0 + 2.8.0 2.0.4.RELEASE 3.1 diff --git a/google-auto-project/pom.xml b/google-auto-project/pom.xml index 034fea5aad..175e0c20c6 100644 --- a/google-auto-project/pom.xml +++ b/google-auto-project/pom.xml @@ -8,7 +8,6 @@ google-auto-project pom - com.baeldung parent-modules diff --git a/gradle-modules/gradle-7/README.md b/gradle-modules/gradle-7/README.md index e59b59f9fd..fe05a4b9bc 100644 --- a/gradle-modules/gradle-7/README.md +++ b/gradle-modules/gradle-7/README.md @@ -5,5 +5,4 @@ - [Working With Multiple Repositories in Gradle](https://www.baeldung.com/java-gradle-multiple-repositories) - [Different Dependency Version Declarations in Gradle](https://www.baeldung.com/gradle-different-dependency-version-declarations) - [Generating Javadoc With Gradle](https://www.baeldung.com/java-gradle-javadoc) -- [Generating WSDL Stubs With Gradle](https://www.baeldung.com/java-gradle-create-wsdl-stubs) -- [Gradle Toolchains Support for JVM Projects](https://www.baeldung.com/java-gradle-toolchains-jvm-projects) +- [Generating WSDL Stubs With Gradle](https://www.baeldung.com/java-gradle-create-wsdl-stubs) \ No newline at end of file diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/.gitignore b/gradle-modules/gradle-7/conditional-dependency-demo/.gitignore index c2065bc262..d33fc4ef35 100644 --- a/gradle-modules/gradle-7/conditional-dependency-demo/.gitignore +++ b/gradle-modules/gradle-7/conditional-dependency-demo/.gitignore @@ -1,7 +1,7 @@ HELP.md .gradle build/ -!gradle/wrapper/gradle-wrapper.jar +!../gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ !**/src/test/**/build/ diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 41d9927a4d..0000000000 Binary files a/gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 00e33edef6..0000000000 --- a/gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/gradlew b/gradle-modules/gradle-7/conditional-dependency-demo/gradlew deleted file mode 100755 index 1b6c787337..0000000000 --- a/gradle-modules/gradle-7/conditional-dependency-demo/gradlew +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/gradlew.bat b/gradle-modules/gradle-7/conditional-dependency-demo/gradlew.bat deleted file mode 100644 index 107acd32c4..0000000000 --- a/gradle-modules/gradle-7/conditional-dependency-demo/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/gradle-modules/gradle-7/gradle-javadoc/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/gradle-javadoc/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f0..0000000000 Binary files a/gradle-modules/gradle-7/gradle-javadoc/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle-modules/gradle-7/gradle-javadoc/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-7/gradle-javadoc/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index ae04661ee7..0000000000 --- a/gradle-modules/gradle-7/gradle-javadoc/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/gradle-javadoc/gradlew b/gradle-modules/gradle-7/gradle-javadoc/gradlew deleted file mode 100755 index a69d9cb6c2..0000000000 --- a/gradle-modules/gradle-7/gradle-javadoc/gradlew +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle b/gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle index e368dc5c06..6d0cfc1972 100644 --- a/gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle +++ b/gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id("com.github.bjornvester.wsdl2java") version "1.2" + id 'com.github.bjornvester.wsdl2java' version '2.0.2' } repositories { @@ -17,7 +17,6 @@ test { useJUnitPlatform() } - wsdl2java { - cxfVersion.set("3.4.4") + cxfVersion.set("4.0.2") } diff --git a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index ccebba7710..0000000000 Binary files a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew.bat b/gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew.bat deleted file mode 100644 index 6689b85bee..0000000000 --- a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.properties similarity index 82% rename from gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.properties rename to gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.properties index 42defcc94b..878fe049c2 100644 --- a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-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-7/dependency-version/gradlew b/gradle-modules/gradle-7/gradlew old mode 100755 new mode 100644 similarity index 91% rename from gradle-modules/gradle-7/dependency-version/gradlew rename to gradle-modules/gradle-7/gradlew index 79a61d421c..1aa94a4269 --- a/gradle-modules/gradle-7/dependency-version/gradlew +++ b/gradle-modules/gradle-7/gradlew @@ -83,10 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradle-modules/gradle-7/dependency-version/gradlew.bat b/gradle-modules/gradle-7/gradlew.bat similarity index 100% rename from gradle-modules/gradle-7/dependency-version/gradlew.bat rename to gradle-modules/gradle-7/gradlew.bat diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 41d9927a4d..0000000000 Binary files a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 070cb702f0..0000000000 --- a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew b/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew deleted file mode 100755 index 1b6c787337..0000000000 --- a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew.bat b/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew.bat deleted file mode 100644 index 107acd32c4..0000000000 --- a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 41d9927a4d..0000000000 Binary files a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 070cb702f0..0000000000 --- a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew b/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew deleted file mode 100755 index 1b6c787337..0000000000 --- a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew.bat b/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew.bat deleted file mode 100644 index 107acd32c4..0000000000 --- a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/settings.gradle b/gradle-modules/gradle-7/multiple-repositories-demo/settings.gradle new file mode 100644 index 0000000000..b5c2e6ecaa --- /dev/null +++ b/gradle-modules/gradle-7/multiple-repositories-demo/settings.gradle @@ -0,0 +1,4 @@ +rootProject.name = 'multiple-repositories-demo' + +include 'multiple-repositories' +include 'publish-package' \ No newline at end of file diff --git a/gradle-modules/gradle-7/settings.gradle b/gradle-modules/gradle-7/settings.gradle new file mode 100644 index 0000000000..0685ca8f59 --- /dev/null +++ b/gradle-modules/gradle-7/settings.gradle @@ -0,0 +1,7 @@ +rootProject.name = 'gradle-7' + +include 'conditional-dependency-demo' +include 'dependency-version' +include 'gradle-javadoc' +include 'gradle-wsdl-stubs' +include 'multiple-repositories-demo' \ No newline at end of file diff --git a/gradle-modules/gradle-8/README.md b/gradle-modules/gradle-8/README.md new file mode 100644 index 0000000000..53e5fa4ae0 --- /dev/null +++ b/gradle-modules/gradle-8/README.md @@ -0,0 +1,4 @@ + +### Relevant Articles: + +- [Gradle Toolchains Support for JVM Projects](https://www.baeldung.com/java-gradle-toolchains-jvm-projects) diff --git a/gradle-modules/gradle-7/toolchains-feature/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.properties similarity index 82% rename from gradle-modules/gradle-7/toolchains-feature/gradle/wrapper/gradle-wrapper.properties rename to gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.properties index 37aef8d3f0..3fa8f862f7 100644 --- a/gradle-modules/gradle-7/toolchains-feature/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew b/gradle-modules/gradle-8/gradlew old mode 100755 new mode 100644 similarity index 91% rename from gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew rename to gradle-modules/gradle-8/gradlew index 79a61d421c..1aa94a4269 --- a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew +++ b/gradle-modules/gradle-8/gradlew @@ -83,10 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradle-modules/gradle-7/toolchains-feature/gradlew.bat b/gradle-modules/gradle-8/gradlew.bat similarity index 100% rename from gradle-modules/gradle-7/toolchains-feature/gradlew.bat rename to gradle-modules/gradle-8/gradlew.bat diff --git a/gradle-modules/gradle-8/settings.gradle b/gradle-modules/gradle-8/settings.gradle new file mode 100644 index 0000000000..f2098b2611 --- /dev/null +++ b/gradle-modules/gradle-8/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = 'gradle-8' + +include 'toolchains-feature' \ No newline at end of file diff --git a/gradle-modules/gradle-7/toolchains-feature/.gitattributes b/gradle-modules/gradle-8/toolchains-feature/.gitattributes similarity index 100% rename from gradle-modules/gradle-7/toolchains-feature/.gitattributes rename to gradle-modules/gradle-8/toolchains-feature/.gitattributes diff --git a/gradle-modules/gradle-7/toolchains-feature/.gitignore b/gradle-modules/gradle-8/toolchains-feature/.gitignore similarity index 100% rename from gradle-modules/gradle-7/toolchains-feature/.gitignore rename to gradle-modules/gradle-8/toolchains-feature/.gitignore diff --git a/gradle-modules/gradle-7/toolchains-feature/build.gradle b/gradle-modules/gradle-8/toolchains-feature/build.gradle similarity index 100% rename from gradle-modules/gradle-7/toolchains-feature/build.gradle rename to gradle-modules/gradle-8/toolchains-feature/build.gradle diff --git a/gradle-modules/gradle-7/toolchains-feature/settings.gradle b/gradle-modules/gradle-8/toolchains-feature/settings.gradle similarity index 100% rename from gradle-modules/gradle-7/toolchains-feature/settings.gradle rename to gradle-modules/gradle-8/toolchains-feature/settings.gradle diff --git a/gradle-modules/gradle-customization/gradle-protobuf/gradlew b/gradle-modules/gradle-customization/gradle-protobuf/gradlew old mode 100755 new mode 100644 diff --git a/gradle-modules/settings.gradle b/gradle-modules/settings.gradle index 34dbd0cf53..cfd8b14d48 100644 --- a/gradle-modules/settings.gradle +++ b/gradle-modules/settings.gradle @@ -3,3 +3,5 @@ include 'gradle' include 'gradle-5' include 'gradle-6' include 'gradle-7' +include 'gradle-8' +include 'gradle-customization' diff --git a/intelliJ-modules/.gitignore b/intelliJ-modules/.gitignore new file mode 100644 index 0000000000..d16386367f --- /dev/null +++ b/intelliJ-modules/.gitignore @@ -0,0 +1 @@ +build/ \ No newline at end of file diff --git a/gradle-modules/gradle-7/dependency-version/gradle/wrapper/gradle-wrapper.properties b/intelliJ-modules/gradle/wrapper/gradle-wrapper.properties similarity index 82% rename from gradle-modules/gradle-7/dependency-version/gradle/wrapper/gradle-wrapper.properties rename to intelliJ-modules/gradle/wrapper/gradle-wrapper.properties index bdc9a83b1e..62f495dfed 100644 --- a/gradle-modules/gradle-7/dependency-version/gradle/wrapper/gradle-wrapper.properties +++ b/intelliJ-modules/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/toolchains-feature/gradlew b/intelliJ-modules/gradlew old mode 100755 new mode 100644 similarity index 98% rename from gradle-modules/gradle-7/toolchains-feature/gradlew rename to intelliJ-modules/gradlew index aeb74cbb43..fcb6fca147 --- a/gradle-modules/gradle-7/toolchains-feature/gradlew +++ b/intelliJ-modules/gradlew @@ -130,10 +130,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. diff --git a/gradle-modules/gradle-7/gradle-javadoc/gradlew.bat b/intelliJ-modules/gradlew.bat similarity index 96% rename from gradle-modules/gradle-7/gradle-javadoc/gradlew.bat rename to intelliJ-modules/gradlew.bat index 53a6b238d4..93e3f59f13 100644 --- a/gradle-modules/gradle-7/gradle-javadoc/gradlew.bat +++ b/intelliJ-modules/gradlew.bat @@ -1,91 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/intelliJ-modules/settings.gradle b/intelliJ-modules/settings.gradle new file mode 100644 index 0000000000..ff10e09b3c --- /dev/null +++ b/intelliJ-modules/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = 'intellij-modules' +include 'stackoverflow-plugin' +include 'stackoverflow-plugin-gradle' diff --git a/intelliJ-modules/stackoverflow-plugin-gradle/build.gradle b/intelliJ-modules/stackoverflow-plugin-gradle/build.gradle index cd0cc258bf..3967a1f075 100644 --- a/intelliJ-modules/stackoverflow-plugin-gradle/build.gradle +++ b/intelliJ-modules/stackoverflow-plugin-gradle/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.jetbrains.intellij' version '0.4.21' + id 'org.jetbrains.intellij' version '1.16.0' } group 'com.baeldung' @@ -11,15 +11,17 @@ repositories { } dependencies { - testCompile group: 'junit', name: 'junit', version: '4.12' + testImplementation('junit:junit:4.12') } // See https://github.com/JetBrains/gradle-intellij-plugin/ intellij { - version '2020.1.1' + version = "2022.2.5" + type = "IC" } + patchPluginXml { - changeNotes """ + changeNotes = """ Add change notes here.
most HTML tags may be used""" } \ No newline at end of file diff --git a/intelliJ-modules/stackoverflow-plugin/build.gradle b/intelliJ-modules/stackoverflow-plugin/build.gradle new file mode 100644 index 0000000000..81962e0e0a --- /dev/null +++ b/intelliJ-modules/stackoverflow-plugin/build.gradle @@ -0,0 +1,5 @@ +// this project is not supposed to be built. We check only if it compiles fine. + +plugins { + id 'java' +} \ No newline at end of file diff --git a/intelliJ-modules/stackoverflow-plugin/settings.gradle b/intelliJ-modules/stackoverflow-plugin/settings.gradle new file mode 100644 index 0000000000..4ebea35284 --- /dev/null +++ b/intelliJ-modules/stackoverflow-plugin/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'stackoverflow-plugin' diff --git a/jackson-modules/jackson-annotations/pom.xml b/jackson-modules/jackson-annotations/pom.xml index e2d5e1e607..59d7d3d197 100644 --- a/jackson-modules/jackson-annotations/pom.xml +++ b/jackson-modules/jackson-annotations/pom.xml @@ -21,7 +21,7 @@ io.rest-assured json-path - ${rest-assured.version} + ${json-path.version} test @@ -59,7 +59,7 @@ 2.1.214 - 3.1.1 + 5.3.2 2.5.0 diff --git a/java-websocket/pom.xml b/java-websocket/pom.xml index d529b32022..fd97fd9db3 100644 --- a/java-websocket/pom.xml +++ b/java-websocket/pom.xml @@ -29,7 +29,7 @@ 1.1 - 2.8.0 + 2.10.1 \ No newline at end of file diff --git a/javaxval/pom.xml b/javaxval/pom.xml index bececb2ea7..c4a30f915d 100644 --- a/javaxval/pom.xml +++ b/javaxval/pom.xml @@ -37,7 +37,7 @@ - 6.2.0.Final + 8.0.1.Final 3.0.4 diff --git a/jersey/README.md b/jersey/README.md index aa5a6a3b28..24e39f02a2 100644 --- a/jersey/README.md +++ b/jersey/README.md @@ -12,3 +12,4 @@ This module contains articles about Jersey. - [Add a Header to a Jersey SSE Client Request](https://www.baeldung.com/jersey-sse-client-request-headers) - [Exception Handling With Jersey](https://www.baeldung.com/java-exception-handling-jersey) - [@FormDataParam vs. @FormParam in Jersey](https://www.baeldung.com/jersey-formdataparam-vs-formparam) +- [Add a List as Query Parameter in Jersey](https://www.baeldung.com/java-jersey-list-query-param) diff --git a/jersey/src/main/java/com/baeldung/jersey/client/listdemo/JerseyListDemo.java b/jersey/src/main/java/com/baeldung/jersey/client/listdemo/JerseyListDemo.java new file mode 100644 index 0000000000..52be341653 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/client/listdemo/JerseyListDemo.java @@ -0,0 +1,15 @@ +package com.baeldung.jersey.client.listdemo; + +import java.util.List; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.QueryParam; + +@Path("/") +public class JerseyListDemo { + @GET + public String getItems(@QueryParam("items") List items) { + return "Received items: " + items; + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/client/listdemo/ListDemoApp.java b/jersey/src/main/java/com/baeldung/jersey/client/listdemo/ListDemoApp.java new file mode 100644 index 0000000000..7f5be883da --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/client/listdemo/ListDemoApp.java @@ -0,0 +1,9 @@ +package com.baeldung.jersey.client.listdemo; + +import org.glassfish.jersey.server.ResourceConfig; + +public class ListDemoApp extends ResourceConfig { + public ListDemoApp() { + packages("com.baeldung.jersey.client.listdemo"); + } +} diff --git a/jersey/src/test/java/com/baeldung/jersey/client/listdemo/JerseyListDemoUnitTest.java b/jersey/src/test/java/com/baeldung/jersey/client/listdemo/JerseyListDemoUnitTest.java new file mode 100644 index 0000000000..0aff6dcabf --- /dev/null +++ b/jersey/src/test/java/com/baeldung/jersey/client/listdemo/JerseyListDemoUnitTest.java @@ -0,0 +1,57 @@ +package com.baeldung.jersey.client.listdemo; + +import static org.junit.Assert.assertEquals; + +import java.net.URI; +import java.util.Arrays; +import java.util.List; + +import org.glassfish.jersey.test.JerseyTest; +import org.glassfish.jersey.test.TestProperties; +import org.junit.Test; + +import jakarta.ws.rs.core.Application; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; + +public class JerseyListDemoUnitTest extends JerseyTest { + + @Override + protected Application configure() { + enable(TestProperties.LOG_TRAFFIC); + enable(TestProperties.DUMP_ENTITY); + return new ListDemoApp(); + } + + @Test + public void givenList_whenUsingQueryParam_thenPassParamsAsList() { + Response response = target("/") + .queryParam("items", "item1", "item2") + .request() + .get(); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + assertEquals("Received items: [item1, item2]", response.readEntity(String.class)); + } + + @Test + public void givenList_whenUsingCommaSeparatedString_thenPassParamsAsList() { + Response response = target("/") + .queryParam("items", "item1,item2") + .request() + .get(); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + assertEquals("Received items: [item1,item2]", response.readEntity(String.class)); + } + + @Test + public void givenList_whenUsingUriBuilder_thenPassParamsAsList() { + List itemsList = Arrays.asList("item1", "item2"); + UriBuilder builder = UriBuilder.fromUri("/"); + for (String item : itemsList) { + builder.queryParam("items", item); + } + URI uri = builder.build(); + String expectedUri = "/?items=item1&items=item2"; + assertEquals(expectedUri, uri.toString()); + } +} diff --git a/json-modules/gson/pom.xml b/json-modules/gson/pom.xml index ecfbaa7be4..9e29bab3c4 100644 --- a/json-modules/gson/pom.xml +++ b/json-modules/gson/pom.xml @@ -64,8 +64,8 @@ - 2.8.0 - 2.9.6 + 2.10.1 + 2.12.5 \ No newline at end of file diff --git a/json-modules/gson/src/test/java/com/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java b/json-modules/gson/src/test/java/com/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java index 9f07617969..e1e5e48269 100644 --- a/json-modules/gson/src/test/java/com/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java +++ b/json-modules/gson/src/test/java/com/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java @@ -1,6 +1,10 @@ package com.baeldung.gson.conversion; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.google.gson.*; + import org.junit.Assert; import org.junit.jupiter.api.Test; @@ -10,24 +14,29 @@ public class JsonObjectConversionsUnitTest { void whenUsingJsonParser_thenConvertToJsonObject() throws Exception { // Example 1: Using JsonParser String json = "{ \"name\": \"Baeldung\", \"java\": true }"; - - JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject(); - - Assert.assertTrue(jsonObject.isJsonObject()); - Assert.assertTrue(jsonObject.get("name").getAsString().equals("Baeldung")); - Assert.assertTrue(jsonObject.get("java").getAsBoolean() == true); + + JsonObject jsonObject = JsonParser.parseString(json) + .getAsJsonObject(); + + assertTrue(jsonObject.isJsonObject()); + assertEquals("Baeldung", jsonObject.get("name") + .getAsString()); + assertTrue(jsonObject.get("java") + .getAsBoolean()); } @Test void whenUsingGsonInstanceFromJson_thenConvertToJsonObject() throws Exception { // Example 2: Using fromJson String json = "{ \"name\": \"Baeldung\", \"java\": true }"; - + JsonObject convertedObject = new Gson().fromJson(json, JsonObject.class); - - Assert.assertTrue(convertedObject.isJsonObject()); - Assert.assertTrue(convertedObject.get("name").getAsString().equals("Baeldung")); - Assert.assertTrue(convertedObject.get("java").getAsBoolean() == true); + + assertTrue(convertedObject.isJsonObject()); + assertEquals("Baeldung", convertedObject.get("name") + .getAsString()); + assertTrue(convertedObject.get("java") + .getAsBoolean()); } } diff --git a/json-modules/gson/src/test/java/com/baeldung/gson/deserialization/test/GsonDeserializationUnitTest.java b/json-modules/gson/src/test/java/com/baeldung/gson/deserialization/test/GsonDeserializationUnitTest.java index adc046ed8e..81d59cf364 100644 --- a/json-modules/gson/src/test/java/com/baeldung/gson/deserialization/test/GsonDeserializationUnitTest.java +++ b/json-modules/gson/src/test/java/com/baeldung/gson/deserialization/test/GsonDeserializationUnitTest.java @@ -3,8 +3,9 @@ package com.baeldung.gson.deserialization.test; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.not; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; + import java.lang.reflect.Type; import java.util.ArrayList; @@ -68,7 +69,7 @@ public class GsonDeserializationUnitTest { final GenericFoo targetObject = new Gson().fromJson(json, typeToken); - assertEquals(targetObject.theValue, new Integer(1)); + assertEquals(targetObject.theValue, Integer.valueOf(1)); } // tests - multiple elements @@ -98,8 +99,7 @@ public class GsonDeserializationUnitTest { @Test public void whenDeserializingJsonIntoElements_thenCorrect() { final String jsonSourceObject = "{\"valueInt\":7,\"valueString\":\"seven\"}"; - final JsonParser jParser = new JsonParser(); - final JsonElement jElement = jParser.parse(jsonSourceObject); + final JsonElement jElement = JsonParser.parseString(jsonSourceObject); final JsonObject jObject = jElement.getAsJsonObject(); final int intValue = jObject.get("valueInt").getAsInt(); final String stringValue = jObject.get("valueString").getAsString(); diff --git a/json-modules/gson/src/test/java/com/baeldung/gson/jsoncompare/JsonCompareUnitTest.java b/json-modules/gson/src/test/java/com/baeldung/gson/jsoncompare/JsonCompareUnitTest.java index 84989a7411..4235eb426a 100644 --- a/json-modules/gson/src/test/java/com/baeldung/gson/jsoncompare/JsonCompareUnitTest.java +++ b/json-modules/gson/src/test/java/com/baeldung/gson/jsoncompare/JsonCompareUnitTest.java @@ -16,79 +16,71 @@ public class JsonCompareUnitTest { @Test public void givenIdenticalSimpleObjects_whenCompared_thenEqual() { - JsonParser parser = new JsonParser(); String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27 }}"; String string2 = "{\"customer\": {\"id\": \"44521\", \"fullName\": \"Emily Jenkins\",\"age\": 27}}"; - assertTrue(parser.parse(string1) - .isJsonObject()); - assertEquals(parser.parse(string1), parser.parse(string2)); + assertTrue(JsonParser.parseString(string1).isJsonObject()); + assertEquals(JsonParser.parseString(string1), JsonParser.parseString(string2)); } @Test public void givenSameObjectsInDifferentOrder_whenCompared_thenEqual() { - JsonParser parser = new JsonParser(); String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27 }}"; String string2 = "{\"customer\": {\"id\": \"44521\",\"age\": 27, \"fullName\": \"Emily Jenkins\" }}"; - JsonElement json1 = parser.parse(string1); - JsonElement json2 = parser.parse(string2); + JsonElement json1 = JsonParser.parseString(string1); + JsonElement json2 = JsonParser.parseString(string2); assertEquals(json1, json2); } @Test public void givenIdenticalArrays_whenCompared_thenEqual() { - JsonParser parser = new JsonParser(); String string1 = "[10, 20, 30]"; String string2 = "[10, 20, 30]"; - assertTrue(parser.parse(string1) + assertTrue(JsonParser.parseString(string1) .isJsonArray()); - assertEquals(parser.parse(string1), parser.parse(string2)); + assertEquals(JsonParser.parseString(string1), JsonParser.parseString(string2)); } @Test public void givenArraysInDifferentOrder_whenCompared_thenNotEqual() { - JsonParser parser = new JsonParser(); String string1 = "[20, 10, 30]"; String string2 = "[10, 20, 30]"; - assertNotEquals(parser.parse(string1), parser.parse(string2)); + assertNotEquals(JsonParser.parseString(string1), JsonParser.parseString(string2)); } @Test public void givenIdenticalNestedObjects_whenCompared_thenEqual() { - JsonParser parser = new JsonParser(); String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"fav_product\": \"Coke\", \"last_buy\": \"2012-04-23\"}}}"; String string2 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"fav_product\": \"Coke\"}}}"; - JsonElement json1 = parser.parse(string1); - JsonElement json2 = parser.parse(string2); + JsonElement json1 = JsonParser.parseString(string1); + JsonElement json2 = JsonParser.parseString(string2); assertEquals(json1, json2); } @Test public void givenIdenticalNestedObjectsWithArray_whenCompared_thenEqual() { - JsonParser parser = new JsonParser(); String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"prouducts\": [\"banana\", \"eggs\"]}}}"; String string2 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"prouducts\": [\"banana\", \"eggs\"]}}}"; - JsonElement json1 = parser.parse(string1); - JsonElement json2 = parser.parse(string2); + JsonElement json1 = JsonParser.parseString(string1); + JsonElement json2 = JsonParser.parseString(string2); assertEquals(json1, json2); } @Test public void givenNestedObjectsDifferentArrayOrder_whenCompared_thenNotEqual() { - JsonParser parser = new JsonParser(); String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"prouducts\": [\"banana\", \"eggs\"]}}}"; String string2 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"prouducts\": [\"eggs\", \"banana\"]}}}"; - JsonElement json1 = parser.parse(string1); - JsonElement json2 = parser.parse(string2); + JsonElement json1 = JsonParser.parseString(string1); + JsonElement json2 = JsonParser.parseString(string2); assertNotEquals(json1, json2); } diff --git a/json-modules/gson/src/test/java/com/baeldung/gson/primitives/PrimitiveValuesUnitTest.java b/json-modules/gson/src/test/java/com/baeldung/gson/primitives/PrimitiveValuesUnitTest.java index e1241fa92a..00edcd426a 100644 --- a/json-modules/gson/src/test/java/com/baeldung/gson/primitives/PrimitiveValuesUnitTest.java +++ b/json-modules/gson/src/test/java/com/baeldung/gson/primitives/PrimitiveValuesUnitTest.java @@ -43,8 +43,8 @@ public class PrimitiveValuesUnitTest { gson.toJson(model); } - @Test(expected = IllegalArgumentException.class) public void - whenSerializingNaN_thenShouldRaiseAnException() { + @Test(expected = IllegalArgumentException.class) + public void whenSerializingNaN_thenShouldRaiseAnException() { FloatExample model = new FloatExample(); model.value = Float.NaN; @@ -52,7 +52,8 @@ public class PrimitiveValuesUnitTest { gson.toJson(model); } - @Test public void whenDeserializingFromJSON_thenShouldParseTheValueInTheString() { + @Test + public void whenDeserializingFromJSON_thenShouldParseTheValueInTheString() { String json = "{\"byteValue\": 17, \"shortValue\": 3, \"intValue\": 3, " + "\"longValue\": 3, \"floatValue\": 3.5" + ", \"doubleValue\": 3.5" + ", \"booleanValue\": true, \"charValue\": \"a\"}"; @@ -72,14 +73,16 @@ public class PrimitiveValuesUnitTest { // @formatter:on } - @Test public void whenDeserializingHighPrecissionNumberIntoFloat_thenShouldPerformRounding() { + @Test + public void whenDeserializingHighPrecissionNumberIntoFloat_thenShouldPerformRounding() { String json = "{\"value\": 12.123425589123456}"; Gson gson = new Gson(); FloatExample model = gson.fromJson(json, FloatExample.class); assertEquals(12.123426f, model.value, 0.000001); } - @Test public void whenDeserializingHighPrecissiongNumberIntoDouble_thenShouldPerformRounding() { + @Test + public void whenDeserializingHighPrecissiongNumberIntoDouble_thenShouldPerformRounding() { String json = "{\"value\": 12.123425589123556}"; Gson gson = new Gson(); DoubleExample model = gson.fromJson(json, DoubleExample.class); @@ -87,12 +90,12 @@ public class PrimitiveValuesUnitTest { } - @Test public void whenDeserializingValueThatOverflows_thenShouldOverflowSilently() { + @Test(expected = JsonSyntaxException.class) + public void whenDeserializingValueThatOverflows_thenShouldRaiseAnException() { Gson gson = new Gson(); String json = "{\"value\": \"300\"}"; ByteExample model = gson.fromJson(json, ByteExample.class); - assertEquals(44, model.value); } @Test public void whenDeserializingRealIntoByte_thenShouldRaiseAnException() { diff --git a/json-modules/gson/src/test/java/com/baeldung/gson/serialization/GsonSerializeUnitTest.java b/json-modules/gson/src/test/java/com/baeldung/gson/serialization/GsonSerializeUnitTest.java index 21d2bedd24..0d54cffbb4 100644 --- a/json-modules/gson/src/test/java/com/baeldung/gson/serialization/GsonSerializeUnitTest.java +++ b/json-modules/gson/src/test/java/com/baeldung/gson/serialization/GsonSerializeUnitTest.java @@ -41,8 +41,7 @@ public class GsonSerializeUnitTest { .serializeNulls() .disableHtmlEscaping() .create() - .toJson(new JsonParser() - .parse("{\"imdbId\":null,\"actors\":[{\"IMDB Code\":\"nm2199632\",\"Date Of Birth\":\"21-09-1982\",\"N° Film: \":3,\"filmography\":\"Apocalypto-Beatdown-Wind Walkers\"}]}")); + .toJson(JsonParser.parseString("{\"imdbId\":null,\"actors\":[{\"IMDB Code\":\"nm2199632\",\"Date Of Birth\":\"21-09-1982\",\"N° Film: \":3,\"filmography\":\"Apocalypto-Beatdown-Wind Walkers\"}]}")); Assert.assertEquals(gson.toJson(movieWithNullValue), expectedOutput); } } diff --git a/json-modules/json-2/pom.xml b/json-modules/json-2/pom.xml index 6cca576fb1..b9a75e8aff 100644 --- a/json-modules/json-2/pom.xml +++ b/json-modules/json-2/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 json-2 0.0.1-SNAPSHOT diff --git a/json-modules/json-arrays/pom.xml b/json-modules/json-arrays/pom.xml index 10c487fbda..ec492b49cc 100644 --- a/json-modules/json-arrays/pom.xml +++ b/json-modules/json-arrays/pom.xml @@ -38,7 +38,7 @@ 1.0 - 2.8.5 + 2.10.1 1.1.2 2.28.0 diff --git a/json-modules/json-path/pom.xml b/json-modules/json-path/pom.xml index 88b81dfc68..763a275290 100644 --- a/json-modules/json-path/pom.xml +++ b/json-modules/json-path/pom.xml @@ -13,7 +13,6 @@
- com.jayway.jsonpath json-path @@ -22,8 +21,7 @@ - - 2.4.0 + 2.8.0 \ No newline at end of file diff --git a/json-modules/json/pom.xml b/json-modules/json/pom.xml index 27c9262279..ba075be679 100644 --- a/json-modules/json/pom.xml +++ b/json-modules/json/pom.xml @@ -68,7 +68,7 @@ 1.0.72 1.0 1.0.1 - 2.8.5 + 2.10.1 1.1.2 2.28.0 diff --git a/libraries-5/pom.xml b/libraries-5/pom.xml index c98a66c094..a043b4bfa8 100644 --- a/libraries-5/pom.xml +++ b/libraries-5/pom.xml @@ -141,7 +141,7 @@ 2.5.11 0.8.1 3.0.14 - 2.5.5 + 3.1.8 3.0.2 4.5.1 1.0 diff --git a/libraries-6/pom.xml b/libraries-6/pom.xml index 139edab34f..9fa44d3a32 100644 --- a/libraries-6/pom.xml +++ b/libraries-6/pom.xml @@ -108,7 +108,7 @@ org.agrona agrona - 1.17.1 + ${agrona.version} @@ -126,7 +126,7 @@ org.codehaus.mojo exec-maven-plugin - 1.6.0 + ${exec-maven-plugin.version} generate-sources @@ -154,14 +154,14 @@ uk.co.real-logic sbe-tool - 1.27.0 + ${sbe-tool.version} org.codehaus.mojo build-helper-maven-plugin - 3.0.0 + ${build-helper-maven-plugin.version} add-source @@ -204,7 +204,11 @@ 3.0 1.8.1 8.12.9 - 2.4.4 + 3.2.0 + 1.17.1 + 1.6.0 + 1.27.0 + 3.0.0 \ No newline at end of file diff --git a/libraries-data-io/pom.xml b/libraries-data-io/pom.xml index 2e126610d4..c8d895b4e5 100644 --- a/libraries-data-io/pom.xml +++ b/libraries-data-io/pom.xml @@ -101,12 +101,12 @@ 1.21 4.0.1 1.7.0 - 4.1 + 5.8 1.23.0 v4-rev493-1.21.0 6.1.2 2.3.1 - 2.8.7 + 2.10.1 1.15 0.14.2 3.17.3 diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index a721e967d2..85ef01e704 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -210,7 +210,7 @@ 3.3.1 2.14.0 2.9.1 - 2.9.1 + 2.10.1 1.1.1 1.5.0 5.2.0 diff --git a/libraries-http-2/pom.xml b/libraries-http-2/pom.xml index fa3b6534db..c80c5729a7 100644 --- a/libraries-http-2/pom.xml +++ b/libraries-http-2/pom.xml @@ -110,7 +110,7 @@ 4.9.1 - 2.8.5 + 2.10.1 4.9.1 1.0.3 9.4.19.v20190610 diff --git a/libraries-http/pom.xml b/libraries-http/pom.xml index 18ba571f60..c726b56b5d 100644 --- a/libraries-http/pom.xml +++ b/libraries-http/pom.xml @@ -103,7 +103,7 @@ - 2.8.5 + 2.10.1 4.5.3 4.9.1 1.23.0 diff --git a/libraries-io/pom.xml b/libraries-io/pom.xml index fa89ebeabe..7464b9a507 100644 --- a/libraries-io/pom.xml +++ b/libraries-io/pom.xml @@ -56,10 +56,10 @@ 0.1.55 - 0.27.0 + 0.37.0 2.4 2.9.0 - 5.7.1 + 5.8 17 17 UTF-8 diff --git a/libraries-io/src/test/java/com/baeldung/java/io/remote/SftpFileTransferLiveTest.java b/libraries-io/src/test/java/com/baeldung/java/io/remote/SftpFileTransferLiveTest.java index 5846128082..81c6cb556c 100644 --- a/libraries-io/src/test/java/com/baeldung/java/io/remote/SftpFileTransferLiveTest.java +++ b/libraries-io/src/test/java/com/baeldung/java/io/remote/SftpFileTransferLiveTest.java @@ -20,14 +20,14 @@ import net.schmizz.sshj.transport.verification.PromiscuousVerifier; public class SftpFileTransferLiveTest { - private String remoteHost = "HOST_NAME_HERE"; - private String username = "USERNAME_HERE"; - private String password = "PASSWORD_HERE"; - private String localFile = "src/main/resources/input.txt"; - private String remoteFile = "welcome.txt"; - private String localDir = "src/main/resources/"; - private String remoteDir = "remote_sftp_test/"; - private String knownHostsFileLoc = "/Users/USERNAME/known_hosts_sample"; + private final String remoteHost = "HOST_NAME_HERE"; + private final String username = "USERNAME_HERE"; + private final String password = "PASSWORD_HERE"; + private final String localFile = "src/main/resources/input.txt"; + private final String remoteFile = "welcome.txt"; + private final String localDir = "src/main/resources/"; + private final String remoteDir = "remote_sftp_test/"; + private final String knownHostsFileLoc = "/Users/USERNAME/known_hosts_sample"; @Test public void whenUploadFileUsingJsch_thenSuccess() throws JSchException, SftpException { @@ -100,6 +100,7 @@ public class SftpFileTransferLiveTest { client.addHostKeyVerifier(new PromiscuousVerifier()); client.connect(remoteHost); client.authPassword(username, password); + client.useCompression(); return client; } diff --git a/libraries-llms/README.md b/libraries-llms/README.md new file mode 100644 index 0000000000..78a621ffa6 --- /dev/null +++ b/libraries-llms/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Introduction to LangChain](https://www.baeldung.com/java-langchain-basics) diff --git a/libraries-llms/pom.xml b/libraries-llms/pom.xml new file mode 100644 index 0000000000..3d5ed6830e --- /dev/null +++ b/libraries-llms/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + libraries-llms + libraries-llms + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + dev.langchain4j + langchain4j + ${langchain4j.version} + + + dev.langchain4j + langchain4j-embeddings + ${langchain4j.version} + + + dev.langchain4j + langchain4j-open-ai + ${langchain4j.version} + + + dev.langchain4j + langchain4j-embeddings-all-minilm-l6-v2 + ${langchain4j.version} + + + + + 0.23.0 + + + \ No newline at end of file diff --git a/libraries-llms/src/test/java/com/baeldung/langchain/ChainWithDocumentLiveTest.java b/libraries-llms/src/test/java/com/baeldung/langchain/ChainWithDocumentLiveTest.java new file mode 100644 index 0000000000..39746ce810 --- /dev/null +++ b/libraries-llms/src/test/java/com/baeldung/langchain/ChainWithDocumentLiveTest.java @@ -0,0 +1,65 @@ +package com.baeldung.langchain; + +import static dev.langchain4j.data.document.FileSystemDocumentLoader.loadDocument; +import static java.time.Duration.ofSeconds; +import static org.junit.Assert.assertNotNull; + +import java.nio.file.Paths; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import dev.langchain4j.chain.ConversationalRetrievalChain; +import dev.langchain4j.data.document.Document; +import dev.langchain4j.data.document.splitter.DocumentSplitters; +import dev.langchain4j.data.segment.TextSegment; +import dev.langchain4j.memory.chat.MessageWindowChatMemory; +import dev.langchain4j.model.chat.ChatLanguageModel; +import dev.langchain4j.model.embedding.AllMiniLmL6V2EmbeddingModel; +import dev.langchain4j.model.embedding.EmbeddingModel; +import dev.langchain4j.model.input.PromptTemplate; +import dev.langchain4j.model.openai.OpenAiChatModel; +import dev.langchain4j.retriever.EmbeddingStoreRetriever; +import dev.langchain4j.store.embedding.EmbeddingStore; +import dev.langchain4j.store.embedding.EmbeddingStoreIngestor; +import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore; + +public class ChainWithDocumentLiveTest { + + private static final Logger logger = LoggerFactory.getLogger(ChainWithDocumentLiveTest.class); + + @Test + public void givenChainWithDocument_whenPrompted_thenValidResponse() { + EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel(); + + EmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>(); + + EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder() + .documentSplitter(DocumentSplitters.recursive(500, 0)) + .embeddingModel(embeddingModel) + .embeddingStore(embeddingStore) + .build(); + + Document document = loadDocument(Paths.get("src/test/resources/example-files/simpson's_adventures.txt")); + ingestor.ingest(document); + + ChatLanguageModel chatModel = OpenAiChatModel.builder() + .apiKey(Constants.OPENAI_API_KEY) + .timeout(ofSeconds(60)) + .build(); + + ConversationalRetrievalChain chain = ConversationalRetrievalChain.builder() + .chatLanguageModel(chatModel) + .retriever(EmbeddingStoreRetriever.from(embeddingStore, embeddingModel)) + .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) + .promptTemplate(PromptTemplate.from("Answer the following question to the best of your ability: {{question}}\n\nBase your answer on the following information:\n{{information}}")) + .build(); + + String answer = chain.execute("Who is Simpson?"); + + logger.info(answer); + assertNotNull(answer); + } + +} diff --git a/libraries-llms/src/test/java/com/baeldung/langchain/ChatWithDocumentLiveTest.java b/libraries-llms/src/test/java/com/baeldung/langchain/ChatWithDocumentLiveTest.java new file mode 100644 index 0000000000..41540f4888 --- /dev/null +++ b/libraries-llms/src/test/java/com/baeldung/langchain/ChatWithDocumentLiveTest.java @@ -0,0 +1,81 @@ +package com.baeldung.langchain; + +import static dev.langchain4j.data.document.FileSystemDocumentLoader.loadDocument; +import static dev.langchain4j.model.openai.OpenAiModelName.GPT_3_5_TURBO; +import static java.time.Duration.ofSeconds; +import static java.util.stream.Collectors.joining; +import static org.junit.Assert.assertNotNull; + +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import dev.langchain4j.data.document.Document; +import dev.langchain4j.data.document.DocumentSplitter; +import dev.langchain4j.data.document.splitter.DocumentSplitters; +import dev.langchain4j.data.embedding.Embedding; +import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.data.segment.TextSegment; +import dev.langchain4j.model.chat.ChatLanguageModel; +import dev.langchain4j.model.embedding.AllMiniLmL6V2EmbeddingModel; +import dev.langchain4j.model.embedding.EmbeddingModel; +import dev.langchain4j.model.input.Prompt; +import dev.langchain4j.model.input.PromptTemplate; +import dev.langchain4j.model.openai.OpenAiChatModel; +import dev.langchain4j.model.openai.OpenAiTokenizer; +import dev.langchain4j.store.embedding.EmbeddingMatch; +import dev.langchain4j.store.embedding.EmbeddingStore; +import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore; + +public class ChatWithDocumentLiveTest { + + private static final Logger logger = LoggerFactory.getLogger(ChatWithDocumentLiveTest.class); + + @Test + public void givenDocument_whenPrompted_thenValidResponse() { + Document document = loadDocument(Paths.get("src/test/resources/example-files/simpson's_adventures.txt")); + DocumentSplitter splitter = DocumentSplitters.recursive(100, 0, new OpenAiTokenizer(GPT_3_5_TURBO)); + List segments = splitter.split(document); + + EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel(); + List embeddings = embeddingModel.embedAll(segments) + .content(); + EmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>(); + embeddingStore.addAll(embeddings, segments); + + String question = "Who is Simpson?"; + Embedding questionEmbedding = embeddingModel.embed(question) + .content(); + int maxResults = 3; + double minScore = 0.7; + List> relevantEmbeddings = embeddingStore.findRelevant(questionEmbedding, maxResults, minScore); + + PromptTemplate promptTemplate = PromptTemplate.from("Answer the following question to the best of your ability:\n" + "\n" + "Question:\n" + "{{question}}\n" + "\n" + "Base your answer on the following information:\n" + "{{information}}"); + + String information = relevantEmbeddings.stream() + .map(match -> match.embedded() + .text()) + .collect(joining("\n\n")); + + Map variables = new HashMap<>(); + variables.put("question", question); + variables.put("information", information); + + Prompt prompt = promptTemplate.apply(variables); + ChatLanguageModel chatModel = OpenAiChatModel.builder() + .apiKey(Constants.OPENAI_API_KEY) + .timeout(ofSeconds(60)) + .build(); + AiMessage aiMessage = chatModel.generate(prompt.toUserMessage()) + .content(); + + logger.info(aiMessage.text()); + assertNotNull(aiMessage.text()); + } + +} diff --git a/libraries-llms/src/test/java/com/baeldung/langchain/ChatWithMemoryLiveTest.java b/libraries-llms/src/test/java/com/baeldung/langchain/ChatWithMemoryLiveTest.java new file mode 100644 index 0000000000..3d265d3f3f --- /dev/null +++ b/libraries-llms/src/test/java/com/baeldung/langchain/ChatWithMemoryLiveTest.java @@ -0,0 +1,43 @@ +package com.baeldung.langchain; + +import static dev.langchain4j.data.message.UserMessage.userMessage; +import static dev.langchain4j.model.openai.OpenAiModelName.GPT_3_5_TURBO; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.memory.ChatMemory; +import dev.langchain4j.memory.chat.TokenWindowChatMemory; +import dev.langchain4j.model.chat.ChatLanguageModel; +import dev.langchain4j.model.openai.OpenAiChatModel; +import dev.langchain4j.model.openai.OpenAiTokenizer; + +public class ChatWithMemoryLiveTest { + + private static final Logger logger = LoggerFactory.getLogger(ChatWithMemoryLiveTest.class); + + @Test + public void givenMemory_whenPrompted_thenValidResponse() { + ChatLanguageModel model = OpenAiChatModel.withApiKey(Constants.OPENAI_API_KEY); + ChatMemory chatMemory = TokenWindowChatMemory.withMaxTokens(300, new OpenAiTokenizer(GPT_3_5_TURBO)); + + chatMemory.add(userMessage("Hello, my name is Kumar")); + AiMessage answer = model.generate(chatMemory.messages()) + .content(); + logger.info(answer.text()); + chatMemory.add(answer); + assertNotNull(answer.text()); + + chatMemory.add(userMessage("What is my name?")); + AiMessage answerWithName = model.generate(chatMemory.messages()) + .content(); + logger.info(answerWithName.text()); + chatMemory.add(answerWithName); + assertThat(answerWithName.text()).contains("Kumar"); + } + +} diff --git a/libraries-llms/src/test/java/com/baeldung/langchain/Constants.java b/libraries-llms/src/test/java/com/baeldung/langchain/Constants.java new file mode 100644 index 0000000000..380415bf9c --- /dev/null +++ b/libraries-llms/src/test/java/com/baeldung/langchain/Constants.java @@ -0,0 +1,12 @@ +package com.baeldung.langchain; + +public class Constants { + + /** + * A limited access key for access to OpenAI language models can be generated by first + * registering for free at (https://platform.openai.com/signup) and then by navigating + * to "Create new secret key" page at (https://platform.openai.com/account/api-keys). + */ + public static String OPENAI_API_KEY = ""; + +} diff --git a/libraries-llms/src/test/java/com/baeldung/langchain/PromptTemplatesLiveTest.java b/libraries-llms/src/test/java/com/baeldung/langchain/PromptTemplatesLiveTest.java new file mode 100644 index 0000000000..cd2ea642ed --- /dev/null +++ b/libraries-llms/src/test/java/com/baeldung/langchain/PromptTemplatesLiveTest.java @@ -0,0 +1,41 @@ +package com.baeldung.langchain; + +import static dev.langchain4j.model.openai.OpenAiModelName.GPT_3_5_TURBO; +import static org.junit.Assert.assertNotNull; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import dev.langchain4j.model.chat.ChatLanguageModel; +import dev.langchain4j.model.input.Prompt; +import dev.langchain4j.model.input.PromptTemplate; +import dev.langchain4j.model.openai.OpenAiChatModel; + +public class PromptTemplatesLiveTest { + + private static final Logger logger = LoggerFactory.getLogger(PromptTemplatesLiveTest.class); + + @Test + public void givenPromptTemplate_whenSuppliedInput_thenValidResponse() { + PromptTemplate promptTemplate = PromptTemplate.from("Tell me a {{adjective}} joke about {{content}}.."); + Map variables = new HashMap<>(); + variables.put("adjective", "funny"); + variables.put("content", "humans"); + Prompt prompt = promptTemplate.apply(variables); + + ChatLanguageModel model = OpenAiChatModel.builder() + .apiKey(Constants.OPENAI_API_KEY) + .modelName(GPT_3_5_TURBO) + .temperature(0.3) + .build(); + + String response = model.generate(prompt.text()); + logger.info(response); + assertNotNull(response); + } + +} diff --git a/libraries-llms/src/test/java/com/baeldung/langchain/ServiceWithToolsLiveTest.java b/libraries-llms/src/test/java/com/baeldung/langchain/ServiceWithToolsLiveTest.java new file mode 100644 index 0000000000..7ebfcba4df --- /dev/null +++ b/libraries-llms/src/test/java/com/baeldung/langchain/ServiceWithToolsLiveTest.java @@ -0,0 +1,49 @@ +package com.baeldung.langchain; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import dev.langchain4j.agent.tool.Tool; +import dev.langchain4j.memory.chat.MessageWindowChatMemory; +import dev.langchain4j.model.openai.OpenAiChatModel; +import dev.langchain4j.service.AiServices; + +public class ServiceWithToolsLiveTest { + + private static final Logger logger = LoggerFactory.getLogger(ServiceWithToolsLiveTest.class); + + static class Calculator { + @Tool("Calculates the length of a string") + int stringLength(String s) { + return s.length(); + } + + @Tool("Calculates the sum of two numbers") + int add(int a, int b) { + return a + b; + } + } + + interface Assistant { + String chat(String userMessage); + } + + @Test + public void givenServiceWithTools_whenPrompted_thenValidResponse() { + Assistant assistant = AiServices.builder(Assistant.class) + .chatLanguageModel(OpenAiChatModel.withApiKey(Constants.OPENAI_API_KEY)) + .tools(new Calculator()) + .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) + .build(); + + String question = "What is the sum of the numbers of letters in the words \"language\" and \"model\"?"; + String answer = assistant.chat(question); + + logger.info(answer); + assertThat(answer).contains("13"); + } + +} diff --git a/libraries-llms/src/test/resources/example-files/simpson's_adventures.txt b/libraries-llms/src/test/resources/example-files/simpson's_adventures.txt new file mode 100644 index 0000000000..ae6de80be0 --- /dev/null +++ b/libraries-llms/src/test/resources/example-files/simpson's_adventures.txt @@ -0,0 +1,28 @@ +Once upon a time in the town of VeggieVille, there lived a cheerful carrot named Simpson. +Simpson was a radiant carrot, always beaming with joy and positivity. +His vibrant orange skin and lush green top were a sight to behold, but it was his infectious laughter and warm personality that really set him apart. + +Simpson had a diverse group of friends, each a vegetable with their own unique characteristics. +There was Bella the blushing beetroot, always ready with a riddle or two; Timmy the timid tomato, a gentle soul with a heart of gold; and Percy the prankster potato, whose jokes always brought a smile to everyone's faces. +Despite their differences, they shared a close bond, their friendship as robust as their natural goodness. + +Their lives were filled with delightful adventures, from playing hide-and-seek amidst the leafy lettuce to swimming in the dewy droplets that pooled on the cabbage leaves. +Their favorite place, though, was the sunlit corner of the vegetable patch, where they would bask in the warmth of the sun, share stories, and have hearty laughs. + +One day, a bunch of pesky caterpillars invaded VeggieVille. +The vegetables were terrified, fearing they would be nibbled to nothingness. +But Simpson, with his usual sunny disposition, had an idea. +He proposed they host a grand feast for the caterpillars, with the juiciest leaves from the outskirts of the town. +Simpson's optimism was contagious, and his friends eagerly joined in to prepare the feast. + +When the caterpillars arrived, they were pleasantly surprised. +They enjoyed the feast and were so impressed with the vegetables' hospitality that they promised not to trouble VeggieVille again. +In return, they agreed to help pollinate the flowers, contributing to a more lush and vibrant VeggieVille. + +Simpson's idea had saved the day, but he humbly attributed the success to their teamwork and friendship. +They celebrated their victory with a grand party, filled with laughter, dance, and merry games. +That night, under the twinkling stars, they made a pact to always stand by each other, come what may. + +From then on, the story of the happy carrot and his friends spread far and wide, a tale of friendship, unity, and positivity. +Simpson, Bella, Timmy, and Percy continued to live their joyful lives, their laughter echoing through VeggieVille. +And so, the tale of the happy carrot and his friends serves as a reminder that no matter the challenge, with optimism, teamwork, and a bit of creativity, anything is possible. \ No newline at end of file diff --git a/libraries-testing/pom.xml b/libraries-testing/pom.xml index 2c7f231fdc..8db9e4e5c5 100644 --- a/libraries-testing/pom.xml +++ b/libraries-testing/pom.xml @@ -213,7 +213,7 @@ 1.9.9 1.46.0 1.9.0 - 3.6.12 + 4.0.18 1.5.0 3.0.0 0.8.1 diff --git a/libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchUnitTest.java b/libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchManualTest.java similarity index 98% rename from libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchUnitTest.java rename to libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchManualTest.java index 9724c2bcae..7db104bd57 100644 --- a/libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchUnitTest.java +++ b/libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchManualTest.java @@ -14,7 +14,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; -public class SmurfsArchUnitTest { +public class SmurfsArchManualTest { @Test public void givenPresentationLayerClasses_thenWrongCheckFails() { diff --git a/libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusManualTest.java similarity index 98% rename from libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusManualTest.java index e95b63aa96..ec5346d27b 100644 --- a/libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java +++ b/libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusManualTest.java @@ -14,7 +14,7 @@ import static com.baeldung.serenity.membership.MemberGrade.Gold; import static com.baeldung.serenity.membership.MemberGrade.Silver; @RunWith(SerenityRunner.class) -public class MemberStatusIntegrationTest { +public class MemberStatusManualTest { @Steps private MemberStatusSteps memberSteps; diff --git a/mapstruct/pom.xml b/mapstruct/pom.xml index 7c279acb7b..5332bcaeb3 100644 --- a/mapstruct/pom.xml +++ b/mapstruct/pom.xml @@ -73,7 +73,7 @@ - 1.5.5.Final + 1.6.0.Beta1 4.3.4.RELEASE 0.2.0 diff --git a/maven-modules/jacoco-coverage-aggregation/jacoco-coverage-services-example/pom.xml b/maven-modules/jacoco-coverage-aggregation/jacoco-coverage-services-example/pom.xml index 2c06694b46..223689f8ff 100644 --- a/maven-modules/jacoco-coverage-aggregation/jacoco-coverage-services-example/pom.xml +++ b/maven-modules/jacoco-coverage-aggregation/jacoco-coverage-services-example/pom.xml @@ -13,8 +13,7 @@ jacoco-coverage-aggregation 1.0 - - + org.springframework @@ -28,7 +27,7 @@ test - + @@ -43,7 +42,7 @@ - + 5.9.2 6.0.11 diff --git a/maven-modules/jacoco-coverage-aggregation/pom.xml b/maven-modules/jacoco-coverage-aggregation/pom.xml index 70243973e8..6d1aab3c3d 100644 --- a/maven-modules/jacoco-coverage-aggregation/pom.xml +++ b/maven-modules/jacoco-coverage-aggregation/pom.xml @@ -21,7 +21,7 @@ jacoco-coverage-controllers-example jacoco-coverage-aggregate-report - + diff --git a/maven-modules/versions-maven-plugin/original/pom.xml b/maven-modules/versions-maven-plugin/original/pom.xml index 2d81274611..6026dac9fe 100644 --- a/maven-modules/versions-maven-plugin/original/pom.xml +++ b/maven-modules/versions-maven-plugin/original/pom.xml @@ -18,11 +18,6 @@ commons-collections4 ${commons-collections4.version} - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - org.apache.commons commons-compress diff --git a/maven-modules/versions-maven-plugin/pom.xml b/maven-modules/versions-maven-plugin/pom.xml index 9c837cefa0..ec1e0ceaba 100644 --- a/maven-modules/versions-maven-plugin/pom.xml +++ b/maven-modules/versions-maven-plugin/pom.xml @@ -7,6 +7,17 @@ versions-maven-plugin 0.0.1-SNAPSHOT versions-maven-plugin + pom + + + maven-modules + com.baeldung + 0.0.1-SNAPSHOT + + + + original + diff --git a/parent-boot-3/pom.xml b/parent-boot-3/pom.xml index dabcd7850b..9f9d6f7901 100644 --- a/parent-boot-3/pom.xml +++ b/parent-boot-3/pom.xml @@ -230,7 +230,7 @@ 3.3.0 2.22.2 - 3.1.2 + 3.1.5 5.8.2 0.9.17 17 diff --git a/parent-java/pom.xml b/parent-java/pom.xml index b08925e040..03cafac55b 100644 --- a/parent-java/pom.xml +++ b/parent-java/pom.xml @@ -40,7 +40,7 @@ - 2.3.7 + 3.2.0 \ No newline at end of file diff --git a/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/BillPughSingleton.java b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/BillPughSingleton.java new file mode 100644 index 0000000000..f558706a07 --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/BillPughSingleton.java @@ -0,0 +1,15 @@ +package com.baledung.billpugh; + +public class BillPughSingleton { + private BillPughSingleton() { + + } + + private static class SingletonHelper { + private static final BillPughSingleton BILL_PUGH_SINGLETON_INSTANCE = new BillPughSingleton(); + } + + public static BillPughSingleton getInstance() { + return SingletonHelper.BILL_PUGH_SINGLETON_INSTANCE; + } +} diff --git a/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/EagerLoadedSingleton.java b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/EagerLoadedSingleton.java new file mode 100644 index 0000000000..c0a535f2d5 --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/EagerLoadedSingleton.java @@ -0,0 +1,11 @@ +package com.baledung.billpugh; + +public class EagerLoadedSingleton { + private static final EagerLoadedSingleton EAGER_LOADED_SINGLETON = new EagerLoadedSingleton(); + private EagerLoadedSingleton() { + + } + public static EagerLoadedSingleton getInstance() { + return EAGER_LOADED_SINGLETON; + } +} diff --git a/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/LazyLoadedSingleton.java b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/LazyLoadedSingleton.java new file mode 100644 index 0000000000..b4967a58cd --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/LazyLoadedSingleton.java @@ -0,0 +1,15 @@ +package com.baledung.billpugh; + +public class LazyLoadedSingleton { + private static LazyLoadedSingleton lazyLoadedSingletonObj; + + private LazyLoadedSingleton() { + } + + public static LazyLoadedSingleton getInstance() { + if (null == lazyLoadedSingletonObj) { + lazyLoadedSingletonObj = new LazyLoadedSingleton(); + } + return lazyLoadedSingletonObj; + } +} diff --git a/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/SynchronizedLazyLoadedSingleton.java b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/SynchronizedLazyLoadedSingleton.java new file mode 100644 index 0000000000..fe3457e054 --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/SynchronizedLazyLoadedSingleton.java @@ -0,0 +1,15 @@ +package com.baledung.billpugh; + +public class SynchronizedLazyLoadedSingleton { + private static SynchronizedLazyLoadedSingleton synchronizedLazyLoadedSingleton; + + private SynchronizedLazyLoadedSingleton() { + } + + public static synchronized SynchronizedLazyLoadedSingleton getInstance() { + if (null == synchronizedLazyLoadedSingleton) { + synchronizedLazyLoadedSingleton = new SynchronizedLazyLoadedSingleton(); + } + return synchronizedLazyLoadedSingleton; + } +} \ No newline at end of file diff --git a/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/BillPughSingletonUnitTest.java b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/BillPughSingletonUnitTest.java new file mode 100644 index 0000000000..dcf2098b4b --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/BillPughSingletonUnitTest.java @@ -0,0 +1,43 @@ +package com.baledung.billpugh; + +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class BillPughSingletonUnitTest { + Logger logger = LoggerFactory.getLogger(BillPughSingletonUnitTest.class); + @Test + void givenSynchronizedLazyLoadedImpl_whenCallgetInstance_thenReturnSingleton() { + Set setHoldingSingletonObj = new HashSet<>(); + List> futures = new ArrayList<>(); + + ExecutorService executorService = Executors.newFixedThreadPool(10); + Callable runnableTask = () -> { + logger.info("run called for:" + Thread.currentThread().getName()); + return BillPughSingleton.getInstance(); + }; + + int count = 0; + while(count < 10) { + futures.add(executorService.submit(runnableTask)); + count++; + } + futures.forEach(e -> { + try { + setHoldingSingletonObj.add(e.get()); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }); + executorService.shutdown(); + assertEquals(1, setHoldingSingletonObj.size()); + } +} diff --git a/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/EagerLoadedSingletonUnitTest.java b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/EagerLoadedSingletonUnitTest.java new file mode 100644 index 0000000000..fd65ff6c5b --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/EagerLoadedSingletonUnitTest.java @@ -0,0 +1,46 @@ +package com.baledung.billpugh; + +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class EagerLoadedSingletonUnitTest { + + Logger logger = LoggerFactory.getLogger(EagerLoadedSingletonUnitTest.class); + + @Test + void giveEagerLoadedImpl_whenCallgetInstance_thenReturnSingleton() { + Set set = new HashSet<>(); + List> futures = new ArrayList<>(); + + ExecutorService executorService = Executors.newFixedThreadPool(10); + Callable runnableTask = () -> { + logger.info("run called for:" + Thread.currentThread().getName()); + return EagerLoadedSingleton.getInstance(); + }; + + int count = 0; + while(count < 10) { + futures.add(executorService.submit(runnableTask)); + count++; + } + futures.forEach(e -> { + try { + set.add(e.get()); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }); + executorService.shutdown(); + assertEquals(1, set.size()); + } + +} diff --git a/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/LazyLoadedSingletonUnitTest.java b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/LazyLoadedSingletonUnitTest.java new file mode 100644 index 0000000000..0e0ea25779 --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/LazyLoadedSingletonUnitTest.java @@ -0,0 +1,17 @@ +package com.baledung.billpugh; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + +public class LazyLoadedSingletonUnitTest { + + @Test + void givenLazyLoadedImpl_whenCallGetInstance_thenReturnSingleInstance() throws ClassNotFoundException { + Class bs = Class.forName("com.baledung.billpugh.LazyLoadedSingleton"); + assertThrows(IllegalAccessException.class, () -> bs.getDeclaredConstructor().newInstance()); + + LazyLoadedSingleton lazyLoadedSingletonObj1 = LazyLoadedSingleton.getInstance(); + LazyLoadedSingleton lazyLoadedSingletonObj2 = LazyLoadedSingleton.getInstance(); + assertEquals(lazyLoadedSingletonObj1.hashCode(), lazyLoadedSingletonObj2.hashCode()); + } +} diff --git a/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/SynchronizedLazyLoadedSingletonUnitTest.java b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/SynchronizedLazyLoadedSingletonUnitTest.java new file mode 100644 index 0000000000..1f1636b458 --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/SynchronizedLazyLoadedSingletonUnitTest.java @@ -0,0 +1,44 @@ +package com.baledung.billpugh; + +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class SynchronizedLazyLoadedSingletonUnitTest { + Logger logger = LoggerFactory.getLogger(SynchronizedLazyLoadedSingletonUnitTest.class); + @Test + void giveSynchronizedLazyLoadedImpl_whenCallgetInstance_thenReturnSingleton() { + Set setHoldingSingletonObj = new HashSet<>(); + List> futures = new ArrayList<>(); + + ExecutorService executorService = Executors.newFixedThreadPool(10); + Callable runnableTask = () -> { + logger.info("run called for:" + Thread.currentThread().getName()); + return SynchronizedLazyLoadedSingleton.getInstance(); + }; + + int count = 0; + while(count < 10) { + futures.add(executorService.submit(runnableTask)); + count++; + } + futures.forEach(e -> { + try { + setHoldingSingletonObj.add(e.get()); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }); + executorService.shutdown(); + assertEquals(1, setHoldingSingletonObj.size()); + } + +} diff --git a/performance-tests/pom.xml b/performance-tests/pom.xml index 542a505b16..d22a9cf3ac 100644 --- a/performance-tests/pom.xml +++ b/performance-tests/pom.xml @@ -151,8 +151,8 @@ 1.5.4 6.5.2 - 1.5.2.Final - 3.1.0 + 1.6.0.Beta1 + 3.2.0 1.6.1.CR2 1.8 diff --git a/persistence-modules/core-java-persistence-3/pom.xml b/persistence-modules/core-java-persistence-3/pom.xml new file mode 100644 index 0000000000..26ac2a5218 --- /dev/null +++ b/persistence-modules/core-java-persistence-3/pom.xml @@ -0,0 +1,29 @@ + + 4.0.0 + com.baeldung.core-java-persistence-3 + core-java-persistence-3 + core-java-persistence-3 + 0.1.0-SNAPSHOT + jar + + com.baeldung + persistence-modules + 1.0.0-SNAPSHOT + + + + com.h2database + h2 + ${h2.version} + + + commons-dbutils + commons-dbutils + ${commons-dbutils.version} + + + + 2.1.214 + 1.8.1 + + \ No newline at end of file diff --git a/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java b/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java new file mode 100644 index 0000000000..e449beb83a --- /dev/null +++ b/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java @@ -0,0 +1,107 @@ +package com.baeldung.resultsettomap; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.dbutils.QueryRunner; +import org.apache.commons.dbutils.ResultSetHandler; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class ResultSetToMapUnitTest { + private static Connection connection = null; + private static final String JDBC_URL = "jdbc:h2:mem:testDatabase"; + private static final String USERNAME = "dbUser"; + private static final String PASSWORD = "dbPassword"; + + @Before + public void setup() throws Exception { + connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD); + initialDataSetup(); + } + + private void initialDataSetup() throws SQLException { + Statement statement = connection.createStatement(); + String ddlQuery = "CREATE TABLE employee (empId INTEGER not null, empName VARCHAR(50), empCity VARCHAR(50), PRIMARY KEY (empId))"; + statement.execute(ddlQuery); + List sqlQueryList = Arrays.asList("INSERT INTO employee VALUES (1, 'Steve','London')", "INSERT INTO employee VALUES (2, 'John','London')", "INSERT INTO employee VALUES (3, 'David', 'Sydney')", + "INSERT INTO employee VALUES (4, 'Kevin','London')", "INSERT INTO employee VALUES (5, 'Jade', 'Sydney')"); + + for (String query : sqlQueryList) { + statement.execute(query); + } + } + + @Test + public void whenUsingContainsKey_thenConvertResultSetToMap() throws SQLException { + ResultSet resultSet = connection.prepareStatement("SELECT * FROM employee") + .executeQuery(); + Map> valueMap = new HashMap<>(); + + while (resultSet.next()) { + String empCity = resultSet.getString("empCity"); + String empName = resultSet.getString("empName"); + if (!valueMap.containsKey(empCity)) { + valueMap.put(empCity, new ArrayList<>()); + } + valueMap.get(empCity) + .add(empName); + } + assertEquals(3, valueMap.get("London") + .size()); + } + + @Test + public void whenUsingComputeIfAbsent_thenConvertResultSetToMap() throws SQLException { + ResultSet resultSet = connection.prepareStatement("SELECT * FROM employee") + .executeQuery(); + Map> valueMap = new HashMap<>(); + + while (resultSet.next()) { + String empCity = resultSet.getString("empCity"); + String empName = resultSet.getString("empName"); + valueMap.computeIfAbsent(empCity, data -> new ArrayList<>()) + .add(empName); + } + assertEquals(3, valueMap.get("London") + .size()); + } + + @Test + public void whenUsingDbUtils_thenConvertResultSetToMap() throws SQLException { + + ResultSetHandler>> handler = new ResultSetHandler>>() { + public Map> handle(ResultSet resultSet) throws SQLException { + Map> result = new HashMap<>(); + while (resultSet.next()) { + String empCity = resultSet.getString("empCity"); + String empName = resultSet.getString("empName"); + result.computeIfAbsent(empCity, data -> new ArrayList<>()) + .add(empName); + } + return result; + } + }; + + QueryRunner run = new QueryRunner(); + Map> valueMap = run.query(connection, "SELECT * FROM employee", handler); + assertEquals(3, valueMap.get("London") + .size()); + } + + @After + public void preDestroy() throws Exception { + connection.close(); + } +} diff --git a/persistence-modules/deltaspike/src/test/resources/META-INF/persistence.xml b/persistence-modules/deltaspike/src/test/resources/META-INF/persistence.xml index ffcf20878c..60b415abd7 100644 --- a/persistence-modules/deltaspike/src/test/resources/META-INF/persistence.xml +++ b/persistence-modules/deltaspike/src/test/resources/META-INF/persistence.xml @@ -35,7 +35,7 @@ - + diff --git a/persistence-modules/deltaspike/src/test/resources/logback-test.xml b/persistence-modules/deltaspike/src/test/resources/logback-test.xml index bdc292924b..6a9aa37e7f 100644 --- a/persistence-modules/deltaspike/src/test/resources/logback-test.xml +++ b/persistence-modules/deltaspike/src/test/resources/logback-test.xml @@ -7,7 +7,7 @@ - + diff --git a/persistence-modules/hibernate-mapping/pom.xml b/persistence-modules/hibernate-mapping/pom.xml index 1e3dc8be5f..0ce112b9e6 100644 --- a/persistence-modules/hibernate-mapping/pom.xml +++ b/persistence-modules/hibernate-mapping/pom.xml @@ -20,7 +20,7 @@ test - org.hibernate + org.hibernate.orm hibernate-core ${hibernate.version} @@ -36,7 +36,7 @@ - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -82,7 +82,7 @@ 2.1.214 6.1.7.Final 2.21.1 - 8.0.0.Final + 8.0.1.Final 3.0.1-b11 1.1 1.4.2 diff --git a/persistence-modules/hibernate-queries/pom.xml b/persistence-modules/hibernate-queries/pom.xml index bb60c7b83a..76f230a72d 100644 --- a/persistence-modules/hibernate-queries/pom.xml +++ b/persistence-modules/hibernate-queries/pom.xml @@ -99,7 +99,7 @@ 8.0.32 2.6.0 2.1.214 - 6.1.7.Final + 6.3.1.Final 1.17.6 diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java index ff9ccb017b..f561a33f08 100644 --- a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java @@ -16,4 +16,11 @@ public class HibernateUtil { return session; } + public static SessionFactory getHibernateSessionFactory() { + + final SessionFactory sessionFactory = new Configuration().configure("criteria.cfg.xml").buildSessionFactory(); + + return sessionFactory; + } + } diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/CriteriaDefinitionApplicationView.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/CriteriaDefinitionApplicationView.java new file mode 100644 index 0000000000..9f32aa06e3 --- /dev/null +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/CriteriaDefinitionApplicationView.java @@ -0,0 +1,126 @@ +package com.baeldung.hibernate.criteria.view; + +import java.util.List; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.query.criteria.CriteriaDefinition; +import org.hibernate.query.criteria.JpaRoot; + +import com.baeldung.hibernate.criteria.model.Item; +import com.baeldung.hibernate.criteria.util.HibernateUtil; + +public class CriteriaDefinitionApplicationView { + + public CriteriaDefinitionApplicationView() { + + } + + public String[] greaterThanCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final SessionFactory sessionFactory = HibernateUtil.getHibernateSessionFactory(); + + CriteriaDefinition query = new CriteriaDefinition<>(sessionFactory, Item.class) { + { + JpaRoot message = from(Item.class); + where(gt(message.get("itemPrice"), 1000)); + } + }; + + List items = session.createSelectionQuery(query).list(); + + final String greaterThanItems[] = new String[items.size()]; + for (int i = 0; i < items.size(); i++) { + greaterThanItems[i] = items.get(i).getItemName(); + } + + session.close(); + + return greaterThanItems; + } + + public String[] lessThanCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final SessionFactory sessionFactory = HibernateUtil.getHibernateSessionFactory(); + + CriteriaDefinition query = new CriteriaDefinition<>(sessionFactory, Item.class) { + { + JpaRoot message = from(Item.class); + where(lt(message.get("itemPrice"), 1000)); + } + }; + + List items = session.createSelectionQuery(query).list(); + final String lessThanItems[] = new String[items.size()]; + for (int i = 0; i < items.size(); i++) { + lessThanItems[i] = items.get(i).getItemName(); + } + + session.close(); + + return lessThanItems; + } + + public String[] likeCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final SessionFactory sessionFactory = HibernateUtil.getHibernateSessionFactory(); + + CriteriaDefinition query = new CriteriaDefinition<>(sessionFactory, Item.class) { + { + JpaRoot item = from(Item.class); + where(like(item.get("itemName"), "%chair%")); + } + }; + + List items = session.createSelectionQuery(query).list(); + + final String likeItems[] = new String[items.size()]; + for (int i = 0; i < items.size(); i++) { + likeItems[i] = items.get(i).getItemName(); + } + session.close(); + return likeItems; + } + + public String[] likeCaseCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final SessionFactory sessionFactory = HibernateUtil.getHibernateSessionFactory(); + + CriteriaDefinition query = new CriteriaDefinition<>(sessionFactory, Item.class) { + { + JpaRoot item = from(Item.class); + where(like(lower(item.get("itemName")), "%chair%")); + } + }; + + List items = session.createSelectionQuery(query).list(); + + final String likeItems[] = new String[items.size()]; + for (int i = 0; i < items.size(); i++) { + likeItems[i] = items.get(i).getItemName(); + } + session.close(); + return likeItems; + } + + public String[] betweenCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final SessionFactory sessionFactory = HibernateUtil.getHibernateSessionFactory(); + + CriteriaDefinition query = new CriteriaDefinition<>(sessionFactory, Item.class) { + { + JpaRoot item = from(Item.class); + where(between(item.get("itemPrice"), 100, 200)); + } + }; + + List items = session.createSelectionQuery(query).list(); + + final String betweenItems[] = new String[items.size()]; + for (int i = 0; i < items.size(); i++) { + betweenItems[i] = items.get(i).getItemName(); + } + session.close(); + return betweenItems; + } +} diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java index 58d8e8628a..e9c7548c7d 100644 --- a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java @@ -4,8 +4,13 @@ package com.baeldung.hibernate.customtypes; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import org.hibernate.dialect.Dialect; +import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation; +import org.hibernate.type.BasicType; import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; +import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators; +import org.hibernate.type.spi.TypeConfiguration; import io.hypersistence.utils.hibernate.type.array.internal.AbstractArrayTypeDescriptor; @@ -49,4 +54,10 @@ public class LocalDateStringJavaDescriptor extends AbstractArrayTypeDescriptor expectedLikeList = session.createQuery("From Item where itemName like '%chair%'").list(); + final String expectedLikeItems[] = new String[expectedLikeList.size()]; + for (int i = 0; i < expectedLikeList.size(); i++) { + expectedLikeItems[i] = expectedLikeList.get(i).getItemName(); + } + session.close(); + assertArrayEquals(expectedLikeItems, criteriaDefinition.likeCriteria()); + } + + @Test + public void givenHibernateSession_whenExecutingCaseSensitiveLikeCriteriaQuery_thenExpectMatchingItems() { + final Session session = HibernateUtil.getHibernateSession(); + final List expectedChairCaseList = session.createQuery("From Item where itemName like '%Chair%'").list(); + final String expectedChairCaseItems[] = new String[expectedChairCaseList.size()]; + for (int i = 0; i < expectedChairCaseList.size(); i++) { + expectedChairCaseItems[i] = expectedChairCaseList.get(i).getItemName(); + } + session.close(); + assertArrayEquals(expectedChairCaseItems, criteriaDefinition.likeCaseCriteria()); + } + + @Test + public void givenHibernateSession_whenExecutingGreaterThanCriteriaQuery_thenExpectMatchingItems() { + final Session session = HibernateUtil.getHibernateSession(); + final List expectedGreaterThanList = session.createQuery("From Item where itemPrice>1000").list(); + final String expectedGreaterThanItems[] = new String[expectedGreaterThanList.size()]; + for (int i = 0; i < expectedGreaterThanList.size(); i++) { + expectedGreaterThanItems[i] = expectedGreaterThanList.get(i).getItemName(); + } + session.close(); + assertArrayEquals(expectedGreaterThanItems, criteriaDefinition.greaterThanCriteria()); + } + + @Test + public void givenHibernateSession_whenExecutingLessThanCriteriaQuery_thenExpectMatchingItems() { + final Session session = HibernateUtil.getHibernateSession(); + final List expectedLessList = session.createQuery("From Item where itemPrice<1000").list(); + final String expectedLessThanItems[] = new String[expectedLessList.size()]; + for (int i = 0; i < expectedLessList.size(); i++) { + expectedLessThanItems[i] = expectedLessList.get(i).getItemName(); + } + session.close(); + assertArrayEquals(expectedLessThanItems, criteriaDefinition.lessThanCriteria()); + } + + @Test + public void givenHibernateSession_whenExecutingBetweenCriteriaQuery_thenExpectMatchingItems() { + final Session session = HibernateUtil.getHibernateSession(); + final List expectedBetweenList = session.createQuery("From Item where itemPrice between 100 and 200").list(); + final String expectedPriceBetweenItems[] = new String[expectedBetweenList.size()]; + for (int i = 0; i < expectedBetweenList.size(); i++) { + expectedPriceBetweenItems[i] = expectedBetweenList.get(i).getItemName(); + } + session.close(); + assertArrayEquals(expectedPriceBetweenItems, criteriaDefinition.betweenCriteria()); + } + + +} diff --git a/persistence-modules/jpa-hibernate-cascade-type/pom.xml b/persistence-modules/jpa-hibernate-cascade-type/pom.xml index fd0ae117c7..90dd826a6e 100644 --- a/persistence-modules/jpa-hibernate-cascade-type/pom.xml +++ b/persistence-modules/jpa-hibernate-cascade-type/pom.xml @@ -24,27 +24,15 @@ - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} - - javax.el - javax.el-api - ${javax.el-api.version} - - - org.glassfish - javax.el - ${org.glassfish.javax.el.version} - 5.4.3.Final - 6.0.17.Final - 3.0.0 - 3.0.1-b11 + 8.0.1.Final \ No newline at end of file diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index eb4b212771..6823b460b2 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -21,6 +21,7 @@ blaze-persistence core-java-persistence core-java-persistence-2 + core-java-persistence-3 couchbase elasticsearch flyway @@ -120,6 +121,7 @@ scylladb spring-data-cassandra-2 spring-data-jpa-repo-3 + spring-boot-persistence-4 diff --git a/persistence-modules/redis/pom.xml b/persistence-modules/redis/pom.xml index 571487af3d..98be674a8e 100644 --- a/persistence-modules/redis/pom.xml +++ b/persistence-modules/redis/pom.xml @@ -57,7 +57,7 @@ 0.6 3.20.0 - 4.3.2 + 5.0.2 4.1.90.Final diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/service/MovieAtlasSearchService.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/service/MovieAtlasSearchService.java index 55d47759d5..90de7b3d1d 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/service/MovieAtlasSearchService.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/service/MovieAtlasSearchService.java @@ -11,13 +11,12 @@ import static com.mongodb.client.model.Projections.excludeId; import static com.mongodb.client.model.Projections.fields; import static com.mongodb.client.model.Projections.include; import static com.mongodb.client.model.Projections.metaSearchScore; +import static com.mongodb.client.model.search.SearchCollector.facet; import static com.mongodb.client.model.search.SearchCount.total; -import static com.mongodb.client.model.search.SearchFacet.combineToBson; import static com.mongodb.client.model.search.SearchFacet.numberFacet; import static com.mongodb.client.model.search.SearchFacet.stringFacet; import static com.mongodb.client.model.search.SearchOperator.compound; import static com.mongodb.client.model.search.SearchOperator.numberRange; -import static com.mongodb.client.model.search.SearchOperator.of; import static com.mongodb.client.model.search.SearchOperator.text; import static com.mongodb.client.model.search.SearchOptions.searchOptions; import static com.mongodb.client.model.search.SearchPath.fieldPath; @@ -67,7 +66,7 @@ public class MovieAtlasSearchService { builder.append("]"); LogManager.getLogger(MovieAtlasSearchService.class) - .debug(builder.toString()); + .debug(builder.toString()); } public Document late90sMovies(int skip, int limit, String keywords, SearchScore modifier) { @@ -130,7 +129,7 @@ public class MovieAtlasSearchService { debug(pipeline); return collection.aggregate(pipeline) - .first(); + .first(); } public Collection moviesByKeywords(String keywords) { @@ -150,34 +149,33 @@ public class MovieAtlasSearchService { debug(pipeline); return collection.aggregate(pipeline) - .into(new ArrayList()); + .into(new ArrayList<>()); } public Document genresThroughTheDecades(String genre) { List pipeline = asList( - searchMeta(of( - new Document("facet", - new Document("operator", - text( - fieldPath("genres"), genre - ) - ).append("facets", combineToBson(asList( - stringFacet("genresFacet", - fieldPath("genres") - ).numBuckets(5), - numberFacet("yearFacet", - fieldPath("year"), - asList(1900, 1930, 1960, 1990, 2020) - ) - ))) - )), - searchOptions() - .index(config.getFacetIndex()) + searchMeta( + facet( + text( + fieldPath("genres"), genre + ), + asList( + stringFacet("genresFacet", + fieldPath("genres") + ).numBuckets(5), + numberFacet("yearFacet", + fieldPath("year"), + asList(1900, 1930, 1960, 1990, 2020) + ) + ) + ), + searchOptions() + .index(config.getFacetIndex()) ) ); - + debug(pipeline); return collection.aggregate(pipeline) - .first(); + .first(); } } diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/web/MovieAtlasSearchController.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/web/MovieAtlasSearchController.java index 4c41915347..af8640179f 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/web/MovieAtlasSearchController.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/web/MovieAtlasSearchController.java @@ -1,5 +1,7 @@ package com.baeldung.boot.atlassearch.web; +import static com.mongodb.client.model.search.SearchPath.fieldPath; + import java.util.Collection; import org.bson.Document; @@ -33,7 +35,7 @@ public class MovieAtlasSearchController { @GetMapping("90s/{skip}/{limit}/with/{keywords}") Document getMoviesUsingScoreBoost(@PathVariable int skip, @PathVariable int limit, @PathVariable String keywords) { - return service.late90sMovies(skip, limit, keywords, SearchScore.boost(2)); + return service.late90sMovies(skip, limit, keywords, SearchScore.boost(fieldPath("imdb.votes"))); } @PostMapping("90s/{skip}/{limit}/with/{keywords}") diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/MongoDbHashMapIntegrationTest.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/MongoDbHashMapLiveTest.java similarity index 76% rename from persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/MongoDbHashMapIntegrationTest.java rename to persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/MongoDbHashMapLiveTest.java index bbf425f277..29588df8a9 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/MongoDbHashMapIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/MongoDbHashMapLiveTest.java @@ -13,21 +13,35 @@ import java.util.Map; import java.util.Set; import org.bson.Document; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; import com.mongodb.BasicDBObject; -@SpringBootTest +/** + * Steps to run locally: + * - Open embedded.properties and include: + * - spring.data.mongodb.uri= + * - spring.data.mongodb.database=sample_mflix + * + * Pre-requisites: + * - Following the steps to import the sample_mflix database + */ @DirtiesContext +@RunWith(SpringRunner.class) @TestPropertySource("/embedded.properties") -class MongoDbHashMapIntegrationTest { +@SpringBootTest(classes = SpringBootHashMapApplication.class) +class MongoDbHashMapLiveTest { + private static final String COLLECTION_NAME = "hashmap-test-collection"; private static final Map MAP = new HashMap<>(); private static final Set> MAP_SET = new HashSet<>(); @@ -52,17 +66,22 @@ class MongoDbHashMapIntegrationTest { MAP_SET.add(MAP); MAP_SET.add(otherMap); } + + @AfterEach + void destroy() { + mongo.dropCollection(COLLECTION_NAME); + } @Test void whenUsingMap_thenInsertSucceeds() { - Map saved = mongo.insert(MAP, "map-collection"); + Map saved = mongo.insert(MAP, COLLECTION_NAME); assertHasMongoId(saved); } @Test void whenMapSet_thenInsertSucceeds() { - Collection> saved = mongo.insert(MAP_SET, "map-set"); + Collection> saved = mongo.insert(MAP_SET, COLLECTION_NAME); saved.forEach(this::assertHasMongoId); assertEquals(2, saved.size()); @@ -72,7 +91,7 @@ class MongoDbHashMapIntegrationTest { void givenMap_whenDocumentConstructed_thenInsertSucceeds() { Document document = new Document(MAP); - Document saved = mongo.insert(document, "doc-collection"); + Document saved = mongo.insert(document, COLLECTION_NAME); assertHasMongoId(saved); } @@ -81,7 +100,7 @@ class MongoDbHashMapIntegrationTest { void givenMap_whenBasicDbObjectConstructed_thenInsertSucceeds() { BasicDBObject dbObject = new BasicDBObject(MAP); - BasicDBObject saved = mongo.insert(dbObject, "db-collection"); + BasicDBObject saved = mongo.insert(dbObject, COLLECTION_NAME); assertHasMongoId(saved); } @@ -114,7 +133,7 @@ class MongoDbHashMapIntegrationTest { set.add(document); }, Set::addAll); - Collection saved = mongo.insert(docs, "custom-set"); + Collection saved = mongo.insert(docs, COLLECTION_NAME); saved.forEach(this::assertHasMongoId); } } diff --git a/persistence-modules/spring-data-couchbase-2/pom.xml b/persistence-modules/spring-data-couchbase-2/pom.xml index deb7d3b524..eda2c45371 100644 --- a/persistence-modules/spring-data-couchbase-2/pom.xml +++ b/persistence-modules/spring-data-couchbase-2/pom.xml @@ -40,7 +40,7 @@ - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -71,8 +71,8 @@ 6.0.6 5.0.3 - 8.0.0.Final - 2.12.2 + 8.0.1.Final + 2.12.5 \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-enterprise/pom.xml b/persistence-modules/spring-data-jpa-enterprise/pom.xml index 6bd89032fa..d998849ffb 100644 --- a/persistence-modules/spring-data-jpa-enterprise/pom.xml +++ b/persistence-modules/spring-data-jpa-enterprise/pom.xml @@ -45,7 +45,7 @@ org.mapstruct - mapstruct-jdk8 + mapstruct ${mapstruct.version} provided @@ -97,7 +97,7 @@ - 1.3.1.Final + 1.6.0.Beta1 1.19.1 diff --git a/persistence-modules/spring-data-jpa-query/README.md b/persistence-modules/spring-data-jpa-query/README.md index 27443c2026..27e7087592 100644 --- a/persistence-modules/spring-data-jpa-query/README.md +++ b/persistence-modules/spring-data-jpa-query/README.md @@ -5,7 +5,7 @@ This module contains articles about querying data using Spring Data JPA ### Relevant Articles: - [The Exists Query in Spring Data](https://www.baeldung.com/spring-data-exists-query) - [Customizing the Result of JPA Queries with Aggregation Functions](https://www.baeldung.com/jpa-queries-custom-result-with-aggregation-functions) -- [Limiting Query Results with JPA and Spring Data JPA](https://www.baeldung.com/jpa-limit-query-results) +- [Limiting Query Results With JPA and Spring Data JPA](https://www.baeldung.com/jpa-limit-query-results) - [Sorting Query Results with Spring Data](https://www.baeldung.com/spring-data-sorting) - [Spring Data JPA Query by Example](https://www.baeldung.com/spring-data-query-by-example) - [JPA Join Types](https://www.baeldung.com/jpa-join-types) diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml index ab133192a0..052935e215 100644 --- a/persistence-modules/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -50,6 +50,7 @@ redis.clients jedis + ${jedis.version} jar @@ -83,6 +84,7 @@ 3.2.4 0.10.0 0.6 + 5.0.2 \ No newline at end of file diff --git a/persistence-modules/spring-jdbc-2/README.md b/persistence-modules/spring-jdbc-2/README.md new file mode 100644 index 0000000000..5edb34f4c5 --- /dev/null +++ b/persistence-modules/spring-jdbc-2/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [A Guide to Spring 6 JdbcClient API](https://www.baeldung.com/spring-6-jdbcclient-api) diff --git a/persistence-modules/spring-jpa/pom.xml b/persistence-modules/spring-jpa/pom.xml index c08e4f823a..10e44c0ce4 100644 --- a/persistence-modules/spring-jpa/pom.xml +++ b/persistence-modules/spring-jpa/pom.xml @@ -71,7 +71,7 @@ - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -122,7 +122,7 @@ 6.0.0 - 8.0.0.Final + 8.0.1.Final 2.0.2 2.1.214 5.0.0 diff --git a/pom.xml b/pom.xml index 7bde142fbc..47c566023d 100644 --- a/pom.xml +++ b/pom.xml @@ -1,8 +1,8 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung parent-modules @@ -344,7 +344,7 @@ core-java-modules/core-java-security core-java-modules/core-java-lang core-java-modules/core-java-lang-math-3 - + core-java-modules/core-java-streams-2 @@ -362,7 +362,7 @@ web-modules/java-lite persistence-modules/deltaspike persistence-modules/hibernate-ogm - persistence-modules/spring-data-cassandra-reactive + persistence-modules/spring-data-cassandra-reactive java-nashorn jeromq spring-ejb-modules/ejb-beans @@ -517,7 +517,7 @@ core-java-modules/core-java-security core-java-modules/core-java-lang core-java-modules/core-java-lang-math-3 - + core-java-modules/core-java-streams-2 @@ -533,7 +533,7 @@ web-modules/java-lite persistence-modules/deltaspike persistence-modules/hibernate-ogm - persistence-modules/spring-data-cassandra-reactive + persistence-modules/spring-data-cassandra-reactive java-nashorn jeromq spring-ejb-modules/ejb-beans @@ -690,35 +690,157 @@ - parent-boot-3 - lombok-modules - osgi - spring-katharsis - logging-modules - spring-boot-modules - apache-httpclient - apache-httpclient4 + akka-modules + algorithms-modules + antlr + apache-cxf-modules apache-httpclient-2 - spring-mobile - microservices-modules - spring-ejb-modules - spring-di - spring-di-2 - spring-jinq - vavr-modules - java-websocket + apache-httpclient4 + apache-httpclient + apache-kafka-2 + apache-kafka + apache-libraries-2 + apache-libraries + apache-olingo + apache-poi-2 + apache-poi-3 + apache-poi + apache-thrift + apache-tika + apache-velocity + asciidoctor + asm + atomikos + atomix + aws-modules azure - netflix-modules - spf4j - spring-jersey - jersey - jaxb - + bazel + checker-framework + core-groovy-modules + core-java-modules + custom-pmd + data-structures + deeplearning4j + di-modules + disruptor + docker-modules + dozer + drools + dubbo + + gcp-firebase + geotools + google-auto-project + google-cloud + gradle-modules/gradle/maven-to-gradle + graphql-modules + grpc + guava-modules + hazelcast + httpclient-simple + hystrix + image-compressing + image-processing + jackson-modules + jackson-simple + java-blockchain + java-jdi + + java-rmi + java-spi + java-websocket javafx - spring-batch + javax-sound + javaxval-2 + javaxval + jaxb + jersey + jetbrains + jgit + jhipster-6 + jib + jmeter + jmh + jsf + json-modules + jsoup + jws + ksqldb + kubernetes-modules + language-interop + libraries-2 + libraries-3 + libraries-4 + libraries-5 + libraries-6 + libraries-ai + libraries-apache-commons-2 + libraries-apache-commons-collections + libraries-apache-commons-io + libraries-apache-commons + libraries-concurrency + libraries-data-2 + libraries-data-db + libraries-data-io + libraries-data + libraries-files + libraries-http-2 + libraries-http + libraries-io + libraries-llms + libraries-primitive + libraries-rpc + libraries-security + libraries-server-2 + libraries-server + libraries-testing + libraries-transform + libraries + lightrun + logging-modules + lombok-modules + lucene + mapstruct + maven-modules + mesos-marathon + messaging-modules + metrics + microservices-modules + mustache + mybatis + netflix-modules + optaplanner + orika + osgi + parent-boot-3 + patterns-modules + pdf-2 + pdf + performance-tests + persistence-modules + persistence-modules/spring-data-neo4j + protobuffer + quarkus-modules + reactive-systems + reactor-core + rsocket + rule-engines-modules + rxjava-modules + saas-modules + security-modules + server-modules + spf4j + spring-5-webflux-2 + spring-5-webflux + spring-5 + spring-activiti + spring-actuator + spring-aop-2 + spring-aop spring-batch-2 + spring-batch + spring-boot-modules spring-boot-rest - spring-drools spring-cloud-modules/spring-cloud-azure spring-cloud-modules/spring-cloud-circuit-breaker spring-cloud-modules/spring-cloud-contract @@ -728,208 +850,58 @@ spring-cloud-modules/spring-cloud-security spring-cloud-modules/spring-cloud-stream-starters spring-cloud-modules/spring-cloud-zuul-eureka-integration - - spring-exceptions - spring-jenkins-pipeline - spring-core - spring-core-4 - spring-integration - spring-remoting-modules - libraries-security - libraries-data-db - - performance-tests - security-modules - libraries-server-2 - orika - patterns-modules - json-modules - libraries-data - saas-modules - server-modules - apache-cxf-modules - - spring-aop - jmeter - spring-aop-2 - - algorithms-modules - apache-libraries - apache-libraries-2 - apache-poi - apache-velocity - di-modules - asciidoctor - aws-modules - - checker-framework - core-groovy-modules - - core-java-modules - custom-pmd - data-structures - jackson-modules - jmh - deeplearning4j - docker-modules - drools - guava-modules - kubernetes-modules - libraries-concurrency - jhipster-6 - libraries-testing - maven-modules - optaplanner - persistence-modules - quarkus-modules - spring-reactive-modules - spring-swagger-codegen/custom-validations-opeanpi-codegen - testing-modules - testing-modules/mockito-simple - - rule-engines-modules - - reactive-systems - rxjava-modules - - lightrun - tablesaw - image-compressing - geotools - - jws - - - - akka-modules - httpclient-simple - antlr - apache-kafka - apache-kafka-2 - apache-olingo - - apache-poi-2 - apache-poi-3 - apache-thrift - apache-tika - - asm - atomikos - atomix - - bazel - google-auto-project - disruptor - dozer - dubbo - - google-cloud - graphql-modules - grpc - hazelcast - hystrix - jackson-simple - java-blockchain - java-jdi - java-rmi - java-spi - javax-sound - javaxval - javaxval-2 - jetbrains - jgit - jib - - java-native - jsoup - ksqldb - jsf - - libraries - libraries-2 - libraries-4 - libraries-5 - libraries-6 - - libraries-apache-commons - libraries-apache-commons-2 - libraries-apache-commons-collections - libraries-apache-commons-io - libraries-data-2 - libraries-data-io - libraries-files - libraries-http - libraries-http-2 - libraries-io - libraries-primitive - libraries-rpc - libraries-server - libraries-transform - - lucene - mapstruct - mesos-marathon - metrics - mustache - mybatis - pdf - pdf-2 - protobuffer - reactor-core - rsocket - - - spring-5 - spring-5-webflux - spring-5-webflux-2 - spring-6-rsocket - spring-activiti - spring-actuator spring-core-2 spring-core-3 + spring-core-4 + spring-core spring-credhub - spring-di-3 spring-cucumber - + spring-di-2 + spring-di-3 + spring-di-4 + spring-di + spring-drools + spring-ejb-modules + spring-exceptions + spring-integration + spring-jenkins-pipeline + spring-jersey + spring-jinq + spring-kafka-2 spring-kafka - + spring-katharsis + spring-mobile spring-native - spring-soap - spring-security-modules spring-protobuf + spring-pulsar spring-quartz - + spring-reactive-modules + spring-remoting-modules spring-scheduling - - spring-state-machine + spring-security-modules spring-shell + spring-soap spring-spel + spring-state-machine spring-static-resources + spring-swagger-codegen/custom-validations-opeanpi-codegen spring-threads spring-vault - spring-websockets spring-web-modules + spring-websockets static-analysis + tablesaw tensorflow-java - vertx-modules - xstream - webrtc - - messaging-modules - + testing-modules + testing-modules/mockito-simple vaadin - libraries-3 + vavr-modules + vertx-modules web-modules - xml + webrtc xml-2 - image-processing - language-interop - gradle-modules/gradle/maven-to-gradle - persistence-modules/spring-data-neo4j - gcp-firebase - spring-di-4 - spring-kafka-2 - + xml + xstream @@ -963,255 +935,218 @@ - parent-boot-3 - lombok-modules - osgi - spring-katharsis - logging-modules - spring-boot-modules - apache-httpclient - apache-httpclient4 - apache-httpclient-2 - spring-mobile - microservices-modules - spring-ejb-modules - spring-di - spring-di-2 - spring-jinq - vavr-modules - java-websocket - azure - netflix-modules - spf4j - spring-jersey - jersey - jaxb - - javafx - spring-batch - spring-batch-2 - spring-boot-rest - spring-drools - spring-cloud-modules/spring-cloud-azure - spring-cloud-modules/spring-cloud-circuit-breaker - spring-cloud-modules/spring-cloud-eureka - spring-cloud-modules/spring-cloud-contract - spring-cloud-modules/spring-cloud-data-flow - spring-cloud-modules/spring-cloud-netflix-feign - spring-cloud-modules/spring-cloud-stream-starters - spring-cloud-modules/spring-cloud-security - spring-cloud-modules/spring-cloud-zuul-eureka-integration - - spring-exceptions - spring-jenkins-pipeline - spring-core - spring-core-4 - spring-integration - spring-remoting-modules - libraries-security - libraries-data-db - - performance-tests - security-modules - libraries-server-2 - orika - patterns-modules - json-modules - libraries-data - saas-modules - server-modules - apache-cxf-modules - - algorithms-modules - apache-libraries - apache-libraries-2 - apache-poi - apache-velocity - di-modules - asciidoctor - aws-modules - - checker-framework - - core-groovy-modules - - core-java-modules - gcp-firebase - - - - - - - - - spring-aop - spring-aop-2 - custom-pmd - data-structures - jackson-modules - jmh - deeplearning4j - jmeter - docker-modules - drools - guava-modules - kubernetes-modules - libraries-concurrency - jhipster-6 - libraries-testing - maven-modules - optaplanner - persistence-modules - quarkus-modules - spring-reactive-modules - spring-swagger-codegen/custom-validations-opeanpi-codegen - testing-modules - testing-modules/mockito-simple - - rule-engines-modules - - reactive-systems - rxjava-modules - - lightrun - tablesaw - image-compressing - geotools - - jws - - - akka-modules + algorithms-modules antlr - apache-kafka + apache-cxf-modules + apache-httpclient-2 + apache-httpclient4 + apache-httpclient apache-kafka-2 + apache-kafka + apache-libraries-2 + apache-libraries apache-olingo - apache-poi-2 apache-poi-3 + apache-poi apache-thrift apache-tika - + apache-velocity + asciidoctor asm atomikos atomix - + aws-modules + azure bazel - google-auto-project + checker-framework + core-groovy-modules + core-java-modules + custom-pmd + data-structures + deeplearning4j + di-modules disruptor + docker-modules dozer - + drools dubbo + gcp-firebase + geotools + google-auto-project google-cloud + gradle-modules/gradle/maven-to-gradle graphql-modules grpc + guava-modules hazelcast httpclient-simple hystrix + image-compressing + image-processing + jackson-modules jackson-simple java-blockchain java-jdi + java-rmi java-spi + java-websocket + javafx javax-sound - javaxval javaxval-2 + javaxval + jaxb + jersey jetbrains jgit + jhipster-6 jib - - java-native - jsoup + jmeter + jmh jsf + json-modules + jsoup + jws ksqldb - - libraries + kubernetes-modules + language-interop libraries-2 + libraries-3 libraries-4 libraries-5 libraries-6 - libraries-apache-commons + libraries-ai libraries-apache-commons-2 libraries-apache-commons-collections libraries-apache-commons-io - libraries-data-2 + libraries-apache-commons + libraries-concurrency + libraries-data-2 + libraries-data-db libraries-data-io + libraries-data libraries-files - libraries-http libraries-http-2 + libraries-http libraries-io - libraries-ai + libraries-llms libraries-primitive libraries-rpc + libraries-security + libraries-server-2 libraries-server + libraries-testing libraries-transform - + libraries + lightrun + logging-modules + lombok-modules lucene mapstruct + maven-modules mesos-marathon + messaging-modules metrics + microservices-modules mustache mybatis - pdf + netflix-modules + optaplanner + orika + osgi + parent-boot-3 + patterns-modules pdf-2 + pdf + performance-tests + persistence-modules + persistence-modules/spring-data-neo4j protobuffer + quarkus-modules + reactive-systems reactor-core rsocket - - - - spring-5 - spring-5-webflux + rule-engines-modules + rxjava-modules + saas-modules + security-modules + server-modules + spf4j spring-5-webflux-2 + spring-5-webflux + spring-5 spring-activiti + spring-actuator + spring-aop-2 + spring-aop + spring-batch-2 + spring-batch + spring-boot-modules + spring-boot-rest + spring-cloud-modules/spring-cloud-azure + spring-cloud-modules/spring-cloud-circuit-breaker + spring-cloud-modules/spring-cloud-contract + spring-cloud-modules/spring-cloud-data-flow + spring-cloud-modules/spring-cloud-eureka + spring-cloud-modules/spring-cloud-netflix-feign + spring-cloud-modules/spring-cloud-security + spring-cloud-modules/spring-cloud-stream-starters + spring-cloud-modules/spring-cloud-zuul-eureka-integration spring-core-2 spring-core-3 + spring-core-4 + spring-core spring-credhub - spring-di-3 spring-cucumber - + spring-di-2 + spring-di-3 + spring-di-4 + spring-di + spring-drools + spring-ejb-modules + spring-exceptions + spring-integration + spring-jenkins-pipeline + spring-jersey + spring-jinq + spring-kafka-2 spring-kafka - + spring-katharsis + spring-mobile spring-native - spring-soap - spring-security-modules spring-protobuf + spring-pulsar spring-quartz - + spring-reactive-modules + spring-remoting-modules spring-scheduling - - spring-state-machine + spring-security-modules spring-shell + spring-soap spring-spel + spring-state-machine spring-static-resources + spring-swagger-codegen/custom-validations-opeanpi-codegen spring-threads spring-vault - spring-websockets spring-web-modules + spring-websockets static-analysis + tablesaw tensorflow-java - vertx-modules - xstream - webrtc - - messaging-modules - + testing-modules + testing-modules/mockito-simple vaadin - libraries-3 + vavr-modules + vertx-modules web-modules - xml + webrtc xml-2 - image-processing - language-interop - gradle-modules/gradle/maven-to-gradle - persistence-modules/spring-data-neo4j - spring-actuator - spring-di-4 - spring-kafka-2 - + xml + xstream diff --git a/reactive-systems/docker-compose.yml b/reactive-systems/docker-compose.yml new file mode 100644 index 0000000000..51e15f6a19 --- /dev/null +++ b/reactive-systems/docker-compose.yml @@ -0,0 +1,57 @@ +version: '3' +services: + frontend: + build: ./frontend + ports: + - "80:80" + zookeeper: + image: confluentinc/cp-zookeeper:latest + environment: + ZOOKEEPER_CLIENT_PORT: 2181 + ZOOKEEPER_TICK_TIME: 2000 + ports: + - 22181:2181 + kafka: + image: confluentinc/cp-kafka:latest + container_name: kafka-broker + depends_on: + - zookeeper + ports: + - 29092:29092 + environment: + KAFKA_BROKER_ID: 1 + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-broker:9092,PLAINTEXT_HOST://localhost:29092 + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT + KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 + mongodb: + container_name: mongo-db + image: mongo:6.0 + volumes: + - ~/mongo:/data/db + ports: + - "27017:27017" + healthcheck: + test: exit 0 + order-service: + build: ./order-service + ports: + - "8080:8080" + depends_on: + mongodb: + condition: service_healthy + inventory-service: + build: ./inventory-service + ports: + - "8081:8081" + depends_on: + mongodb: + condition: service_healthy + shipping-service: + build: ./shipping-service + ports: + - "8082:8082" + depends_on: + mongodb: + condition: service_healthy \ No newline at end of file diff --git a/reactive-systems/inventory-service/Dockerfile b/reactive-systems/inventory-service/Dockerfile index d37887cf34..d0900decfa 100644 --- a/reactive-systems/inventory-service/Dockerfile +++ b/reactive-systems/inventory-service/Dockerfile @@ -1,3 +1,3 @@ FROM openjdk:8-jdk-alpine -COPY target/inventory-service-async-0.0.1-SNAPSHOT.jar app.jar +COPY target/inventory-service-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java","-jar","-Dspring.profiles.active=docker","/app.jar"] \ No newline at end of file diff --git a/reactive-systems/order-service/Dockerfile b/reactive-systems/order-service/Dockerfile index 516e088a05..e48c19c2b1 100644 --- a/reactive-systems/order-service/Dockerfile +++ b/reactive-systems/order-service/Dockerfile @@ -1,3 +1,3 @@ FROM openjdk:8-jdk-alpine -COPY target/order-service-async-0.0.1-SNAPSHOT.jar app.jar +COPY target/order-service-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java","-jar","-Dspring.profiles.active=docker","/app.jar"] \ No newline at end of file diff --git a/reactive-systems/shipping-service/Dockerfile b/reactive-systems/shipping-service/Dockerfile index 4906d1d9a8..ff57bb953d 100644 --- a/reactive-systems/shipping-service/Dockerfile +++ b/reactive-systems/shipping-service/Dockerfile @@ -1,3 +1,3 @@ FROM openjdk:8-jdk-alpine -COPY target/shipping-service-async-0.0.1-SNAPSHOT.jar app.jar +COPY target/shipping-service-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java","-jar","-Dspring.profiles.active=docker","/app.jar"] \ No newline at end of file diff --git a/reactor-core/README.md b/reactor-core/README.md index dccf1fa85c..96355ad703 100644 --- a/reactor-core/README.md +++ b/reactor-core/README.md @@ -13,3 +13,4 @@ This module contains articles about Reactor Core. - [Handling Exceptions in Project Reactor](https://www.baeldung.com/reactor-exceptions) - [Difference Between Flux.create and Flux.generate](https://www.baeldung.com/java-flux-create-generate) - [Difference Between Flux and Mono](https://www.baeldung.com/java-reactor-flux-vs-mono) +- [Working With MathFlux](https://www.baeldung.com/java-reactor-mathflux) diff --git a/reactor-core/pom.xml b/reactor-core/pom.xml index e27a1a2845..dd7533fe73 100644 --- a/reactor-core/pom.xml +++ b/reactor-core/pom.xml @@ -26,6 +26,11 @@ ${reactor.version} test + + io.projectreactor.addons + reactor-extra + ${reactor.version} + org.projectlombok lombok @@ -35,7 +40,7 @@ - 3.4.17 + 3.5.1 \ No newline at end of file diff --git a/reactor-core/src/test/java/com/baeldung/reactor/math/MathFluxOperationsUnitTest.java b/reactor-core/src/test/java/com/baeldung/reactor/math/MathFluxOperationsUnitTest.java new file mode 100644 index 0000000000..2ff8005acd --- /dev/null +++ b/reactor-core/src/test/java/com/baeldung/reactor/math/MathFluxOperationsUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.math; + +import org.junit.Test; + +import reactor.math.MathFlux; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +public class MathFluxOperationsUnitTest { + + @Test + public void givenFluxOfNumbers_whenCalculatingSum_thenExpectCorrectResult() { + Flux numbers = Flux.just(1, 2, 3, 4, 5); + Mono sumMono = MathFlux.sumInt(numbers); + StepVerifier.create(sumMono) + .expectNext(15) + .verifyComplete(); + } + + @Test + public void givenFluxOfNumbers_whenCalculatingAverage_thenExpectCorrectResult() { + Flux numbers = Flux.just(1, 2, 3, 4, 5); + Mono averageMono = MathFlux.averageDouble(numbers); + StepVerifier.create(averageMono) + .expectNext(3.0) + .verifyComplete(); + } + + @Test + public void givenFluxOfNumbers_whenFindingMinElement_thenExpectCorrectResult() { + Flux numbers = Flux.just(3, 1, 5, 2, 4); + Mono minMono = MathFlux.min(numbers); + StepVerifier.create(minMono) + .expectNext(1) + .verifyComplete(); + } + + @Test + public void givenFluxOfNumbers_whenFindingMaxElement_thenExpectCorrectResult() { + Flux numbers = Flux.just(3, 1, 5, 2, 4); + Mono maxMono = MathFlux.max(numbers); + StepVerifier.create(maxMono) + .expectNext(5) + .verifyComplete(); + } + +} diff --git a/security-modules/cas/cas-secured-app/pom.xml b/security-modules/cas/cas-secured-app/pom.xml index 6f1ec22cb5..7c4864b1c0 100644 --- a/security-modules/cas/cas-secured-app/pom.xml +++ b/security-modules/cas/cas-secured-app/pom.xml @@ -36,6 +36,15 @@ spring-boot-devtools runtime + + org.springframework.boot + spring-boot-starter-data-jpa + + + mysql + mysql-connector-java + runtime + org.springframework.boot spring-boot-starter-test @@ -46,6 +55,11 @@ spring-security-test test + + com.h2database + h2 + ${h2.version} + diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java index 62da9cf725..f78d7a45d5 100644 --- a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java @@ -1,7 +1,6 @@ package com.baeldung.cassecuredapp; import org.jasig.cas.client.session.SingleSignOutFilter; -import org.jasig.cas.client.session.SingleSignOutHttpSessionListener; import org.jasig.cas.client.validation.Cas30ServiceTicketValidator; import org.jasig.cas.client.validation.TicketValidator; import org.slf4j.Logger; @@ -9,21 +8,16 @@ import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import org.springframework.context.event.EventListener; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.cas.ServiceProperties; import org.springframework.security.cas.authentication.CasAuthenticationProvider; -import org.springframework.security.cas.web.CasAuthenticationEntryPoint; import org.springframework.security.cas.web.CasAuthenticationFilter; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.User; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutFilter; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; -import javax.servlet.http.HttpSessionEvent; +import com.baeldung.cassecuredapp.service.CasUserDetailsService; @SpringBootApplication public class CasSecuredApplication { @@ -34,6 +28,7 @@ public class CasSecuredApplication { SpringApplication.run(CasSecuredApplication.class, args); } + @Bean public CasAuthenticationFilter casAuthenticationFilter( AuthenticationManager authenticationManager, @@ -58,6 +53,10 @@ public class CasSecuredApplication { return new Cas30ServiceTicketValidator("https://localhost:8443/cas"); } + @Bean + public CasUserDetailsService getUser(){ + return new CasUserDetailsService(); + } @Bean public CasAuthenticationProvider casAuthenticationProvider( TicketValidator ticketValidator, @@ -68,6 +67,8 @@ public class CasSecuredApplication { provider.setUserDetailsService( s -> new User("casuser", "Mellon", true, true, true, true, AuthorityUtils.createAuthorityList("ROLE_ADMIN"))); + //For Authentication with a Database-backed UserDetailsService + //provider.setUserDetailsService(getUser()); provider.setKey("CAS_PROVIDER_LOCALHOST_8900"); return provider; } diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/service/CasUserDetailsService.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/service/CasUserDetailsService.java new file mode 100644 index 0000000000..801f5726b7 --- /dev/null +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/service/CasUserDetailsService.java @@ -0,0 +1,37 @@ +package com.baeldung.cassecuredapp.service; + +import java.util.Collections; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +import com.baeldung.cassecuredapp.user.CasUser; +import com.baeldung.cassecuredapp.user.UserRepository; + +public class CasUserDetailsService implements UserDetailsService { + + @Autowired + private UserRepository userRepository; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + // Get the user from the database. + CasUser casUser = getUserFromDatabase(username); + + // Create a UserDetails object. + UserDetails userDetails = new User( + casUser.getEmail(), + casUser.getPassword(), + Collections.singletonList(new SimpleGrantedAuthority("ROLE_ADMIN"))); + + return userDetails; + } + + private CasUser getUserFromDatabase(String username) { + return userRepository.findByEmail(username); + } +} diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/CasUser.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/CasUser.java new file mode 100644 index 0000000000..2bf96d0994 --- /dev/null +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/CasUser.java @@ -0,0 +1,41 @@ +package com.baeldung.cassecuredapp.user; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class CasUser { + @Id + private Long id; + + @Column(nullable = false, unique = true) + private String email; + + private String password; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/UserRepository.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/UserRepository.java new file mode 100644 index 0000000000..623ccf2e38 --- /dev/null +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/UserRepository.java @@ -0,0 +1,12 @@ +package com.baeldung.cassecuredapp.user; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserRepository extends CrudRepository { + + CasUser findByEmail(@Param("email") String email); + +} diff --git a/security-modules/cas/cas-secured-app/src/main/resources/application.properties b/security-modules/cas/cas-secured-app/src/main/resources/application.properties index f8789997d5..5c93c67ff1 100644 --- a/security-modules/cas/cas-secured-app/src/main/resources/application.properties +++ b/security-modules/cas/cas-secured-app/src/main/resources/application.properties @@ -1,2 +1,8 @@ server.port=8900 -spring.freemarker.suffix=.ftl \ No newline at end of file +spring.freemarker.suffix=.ftl + +#spring.jpa.generate-ddl=false +#spring.datasource.url= jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC +#spring.datasource.username=root +#spring.datasource.password=root +#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver \ No newline at end of file diff --git a/security-modules/cas/cas-server/src/main/resources/application.yml b/security-modules/cas/cas-server/src/main/resources/application.yml index 0c4e4ffde2..a49e86dd09 100644 --- a/security-modules/cas/cas-server/src/main/resources/application.yml +++ b/security-modules/cas/cas-server/src/main/resources/application.yml @@ -8,3 +8,19 @@ server: spring: main: allow-bean-definition-overriding: true +#cas: +# authn: +# accept: +# users: +# jdbc: +# query[0]: +# sql: SELECT * FROM users WHERE email = ? +# url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC +# dialect: org.hibernate.dialect.MySQLDialect +# user: root +# password: root +# ddlAuto: none +# driverClass: com.mysql.cj.jdbc.Driver +# fieldPassword: password +# passwordEncoder: +# type: NONE diff --git a/spring-5-webflux-2/README.md b/spring-5-webflux-2/README.md index 1b01f519a4..a0fafd903e 100644 --- a/spring-5-webflux-2/README.md +++ b/spring-5-webflux-2/README.md @@ -6,4 +6,4 @@ This module contains articles about Spring 5 WebFlux - [Spring Webflux and @Cacheable Annotation](https://www.baeldung.com/spring-webflux-cacheable) - [Comparison Between Mono’s doOnNext() and doOnSuccess()](https://www.baeldung.com/mono-doonnext-doonsuccess) - [How to Access the First Element of a Flux](https://www.baeldung.com/java-flux-first-element) -- [Using zipWhen() with Mono](https://www.baeldung.com/java-mono-zipwhen) +- [Using zipWhen() With Mono](https://www.baeldung.com/java-mono-zipwhen) diff --git a/spring-5-webflux-2/pom.xml b/spring-5-webflux-2/pom.xml index 68945138d4..34cbda6c18 100644 --- a/spring-5-webflux-2/pom.xml +++ b/spring-5-webflux-2/pom.xml @@ -100,7 +100,7 @@ 3.4.5 - 2.9.2 + 3.1.8 1.16.2 diff --git a/spring-6-rsocket/pom.xml b/spring-6-rsocket/pom.xml index 5d15a605ae..7f88df01e2 100644 --- a/spring-6-rsocket/pom.xml +++ b/spring-6-rsocket/pom.xml @@ -1,12 +1,12 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.bealdung - rsocket + spring-6-rsocket 0.0.1-SNAPSHOT - rsocket + spring-6-rsocket com.baeldung @@ -16,7 +16,6 @@ - org.springframework.boot spring-boot-starter-rsocket @@ -66,9 +65,11 @@ + 3.1.3 1.4.11 2.0.9 + diff --git a/spring-activiti/src/test/java/com/baeldung/activitiwithspring/ActivitiWithSpringApplicationIntegrationTest.java b/spring-activiti/src/test/java/com/baeldung/activitiwithspring/ActivitiWithSpringApplicationIntegrationTest.java deleted file mode 100644 index d289693a73..0000000000 --- a/spring-activiti/src/test/java/com/baeldung/activitiwithspring/ActivitiWithSpringApplicationIntegrationTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.baeldung.activitiwithspring; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = ActivitiWithSpringApplication.class) -@AutoConfigureTestDatabase -public class ActivitiWithSpringApplicationIntegrationTest { - - @Test - public void contextLoads() { - } - -} diff --git a/spring-aop-2/pom.xml b/spring-aop-2/pom.xml index 206e1d7d7c..f1257369e0 100644 --- a/spring-aop-2/pom.xml +++ b/spring-aop-2/pom.xml @@ -74,54 +74,54 @@ - - compile-time-weaving + + compile-time-weaving - - - org.springframework - spring-aspects - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - com.baeldung.selfinvocation.CompileTimeWeavingIntegrationTest - - - - - org.codehaus.mojo - aspectj-maven-plugin - ${aspectj-plugin.version} - - ${java.version} - ${java.version} - ${java.version} - ignore - UTF-8 - - - org.springframework - spring-aspects - - - - - - - compile - - - - - - - + + + org.springframework + spring-aspects + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + com.baeldung.selfinvocation.CompileTimeWeavingIntegrationTest + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj-plugin.version} + + ${java.version} + ${java.version} + ${java.version} + ignore + UTF-8 + + + org.springframework + spring-aspects + + + + + + + compile + + + + + + + load-time-weaving diff --git a/spring-batch/pom.xml b/spring-batch/pom.xml index 7d9becf089..20b0ef6d1c 100644 --- a/spring-batch/pom.xml +++ b/spring-batch/pom.xml @@ -74,7 +74,7 @@ 6.0.6 - 5.7.1 + 5.8 4.0.0 4.0.2 2.14.2 diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 259a40dc38..433f23f4ba 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -68,6 +68,9 @@ spring-boot-runtime spring-boot-runtime-2 spring-boot-security + spring-boot-security-2 + spring-boot-ssl-bundles + spring-boot-telegram spring-boot-springdoc spring-boot-swagger spring-boot-swagger-2 diff --git a/spring-boot-modules/spring-boot-3-2/README.md b/spring-boot-modules/spring-boot-3-2/README.md index c176de2310..27f9281725 100644 --- a/spring-boot-modules/spring-boot-3-2/README.md +++ b/spring-boot-modules/spring-boot-3-2/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Spring Boot 3.1’s ConnectionDetails Abstraction](https://www.baeldung.com/spring-boot-3-1-connectiondetails-abstraction) +- [@ConditionalOnThreading Annotation Spring](https://www.baeldung.com/spring-conditionalonthreading) diff --git a/spring-boot-modules/spring-boot-3-2/pom.xml b/spring-boot-modules/spring-boot-3-2/pom.xml index 9e73d8ea32..c85488d44b 100644 --- a/spring-boot-modules/spring-boot-3-2/pom.xml +++ b/spring-boot-modules/spring-boot-3-2/pom.xml @@ -15,6 +15,14 @@ ../../parent-boot-3 + + + repository.spring.release + Spring GA Repository + https://repo.spring.io/milestone + + + org.springframework.boot @@ -94,6 +102,17 @@ org.springframework.boot spring-boot-starter-test + 3.2.0-M2 + + + org.junit.jupiter + junit-jupiter + 5.10.0 + + + org.junit.jupiter + junit-jupiter-api + 5.10.0 org.postgresql @@ -116,6 +135,7 @@ redis.clients jedis + ${jedis.version} jar @@ -175,6 +195,18 @@ + + + + org.springframework.boot + spring-boot-dependencies + 3.2.0-M2 + import + pom + + + + @@ -244,19 +276,17 @@ org.apache.maven.plugins maven-compiler-plugin - - --enable-preview - - 1.5.2.Final + 1.6.0.Beta1 2.0.0 3.0.0-M7 5.14.0 0.2.0 + 5.0.2 diff --git a/spring-boot-modules/spring-boot-3-2/src/test/java/com/baeldung/conditionalonthreading/ConditionalOnThreadingUnitTest.java b/spring-boot-modules/spring-boot-3-2/src/test/java/com/baeldung/conditionalonthreading/ConditionalOnThreadingUnitTest.java new file mode 100644 index 0000000000..ed65769954 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-2/src/test/java/com/baeldung/conditionalonthreading/ConditionalOnThreadingUnitTest.java @@ -0,0 +1,70 @@ +package com.baeldung.conditionalonthreading; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledForJreRange; +import org.junit.jupiter.api.condition.JRE; +import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading; +import org.springframework.boot.autoconfigure.thread.Threading; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +public class ConditionalOnThreadingUnitTest { + + ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() + .withUserConfiguration(CurrentConfig.class); + + @Configuration + static class CurrentConfig { + + @Bean + @ConditionalOnThreading(Threading.PLATFORM) + ThreadingType platformBean() { + return ThreadingType.PLATFORM; + } + + @Bean + @ConditionalOnThreading(Threading.VIRTUAL) + ThreadingType virtualBean() { + return ThreadingType.VIRTUAL; + } + } + + enum ThreadingType { + PLATFORM, VIRTUAL + } + + @Test + @EnabledForJreRange(max = JRE.JAVA_20) + public void whenJava20AndVirtualThreadsEnabled_thenThreadingIsPlatform() { + applicationContextRunner.withPropertyValues("spring.threads.virtual.enabled=true").run(context -> { + Assertions.assertThat(context.getBean(ThreadingType.class)).isEqualTo(ThreadingType.PLATFORM); + }); + } + + @Test + @EnabledForJreRange(max = JRE.JAVA_20) + public void whenJava20AndVirtualThreadsDisabled_thenThreadingIsPlatform() { + applicationContextRunner.withPropertyValues("spring.threads.virtual.enabled=false").run(context -> { + Assertions.assertThat(context.getBean(ThreadingType.class)).isEqualTo(ThreadingType.PLATFORM); + }); + } + + @Test + @EnabledForJreRange(min = JRE.JAVA_21) + public void whenJava21AndVirtualThreadsEnabled_thenThreadingIsVirtual() { + applicationContextRunner.withPropertyValues("spring.threads.virtual.enabled=true").run(context -> { + Assertions.assertThat(context.getBean(ThreadingType.class)).isEqualTo(ThreadingType.VIRTUAL); + }); + } + + @Test + @EnabledForJreRange(min = JRE.JAVA_21) + public void whenJava21AndVirtualThreadsDisabled_thenThreadingIsPlatform() { + applicationContextRunner.withPropertyValues("spring.threads.virtual.enabled=false").run(context -> { + Assertions.assertThat(context.getBean(ThreadingType.class)).isEqualTo(ThreadingType.PLATFORM); + }); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3-testcontainers/pom.xml b/spring-boot-modules/spring-boot-3-testcontainers/pom.xml index 173fb8795c..d24da58742 100644 --- a/spring-boot-modules/spring-boot-3-testcontainers/pom.xml +++ b/spring-boot-modules/spring-boot-3-testcontainers/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-3-testcontainers 0.0.1-SNAPSHOT @@ -16,7 +16,6 @@ - org.springframework.boot spring-boot-starter diff --git a/spring-boot-modules/spring-boot-3/pom.xml b/spring-boot-modules/spring-boot-3/pom.xml index bb8c5dd53c..ae9e9d7308 100644 --- a/spring-boot-modules/spring-boot-3/pom.xml +++ b/spring-boot-modules/spring-boot-3/pom.xml @@ -207,7 +207,7 @@ 19 - 1.5.2.Final + 1.6.0.Beta1 2.2.0 3.0.0-M7 com.baeldung.sample.TodoApplication diff --git a/spring-boot-modules/spring-boot-environment/pom.xml b/spring-boot-modules/spring-boot-environment/pom.xml index 4bdb35358c..9974d41f45 100644 --- a/spring-boot-modules/spring-boot-environment/pom.xml +++ b/spring-boot-modules/spring-boot-environment/pom.xml @@ -9,9 +9,10 @@ Demo project for Spring Boot - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -46,11 +47,6 @@ h2 runtime - - javax.persistence - javax.persistence-api - ${jpa.version} - com.google.guava guava @@ -96,6 +92,15 @@ + + + org.springframework.boot + spring-boot-maven-plugin + + com.baeldung.environmentpostprocessor.PriceCalculationApplication + + + @@ -151,7 +156,6 @@ - 2.2 3.1.7 4.5.8 2021.0.0 diff --git a/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring.factories b/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring.factories deleted file mode 100644 index c36b67f8d7..0000000000 --- a/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,6 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -com.baeldung.environmentpostprocessor.autoconfig.PriceCalculationAutoConfig - -org.springframework.boot.env.EnvironmentPostProcessor=\ -com.baeldung.environmentpostprocessor.PriceCalculationEnvironmentPostProcessor - diff --git a/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/AutoConfiguration.imports b/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/AutoConfiguration.imports new file mode 100644 index 0000000000..350e2efa94 --- /dev/null +++ b/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/AutoConfiguration.imports @@ -0,0 +1 @@ +com.baeldung.environmentpostprocessor.autoconfig.PriceCalculationAutoConfig diff --git a/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/spring.factories b/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/spring.factories new file mode 100644 index 0000000000..ff5e404c84 --- /dev/null +++ b/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/spring.factories @@ -0,0 +1,3 @@ +org.springframework.boot.env.EnvironmentPostProcessor=\ +com.baeldung.environmentpostprocessor.PriceCalculationEnvironmentPostProcessor + diff --git a/spring-boot-modules/spring-boot-graalvm-docker/pom.xml b/spring-boot-modules/spring-boot-graalvm-docker/pom.xml index a3a1b148c2..253e8fceb6 100644 --- a/spring-boot-modules/spring-boot-graalvm-docker/pom.xml +++ b/spring-boot-modules/spring-boot-graalvm-docker/pom.xml @@ -1,41 +1,44 @@ - + 4.0.0 - - - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 - - com.baeldung spring-boot-graalvm-docker 1.0.0 spring-boot-graalvm-docker Spring Boot GrralVM with Docker + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 + + - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-test - test - + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + - - - org.graalvm.buildtools - native-maven-plugin - - - org.springframework.boot - spring-boot-maven-plugin - - + + + org.graalvm.buildtools + native-maven-plugin + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/spring-boot-modules/spring-boot-jasypt/pom.xml b/spring-boot-modules/spring-boot-jasypt/pom.xml index 70bbe35319..0f9ad72b64 100644 --- a/spring-boot-modules/spring-boot-jasypt/pom.xml +++ b/spring-boot-modules/spring-boot-jasypt/pom.xml @@ -27,7 +27,7 @@ com.github.ulisesbocchio - jasypt-spring-boot-starter + jasypt-spring-boot-starter ${jasypt.version} @@ -49,4 +49,5 @@ 3.0.5 + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java index eb7767480f..5b9ce9677a 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java @@ -4,6 +4,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -53,7 +54,8 @@ class SecurityConfig { .hasRole("USER") .anyRequest() .authenticated(); - http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); + http.oauth2ResourceServer((oauth2) -> oauth2 + .jwt(Customizer.withDefaults())); return http.build(); } diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java index e55d307e33..ff1cf0cb42 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java @@ -3,10 +3,11 @@ package com.baeldung.keycloaksoap; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.web.SecurityFilterChain; @Configuration @@ -17,11 +18,11 @@ public class KeycloakSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.csrf() - .disable() + http.csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(auth -> auth.anyRequest() .authenticated()) - .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); + .oauth2ResourceServer((oauth2) -> oauth2 + .jwt(Customizer.withDefaults())); return http.build(); } } diff --git a/spring-boot-modules/spring-boot-libraries/pom.xml b/spring-boot-modules/spring-boot-libraries/pom.xml index d8ca53f013..b0f0c780aa 100644 --- a/spring-boot-modules/spring-boot-libraries/pom.xml +++ b/spring-boot-modules/spring-boot-libraries/pom.xml @@ -18,6 +18,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-validation + org.springframework.boot spring-boot-starter-security @@ -95,7 +99,7 @@ - com.github.vladimir-bukhtoyarov + com.bucket4j bucket4j-core ${bucket4j.version} @@ -219,16 +223,16 @@ 5.0.2 5.2.4 2.2.4 - 2.3.2 + 3.2.0 0.23.0 2.1.0 1.5-beta1 2.1 2.6.0 3.3.0 - 7.6.0 - 0.7.0 - 2.8.2 + 8.1.0 + 0.8.1 + 3.1.8 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries/src/main/resources/ratelimiting/application-bucket4j-starter.yml b/spring-boot-modules/spring-boot-libraries/src/main/resources/ratelimiting/application-bucket4j-starter.yml index ecc9f22e0a..efff65555b 100644 --- a/spring-boot-modules/spring-boot-libraries/src/main/resources/ratelimiting/application-bucket4j-starter.yml +++ b/spring-boot-modules/spring-boot-libraries/src/main/resources/ratelimiting/application-bucket4j-starter.yml @@ -21,19 +21,19 @@ bucket4j: url: /api/v1/area.* http-response-body: "{ \"status\": 429, \"error\": \"Too Many Requests\", \"message\": \"You have exhausted your API Request Quota\" }" rate-limits: - - expression: "getHeader('X-api-key')" + - cache-key: "getHeader('X-api-key')" execute-condition: "getHeader('X-api-key').startsWith('PX001-')" bandwidths: - capacity: 100 time: 1 unit: hours - - expression: "getHeader('X-api-key')" + - cache-key: "getHeader('X-api-key')" execute-condition: "getHeader('X-api-key').startsWith('BX001-')" bandwidths: - capacity: 40 time: 1 unit: hours - - expression: "getHeader('X-api-key')" + - cache-key: "getHeader('X-api-key')" bandwidths: - capacity: 20 time: 1 diff --git a/spring-boot-modules/spring-boot-mvc/README.md b/spring-boot-modules/spring-boot-mvc/README.md index f45feb6169..9257d6eba1 100644 --- a/spring-boot-modules/spring-boot-mvc/README.md +++ b/spring-boot-modules/spring-boot-mvc/README.md @@ -10,4 +10,5 @@ This module contains articles about Spring Web MVC in Spring Boot projects. - [Using Spring ResponseEntity to Manipulate the HTTP Response](https://www.baeldung.com/spring-response-entity) - [The @ServletComponentScan Annotation in Spring Boot](https://www.baeldung.com/spring-servletcomponentscan) - [Guide to Internationalization in Spring Boot](https://www.baeldung.com/spring-boot-internationalization) +- [Localized Validation Messages in REST](https://www.baeldung.com/rest-localized-validation-messages) - More articles: [[next -->]](/spring-boot-modules/spring-boot-mvc-2) diff --git a/spring-boot-modules/spring-boot-mvc/pom.xml b/spring-boot-modules/spring-boot-mvc/pom.xml index 369bcf799b..a251c5049b 100644 --- a/spring-boot-modules/spring-boot-mvc/pom.xml +++ b/spring-boot-modules/spring-boot-mvc/pom.xml @@ -91,6 +91,10 @@ aspectjweaver ${aspectjweaver.version} + + org.projectlombok + lombok + diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/RestValidationApplication.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/RestValidationApplication.java new file mode 100644 index 0000000000..b335aecac2 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/RestValidationApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.restvalidation; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackages = { "com.baeldung.restvalidation" }) +public class RestValidationApplication { + + public static void main(String[] args) { + SpringApplication.run(RestValidationApplication.class, args); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/MessageConfig.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/MessageConfig.java new file mode 100644 index 0000000000..e37e2c9d78 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/MessageConfig.java @@ -0,0 +1,38 @@ +package com.baeldung.restvalidation.config; + +import javax.validation.MessageInterpolator; + +import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ReloadableResourceBundleMessageSource; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; +import org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator; + +@Configuration +public class MessageConfig { + + @Bean + public MessageSource messageSource() { + ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); + messageSource.setBasename("classpath:CustomValidationMessages"); + messageSource.setDefaultEncoding("UTF-8"); + return messageSource; + } + + @Bean + public MessageInterpolator getMessageInterpolator(MessageSource messageSource) { + MessageSourceResourceBundleLocator resourceBundleLocator = new MessageSourceResourceBundleLocator(messageSource); + ResourceBundleMessageInterpolator messageInterpolator = new ResourceBundleMessageInterpolator(resourceBundleLocator); + return new RecursiveLocaleContextMessageInterpolator(messageInterpolator); + } + + @Bean + public LocalValidatorFactoryBean getValidator(MessageInterpolator messageInterpolator) { + LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean(); + bean.setMessageInterpolator(messageInterpolator); + return bean; + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/RecursiveLocaleContextMessageInterpolator.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/RecursiveLocaleContextMessageInterpolator.java new file mode 100644 index 0000000000..003a3d79b0 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/RecursiveLocaleContextMessageInterpolator.java @@ -0,0 +1,36 @@ +package com.baeldung.restvalidation.config; + +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.validation.MessageInterpolator; + +import org.hibernate.validator.messageinterpolation.AbstractMessageInterpolator; +import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; + +public class RecursiveLocaleContextMessageInterpolator extends AbstractMessageInterpolator { + + private static final Pattern PATTERN_PLACEHOLDER = Pattern.compile("\\{([^}]+)\\}"); + + private final MessageInterpolator interpolator; + + public RecursiveLocaleContextMessageInterpolator(ResourceBundleMessageInterpolator interpolator) { + this.interpolator = interpolator; + } + + @Override + public String interpolate(MessageInterpolator.Context context, Locale locale, String message) { + int level = 0; + while (containsPlaceholder(message) && (level++ < 2)) { + message = this.interpolator.interpolate(message, context, locale); + } + return message; + } + + private boolean containsPlaceholder(String code) { + Matcher matcher = PATTERN_PLACEHOLDER.matcher(code); + return matcher.find(); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/response/InputFieldError.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/response/InputFieldError.java new file mode 100644 index 0000000000..06bd764d97 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/response/InputFieldError.java @@ -0,0 +1,12 @@ +package com.baeldung.restvalidation.response; + +import lombok.*; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class InputFieldError { + private String field; + private String message; + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/response/UpdateUserResponse.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/response/UpdateUserResponse.java new file mode 100644 index 0000000000..7eb400cd2c --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/response/UpdateUserResponse.java @@ -0,0 +1,17 @@ +package com.baeldung.restvalidation.response; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import java.util.List; + +import lombok.*; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +public class UpdateUserResponse { + + private List fieldErrors; + +} diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/User.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/User.java new file mode 100644 index 0000000000..f9a7d1a9b5 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/User.java @@ -0,0 +1,15 @@ +package com.baeldung.restvalidation.service1; + +import javax.validation.constraints.NotEmpty; + +import lombok.*; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class User { + + @NotEmpty + private String email; + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/UserService1.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/UserService1.java new file mode 100644 index 0000000000..790b5031e6 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/UserService1.java @@ -0,0 +1,36 @@ +package com.baeldung.restvalidation.service1; + +import org.springframework.http.*; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.stream.Collectors; + +import javax.validation.Valid; + +import com.baeldung.restvalidation.response.InputFieldError; +import com.baeldung.restvalidation.response.UpdateUserResponse; + +@RestController +public class UserService1 { + + @PutMapping(value = "/user1", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity updateUser(@RequestBody @Valid User user, + BindingResult bindingResult) { + if (bindingResult.hasFieldErrors()) { + + List fieldErrorList = bindingResult.getFieldErrors().stream() + .map(error -> new InputFieldError(error.getField(), error.getDefaultMessage())) + .collect(Collectors.toList()); + + UpdateUserResponse updateResponse = new UpdateUserResponse(fieldErrorList); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(updateResponse); + } + else { + // Update logic... + return ResponseEntity.status(HttpStatus.OK).build(); + } + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/User.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/User.java new file mode 100644 index 0000000000..a2e567766c --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/User.java @@ -0,0 +1,15 @@ +package com.baeldung.restvalidation.service2; + +import javax.validation.constraints.NotEmpty; + +import lombok.*; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class User { + + @NotEmpty(message = "{validation.email.notEmpty}") + private String email; + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/UserService2.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/UserService2.java new file mode 100644 index 0000000000..4593a2b1bd --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/UserService2.java @@ -0,0 +1,40 @@ +package com.baeldung.restvalidation.service2; + +import java.util.List; +import java.util.stream.Collectors; + +import javax.validation.Valid; + +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.restvalidation.response.InputFieldError; +import com.baeldung.restvalidation.response.UpdateUserResponse; + +@RestController +public class UserService2 { + + @PutMapping(value = "/user2", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity updateUser(@RequestBody @Valid User user, + BindingResult bindingResult) { + if (bindingResult.hasFieldErrors()) { + + List fieldErrorList = bindingResult.getFieldErrors().stream() + .map(error -> new InputFieldError(error.getField(), error.getDefaultMessage())) + .collect(Collectors.toList()); + + UpdateUserResponse updateResponse = new UpdateUserResponse(fieldErrorList); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(updateResponse); + } + else { + // Update logic... + return ResponseEntity.status(HttpStatus.OK).build(); + } + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmpty.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmpty.java new file mode 100644 index 0000000000..93c7052d5b --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmpty.java @@ -0,0 +1,32 @@ +package com.baeldung.restvalidation.service3; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; + +@Documented +@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) +@Retention(RUNTIME) +@Constraint(validatedBy = { FieldNotEmptyValidator.class }) +public @interface FieldNotEmpty { + + String message() default "{validation.notEmpty}"; + + String field() default "Field"; + + Class[] groups() default {}; + + Class[] payload() default {}; + +} diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmptyValidator.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmptyValidator.java new file mode 100644 index 0000000000..356efc590b --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmptyValidator.java @@ -0,0 +1,16 @@ +package com.baeldung.restvalidation.service3; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +public class FieldNotEmptyValidator implements ConstraintValidator { + + private String message; + private String field; + + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { + return (value != null && !value.toString().trim().isEmpty()); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/User.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/User.java new file mode 100644 index 0000000000..97b38feba4 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/User.java @@ -0,0 +1,13 @@ +package com.baeldung.restvalidation.service3; + +import lombok.*; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class User { + + @FieldNotEmpty(message = "{validation.notEmpty}", field = "{field.personalEmail}") + private String email; + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/UserService3.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/UserService3.java new file mode 100644 index 0000000000..e506b63d8e --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/UserService3.java @@ -0,0 +1,40 @@ +package com.baeldung.restvalidation.service3; + +import java.util.List; +import java.util.stream.Collectors; + +import javax.validation.Valid; + +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.restvalidation.response.InputFieldError; +import com.baeldung.restvalidation.response.UpdateUserResponse; + +@RestController +public class UserService3 { + + @PutMapping(value = "/user3", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity updateUser(@RequestBody @Valid User user, + BindingResult bindingResult) { + if (bindingResult.hasFieldErrors()) { + + List fieldErrorList = bindingResult.getFieldErrors().stream() + .map(error -> new InputFieldError(error.getField(), error.getDefaultMessage())) + .collect(Collectors.toList()); + + UpdateUserResponse updateResponse = new UpdateUserResponse(fieldErrorList); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(updateResponse); + } + else { + // Update logic... + return ResponseEntity.status(HttpStatus.OK).build(); + } + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/resources/CustomValidationMessages.properties b/spring-boot-modules/spring-boot-mvc/src/main/resources/CustomValidationMessages.properties new file mode 100644 index 0000000000..58cabc30c9 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/resources/CustomValidationMessages.properties @@ -0,0 +1,3 @@ +field.personalEmail=Personal Email +validation.notEmpty={field} cannot be empty +validation.email.notEmpty=Email cannot be empty \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/resources/CustomValidationMessages_zh.properties b/spring-boot-modules/spring-boot-mvc/src/main/resources/CustomValidationMessages_zh.properties new file mode 100644 index 0000000000..b4fbe909bb --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/resources/CustomValidationMessages_zh.properties @@ -0,0 +1,3 @@ +field.personalEmail=個人電郵 +validation.notEmpty={field}不能是空白 +validation.email.notEmpty=電郵不能留空 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages.properties b/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages.properties new file mode 100644 index 0000000000..90d3c88a8f --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages.properties @@ -0,0 +1 @@ +javax.validation.constraints.NotEmpty.message=The field cannot be empty \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages_zh.properties b/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages_zh.properties new file mode 100644 index 0000000000..04f415911c --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages_zh.properties @@ -0,0 +1 @@ +javax.validation.constraints.NotEmpty.message=本欄不能留空 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/restvalidation/service1/UserService1IntegrationTest.java b/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/restvalidation/service1/UserService1IntegrationTest.java new file mode 100644 index 0000000000..969a6c17a6 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/restvalidation/service1/UserService1IntegrationTest.java @@ -0,0 +1,75 @@ +package com.baeldung.restvalidation.service1; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Objects; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.*; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.restvalidation.RestValidationApplication; +import com.baeldung.restvalidation.response.InputFieldError; +import com.baeldung.restvalidation.response.UpdateUserResponse; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = RestValidationApplication.class) +class UserService1IntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Test + void whenUpdateValidEmail_thenReturnsOK() { + + // When + ResponseEntity responseEntity = updateUser(new User("test@email.com"), null); + + // Then + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + } + + @Test + void whenUpdateEmptyEmail_thenReturnsErrorMessageInEnglish() { + + // When + ResponseEntity responseEntity = updateUser(new User(""), null); + + // Then + InputFieldError error = responseEntity.getBody().getFieldErrors().get(0); + assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); + assertEquals("The field cannot be empty", error.getMessage()); + } + + @Test + void whenUpdateEmptyEmailWithLanguageHeaderEqualsToZh_thenReturnsErrorMessageInChinese() { + + // When + ResponseEntity responseEntity = updateUser(new User(""), "zh-tw"); + + // Then + InputFieldError error = responseEntity.getBody().getFieldErrors().get(0); + assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); + assertEquals("本欄不能留空", error.getMessage()); + } + + private ResponseEntity updateUser(User user, String language) { + + HttpHeaders headers = new HttpHeaders(); + if (Objects.nonNull(language)) { + headers.set(HttpHeaders.ACCEPT_LANGUAGE, language); + } + + return restTemplate.exchange( + "/user1", + HttpMethod.PUT, + new HttpEntity<>(user, headers), + UpdateUserResponse.class + ); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/restvalidation/service2/UserService2IntegrationTest.java b/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/restvalidation/service2/UserService2IntegrationTest.java new file mode 100644 index 0000000000..3e92229d7b --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/restvalidation/service2/UserService2IntegrationTest.java @@ -0,0 +1,75 @@ +package com.baeldung.restvalidation.service2; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Objects; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.*; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.restvalidation.RestValidationApplication; +import com.baeldung.restvalidation.response.InputFieldError; +import com.baeldung.restvalidation.response.UpdateUserResponse; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = RestValidationApplication.class) +class UserService2IntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Test + void whenUpdateValidEmail_thenReturnsOK() { + + // When + ResponseEntity responseEntity = updateUser(new User("test@email.com"), null); + + // Then + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + } + + @Test + void whenUpdateEmptyEmail_thenReturnsErrorMessageInEnglish() { + + // When + ResponseEntity responseEntity = updateUser(new User(""), null); + + // Then + InputFieldError error = responseEntity.getBody().getFieldErrors().get(0); + assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); + assertEquals("Email cannot be empty", error.getMessage()); + } + + @Test + void whenUpdateEmptyEmailWithLanguageHeaderEqualsToZh_thenReturnsErrorMessageInChinese() { + + // When + ResponseEntity responseEntity = updateUser(new User(""), "zh-tw"); + + // Then + InputFieldError error = responseEntity.getBody().getFieldErrors().get(0); + assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); + assertEquals("電郵不能留空", error.getMessage()); + } + + private ResponseEntity updateUser(User user, String language) { + + HttpHeaders headers = new HttpHeaders(); + if (Objects.nonNull(language)) { + headers.set(HttpHeaders.ACCEPT_LANGUAGE, language); + } + + return restTemplate.exchange( + "/user2", + HttpMethod.PUT, + new HttpEntity<>(user, headers), + UpdateUserResponse.class + ); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/restvalidation/service3/UserService3IntegrationTest.java b/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/restvalidation/service3/UserService3IntegrationTest.java new file mode 100644 index 0000000000..8bc4d460ea --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/restvalidation/service3/UserService3IntegrationTest.java @@ -0,0 +1,75 @@ +package com.baeldung.restvalidation.service3; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Objects; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.*; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.restvalidation.RestValidationApplication; +import com.baeldung.restvalidation.response.InputFieldError; +import com.baeldung.restvalidation.response.UpdateUserResponse; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = RestValidationApplication.class) +class UserService3IntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Test + void whenUpdateValidEmail_thenReturnsOK() { + + // When + ResponseEntity responseEntity = updateUser(new User("test@email.com"), null); + + // Then + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + } + + @Test + void whenUpdateEmptyEmail_thenReturnsErrorMessageInEnglish() { + + // When + ResponseEntity responseEntity = updateUser(new User(""), null); + + // Then + InputFieldError error = responseEntity.getBody().getFieldErrors().get(0); + assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); + assertEquals("Personal Email cannot be empty", error.getMessage()); + } + + @Test + void whenUpdateEmptyEmailWithLanguageHeaderEqualsToZh_thenReturnsErrorMessageInChinese() { + + // When + ResponseEntity responseEntity = updateUser(new User(""), "zh-tw"); + + // Then + InputFieldError error = responseEntity.getBody().getFieldErrors().get(0); + assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); + assertEquals("個人電郵不能是空白", error.getMessage()); + } + + private ResponseEntity updateUser(User user, String language) { + + HttpHeaders headers = new HttpHeaders(); + if (Objects.nonNull(language)) { + headers.set(HttpHeaders.ACCEPT_LANGUAGE, language); + } + + return restTemplate.exchange( + "/user3", + HttpMethod.PUT, + new HttpEntity<>(user, headers), + UpdateUserResponse.class + ); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-runtime-2/README.md b/spring-boot-modules/spring-boot-runtime-2/README.md index f439b0d0bd..3ee05ccc83 100644 --- a/spring-boot-modules/spring-boot-runtime-2/README.md +++ b/spring-boot-modules/spring-boot-runtime-2/README.md @@ -4,5 +4,4 @@ This module contains articles about administering a Spring Boot runtime ### Relevant Articles: - [Configure the Heap Size When Starting a Spring Boot Application](https://www.baeldung.com/spring-boot-heap-size) - - [CORS with Spring](https://www.baeldung.com/spring-cors) - [Max-HTTP-Header-Size in Spring Boot 2](https://www.baeldung.com/spring-boot-max-http-header-size) diff --git a/spring-boot-modules/spring-boot-runtime/README.md b/spring-boot-modules/spring-boot-runtime/README.md index 6f21efe793..6463aaa6c3 100644 --- a/spring-boot-modules/spring-boot-runtime/README.md +++ b/spring-boot-modules/spring-boot-runtime/README.md @@ -10,3 +10,4 @@ This module contains articles about administering a Spring Boot runtime - [Project Configuration with Spring](https://www.baeldung.com/project-configuration-with-spring) - [Spring – Log Incoming Requests](https://www.baeldung.com/spring-http-logging) - [How to Configure Spring Boot Tomcat](https://www.baeldung.com/spring-boot-configure-tomcat) + - [CORS with Spring](https://www.baeldung.com/spring-cors) diff --git a/spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/Account.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/Account.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/Account.java rename to spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/Account.java diff --git a/spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/AccountController.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/AccountController.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/AccountController.java rename to spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/AccountController.java diff --git a/spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/config/WebConfig.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/config/WebConfig.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/config/WebConfig.java rename to spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/config/WebConfig.java diff --git a/spring-boot-modules/spring-boot-security-2/pom.xml b/spring-boot-modules/spring-boot-security-2/pom.xml index db094f33a6..dd8cab81de 100644 --- a/spring-boot-modules/spring-boot-security-2/pom.xml +++ b/spring-boot-modules/spring-boot-security-2/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-security-2 - spring-boot-security-1 + spring-boot-security-2 jar Spring Boot Security Auto-Configuration diff --git a/spring-boot-modules/spring-boot-ssl-bundles/pom.xml b/spring-boot-modules/spring-boot-ssl-bundles/pom.xml index 4802e9ec58..1f4e58f21f 100644 --- a/spring-boot-modules/spring-boot-ssl-bundles/pom.xml +++ b/spring-boot-modules/spring-boot-ssl-bundles/pom.xml @@ -1,18 +1,20 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + spring-boot-ssl-bundles + spring-boot-ssl-bundles + Module for showing usage of SSL Bundles + jar + com.baeldung parent-boot-3 0.0.1-SNAPSHOT ../../parent-boot-3 - springbootsslbundles - spring-boot-ssl-bundles - jar - Module for showing usage of SSL Bundles + org.springframework.boot diff --git a/spring-boot-modules/spring-boot-telegram/pom.xml b/spring-boot-modules/spring-boot-telegram/pom.xml index 67fdf197f8..9077e90400 100644 --- a/spring-boot-modules/spring-boot-telegram/pom.xml +++ b/spring-boot-modules/spring-boot-telegram/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baelding spring-boot-telegram diff --git a/spring-boot-modules/spring-boot-testing/pom.xml b/spring-boot-modules/spring-boot-testing/pom.xml index 257260fc3f..23277d11f3 100644 --- a/spring-boot-modules/spring-boot-testing/pom.xml +++ b/spring-boot-modules/spring-boot-testing/pom.xml @@ -9,9 +9,10 @@ This is simple boot application for demonstrating testing features. - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -67,6 +68,11 @@ ${embedded-redis.version} test + + io.rest-assured + rest-assured + test + @@ -122,7 +128,6 @@ 2.4-M1-groovy-4.0 3.0.0 0.7.2 - 2.5.0 2.17.1 diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/MailServer.java b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/MailServer.java index e23b30759b..3f5ea64d24 100644 --- a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/MailServer.java +++ b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/MailServer.java @@ -2,11 +2,11 @@ package com.baeldung.boot.configurationproperties; import java.util.Map; -import javax.validation.Valid; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/embeddedRedis/configuration/RedisProperties.java b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/embeddedRedis/configuration/RedisProperties.java index 76f2e1bbfe..4e06548d79 100644 --- a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/embeddedRedis/configuration/RedisProperties.java +++ b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/embeddedRedis/configuration/RedisProperties.java @@ -8,7 +8,7 @@ public class RedisProperties { private final int redisPort; private final String redisHost; - public RedisProperties(@Value("${spring.redis.port}") final int redisPort, @Value("${spring.redis.host}") final String redisHost) { + public RedisProperties(@Value("${spring.data.redis.port}") final int redisPort, @Value("${spring.data.redis.host}") final String redisHost) { this.redisPort = redisPort; this.redisHost = redisHost; } diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/testing/Employee.java b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/testing/Employee.java index 2921ecc609..cf68c45793 100644 --- a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/testing/Employee.java +++ b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/testing/Employee.java @@ -1,11 +1,11 @@ package com.baeldung.boot.testing; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.validation.constraints.Size; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.validation.constraints.Size; import java.util.Date; @Entity diff --git a/spring-boot-modules/spring-boot-testing/src/main/resources/application.properties b/spring-boot-modules/spring-boot-testing/src/main/resources/application.properties index 70cae370a4..e3fe989efd 100644 --- a/spring-boot-modules/spring-boot-testing/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-testing/src/main/resources/application.properties @@ -1,6 +1,6 @@ # embedded redis -spring.redis.host= localhost -spring.redis.port= 6379 +spring.data.redis.host= localhost +spring.data.redis.port= 6379 # security spring.security.user.name=john diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig1IntegrationTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig1IntegrationTest.java index 2ca0c74901..a8a322df44 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig1IntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig1IntegrationTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig2IntegrationTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig2IntegrationTest.java index c0bd6570a1..6a9e157827 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig2IntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig2IntegrationTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig3IntegrationTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig3IntegrationTest.java index 1642d4b932..9d4d9759d6 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig3IntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig3IntegrationTest.java @@ -8,7 +8,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.test.context.junit4.SpringRunner; diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig4IntegrationTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig4IntegrationTest.java index 1aa453348b..f28929fbef 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig4IntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig4IntegrationTest.java @@ -5,7 +5,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.test.context.junit4.SpringRunner; diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/autoconfig/AutoConfigIntegrationTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/autoconfig/AutoConfigIntegrationTest.java index 44a02c0c80..447d174fb5 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/autoconfig/AutoConfigIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/autoconfig/AutoConfigIntegrationTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.test.context.junit4.SpringRunner; diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/PropertyValidationUnitTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/PropertyValidationUnitTest.java index 939471dd67..5e70bcb45f 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/PropertyValidationUnitTest.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/PropertyValidationUnitTest.java @@ -2,8 +2,8 @@ package com.baeldung.boot.configurationproperties; import static org.junit.jupiter.api.Assertions.assertEquals; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/embeddedRedis/TestRedisConfiguration.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/embeddedRedis/TestRedisConfiguration.java index c265d99c9b..10e5d56857 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/embeddedRedis/TestRedisConfiguration.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/embeddedRedis/TestRedisConfiguration.java @@ -4,8 +4,8 @@ import com.baeldung.boot.embeddedRedis.configuration.RedisProperties; import org.springframework.boot.test.context.TestConfiguration; import redis.embedded.RedisServer; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; @TestConfiguration public class TestRedisConfiguration { diff --git a/spring-boot-modules/spring-boot-testing/src/test/resources/application.properties b/spring-boot-modules/spring-boot-testing/src/test/resources/application.properties index 1810c7b1eb..bc31991329 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/resources/application.properties +++ b/spring-boot-modules/spring-boot-testing/src/test/resources/application.properties @@ -1,6 +1,6 @@ #embedded redis -spring.redis.host= localhost -spring.redis.port= 6370 +spring.data.redis.host= localhost +spring.data.redis.port= 6370 # security spring.security.user.name=john spring.security.user.password=123 diff --git a/spring-boot-modules/spring-caching-2/pom.xml b/spring-boot-modules/spring-caching-2/pom.xml index 2239256630..ee28ac5ed5 100644 --- a/spring-boot-modules/spring-caching-2/pom.xml +++ b/spring-boot-modules/spring-caching-2/pom.xml @@ -47,6 +47,7 @@ com.github.ben-manes.caffeine caffeine + ${caffeine.version} it.ozimov @@ -64,6 +65,7 @@ 0.7.3 + 3.1.8 \ No newline at end of file diff --git a/spring-boot-modules/spring-caching/pom.xml b/spring-boot-modules/spring-caching/pom.xml index c27ccf3348..f3d9488b89 100644 --- a/spring-boot-modules/spring-caching/pom.xml +++ b/spring-boot-modules/spring-caching/pom.xml @@ -51,6 +51,7 @@ com.github.ben-manes.caffeine caffeine + ${caffeine.version} com.h2database @@ -78,6 +79,7 @@ 3.5.2 + 3.1.8 \ No newline at end of file diff --git a/spring-boot-rest/pom.xml b/spring-boot-rest/pom.xml index db646899ad..71916900a4 100644 --- a/spring-boot-rest/pom.xml +++ b/spring-boot-rest/pom.xml @@ -162,7 +162,7 @@ com.baeldung.SpringBootRestApplication 1.4.11.1 - 3.1.0 + 3.2.0 3.3.0 2.3.7 diff --git a/spring-cloud-modules/spring-cloud-archaius/spring-cloud-archaius-basic-config/src/test/resources/logback-test.xml b/spring-cloud-modules/spring-cloud-archaius/spring-cloud-archaius-basic-config/src/test/resources/logback-test.xml index 8d4771e308..b9242f40a8 100644 --- a/spring-cloud-modules/spring-cloud-archaius/spring-cloud-archaius-basic-config/src/test/resources/logback-test.xml +++ b/spring-cloud-modules/spring-cloud-archaius/spring-cloud-archaius-basic-config/src/test/resources/logback-test.xml @@ -6,6 +6,8 @@ + + diff --git a/spring-cloud-modules/spring-cloud-bootstrap/README.md b/spring-cloud-modules/spring-cloud-bootstrap/README.md index 252058be1f..661dd7c647 100644 --- a/spring-cloud-modules/spring-cloud-bootstrap/README.md +++ b/spring-cloud-modules/spring-cloud-bootstrap/README.md @@ -21,4 +21,4 @@ This module contains articles about bootstrapping Spring Cloud applications that - git commit -m "First commit" - start the config server - start the discovery server - - start all the other servers in any order (gateway, svc-book, svc-rating, zipkin) + - start all the other servers in any order (gateway, zipkin-log-svc-book, zipkin-log-svc-rating, zipkin) diff --git a/spring-cloud-modules/spring-cloud-bootstrap/config/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-bootstrap/config/src/main/resources/logback.xml index 7d900d8ea8..896eaf9c88 100644 --- a/spring-cloud-modules/spring-cloud-bootstrap/config/src/main/resources/logback.xml +++ b/spring-cloud-modules/spring-cloud-bootstrap/config/src/main/resources/logback.xml @@ -7,6 +7,12 @@ + + + + + + diff --git a/spring-cloud-modules/spring-cloud-bootstrap/pom.xml b/spring-cloud-modules/spring-cloud-bootstrap/pom.xml index f4d4073ef1..73b07c826f 100644 --- a/spring-cloud-modules/spring-cloud-bootstrap/pom.xml +++ b/spring-cloud-modules/spring-cloud-bootstrap/pom.xml @@ -19,8 +19,8 @@ discovery gateway gateway-2 - svc-book - svc-rating + zipkin-log-svc-book + zipkin-log-svc-rating customer-service order-service diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/pom.xml b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/pom.xml similarity index 97% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/pom.xml rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/pom.xml index c973968a70..2a6196b92b 100644 --- a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/pom.xml +++ b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/pom.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung.spring.cloud - svc-book + zipkin-log-svc-book 1.0.0-SNAPSHOT - svc-book + zipkin-log-svc-book com.baeldung diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/CookieConfig.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/CookieConfig.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/CookieConfig.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/CookieConfig.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/DataLoader.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/DataLoader.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/DataLoader.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/DataLoader.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SecurityConfig.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SecurityConfig.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SecurityConfig.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SecurityConfig.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SessionConfig.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SessionConfig.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SessionConfig.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SessionConfig.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/Book.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/Book.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/Book.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/Book.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookController.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookController.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookController.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookController.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookNotFoundException.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookNotFoundException.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookNotFoundException.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookNotFoundException.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookRepository.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookRepository.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookRepository.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookRepository.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookService.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookService.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookService.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookService.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/resources/bootstrap.properties b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/resources/bootstrap.properties similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/resources/bootstrap.properties rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/resources/bootstrap.properties diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/resources/logback.xml rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/resources/logback.xml diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/test/java/com/baeldung/SpringContextLiveTest.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/test/java/com/baeldung/SpringContextLiveTest.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/test/java/com/baeldung/SpringContextLiveTest.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/test/resources/bootstrap.properties b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/test/resources/bootstrap.properties similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/test/resources/bootstrap.properties rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/test/resources/bootstrap.properties diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/pom.xml b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/pom.xml similarity index 97% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/pom.xml rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/pom.xml index 29ebb4c4bc..54572eeea2 100644 --- a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/pom.xml +++ b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/pom.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung.spring.cloud - svc-rating + zipkin-log-svc-rating 1.0.0-SNAPSHOT - svc-rating + zipkin-log-svc-rating com.baeldung diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/CookieConfig.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/CookieConfig.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/CookieConfig.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/CookieConfig.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/DataLoader.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/DataLoader.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/DataLoader.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/DataLoader.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SecurityConfig.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SecurityConfig.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SecurityConfig.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SecurityConfig.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SessionConfig.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SessionConfig.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SessionConfig.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SessionConfig.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/Rating.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/Rating.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/Rating.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/Rating.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingCacheRepository.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingCacheRepository.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingCacheRepository.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingCacheRepository.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingController.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingController.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingController.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingController.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingNotFoundException.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingNotFoundException.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingNotFoundException.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingNotFoundException.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingRepository.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingRepository.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingRepository.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingRepository.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingService.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingService.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingService.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingService.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/resources/bootstrap.properties b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/resources/bootstrap.properties similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/resources/bootstrap.properties rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/resources/bootstrap.properties diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/resources/logback.xml rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/resources/logback.xml diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/test/java/com/baeldung/SpringContextLiveTest.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/test/java/com/baeldung/SpringContextLiveTest.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/test/java/com/baeldung/SpringContextLiveTest.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/test/resources/bootstrap.properties b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/test/resources/bootstrap.properties similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/test/resources/bootstrap.properties rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/test/resources/bootstrap.properties diff --git a/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml b/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml index a8c3337de5..234f8b1b60 100644 --- a/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml +++ b/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml @@ -16,10 +16,12 @@ + org.springframework.boot spring-boot-starter-web + org.springframework.boot spring-boot-starter-data-rest @@ -30,16 +32,25 @@ spring-cloud-contract-wiremock test + org.springframework.cloud spring-cloud-contract-stub-runner test + com.baeldung.spring.cloud spring-cloud-contract-producer ${project.parent.version} + stubs test + + + * + * + + diff --git a/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java b/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java index c19b3f3694..c7d8b695db 100644 --- a/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java +++ b/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java @@ -1,24 +1,18 @@ package com.baeldung.spring.cloud.springcloudcontractconsumer.controller; -import com.github.tomakehurst.wiremock.WireMockServer; -import com.github.tomakehurst.wiremock.core.WireMockConfiguration; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner; -import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties; +import org.springframework.cloud.contract.stubrunner.junit.StubRunnerRule; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import static com.github.tomakehurst.wiremock.client.WireMock.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -26,42 +20,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc @AutoConfigureJsonTesters -@AutoConfigureStubRunner(stubsMode = StubRunnerProperties.StubsMode.LOCAL, - ids = "com.baeldung.spring.cloud:spring-cloud-contract-producer:+:stubs:8090") public class BasicMathControllerIntegrationTest { + @Rule + public StubRunnerRule rule = new StubRunnerRule().downloadStub( + "com.baeldung.spring.cloud", + "spring-cloud-contract-producer") + .withPort(8090).failOnNoStubs(true); + @Autowired private MockMvc mockMvc; - private static WireMockServer wireMockServer; - - - @BeforeClass - public static void setupClass() { - WireMockConfiguration wireMockConfiguration = WireMockConfiguration.options().port(8090); // Use the same port as in your code - - wireMockServer = new WireMockServer(wireMockConfiguration); - wireMockServer.start(); - } - - @AfterClass - public static void teardownClass() { - wireMockServer.stop(); - } - - @Before - public void setup() { - wireMockServer.stubFor(get(urlEqualTo("/validate/prime-number?number=1")) - .willReturn(aResponse() - .withStatus(200) - .withHeader("Content-Type", "application/json") - .withBody("Odd"))); - - wireMockServer.stubFor(get(urlEqualTo("/validate/prime-number?number=2")) - .willReturn(aResponse() - .withStatus(200) - .withHeader("Content-Type", "application/json") - .withBody("Even"))); - } @Test public void given_WhenPassEvenNumberInQueryParam_ThenReturnEven() throws Exception { diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerBooksClientIntegrationTest.java b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerBooksClientIntegrationTest.java index 5690c24d77..a70ae1ee22 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerBooksClientIntegrationTest.java +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerBooksClientIntegrationTest.java @@ -63,12 +63,12 @@ class LoadBalancerBooksClientIntegrationTest { String serviceId = "books-service"; RoundRobinLoadBalancer loadBalancer = new RoundRobinLoadBalancer(ServiceInstanceListSuppliers - .toProvider(serviceId, instance(serviceId, "localhost", false), instance(serviceId, "localhost", true)), + .toProvider(serviceId, instance(serviceId, "localhost", 1030, false), instance(serviceId, "localhost", 1031, true)), serviceId, -1); } - private static DefaultServiceInstance instance(String serviceId, String host, boolean secure) { - return new DefaultServiceInstance(serviceId, serviceId, host, 80, secure); + private static DefaultServiceInstance instance(String serviceId, String host, int port, boolean secure) { + return new DefaultServiceInstance(serviceId, serviceId, host, port, secure); } @Test diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerIntegrationTest.java b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerIntegrationTest.java index eee4e7b860..9761b4eb64 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerIntegrationTest.java +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerIntegrationTest.java @@ -80,13 +80,13 @@ class LoadBalancerIntegrationTest { void staticConfigurationWorks() { String serviceId = "test-book-service"; RoundRobinLoadBalancer loadBalancer = new RoundRobinLoadBalancer(ServiceInstanceListSuppliers - .toProvider(serviceId, instance(serviceId, "bookservice1", false), instance(serviceId, "bookservice2", false)), + .toProvider(serviceId, instance(serviceId, "bookservice1", 1030, false), instance(serviceId, "bookservice2", 1031, false)), serviceId, -1); assertLoadBalancer(loadBalancer, Arrays.asList("bookservice1", "bookservice2")); } - private static DefaultServiceInstance instance(String serviceId, String host, boolean secure) { - return new DefaultServiceInstance(serviceId, serviceId, host, 80, secure); + private static DefaultServiceInstance instance(String serviceId, String host, int port, boolean secure) { + return new DefaultServiceInstance(serviceId, serviceId, host, port, secure); } @EnableAutoConfiguration diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/TestConfig.java b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/TestConfig.java index b3770721b1..375c945054 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/TestConfig.java +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/TestConfig.java @@ -14,11 +14,11 @@ public class TestConfig { @Bean(initMethod = "start", destroyMethod = "stop") public WireMockServer mockBooksService() { - return new WireMockServer(options().port(80)); + return new WireMockServer(options().port(1030)); } @Bean(name="secondMockBooksService", initMethod = "start", destroyMethod = "stop") public WireMockServer secondBooksMockService() { - return new WireMockServer(options().port(81)); + return new WireMockServer(options().port(1031)); } } diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/WireMockConfig.java b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/WireMockConfig.java index 3d4f2822f4..a41faa9c5c 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/WireMockConfig.java +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/WireMockConfig.java @@ -11,11 +11,11 @@ public class WireMockConfig { @Bean(initMethod = "start", destroyMethod = "stop") public WireMockServer mockBooksService() { - return new WireMockServer(80); + return new WireMockServer(1030); } @Bean(initMethod = "start", destroyMethod = "stop") public WireMockServer mockBooksService2() { - return new WireMockServer(81); + return new WireMockServer(1031); } } diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-spring-cloud-balancer-test.yml b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-spring-cloud-balancer-test.yml deleted file mode 100644 index ad11d46ae8..0000000000 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-spring-cloud-balancer-test.yml +++ /dev/null @@ -1,19 +0,0 @@ -eureka: - client: - enabled: false - -spring: - application: - name: books-service - cloud: - loadbalancer: - ribbon: - enabled: false - discovery: - client: - simple: - instances: - books-service[0]: - uri: http://localhost:80 - books-service[1]: - uri: http://localhost:81 \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-test.yml b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-test.yml index 231d45004f..6bd5b8efc7 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-test.yml +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-test.yml @@ -14,6 +14,6 @@ spring: simple: instances: books-service[0]: - uri: http://localhost:80 + uri: http://localhost:1030 books-service[1]: - uri: http://localhost:81 + uri: http://localhost:1031 diff --git a/spring-cloud-modules/spring-cloud-gateway-2/pom.xml b/spring-cloud-modules/spring-cloud-gateway-2/pom.xml index 22182e8c78..4228c72d37 100644 --- a/spring-cloud-modules/spring-cloud-gateway-2/pom.xml +++ b/spring-cloud-modules/spring-cloud-gateway-2/pom.xml @@ -57,7 +57,7 @@ test - org.hibernate + org.hibernate.validator hibernate-validator-cdi ${hibernate-validator.version} @@ -116,7 +116,7 @@ - 6.0.2.Final + 8.0.1.Final 0.7.2 9.19 diff --git a/spring-cloud-modules/spring-cloud-gateway/pom.xml b/spring-cloud-modules/spring-cloud-gateway/pom.xml index 76072a59ac..0287ab7588 100644 --- a/spring-cloud-modules/spring-cloud-gateway/pom.xml +++ b/spring-cloud-modules/spring-cloud-gateway/pom.xml @@ -62,7 +62,7 @@ test - org.hibernate + org.hibernate.validator hibernate-validator-cdi ${hibernate-validator.version} @@ -185,7 +185,7 @@ - 6.0.2.Final + 8.0.1.Final 0.7.2 9.19 diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/.gitignore b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/.gitignore similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/.gitignore rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/.gitignore diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/Dockerfile b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/Dockerfile similarity index 62% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/Dockerfile rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/Dockerfile index a0a9d57662..fad9c11a73 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/Dockerfile +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/Dockerfile @@ -1,5 +1,5 @@ FROM openjdk:8-jdk-alpine VOLUME /tmp -COPY target/demo-backend-1.0-SNAPSHOT.jar app.jar +COPY target/minikube-demo-backend-1.0-SNAPSHOT.jar app.jar ENV JAVA_OPTS="" ENTRYPOINT exec java -jar /app.jar --debug \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/pom.xml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/pom.xml similarity index 92% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/pom.xml rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/pom.xml index 2b3f849145..c08c6a5a9d 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/pom.xml +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - demo-backend - demo-backend + minikube-demo-backend + minikube-demo-backend com.baeldung.spring.cloud diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/main/java/com/baeldung/spring/cloud/kubernetes/backend/KubernetesBackendApplication.java b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/main/java/com/baeldung/spring/cloud/kubernetes/backend/KubernetesBackendApplication.java similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/main/java/com/baeldung/spring/cloud/kubernetes/backend/KubernetesBackendApplication.java rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/main/java/com/baeldung/spring/cloud/kubernetes/backend/KubernetesBackendApplication.java diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/main/resources/application.properties b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/main/resources/application.properties similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/main/resources/application.properties rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/main/resources/application.properties diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/main/resources/logback.xml rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/main/resources/logback.xml diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/test/java/com/baeldung/SpringContextTest.java b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/test/java/com/baeldung/SpringContextTest.java similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/test/java/com/baeldung/SpringContextTest.java rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/test/java/com/baeldung/SpringContextTest.java diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/.gitignore b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/.gitignore similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/.gitignore rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/.gitignore diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/Dockerfile b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/Dockerfile similarity index 59% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/Dockerfile rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/Dockerfile index 69adb03a17..207114b1b5 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/Dockerfile +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/Dockerfile @@ -1,5 +1,5 @@ FROM openjdk:8-jdk-alpine VOLUME /tmp -COPY target/demo-frontend-1.0-SNAPSHOT.jar app.jar +COPY target/minikube-demo-frontend-1.0-SNAPSHOT.jar app.jar ENV JAVA_OPTS="" ENTRYPOINT exec java -jar /app.jar \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/pom.xml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/pom.xml similarity index 92% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/pom.xml rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/pom.xml index 85eb944b27..8140807606 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/pom.xml +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - demo-frontend - demo-frontend + minikube-demo-frontend + minikube-demo-frontend com.baeldung.spring.cloud diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java similarity index 95% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java index 635a79e8bb..d76fcdfd5d 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java @@ -22,7 +22,7 @@ public class KubernetesFrontendApplication { RestTemplate restTemplate = new RestTemplate(); String resourceUrl - = "http://demo-backend:8080"; + = "http://minikube-demo-backend:8080"; ResponseEntity response = restTemplate.getForEntity(resourceUrl, String.class); return "Message from backend is: " + response.getBody(); diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/resources/application.properties b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/resources/application.properties similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/resources/application.properties rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/resources/application.properties diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/resources/logback.xml rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/resources/logback.xml diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/test/java/com/baeldung/SpringContextTest.java b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/test/java/com/baeldung/SpringContextTest.java similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/test/java/com/baeldung/SpringContextTest.java rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/test/java/com/baeldung/SpringContextTest.java diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/backend-deployment.yaml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/backend-deployment.yaml index a7e26a6ec5..bcfa80cd7f 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/backend-deployment.yaml +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/backend-deployment.yaml @@ -1,10 +1,10 @@ kind: Service apiVersion: v1 metadata: - name: demo-backend + name: minikube-demo-backend spec: selector: - app: demo-backend + app: minikube-demo-backend tier: backend ports: - protocol: TCP @@ -14,22 +14,22 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: demo-backend + name: dminikube-demo-backend spec: selector: matchLabels: - app: demo-backend + app: minikube-demo-backend tier: backend replicas: 3 template: metadata: labels: - app: demo-backend + app: minikube-demo-backend tier: backend spec: containers: - - name: demo-backend - image: demo-backend:latest + - name: minikube-demo-backend + image: minikube-demo-backend:latest imagePullPolicy: Never ports: - containerPort: 8080 diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/frontend-deployment.yaml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/frontend-deployment.yaml index bf44dce21c..f96c7a1a9c 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/frontend-deployment.yaml +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/frontend-deployment.yaml @@ -1,10 +1,10 @@ kind: Service apiVersion: v1 metadata: - name: demo-frontend + name: minikube-demo-frontend spec: selector: - app: demo-frontend + app: minikube-demo-frontend ports: - protocol: TCP port: 8081 @@ -14,20 +14,20 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: demo-frontend + name: minikube-demo-frontend spec: selector: matchLabels: - app: demo-frontend + app: minikube-demo-frontend replicas: 3 template: metadata: labels: - app: demo-frontend + app: minikube-demo-frontend spec: containers: - - name: demo-frontend - image: demo-frontend:latest + - name: minikube-demo-frontend + image: minikube-demo-frontend:latest imagePullPolicy: Never ports: - containerPort: 8081 diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/pom.xml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/pom.xml index b778ee1b57..1c7456d007 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/pom.xml +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/pom.xml @@ -14,8 +14,8 @@ - demo-backend - demo-frontend + minikube-demo-backend + minikube-demo-frontend \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-demo/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-demo/src/main/resources/logback.xml new file mode 100644 index 0000000000..1533b49c06 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-demo/src/main/resources/logback.xml @@ -0,0 +1,20 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-echo-demo/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-echo-demo/src/main/resources/logback.xml new file mode 100644 index 0000000000..5f3e764e22 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-echo-demo/src/main/resources/logback.xml @@ -0,0 +1,20 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-core-2/pom.xml b/spring-core-2/pom.xml index 2d11cc2124..f27b16acc3 100644 --- a/spring-core-2/pom.xml +++ b/spring-core-2/pom.xml @@ -88,9 +88,8 @@ - org.hibernate + org.hibernate.validator hibernate-validator - ${hibernate.version} @@ -160,8 +159,6 @@ com.baeldung.sample.App 1.3.2 - - 5.2.5.Final 3.6 2.1.0 diff --git a/spring-cucumber/README.md b/spring-cucumber/README.md index 85bc1f65d5..87623b28d4 100644 --- a/spring-cucumber/README.md +++ b/spring-cucumber/README.md @@ -4,3 +4,4 @@ This module contains articles about Spring testing with Cucumber ### Relevant Articles: - [Cucumber Spring Integration](https://www.baeldung.com/cucumber-spring-integration) +- [Overriding Cucumber Option Values](https://www.baeldung.com/java-overriding-cucumber-option-values) diff --git a/spring-di-2/pom.xml b/spring-di-2/pom.xml index 69333c74f1..0bd6c41a8c 100644 --- a/spring-di-2/pom.xml +++ b/spring-di-2/pom.xml @@ -9,9 +9,9 @@ com.baeldung - parent-spring-5 + parent-spring-6 0.0.1-SNAPSHOT - ../parent-spring-5 + ../parent-spring-6 @@ -46,11 +46,6 @@ org.springframework spring-aspects - - javax.inject - javax.inject - ${javax.inject.version} - org.springframework.boot spring-boot-starter-test @@ -84,9 +79,8 @@ - 2.6.1 + 3.1.2 1.14.0 - 1 2.17.1 diff --git a/spring-di-2/src/main/java/com/baeldung/di/aspectj/PersonEntity.java b/spring-di-2/src/main/java/com/baeldung/di/aspectj/PersonEntity.java index f087a97c7e..758a942227 100644 --- a/spring-di-2/src/main/java/com/baeldung/di/aspectj/PersonEntity.java +++ b/spring-di-2/src/main/java/com/baeldung/di/aspectj/PersonEntity.java @@ -3,9 +3,9 @@ package com.baeldung.di.aspectj; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Transient; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Transient; @Entity @Configurable(preConstruction = true) diff --git a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/inject/FieldByNameInjectIntegrationTest.java b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/inject/FieldByNameInjectIntegrationTest.java index d1a75d73ea..f7ca089355 100644 --- a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/inject/FieldByNameInjectIntegrationTest.java +++ b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/inject/FieldByNameInjectIntegrationTest.java @@ -3,8 +3,8 @@ package com.baeldung.wiring.configuration.inject; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import javax.inject.Inject; -import javax.inject.Named; +import jakarta.inject.Inject; +import jakarta.inject.Named; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/inject/FieldInjectIntegrationTest.java b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/inject/FieldInjectIntegrationTest.java index 995f560701..c06205aee8 100644 --- a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/inject/FieldInjectIntegrationTest.java +++ b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/inject/FieldInjectIntegrationTest.java @@ -3,7 +3,7 @@ package com.baeldung.wiring.configuration.inject; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import javax.inject.Inject; +import jakarta.inject.Inject; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/inject/FieldQualifierInjectIntegrationTest.java b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/inject/FieldQualifierInjectIntegrationTest.java index 67fa2bf3d4..2a3e41f63f 100644 --- a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/inject/FieldQualifierInjectIntegrationTest.java +++ b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/inject/FieldQualifierInjectIntegrationTest.java @@ -3,7 +3,7 @@ package com.baeldung.wiring.configuration.inject; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import javax.inject.Inject; +import jakarta.inject.Inject; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/FieldResourceInjectionIntegrationTest.java b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/FieldResourceInjectionIntegrationTest.java index 938d557939..16430a0573 100644 --- a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/FieldResourceInjectionIntegrationTest.java +++ b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/FieldResourceInjectionIntegrationTest.java @@ -5,7 +5,7 @@ import static org.junit.Assert.assertNotNull; import java.io.File; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/MethodByQualifierResourceIntegrationTest.java b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/MethodByQualifierResourceIntegrationTest.java index f49bf70aba..1c1e3388b5 100644 --- a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/MethodByQualifierResourceIntegrationTest.java +++ b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/MethodByQualifierResourceIntegrationTest.java @@ -9,7 +9,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; import com.baeldung.wiring.configuration.ApplicationContextTestResourceQualifier; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.io.File; import static org.junit.Assert.assertEquals; diff --git a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/MethodByTypeResourceIntegrationTest.java b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/MethodByTypeResourceIntegrationTest.java index aecd02a1d5..660610753f 100644 --- a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/MethodByTypeResourceIntegrationTest.java +++ b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/MethodByTypeResourceIntegrationTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; import com.baeldung.wiring.configuration.ApplicationContextTestResourceNameType; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.io.File; import static org.junit.Assert.assertEquals; diff --git a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/MethodResourceInjectionIntegrationTest.java b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/MethodResourceInjectionIntegrationTest.java index 4ef9368c28..0fcc2b1c50 100644 --- a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/MethodResourceInjectionIntegrationTest.java +++ b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/MethodResourceInjectionIntegrationTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; import com.baeldung.wiring.configuration.ApplicationContextTestResourceNameType; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.io.File; import static org.junit.Assert.assertEquals; diff --git a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/NamedResourceIntegrationTest.java b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/NamedResourceIntegrationTest.java index 4339194f63..5aed1ac7cb 100644 --- a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/NamedResourceIntegrationTest.java +++ b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/NamedResourceIntegrationTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; import com.baeldung.wiring.configuration.ApplicationContextTestResourceNameType; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.io.File; import static org.junit.Assert.assertEquals; diff --git a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/QualifierResourceInjectionIntegrationTest.java b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/QualifierResourceInjectionIntegrationTest.java index cc8c669757..03f82adef3 100644 --- a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/QualifierResourceInjectionIntegrationTest.java +++ b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/QualifierResourceInjectionIntegrationTest.java @@ -9,7 +9,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; import com.baeldung.wiring.configuration.ApplicationContextTestResourceQualifier; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.io.File; import static org.junit.Assert.assertEquals; diff --git a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/SetterResourceInjectionIntegrationTest.java b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/SetterResourceInjectionIntegrationTest.java index 90c8677bff..605f86172c 100644 --- a/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/SetterResourceInjectionIntegrationTest.java +++ b/spring-di-2/src/test/java/com/baeldung/wiring/configuration/resource/SetterResourceInjectionIntegrationTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; import com.baeldung.wiring.configuration.ApplicationContextTestResourceNameType; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.io.File; import static org.junit.Assert.assertEquals; diff --git a/spring-di-3/pom.xml b/spring-di-3/pom.xml index 2d635d1f85..ba1a18ae8c 100644 --- a/spring-di-3/pom.xml +++ b/spring-di-3/pom.xml @@ -9,9 +9,9 @@ com.baeldung - parent-spring-5 + parent-spring-6 0.0.1-SNAPSHOT - ../parent-spring-5 + ../parent-spring-6 @@ -45,8 +45,10 @@ - 2.6.1 + 3.1.2 2.17.1 + 2.0.9 + 1.4.11 \ No newline at end of file diff --git a/spring-di-3/src/test/java/com/baeldung/dynamic/autowire/DynamicAutowireIntegrationTest.java b/spring-di-3/src/test/java/com/baeldung/dynamic/autowire/DynamicAutowireIntegrationTest.java index 56582ecb66..d93f94b0e3 100644 --- a/spring-di-3/src/test/java/com/baeldung/dynamic/autowire/DynamicAutowireIntegrationTest.java +++ b/spring-di-3/src/test/java/com/baeldung/dynamic/autowire/DynamicAutowireIntegrationTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = DynamicAutowireConfig.class) diff --git a/spring-di-4/pom.xml b/spring-di-4/pom.xml index c6572495cb..1eec8efcf0 100644 --- a/spring-di-4/pom.xml +++ b/spring-di-4/pom.xml @@ -9,9 +9,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-boot-3 diff --git a/spring-di-4/src/main/java/com/baeldung/sampleabstract/BallService.java b/spring-di-4/src/main/java/com/baeldung/sampleabstract/BallService.java index 0d951aac8b..541d8dfb6b 100644 --- a/spring-di-4/src/main/java/com/baeldung/sampleabstract/BallService.java +++ b/spring-di-4/src/main/java/com/baeldung/sampleabstract/BallService.java @@ -2,7 +2,7 @@ package com.baeldung.sampleabstract; import org.springframework.beans.factory.annotation.Autowired; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; public abstract class BallService { diff --git a/spring-di/pom.xml b/spring-di/pom.xml index af0601deb6..bae7263ef9 100644 --- a/spring-di/pom.xml +++ b/spring-di/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-spring-5 + parent-spring-6 0.0.1-SNAPSHOT - ../parent-spring-5 + ../parent-spring-6 @@ -48,11 +48,6 @@ spring-context ${spring.version} - - javax.inject - javax.inject - ${javax.inject.version} - com.google.guava guava @@ -71,7 +66,7 @@ org.springframework.boot spring-boot-test - ${mockito.spring.boot.version} + ${spring-boot.version} test @@ -89,11 +84,6 @@ - - javax.annotation - javax.annotation-api - ${annotation-api.version} - @@ -143,11 +133,7 @@ org.baeldung.org.baeldung.sample.App - 1.3.2 - 1.4.4.RELEASE - 1 - 1.5.2.RELEASE - 1.10.19 + 3.1.2 1.9.5 diff --git a/spring-ejb-modules/ejb-beans/pom.xml b/spring-ejb-modules/ejb-beans/pom.xml index 94f7963ad6..6203db5f5a 100644 --- a/spring-ejb-modules/ejb-beans/pom.xml +++ b/spring-ejb-modules/ejb-beans/pom.xml @@ -192,7 +192,7 @@ 2.21.0 2.8 8.2.1.Final - 2.10.12 + 2.12.5 \ No newline at end of file diff --git a/spring-exceptions/pom.xml b/spring-exceptions/pom.xml index 49c44f88f2..e0071a4206 100644 --- a/spring-exceptions/pom.xml +++ b/spring-exceptions/pom.xml @@ -72,7 +72,7 @@ - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -108,11 +108,6 @@ ${org.springframework.version} test - - javax.el - el-api - ${javax.el.version} - org.apache.derby derby @@ -171,8 +166,7 @@ 7.0.73 10.13.1.1 - 5.3.3.Final - 2.2 + 8.0.1.Final 2.3.0 4.4.5 diff --git a/spring-integration/src/test/resources/logback-test.xml b/spring-integration/src/test/resources/logback-test.xml index 98bfc86d71..352dc719df 100644 --- a/spring-integration/src/test/resources/logback-test.xml +++ b/spring-integration/src/test/resources/logback-test.xml @@ -9,7 +9,7 @@ - + diff --git a/spring-jenkins-pipeline/src/test/resources/logback-test.xml b/spring-jenkins-pipeline/src/test/resources/logback-test.xml index b9242f40a8..69ab60701a 100644 --- a/spring-jenkins-pipeline/src/test/resources/logback-test.xml +++ b/spring-jenkins-pipeline/src/test/resources/logback-test.xml @@ -8,6 +8,12 @@ + + + + + + diff --git a/spring-kafka-2/pom.xml b/spring-kafka-2/pom.xml index 0bca20447d..fdf7da7438 100644 --- a/spring-kafka-2/pom.xml +++ b/spring-kafka-2/pom.xml @@ -65,6 +65,8 @@ 1.16.2 + 3.0.12 + 3.6.0 1.16.2 diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/IotSensorData.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/IotSensorData.java new file mode 100644 index 0000000000..350f6911f3 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/IotSensorData.java @@ -0,0 +1,31 @@ +package com.baeldung.spring.kafka.kafkasplitting; + +public class IotSensorData { + private String sensorType; + private String value; + private String sensorId; + + public String getSensorType() { + return sensorType; + } + + public void setSensorType(String sensorType) { + this.sensorType = sensorType; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getSensorId() { + return sensorId; + } + + public void setSensorId(String sensorId) { + this.sensorId = sensorId; + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaConsumerConfig.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaConsumerConfig.java new file mode 100644 index 0000000000..70640cb582 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaConsumerConfig.java @@ -0,0 +1,43 @@ +package com.baeldung.spring.kafka.kafkasplitting; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +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.config.KafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.listener.ConcurrentMessageListenerContainer; +import org.springframework.kafka.support.serializer.JsonDeserializer; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +class KafkaConsumerConfig { + + @Value("${spring.kafka.consumer.group-id}") + private String groupId; + @Value("${spring.kafka.bootstrap-servers}") + private String bootstrapServers; + + @Bean + public ConsumerFactory consumerFactory() { + Map props = new HashMap<>(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class); + + return new DefaultKafkaConsumerFactory<>(props, new StringDeserializer(), new JsonDeserializer<>(IotSensorData.class)); + } + + @Bean + KafkaListenerContainerFactory> kafkaListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory()); + return factory; + } +} \ No newline at end of file diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaIotConsumerService.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaIotConsumerService.java new file mode 100644 index 0000000000..bbd0c549ab --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaIotConsumerService.java @@ -0,0 +1,28 @@ +package com.baeldung.spring.kafka.kafkasplitting; + +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Service; + +@Service +public class KafkaIotConsumerService { + + @KafkaListener(topics = "iot_sensor_data") + public void consumeIotData(IotSensorData item) { + System.out.println("Consumed Message in original \"iot_sensor_data\" topic :" + item.getSensorType()); + } + + @KafkaListener(topics = "iot_sensor_data_temp") + public void consumeIotTemperatureData(IotSensorData item) { + System.out.println("Consumed Temparature data :" + item.getValue()); + } + + @KafkaListener(topics = "iot_sensor_data_hum") + public void consumeIotHumidityData(IotSensorData item) { + System.out.println("Consumed Humidity data :" + item.getValue()); + } + + @KafkaListener(topics = "iot_sensor_data_move") + public void consumeIotMovementData(IotSensorData item) { + System.out.println("Consumed Movement data :" + item.getValue()); + } +} \ No newline at end of file diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaStreamsConfig.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaStreamsConfig.java new file mode 100644 index 0000000000..c4eb1501fd --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaStreamsConfig.java @@ -0,0 +1,62 @@ +package com.baeldung.spring.kafka.kafkasplitting; + +import org.apache.kafka.common.serialization.Serde; +import org.apache.kafka.common.serialization.Serdes; +import org.apache.kafka.streams.StreamsBuilder; +import org.apache.kafka.streams.kstream.Branched; +import org.apache.kafka.streams.kstream.Consumed; +import org.apache.kafka.streams.kstream.KStream; +import org.apache.kafka.streams.processor.TopicNameExtractor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.annotation.EnableKafka; +import org.springframework.kafka.annotation.EnableKafkaStreams; +import org.springframework.kafka.support.KafkaStreamBrancher; +import org.springframework.kafka.support.serializer.JsonDeserializer; +import org.springframework.kafka.support.serializer.JsonSerializer; + +@Configuration +@EnableKafka +@EnableKafkaStreams +class KafkaStreamsConfig { + @Value("${kafka.topics.iot}") + private String iotTopicName; + + @Bean + public Serde iotSerde() { + return Serdes.serdeFrom(new JsonSerializer<>(), new JsonDeserializer<>(IotSensorData.class)); + } + + @Bean + public KStream iotStream(StreamsBuilder streamsBuilder) { + KStream stream = streamsBuilder.stream(iotTopicName, Consumed.with(Serdes.String(), iotSerde())); + stream.split() + .branch((key, value) -> value.getSensorType() != null, + Branched.withConsumer(ks -> ks.to((key, value, recordContext) -> String.format("%s_%s", iotTopicName, value.getSensorType())))) + .noDefaultBranch(); + return stream; + } + + @Bean + public KStream iotBrancher(StreamsBuilder streamsBuilder) { + KStream stream = streamsBuilder.stream(iotTopicName, Consumed.with(Serdes.String(), iotSerde())); + + new KafkaStreamBrancher() + .branch((key, value) -> "temp".equals(value.getSensorType()), (ks) -> ks.to(iotTopicName + "_temp")) + .branch((key, value) -> "move".equals(value.getSensorType()), (ks) -> ks.to(iotTopicName + "_move")) + .branch((key, value) -> "hum".equals(value.getSensorType()), (ks) -> ks.to(iotTopicName + "_hum")) + .defaultBranch(ks -> ks.to(String.format("%s_unknown", iotTopicName))) + .onTopOf(stream); + + return stream; + } + + @Bean + public KStream iotTopicExtractor(StreamsBuilder streamsBuilder) { + KStream stream = streamsBuilder.stream(iotTopicName, Consumed.with(Serdes.String(), iotSerde())); + TopicNameExtractor sensorTopicExtractor = (key, value, recordContext) -> String.format("%s_%s", iotTopicName, value.getSensorType()); + stream.to(sensorTopicExtractor); + return stream; + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/SpringBootKafkaStreamsSplittingApp.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/SpringBootKafkaStreamsSplittingApp.java new file mode 100644 index 0000000000..6101eeb13d --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/SpringBootKafkaStreamsSplittingApp.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.kafka.kafkasplitting; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootKafkaStreamsSplittingApp { + public static void main(String[] args) { + SpringApplication.run(SpringBootKafkaStreamsSplittingApp.class, args); + } + +} diff --git a/spring-kafka-2/src/main/resources/application.properties b/spring-kafka-2/src/main/resources/application.properties index ed844cadf8..9111491b58 100644 --- a/spring-kafka-2/src/main/resources/application.properties +++ b/spring-kafka-2/src/main/resources/application.properties @@ -19,4 +19,8 @@ kafka.backoff.max_failure=5 # multiple listeners properties multiple-listeners.books.topic.name=books +spring.kafka.streams.application-id=baeldung-streams +spring.kafka.consumer.group-id=baeldung-group +spring.kafka.streams.properties[default.key.serde]=org.apache.kafka.common.serialization.Serdes$StringSerde +kafka.topics.iot=iot_sensor_data 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-pulsar/pom.xml b/spring-pulsar/pom.xml index 05debcab1c..a1c834f830 100644 --- a/spring-pulsar/pom.xml +++ b/spring-pulsar/pom.xml @@ -15,10 +15,6 @@ ../parent-boot-3 - - 17 - 0.2.0 - org.springframework.boot @@ -47,6 +43,7 @@ + 17 0.2.0 diff --git a/spring-reactive-modules/spring-reactive-2/pom.xml b/spring-reactive-modules/spring-reactive-2/pom.xml index 13970851cd..90c5300cc8 100644 --- a/spring-reactive-modules/spring-reactive-2/pom.xml +++ b/spring-reactive-modules/spring-reactive-2/pom.xml @@ -5,9 +5,9 @@ 4.0.0 spring-reactive-2 0.0.1-SNAPSHOT - spring-5-reactive-2 + spring-reactive-2 jar - spring 5 sample project about new features + spring sample project about new features com.baeldung.spring.reactive diff --git a/spring-reactive-modules/spring-reactive-3/pom.xml b/spring-reactive-modules/spring-reactive-3/pom.xml index 96f23f1339..bf2cdbbf2d 100644 --- a/spring-reactive-modules/spring-reactive-3/pom.xml +++ b/spring-reactive-modules/spring-reactive-3/pom.xml @@ -5,9 +5,9 @@ 4.0.0 spring-reactive-3 0.0.1-SNAPSHOT - spring-5-reactive-3 + spring-reactive-3 jar - spring 5 sample project about new features + spring sample project about new features com.baeldung.spring.reactive diff --git a/spring-reactive-modules/spring-reactive-data-couchbase/pom.xml b/spring-reactive-modules/spring-reactive-data-couchbase/pom.xml index 52b10f39d9..2ac8ad19ac 100644 --- a/spring-reactive-modules/spring-reactive-data-couchbase/pom.xml +++ b/spring-reactive-modules/spring-reactive-data-couchbase/pom.xml @@ -1,10 +1,10 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-reactive-data-couchbase - spring-data-couchbase + spring-reactive-data-couchbase jar diff --git a/spring-reactive-modules/spring-reactive-data/pom.xml b/spring-reactive-modules/spring-reactive-data/pom.xml index 03ea440b4f..a598315d5d 100644 --- a/spring-reactive-modules/spring-reactive-data/pom.xml +++ b/spring-reactive-modules/spring-reactive-data/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-reactive-data - spring-reactive-data-2 + spring-reactive-data jar diff --git a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java index e6f8ba35c2..7775f61467 100644 --- a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java +++ b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java @@ -53,11 +53,10 @@ public class EmployeeFunctionalConfig { @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { - http.csrf() - .disable() - .authorizeExchange() - .anyExchange() - .permitAll(); + http.csrf(csrf -> csrf.disable()) + .authorizeExchange( + exchanges -> exchanges.anyExchange().permitAll() + ); return http.build(); } } \ No newline at end of file diff --git a/spring-security-modules/pom.xml b/spring-security-modules/pom.xml index ed8279c5f7..1b3db18b84 100644 --- a/spring-security-modules/pom.xml +++ b/spring-security-modules/pom.xml @@ -10,8 +10,9 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 diff --git a/spring-security-modules/spring-security-acl/pom.xml b/spring-security-modules/spring-security-acl/pom.xml index 7facc1b14b..734b85800a 100644 --- a/spring-security-modules/spring-security-acl/pom.xml +++ b/spring-security-modules/spring-security-acl/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-auth0/pom.xml b/spring-security-modules/spring-security-auth0/pom.xml index 106a0db29f..8ee59eeac1 100644 --- a/spring-security-modules/spring-security-auth0/pom.xml +++ b/spring-security-modules/spring-security-auth0/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-azuread/pom.xml b/spring-security-modules/spring-security-azuread/pom.xml index c1fe08b47a..7e67a7e635 100644 --- a/spring-security-modules/spring-security-azuread/pom.xml +++ b/spring-security-modules/spring-security-azuread/pom.xml @@ -6,9 +6,8 @@ 4.0.0 com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 spring-security-azuread diff --git a/spring-security-modules/spring-security-cognito/pom.xml b/spring-security-modules/spring-security-cognito/pom.xml index 56754ddf99..2e359382a7 100644 --- a/spring-security-modules/spring-security-cognito/pom.xml +++ b/spring-security-modules/spring-security-cognito/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-core-2/pom.xml b/spring-security-modules/spring-security-core-2/pom.xml index 5d77098869..54aac0d9a7 100644 --- a/spring-security-modules/spring-security-core-2/pom.xml +++ b/spring-security-modules/spring-security-core-2/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-core/pom.xml b/spring-security-modules/spring-security-core/pom.xml index 03d7030057..2a18145ac0 100644 --- a/spring-security-modules/spring-security-core/pom.xml +++ b/spring-security-modules/spring-security-core/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-ldap/pom.xml b/spring-security-modules/spring-security-ldap/pom.xml index 471ffff4a1..9f4f3b4106 100644 --- a/spring-security-modules/spring-security-ldap/pom.xml +++ b/spring-security-modules/spring-security-ldap/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-legacy-oidc/pom.xml b/spring-security-modules/spring-security-legacy-oidc/pom.xml index e98486b0ff..55b6e780b2 100644 --- a/spring-security-modules/spring-security-legacy-oidc/pom.xml +++ b/spring-security-modules/spring-security-legacy-oidc/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-oauth2-sso/pom.xml b/spring-security-modules/spring-security-oauth2-sso/pom.xml index a87e4d7814..d8101d2313 100644 --- a/spring-security-modules/spring-security-oauth2-sso/pom.xml +++ b/spring-security-modules/spring-security-oauth2-sso/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-oauth2/pom.xml b/spring-security-modules/spring-security-oauth2/pom.xml index 1b30f6685d..977e2c16fd 100644 --- a/spring-security-modules/spring-security-oauth2/pom.xml +++ b/spring-security-modules/spring-security-oauth2/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-oidc/pom.xml b/spring-security-modules/spring-security-oidc/pom.xml index 70031b7396..c27c084ad7 100644 --- a/spring-security-modules/spring-security-oidc/pom.xml +++ b/spring-security-modules/spring-security-oidc/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-okta/pom.xml b/spring-security-modules/spring-security-okta/pom.xml index 98b8abedb4..5ae1241b18 100644 --- a/spring-security-modules/spring-security-okta/pom.xml +++ b/spring-security-modules/spring-security-okta/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-opa/pom.xml b/spring-security-modules/spring-security-opa/pom.xml index 72b0574253..a6240f6e69 100644 --- a/spring-security-modules/spring-security-opa/pom.xml +++ b/spring-security-modules/spring-security-opa/pom.xml @@ -7,9 +7,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-pkce/pom.xml b/spring-security-modules/spring-security-pkce/pom.xml index 5899b297b4..e0bd8eb90e 100644 --- a/spring-security-modules/spring-security-pkce/pom.xml +++ b/spring-security-modules/spring-security-pkce/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-saml/pom.xml b/spring-security-modules/spring-security-saml/pom.xml index 8a9b418374..8d7cce939f 100644 --- a/spring-security-modules/spring-security-saml/pom.xml +++ b/spring-security-modules/spring-security-saml/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-saml2/src/main/java/com/baeldung/saml/SecurityConfig.java b/spring-security-modules/spring-security-saml2/src/main/java/com/baeldung/saml/SecurityConfig.java index 9078953d02..524cb3b0bc 100644 --- a/spring-security-modules/spring-security-saml2/src/main/java/com/baeldung/saml/SecurityConfig.java +++ b/spring-security-modules/spring-security-saml2/src/main/java/com/baeldung/saml/SecurityConfig.java @@ -7,6 +7,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.saml2.provider.service.metadata.OpenSamlMetadataResolver; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver; @@ -25,10 +26,9 @@ public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { DefaultRelyingPartyRegistrationResolver relyingPartyRegistrationResolver = new DefaultRelyingPartyRegistrationResolver(this.relyingPartyRegistrationRepository); - Saml2MetadataFilter filter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver()); - - http.authorizeHttpRequests(authorize -> authorize.anyRequest() - .authenticated()) + Saml2MetadataFilter filter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver()); + + http.csrf(AbstractHttpConfigurer::disable).authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated()) .saml2Login(withDefaults()) .saml2Logout(withDefaults()) .addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class); diff --git a/spring-security-modules/spring-security-saml2/src/main/resources/metadata/metadata-idp-okta.xml b/spring-security-modules/spring-security-saml2/src/main/resources/metadata/metadata-idp-okta.xml index 83976805c4..785effccc6 100644 --- a/spring-security-modules/spring-security-saml2/src/main/resources/metadata/metadata-idp-okta.xml +++ b/spring-security-modules/spring-security-saml2/src/main/resources/metadata/metadata-idp-okta.xml @@ -1,17 +1,17 @@ MIIDqDCCApCgAwIBAgIGAYZ6plFwMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEG -A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU -MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi01NjYxNzIyMjEcMBoGCSqGSIb3DQEJ -ARYNaW5mb0Bva3RhLmNvbTAeFw0yMzAyMjIxOTQxNDVaFw0zMzAyMjIxOTQyNDVaMIGUMQswCQYD -VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG -A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi01NjYxNzIyMjEc -MBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAMCoER+Qlx6xBBUAcIxRk5ItmfldF+Rc+z+FCY/Ow7+cNBOIenRGfQLirQMwKzvZAg2o52xm -OrtqsHX3NLEnSQDyQp/sE7MueHQCGcDnCAQEeOVbDSPW7bDOeK/qNyecTPKZreL70TQLPpeA9x7l -WA59zxOX9or9BLuQJrXKOU/cZ4BXzue351R2qmuj7IqbXmsbetKegVFShYJZ9e9ta42OK1T8oDez -dKZbPj5el1kj2jJ08GzO3TDg9j5B21x3sz2bxg6vFMP7e10hgLicxKVw1P5ZG995wUA+E8YbFehi -YXRlcJiiKhmjRvHFl1F5vM4DPLaL4b8BJ1E21Byhb2cCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA -FMy00eWU4klEdV2PhoOPZE8Phj6tVDtEjr+ol7L7RJh6u2WPwLm6U9vE9wQ0/OYhOjThUsZqxqjL -SqhZeMiFwohL6K5cmW2wTkxgfICyPY9g3BVDtogsZgbI0clIG5slwgiy9Kn7wQpSHWDvpEZXwmyV -KodcWIpgBf0dUdBhsx+o34eG7ajsLb9HEisF0ntxlKdG2LJqlkJBtiUgI2Wo2jNshfzA7Cp9cNio -+j3f1dwyWmmwWkyxGkEw8UwuwKMDHfuAwyBmZJmmG9zkHMlHkgQxxq3iI8Bs9E3lKYXtwLE7K+xe -rTdWegAfIP7LXC3JKN1N/Meke5FJLXmWAMXKIw==urn:oasis:names:tc:SAML:1.1:nameid-format:unspecifiedurn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress \ No newline at end of file + A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU + MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi01NjYxNzIyMjEcMBoGCSqGSIb3DQEJ + ARYNaW5mb0Bva3RhLmNvbTAeFw0yMzAyMjIxOTQxNDVaFw0zMzAyMjIxOTQyNDVaMIGUMQswCQYD + VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG + A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi01NjYxNzIyMjEc + MBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC + ggEBAMCoER+Qlx6xBBUAcIxRk5ItmfldF+Rc+z+FCY/Ow7+cNBOIenRGfQLirQMwKzvZAg2o52xm + OrtqsHX3NLEnSQDyQp/sE7MueHQCGcDnCAQEeOVbDSPW7bDOeK/qNyecTPKZreL70TQLPpeA9x7l + WA59zxOX9or9BLuQJrXKOU/cZ4BXzue351R2qmuj7IqbXmsbetKegVFShYJZ9e9ta42OK1T8oDez + dKZbPj5el1kj2jJ08GzO3TDg9j5B21x3sz2bxg6vFMP7e10hgLicxKVw1P5ZG995wUA+E8YbFehi + YXRlcJiiKhmjRvHFl1F5vM4DPLaL4b8BJ1E21Byhb2cCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA + FMy00eWU4klEdV2PhoOPZE8Phj6tVDtEjr+ol7L7RJh6u2WPwLm6U9vE9wQ0/OYhOjThUsZqxqjL + SqhZeMiFwohL6K5cmW2wTkxgfICyPY9g3BVDtogsZgbI0clIG5slwgiy9Kn7wQpSHWDvpEZXwmyV + KodcWIpgBf0dUdBhsx+o34eG7ajsLb9HEisF0ntxlKdG2LJqlkJBtiUgI2Wo2jNshfzA7Cp9cNio + +j3f1dwyWmmwWkyxGkEw8UwuwKMDHfuAwyBmZJmmG9zkHMlHkgQxxq3iI8Bs9E3lKYXtwLE7K+xe + rTdWegAfIP7LXC3JKN1N/Meke5FJLXmWAMXKIw==urn:oasis:names:tc:SAML:1.1:nameid-format:unspecifiedurn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress \ No newline at end of file diff --git a/spring-security-modules/spring-security-social-login/pom.xml b/spring-security-modules/spring-security-social-login/pom.xml index ddda4235be..5efa5b703c 100644 --- a/spring-security-modules/spring-security-social-login/pom.xml +++ b/spring-security-modules/spring-security-social-login/pom.xml @@ -9,9 +9,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-angular/pom.xml b/spring-security-modules/spring-security-web-angular/pom.xml index 2a745bc6cc..15dc4d007c 100644 --- a/spring-security-modules/spring-security-web-angular/pom.xml +++ b/spring-security-modules/spring-security-web-angular/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-boot-1/pom.xml b/spring-security-modules/spring-security-web-boot-1/pom.xml index fa0fd567fe..08adb700ec 100644 --- a/spring-security-modules/spring-security-web-boot-1/pom.xml +++ b/spring-security-modules/spring-security-web-boot-1/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-boot-2/pom.xml b/spring-security-modules/spring-security-web-boot-2/pom.xml index 3ba8726f51..2255f8b035 100644 --- a/spring-security-modules/spring-security-web-boot-2/pom.xml +++ b/spring-security-modules/spring-security-web-boot-2/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-boot-3/pom.xml b/spring-security-modules/spring-security-web-boot-3/pom.xml index 5229068dfa..0b71e89527 100644 --- a/spring-security-modules/spring-security-web-boot-3/pom.xml +++ b/spring-security-modules/spring-security-web-boot-3/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-boot-4/pom.xml b/spring-security-modules/spring-security-web-boot-4/pom.xml index ffbed0f8ab..b5bfc55a9f 100644 --- a/spring-security-modules/spring-security-web-boot-4/pom.xml +++ b/spring-security-modules/spring-security-web-boot-4/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-boot-5/pom.xml b/spring-security-modules/spring-security-web-boot-5/pom.xml index f4e2e3ad92..14b8d87f25 100644 --- a/spring-security-modules/spring-security-web-boot-5/pom.xml +++ b/spring-security-modules/spring-security-web-boot-5/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-login-2/pom.xml b/spring-security-modules/spring-security-web-login-2/pom.xml index 2d92a8567f..a44543a6ba 100644 --- a/spring-security-modules/spring-security-web-login-2/pom.xml +++ b/spring-security-modules/spring-security-web-login-2/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-mvc/pom.xml b/spring-security-modules/spring-security-web-mvc/pom.xml index 505826d1a2..10dd89f618 100644 --- a/spring-security-modules/spring-security-web-mvc/pom.xml +++ b/spring-security-modules/spring-security-web-mvc/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml b/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml index 3c842a8a54..9a3b21af92 100644 --- a/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml +++ b/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-rest-custom/pom.xml b/spring-security-modules/spring-security-web-rest-custom/pom.xml index dfd2f59aaf..2e55fe8b89 100644 --- a/spring-security-modules/spring-security-web-rest-custom/pom.xml +++ b/spring-security-modules/spring-security-web-rest-custom/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-springdoc/pom.xml b/spring-security-modules/spring-security-web-springdoc/pom.xml index 03e938f1c8..30102fd83d 100644 --- a/spring-security-modules/spring-security-web-springdoc/pom.xml +++ b/spring-security-modules/spring-security-web-springdoc/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-thymeleaf/pom.xml b/spring-security-modules/spring-security-web-thymeleaf/pom.xml index c13aa6a471..dd5f2d7c97 100644 --- a/spring-security-modules/spring-security-web-thymeleaf/pom.xml +++ b/spring-security-modules/spring-security-web-thymeleaf/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/customuserdetails/SecurityConfiguration.java b/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/customuserdetails/SecurityConfiguration.java index cfec910ce9..d438aefcdc 100644 --- a/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/customuserdetails/SecurityConfiguration.java +++ b/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/customuserdetails/SecurityConfiguration.java @@ -28,7 +28,7 @@ public class SecurityConfiguration { .formLogin() .loginPage("/login") .permitAll() - .successForwardUrl("/index") + .defaultSuccessUrl("/index") .and() .logout() .permitAll() diff --git a/spring-security-modules/spring-security-web-x509/pom.xml b/spring-security-modules/spring-security-web-x509/pom.xml index 5282ab7d83..ec0331fd53 100644 --- a/spring-security-modules/spring-security-web-x509/pom.xml +++ b/spring-security-modules/spring-security-web-x509/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-static-resources/pom.xml b/spring-static-resources/pom.xml index f682eafdbe..875b8de31b 100644 --- a/spring-static-resources/pom.xml +++ b/spring-static-resources/pom.xml @@ -117,16 +117,10 @@ ${jackson.version} - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} - - - joda-time - joda-time - ${joda-time.version} - com.github.jknack @@ -194,9 +188,8 @@ 1.8.9 - 6.0.10.Final + 8.0.1.Final 4.1.0 - 2.10 1 1.5.1 diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml index b57a014a8f..95d3239b96 100644 --- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml @@ -26,16 +26,6 @@ spring-boot-starter-test test - - org.hibernate - hibernate-validator - ${hibernate-validator.version} - - - javax.validation - validation-api - ${validation-api.version} - org.openapitools openapi-generator @@ -97,8 +87,6 @@ 3.0.0 2.17.1 1.7.0 - 6.0.10.Final - 2.0.1.Final 3.3.4 2.10.0.pr3 5.1.0 diff --git a/spring-web-modules/spring-mvc-basics-2/pom.xml b/spring-web-modules/spring-mvc-basics-2/pom.xml index 28eb3a16f2..613e42dee3 100644 --- a/spring-web-modules/spring-mvc-basics-2/pom.xml +++ b/spring-web-modules/spring-mvc-basics-2/pom.xml @@ -42,7 +42,7 @@ ${jstl.version} - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -148,7 +148,7 @@ - 6.0.10.Final + 8.0.1.Final enter-location-of-server 3.0.11.RELEASE 2.4.12 diff --git a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/CustomerController.java b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/CustomerController.java index 8ecfce58e3..e1d2a8e37f 100644 --- a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/CustomerController.java +++ b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/CustomerController.java @@ -1,6 +1,6 @@ package com.baeldung.spring.controller; -import javax.validation.Valid; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; diff --git a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/EmployeeController.java b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/EmployeeController.java index 6543a98af1..5299d8289b 100644 --- a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/EmployeeController.java +++ b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/EmployeeController.java @@ -3,7 +3,7 @@ package com.baeldung.spring.controller; import java.util.HashMap; import java.util.Map; -import javax.validation.Valid; +import jakarta.validation.Valid; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; diff --git a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/MailController.java b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/MailController.java index b6e19a4c39..f4088b8bb3 100644 --- a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/MailController.java +++ b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/MailController.java @@ -8,7 +8,7 @@ import java.util.Set; import javax.mail.MessagingException; import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; diff --git a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/Employee.java b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/Employee.java index 900770b873..a0641b0a32 100644 --- a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/Employee.java +++ b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/Employee.java @@ -1,7 +1,7 @@ package com.baeldung.spring.domain; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; public class Employee { diff --git a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/MailObject.java b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/MailObject.java index d425ca9a26..23807926ca 100644 --- a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/MailObject.java +++ b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/MailObject.java @@ -1,8 +1,8 @@ package com.baeldung.spring.domain; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; /** * Created by Olga on 7/20/2016. diff --git a/spring-web-modules/spring-mvc-basics-5/pom.xml b/spring-web-modules/spring-mvc-basics-5/pom.xml index e0d603e303..1c8c87a2ef 100644 --- a/spring-web-modules/spring-mvc-basics-5/pom.xml +++ b/spring-web-modules/spring-mvc-basics-5/pom.xml @@ -82,7 +82,7 @@ 1.3.2 - 2.7.0 + 2.8.0 2.3.5 2.0.0 3.0.0 diff --git a/spring-web-modules/spring-mvc-crash/pom.xml b/spring-web-modules/spring-mvc-crash/pom.xml index f3faa18816..9bfcfb488e 100644 --- a/spring-web-modules/spring-mvc-crash/pom.xml +++ b/spring-web-modules/spring-mvc-crash/pom.xml @@ -147,7 +147,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-mvc-forms-jsp/pom.xml b/spring-web-modules/spring-mvc-forms-jsp/pom.xml index 3ad815e95f..5096c6e23d 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/pom.xml +++ b/spring-web-modules/spring-mvc-forms-jsp/pom.xml @@ -48,7 +48,7 @@ ${mysql-connector-java.version} - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -102,7 +102,7 @@ - 6.0.10.Final + 8.0.1.Final 5.2.5.Final 6.0.6 1.3.2 diff --git a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/CustomerController.java b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/CustomerController.java index 586c2467fe..81dd700551 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/CustomerController.java +++ b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/CustomerController.java @@ -1,6 +1,6 @@ package com.baeldung.springmvcforms.controller; -import javax.validation.Valid; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; diff --git a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/EmployeeController.java b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/EmployeeController.java index 478b3532fe..9c0b3a7086 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/EmployeeController.java +++ b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/EmployeeController.java @@ -7,7 +7,7 @@ import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.HashMap; import java.util.Map; diff --git a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/UserController.java b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/UserController.java index f5553cf2b7..80f56645a9 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/UserController.java +++ b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/UserController.java @@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/Employee.java b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/Employee.java index 23cb72b3dc..ae174e2020 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/Employee.java +++ b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/Employee.java @@ -1,7 +1,7 @@ package com.baeldung.springmvcforms.domain; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; public class Employee { diff --git a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/User.java b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/User.java index 9e0e7c99be..db055763a4 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/User.java +++ b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/User.java @@ -1,11 +1,11 @@ package com.baeldung.springmvcforms.domain; -import javax.validation.constraints.Digits; -import javax.validation.constraints.Email; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.Digits; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; public class User { diff --git a/spring-web-modules/spring-mvc-java-2/pom.xml b/spring-web-modules/spring-mvc-java-2/pom.xml index d88a9c320a..b1b5a797f8 100644 --- a/spring-web-modules/spring-mvc-java-2/pom.xml +++ b/spring-web-modules/spring-mvc-java-2/pom.xml @@ -41,6 +41,11 @@ jaxb-runtime ${jaxb-runtime.version} + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + @@ -57,6 +62,7 @@ 4.0.1 5.2.2.RELEASE 2.3.5 + 1.5 \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertFileToMultipartFileUnitTest.java b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertFileToMultipartFileUnitTest.java new file mode 100644 index 0000000000..7d99f7f9bb --- /dev/null +++ b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertFileToMultipartFileUnitTest.java @@ -0,0 +1,45 @@ +package com.baeldung.multipart.file; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.disk.DiskFileItem; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.commons.CommonsMultipartFile; +import org.springframework.mock.web.MockMultipartFile; + +public class ConvertFileToMultipartFileUnitTest { + + @Test + public void givenFile_whenCreateMultipartFile_thenContentMatch() throws IOException { + File file = new File("src/main/resources/targetFile.tmp"); + byte[] fileBytes = Files.readAllBytes(file.toPath()); + MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", fileBytes); + String fileContent = new String(multipartFile.getBytes()); + assertEquals("Hello World", fileContent); + assertEquals("targetFile.tmp", multipartFile.getOriginalFilename()); + } + + @Test + public void givenFile_whenCreateMultipartFileUsingCommonsMultipart_thenContentMatch() throws IOException { + File file = new File("src/main/resources/targetFile.tmp"); + FileItem fileItem = new DiskFileItem("file", Files.probeContentType(file.toPath()), false, file.getName(), (int) file.length(), file.getParentFile()); + InputStream input = new FileInputStream(file); + OutputStream outputStream = fileItem.getOutputStream(); + IOUtils.copy(input, outputStream); + MultipartFile multipartFile = new CommonsMultipartFile(fileItem); + String fileContent = new String(multipartFile.getBytes()); + assertEquals("Hello World", fileContent); + assertEquals("targetFile.tmp", multipartFile.getOriginalFilename()); + } + +} diff --git a/spring-web-modules/spring-mvc-java/pom.xml b/spring-web-modules/spring-mvc-java/pom.xml index 8098f07282..395b12a278 100644 --- a/spring-web-modules/spring-mvc-java/pom.xml +++ b/spring-web-modules/spring-mvc-java/pom.xml @@ -101,7 +101,6 @@ org.hibernate.validator hibernate-validator - ${hibernate-validator.version} org.glassfish @@ -217,8 +216,6 @@ 6.0.10.Final 5.1.40 - - 6.0.10.Final 2.2.0 @@ -237,7 +234,7 @@ 4.0.1 2.3.3 2.32 - 2.4.0 + 2.8.0 com.baeldung.SpringMVCApplication diff --git a/spring-web-modules/spring-mvc-xml-2/pom.xml b/spring-web-modules/spring-mvc-xml-2/pom.xml index 8c0062f538..49590758cc 100644 --- a/spring-web-modules/spring-mvc-xml-2/pom.xml +++ b/spring-web-modules/spring-mvc-xml-2/pom.xml @@ -10,8 +10,9 @@ com.baeldung - spring-web-modules + parent-spring-6 0.0.1-SNAPSHOT + ../../parent-spring-6 @@ -19,26 +20,18 @@ org.springframework spring-web - ${spring.version} org.springframework spring-webmvc - ${spring.version} - javax.servlet - javax.servlet-api - ${javax.servlet-api.version} + jakarta.servlet + jakarta.servlet-api + ${jakarta.servlet-api.version} provided - - javax.servlet - jstl - ${jstl.version} - runtime - org.hibernate.validator hibernate-validator @@ -57,9 +50,9 @@ ${commons-io.version} - org.glassfish - javax.el - ${javax.el.version} + org.glassfish.expressly + expressly + ${expressly.version} org.springframework.boot @@ -98,9 +91,11 @@ 5.1.40 4.4.5 4.5.2 - 6.0.10.Final - 3.0.1-b08 + 8.0.1.Final + 5.0.0 1.6.1 + 6.0.0 + 3.1.5 \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/controller/ConstraintViolationExceptionHandler.java b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/controller/ConstraintViolationExceptionHandler.java index 645b36c2a5..d3d833a696 100644 --- a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/controller/ConstraintViolationExceptionHandler.java +++ b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/controller/ConstraintViolationExceptionHandler.java @@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; -import javax.validation.ConstraintViolationException; +import jakarta.validation.ConstraintViolationException; @ControllerAdvice public class ConstraintViolationExceptionHandler extends ResponseEntityExceptionHandler { diff --git a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/paramsvalidation/RequestAndPathVariableValidationController.java b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/paramsvalidation/RequestAndPathVariableValidationController.java index 4768237871..e1842564ac 100644 --- a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/paramsvalidation/RequestAndPathVariableValidationController.java +++ b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/paramsvalidation/RequestAndPathVariableValidationController.java @@ -7,11 +7,11 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; @Controller @RequestMapping("/public/api/1") diff --git a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/Person.java b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/Person.java index ed2fa903ef..a08f0f515c 100644 --- a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/Person.java +++ b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/Person.java @@ -2,7 +2,7 @@ package com.baeldung.spring.taglibrary; import java.util.List; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; import org.springframework.web.multipart.MultipartFile; diff --git a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/PersonController.java b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/PersonController.java index 0fcb66f2dd..79e65b1fde 100644 --- a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/PersonController.java +++ b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/PersonController.java @@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; 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-session/spring-session-redis/pom.xml b/spring-web-modules/spring-session/spring-session-redis/pom.xml index 6824a3632d..6b1aec24e4 100644 --- a/spring-web-modules/spring-session/spring-session-redis/pom.xml +++ b/spring-web-modules/spring-session/spring-session-redis/pom.xml @@ -40,12 +40,14 @@ redis.clients jedis + ${jedis.version} jar 0.6 + 5.0.2 \ No newline at end of file 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/junit-5-advanced/pom.xml b/testing-modules/junit-5-advanced/pom.xml index 3ae62eac2e..411f189638 100644 --- a/testing-modules/junit-5-advanced/pom.xml +++ b/testing-modules/junit-5-advanced/pom.xml @@ -45,7 +45,18 @@ ${junit-platform.version} test - + + org.junit.platform + junit-platform-launcher + ${junit-platform.version} + test + + + org.junit.platform + junit-platform-commons + ${junit-platform.version} + test + @@ -70,7 +81,7 @@ 1.49 3.24.2 - 1.9.2 + 1.10.1 3.0.0 diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassOneUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassOneUnitTest.java index 4ce092796e..cfb77c8d41 100644 --- a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassOneUnitTest.java +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassOneUnitTest.java @@ -10,4 +10,8 @@ public class ClassOneUnitTest { Assertions.assertTrue(true); } + @Test + public void whenFalse_thenFalse() { + Assertions.assertFalse(false); + } } diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/subpackage/ClassTwoUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/subpackage/ClassTwoUnitTest.java index bb63fcda63..be5b3380c7 100644 --- a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/subpackage/ClassTwoUnitTest.java +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/subpackage/ClassTwoUnitTest.java @@ -8,4 +8,9 @@ public class ClassTwoUnitTest { public void whenTrue_thenTrue() { Assertions.assertTrue(true); } + + @Test + public void whenFalse_thenFalse() { + Assertions.assertFalse(false); + } } diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectMethodsSuite.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectMethodsSuite.java new file mode 100644 index 0000000000..e0d17dc0e4 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectMethodsSuite.java @@ -0,0 +1,14 @@ +package com.baeldung.testsuite.suites; + +import com.baeldung.testsuite.ClassOneUnitTest; +import org.junit.platform.suite.api.SelectMethod; +import org.junit.platform.suite.api.Suite; +import org.junit.platform.suite.api.SuiteDisplayName; + +@Suite +@SuiteDisplayName("My Test Suite") +@SelectMethod(type = ClassOneUnitTest.class, name = "whenFalse_thenFalse") +@SelectMethod("com.baeldung.testsuite.subpackage.ClassTwoUnitTest#whenFalse_thenFalse") +public class JUnitSelectMethodsSuite { + // runs ClassOneUnitTest and ClassTwoUnitTest +} \ No newline at end of file diff --git a/testing-modules/junit-5-basics-2/pom.xml b/testing-modules/junit-5-basics-2/pom.xml index 85b6c707fb..b430161380 100644 --- a/testing-modules/junit-5-basics-2/pom.xml +++ b/testing-modules/junit-5-basics-2/pom.xml @@ -1,16 +1,16 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + junit-5-basics-2 + com.baeldung parent-modules 1.0.0-SNAPSHOT - junit-5-basics-2 - commons-cli @@ -30,6 +30,7 @@ test + diff --git a/testing-modules/rest-assured/pom.xml b/testing-modules/rest-assured/pom.xml index a4860b641d..d07e6d3b28 100644 --- a/testing-modules/rest-assured/pom.xml +++ b/testing-modules/rest-assured/pom.xml @@ -93,11 +93,6 @@ mail ${javax.mail.version} - - joda-time - joda-time - ${joda-time.version} - com.fasterxml.jackson.core jackson-annotations @@ -184,7 +179,6 @@ 4.5.2 0.9 8.0.0 - 2.9.6 1.1 1.2 2.27.2 diff --git a/testing-modules/selenium-2/src/test/java/com/baeldung/selenium/iframe/IframeManualTest.java b/testing-modules/selenium-2/src/test/java/com/baeldung/selenium/iframe/IframeManualTest.java new file mode 100644 index 0000000000..bc617a4777 --- /dev/null +++ b/testing-modules/selenium-2/src/test/java/com/baeldung/selenium/iframe/IframeManualTest.java @@ -0,0 +1,120 @@ +package com.baeldung.selenium.iframe; + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.time.Duration; + + +public class IframeManualTest { + + private WebDriver driver; + private static final int TIMEOUT = 10; + + @BeforeMethod + public void init() { + WebDriverManager.chromedriver().setup(); + driver = new ChromeDriver(); + } + + @Test + public void whenSwitchToFrameUsingWebElement_thenSwitched() { + openDemoPage(); + WebElement iframeElement = driver.findElement(By.cssSelector("#myFrame2")); + + new WebDriverWait(driver, Duration.ofSeconds(10)) + .until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(iframeElement)); + waitForTextInFrame(); + } + + @Test + public void whenSwitchToFrameUsingName_thenSwitched() { + openDemoPage(); + new WebDriverWait(driver, Duration.ofSeconds(10)) + .until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("frameName2")); + waitForTextInFrame(); + } + + @Test + public void whenSwitchToFrameUsingId_thenSwitched() { + openDemoPage(); + new WebDriverWait(driver, Duration.ofSeconds(10)) + .until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("myFrame2")); + waitForTextInFrame(); + } + + @Test + public void whenSwitchToInnerFrameFromOuter_thenSwitched() { + openPageWithNestedFrames(); + switchToNestedFrame(); + waitForLinkInNestedFrame(); + } + + @Test + public void whenSwitchToParentFrame_thenSwitched() { + openPageWithNestedFrames(); + switchToNestedFrame(); + driver.switchTo().parentFrame(); + waitForTextInParentFrame(); + } + + @Test + public void whenSwitchToDefaultContent_thenSwitched() { + openPageWithNestedFrames(); + switchToNestedFrame(); + driver.switchTo().defaultContent(); + waitForElementInDefaultContent(); + } + + @AfterMethod + public void tearDown() { + driver.quit(); + } + + + private void openDemoPage() { + driver.get("https://seleniumbase.io/demo_page"); + new WebDriverWait(driver, Duration.ofSeconds(10)) + .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#myForm"))); + } + + private void openPageWithNestedFrames() { + driver.get("https://seleniumbase.io/w3schools/iframes"); + new WebDriverWait(driver, Duration.ofSeconds(10)) + .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#runbtn"))); + } + + private void switchToNestedFrame() { + driver.switchTo().frame("iframeResult"); + WebElement innerFrame = driver.findElement(By.cssSelector("[src='./demo_iframe.htm']")); + driver.switchTo().frame(innerFrame); + } + + private void waitForTextInFrame() { + new WebDriverWait(driver, Duration.ofSeconds(TIMEOUT)) + .until(ExpectedConditions.textToBePresentInElementLocated(By.cssSelector("h4"), "iFrame Text")); + } + + private void waitForLinkInNestedFrame() { + new WebDriverWait(driver, Duration.ofSeconds(TIMEOUT)) + .until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("[href='https://seleniumbase.io/w3schools/iframes.html']"))); + } + + private void waitForTextInParentFrame() { + new WebDriverWait(driver, Duration.ofSeconds(TIMEOUT)) + .until(ExpectedConditions.textToBePresentInElementLocated(By.cssSelector("h2"), "HTML Iframes (nested iframes)")); + } + + private void waitForElementInDefaultContent() { + new WebDriverWait(driver, Duration.ofSeconds(TIMEOUT)) + .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#runbtn"))); + } +} diff --git a/video-tutorials/jackson-annotations/pom.xml b/video-tutorials/jackson-annotations/pom.xml index eaec50c1f7..542f68d69c 100644 --- a/video-tutorials/jackson-annotations/pom.xml +++ b/video-tutorials/jackson-annotations/pom.xml @@ -114,13 +114,13 @@ - 2.9.6 + 2.12.5 2.8.0 3.0.1 3.0.0 2.2.6 - 3.0.1 + 5.3.2 \ No newline at end of file diff --git a/web-modules/javax-servlets/pom.xml b/web-modules/javax-servlets/pom.xml index 80a1e3af9f..406cfc05c1 100644 --- a/web-modules/javax-servlets/pom.xml +++ b/web-modules/javax-servlets/pom.xml @@ -49,7 +49,7 @@ 4.5.3 - 2.8.2 + 2.10.1 \ No newline at end of file diff --git a/web-modules/spark-java/pom.xml b/web-modules/spark-java/pom.xml index da09467212..e49be68319 100644 --- a/web-modules/spark-java/pom.xml +++ b/web-modules/spark-java/pom.xml @@ -30,7 +30,7 @@ 2.5.4 - 2.8.0 + 2.10.1 \ 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/README.md b/xml-2/README.md index e91078dbf0..e9c1a07586 100644 --- a/xml-2/README.md +++ b/xml-2/README.md @@ -7,3 +7,5 @@ This module contains articles about eXtensible Markup Language (XML) - [Pretty-Print XML in Java](https://www.baeldung.com/java-pretty-print-xml) - [Validate an XML File Against an XSD File](https://www.baeldung.com/java-validate-xml-xsd) - [Converting JSON to XML in Java](https://www.baeldung.com/java-convert-json-to-xml) +- [Convert an XML Object to a String in Java](https://www.baeldung.com/java-convert-xml-object-string) +- [Convert String Containing XML to org.w3c.dom.Document](https://www.baeldung.com/java-convert-string-xml-dom) diff --git a/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java b/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java new file mode 100644 index 0000000000..99e5c7c0cb --- /dev/null +++ b/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java @@ -0,0 +1,110 @@ +package com.baeldung.xml.xml2csv; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +public class Xml2CsvExample { + + private static final String BASE_PATH = "xml/src/main/resources/xml2csv/"; + + private static final String STYLE_XSL = BASE_PATH + "style.xsl"; + private static final String DATA_XML = BASE_PATH + "data.xml"; + private static final String OUTPUT_CSV_XSTL = BASE_PATH + "output_xstl.csv"; + private static final String OUTPUT_CSV_STAX = BASE_PATH + "output_stax.csv"; + + public static void main(String[] args) { + try { + convertXml2CsvXslt(STYLE_XSL, DATA_XML, OUTPUT_CSV_XSTL); + convertXml2CsvStax(DATA_XML, OUTPUT_CSV_STAX); + } catch (IOException | TransformerException e) { + e.printStackTrace(); + } + } + + protected static void convertXml2CsvXslt(String xslPath, String xmlPath, String csvPath) throws IOException, TransformerException { + StreamSource styleSource = new StreamSource(new File(xslPath)); + Transformer transformer = TransformerFactory.newInstance() + .newTransformer(styleSource); + Source source = new StreamSource(new File(xmlPath)); + Result outputTarget = new StreamResult(new File(csvPath)); + transformer.transform(source, outputTarget); + } + + protected static void convertXml2CsvStax(String xmlFilePath, String csvFilePath) throws IOException, TransformerException { + XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + + try (InputStream in = Files.newInputStream(Paths.get(xmlFilePath)); BufferedWriter writer = new BufferedWriter(new FileWriter(csvFilePath))) { + + writer.write("bookstore_id,book_id,category,title,author_id,author_name,price\n"); + + XMLStreamReader reader = inputFactory.createXMLStreamReader(in); + + String currentElement; + StringBuilder csvRow = new StringBuilder(); + StringBuilder bookstoreInfo = new StringBuilder(); + + while (reader.hasNext()) { + int eventType = reader.next(); + + switch (eventType) { + case XMLStreamConstants.START_ELEMENT: + currentElement = reader.getLocalName(); + if ("Bookstore".equals(currentElement)) { + bookstoreInfo.setLength(0); + bookstoreInfo.append(reader.getAttributeValue(null, "id")) + .append(","); + } + if ("Book".equals(currentElement)) { + csvRow.append(bookstoreInfo) + .append(reader.getAttributeValue(null, "id")) + .append(",") + .append(reader.getAttributeValue(null, "category")) + .append(","); + } + if ("Author".equals(currentElement)) { + csvRow.append(reader.getAttributeValue(null, "id")) + .append(","); + } + break; + + case XMLStreamConstants.CHARACTERS: + if (!reader.isWhiteSpace()) { + csvRow.append(reader.getText() + .trim()) + .append(","); + } + break; + + case XMLStreamConstants.END_ELEMENT: + if ("Book".equals(reader.getLocalName())) { + csvRow.setLength(csvRow.length() - 1); + csvRow.append("\n"); + writer.write(csvRow.toString()); + + csvRow.setLength(0); + } + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/xml/src/main/resources/xml2csv/data.xml b/xml/src/main/resources/xml2csv/data.xml new file mode 100644 index 0000000000..385fcf661c --- /dev/null +++ b/xml/src/main/resources/xml2csv/data.xml @@ -0,0 +1,26 @@ + + + + + + Death and the Penguin + Andrey Kurkov + 10.99 + + + Kobzar + Taras Shevchenko + 8.50 + + + + + + + Voroshilovgrad + Serhiy Zhadan + 12.99 + + + + diff --git a/xml/src/main/resources/xml2csv/style.xsl b/xml/src/main/resources/xml2csv/style.xsl new file mode 100644 index 0000000000..ea23880092 --- /dev/null +++ b/xml/src/main/resources/xml2csv/style.xsl @@ -0,0 +1,21 @@ + + + + + bookstore_id,book_id,category,title,author_id,author_name,price + + + + + + + + + + + + + + + + diff --git a/xml/src/test/java/com/baeldung/xml/xml2csv/Xml2CsvExampleUnitTest.java b/xml/src/test/java/com/baeldung/xml/xml2csv/Xml2CsvExampleUnitTest.java new file mode 100644 index 0000000000..3fa44b427c --- /dev/null +++ b/xml/src/test/java/com/baeldung/xml/xml2csv/Xml2CsvExampleUnitTest.java @@ -0,0 +1,155 @@ +package com.baeldung.xml.xml2csv; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import javax.xml.transform.TransformerException; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +public class Xml2CsvExampleUnitTest { + + private static final String BASE_PATH = "src/main/resources/xml2csv/"; + + private static final String STYLE_XSL = BASE_PATH + "style.xsl"; + private static final String DATA_XML = BASE_PATH + "data.xml"; + private static final String TEMP_OUTPUT_CSV = BASE_PATH + "tempOutput.xml"; + + @AfterEach + public void teardown() { + new File(TEMP_OUTPUT_CSV).delete(); + } + + @Test + public void whenConvertXml2CsvXslt_thenCsvFileIsCreated() throws IOException, TransformerException { + Xml2CsvExample.convertXml2CsvXslt(STYLE_XSL, DATA_XML, TEMP_OUTPUT_CSV); + + File csvFile = new File(TEMP_OUTPUT_CSV); + assertTrue(csvFile.exists()); + } + + @Test + public void whenConvertXml2CsvStax_thenCsvFileIsCreated() throws IOException, TransformerException { + Xml2CsvExample.convertXml2CsvStax(DATA_XML, TEMP_OUTPUT_CSV); + + File csvFile = new File(TEMP_OUTPUT_CSV); + assertTrue(csvFile.exists()); + } + + @Test + public void whenConvertXml2CsvXslt_thenCsvFileIsNotEmpty() throws IOException, TransformerException { + Xml2CsvExample.convertXml2CsvXslt(STYLE_XSL, DATA_XML, TEMP_OUTPUT_CSV); + + File csvFile = new File(TEMP_OUTPUT_CSV); + BufferedReader reader = new BufferedReader(new FileReader(csvFile)); + String firstLine = reader.readLine(); + assertNotNull(firstLine); + assertFalse(firstLine.isEmpty()); + + reader.close(); + } + + @Test + public void whenConvertXml2CsvStax_thenCsvFileIsNotEmpty() throws IOException, TransformerException { + Xml2CsvExample.convertXml2CsvStax(DATA_XML, TEMP_OUTPUT_CSV); + + File csvFile = new File(TEMP_OUTPUT_CSV); + BufferedReader reader = new BufferedReader(new FileReader(csvFile)); + String firstLine = reader.readLine(); + assertNotNull(firstLine); + assertFalse(firstLine.isEmpty()); + + reader.close(); + } + + @Test + public void whenConvertXml2CsvXsltWithWrongXSL_thenThrowsException() { + String xslWrongPath = BASE_PATH + "wrongFile.xsl"; + + assertThrows(TransformerException.class, () -> Xml2CsvExample.convertXml2CsvXslt(xslWrongPath, DATA_XML, TEMP_OUTPUT_CSV)); + } + + @Test + public void whenConvertXml2CsvXslt_thenCsvMatchesPattern() throws IOException, TransformerException { + String headerPattern = "^bookstore_id,book_id,category,title,author_id,author_name,price$"; + String dataPattern = "^[A-Z0-9]+,[A-Z0-9]+,[a-zA-Z]+,[a-zA-Z0-9\\s]+,[A-Z0-9]+,[a-zA-Z\\s]+,\\d+(\\.\\d{2})?$"; + + Xml2CsvExample.convertXml2CsvXslt(STYLE_XSL, DATA_XML, TEMP_OUTPUT_CSV); + + File csvFile = new File(TEMP_OUTPUT_CSV); + try(BufferedReader reader = new BufferedReader(new FileReader(csvFile))) { + String line; + boolean isFirstLine = true; + while ((line = reader.readLine()) != null) { + if (isFirstLine) { + assertTrue(line.matches(headerPattern), "Header does not match pattern"); + isFirstLine = false; + } else { + assertTrue(line.matches(dataPattern), "Data line does not match pattern"); + } + } + } + } + + @Test + public void whenConvertXml2Stax_thenCsvMatchesPattern() throws IOException, TransformerException { + String headerPattern = "^bookstore_id,book_id,category,title,author_id,author_name,price$"; + String dataPattern = "^[A-Z0-9]+,[A-Z0-9]+,[a-zA-Z]+,[a-zA-Z0-9\\s]+,[A-Z0-9]+,[a-zA-Z\\s]+,\\d+(\\.\\d{2})?$"; + + Xml2CsvExample.convertXml2CsvStax(DATA_XML, TEMP_OUTPUT_CSV); + + File csvFile = new File(TEMP_OUTPUT_CSV); + try(BufferedReader reader = new BufferedReader(new FileReader(csvFile))) { + String line; + boolean isFirstLine = true; + while ((line = reader.readLine()) != null) { + if (isFirstLine) { + assertTrue(line.matches(headerPattern), "Header does not match pattern"); + isFirstLine = false; + } else { + assertTrue(line.matches(dataPattern), "Data line does not match pattern"); + } + } + } + } + + @Test + public void whenConcurrentConversion_thenNoErrors() throws InterruptedException { + int numThreads = 10; + ExecutorService service = Executors.newFixedThreadPool(numThreads); + CountDownLatch latch = new CountDownLatch(numThreads); + + for (int i = 0; i < numThreads; i++) { + final int threadId = i; + service.execute(() -> { + String threadSpecificOutputCsv = BASE_PATH + "tempOutput" + threadId + ".csv"; + try { + Xml2CsvExample.convertXml2CsvXslt(STYLE_XSL, DATA_XML, threadSpecificOutputCsv); + assertTrue(Files.exists(Paths.get(threadSpecificOutputCsv)), "File should exist"); + } catch (IOException | TransformerException e) { + fail("Exception should not be thrown: " + e.getMessage()); + } finally { + new File(threadSpecificOutputCsv).delete(); + latch.countDown(); + } + }); + } + + latch.await(); + } + +}