diff --git a/apache-shiro/pom.xml b/apache-shiro/pom.xml
index 3df6283437..59bb91d400 100644
--- a/apache-shiro/pom.xml
+++ b/apache-shiro/pom.xml
@@ -39,10 +39,19 @@
jcl-over-slf4j
runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
- 1.4.0
+ 1.5.3
1.2.17
diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/shiro/CustomRealm.java b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/CustomRealm.java
new file mode 100644
index 0000000000..d82fb1a5d5
--- /dev/null
+++ b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/CustomRealm.java
@@ -0,0 +1,96 @@
+package com.baeldung.comparison.shiro;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.authc.UnknownAccountException;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.realm.jdbc.JdbcRealm;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CustomRealm extends JdbcRealm {
+
+ private Logger logger = LoggerFactory.getLogger(CustomRealm.class);
+
+ private Map credentials = new HashMap<>();
+ private Map> roles = new HashMap<>();
+ private Map> permissions = new HashMap<>();
+
+ {
+ credentials.put("Tom", "password");
+ credentials.put("Jerry", "password");
+
+ roles.put("Jerry", new HashSet<>(Arrays.asList("ADMIN")));
+ roles.put("Tom", new HashSet<>(Arrays.asList("USER")));
+
+ permissions.put("ADMIN", new HashSet<>(Arrays.asList("READ", "WRITE")));
+ permissions.put("USER", new HashSet<>(Arrays.asList("READ")));
+ }
+
+ @Override
+ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
+
+ UsernamePasswordToken userToken = (UsernamePasswordToken) token;
+
+ if (userToken.getUsername() == null || userToken.getUsername()
+ .isEmpty() || !credentials.containsKey(userToken.getUsername())) {
+ throw new UnknownAccountException("User doesn't exist");
+ }
+
+ return new SimpleAuthenticationInfo(userToken.getUsername(), credentials.get(userToken.getUsername()), getName());
+ }
+
+ @Override
+ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
+ Set roles = new HashSet<>();
+ Set permissions = new HashSet<>();
+
+ for (Object user : principals) {
+ try {
+ roles.addAll(getRoleNamesForUser(null, (String) user));
+ permissions.addAll(getPermissions(null, null, roles));
+ } catch (SQLException e) {
+ logger.error(e.getMessage());
+ }
+ }
+ SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo(roles);
+ authInfo.setStringPermissions(permissions);
+ return authInfo;
+ }
+
+ @Override
+ protected Set getRoleNamesForUser(Connection conn, String username) throws SQLException {
+ if (!roles.containsKey(username)) {
+ throw new SQLException("User doesn't exist");
+ }
+ return roles.get(username);
+ }
+
+ @Override
+ protected Set getPermissions(Connection conn, String username, Collection roles) throws SQLException {
+ Set userPermissions = new HashSet<>();
+
+ for (String role : roles) {
+ if (!permissions.containsKey(role)) {
+ throw new SQLException("Role doesn't exist");
+ }
+ userPermissions.addAll(permissions.get(role));
+ }
+ return userPermissions;
+ }
+
+}
diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/shiro/ShiroApplication.java b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/ShiroApplication.java
new file mode 100644
index 0000000000..92d43ea957
--- /dev/null
+++ b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/ShiroApplication.java
@@ -0,0 +1,33 @@
+package com.baeldung.comparison.shiro;
+
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
+import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+
+@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
+public class ShiroApplication {
+
+ public static void main(String... args) {
+ SpringApplication.run(ShiroApplication.class, args);
+ }
+
+ @Bean
+ public Realm customRealm() {
+ return new CustomRealm();
+ }
+
+ @Bean
+ public ShiroFilterChainDefinition shiroFilterChainDefinition() {
+ DefaultShiroFilterChainDefinition filter = new DefaultShiroFilterChainDefinition();
+
+ filter.addPathDefinition("/home", "authc");
+ filter.addPathDefinition("/**", "anon");
+
+ return filter;
+ }
+
+}
diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/shiro/controllers/ShiroController.java b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/controllers/ShiroController.java
new file mode 100644
index 0000000000..b819286c57
--- /dev/null
+++ b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/controllers/ShiroController.java
@@ -0,0 +1,99 @@
+package com.baeldung.comparison.shiro.controllers;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.subject.Subject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.baeldung.comparison.shiro.models.UserCredentials;
+
+@Controller
+public class ShiroController {
+
+ private Logger logger = LoggerFactory.getLogger(ShiroController.class);
+
+ @GetMapping("/")
+ public String getIndex() {
+ return "comparison/index";
+ }
+
+ @GetMapping("/login")
+ public String showLoginPage() {
+ return "comparison/login";
+ }
+
+ @PostMapping("/login")
+ public String doLogin(HttpServletRequest req, UserCredentials credentials, RedirectAttributes attr) {
+
+ Subject subject = SecurityUtils.getSubject();
+
+ if (!subject.isAuthenticated()) {
+ UsernamePasswordToken token = new UsernamePasswordToken(credentials.getUsername(), credentials.getPassword());
+ try {
+ subject.login(token);
+ } catch (AuthenticationException ae) {
+ logger.error(ae.getMessage());
+ attr.addFlashAttribute("error", "Invalid Credentials");
+ return "redirect:/login";
+ }
+ }
+ return "redirect:/home";
+ }
+
+ @GetMapping("/home")
+ public String getMeHome(Model model) {
+
+ addUserAttributes(model);
+
+ return "comparison/home";
+ }
+
+ @GetMapping("/admin")
+ public String adminOnly(Model model) {
+ addUserAttributes(model);
+
+ Subject currentUser = SecurityUtils.getSubject();
+ if (currentUser.hasRole("ADMIN")) {
+ model.addAttribute("adminContent", "only admin can view this");
+ }
+ return "comparison/home";
+ }
+
+ @PostMapping("/logout")
+ public String logout() {
+ Subject subject = SecurityUtils.getSubject();
+ subject.logout();
+ return "redirect:/";
+ }
+
+ private void addUserAttributes(Model model) {
+ Subject currentUser = SecurityUtils.getSubject();
+ String permission = "";
+
+ if (currentUser.hasRole("ADMIN")) {
+ model.addAttribute("role", "ADMIN");
+ } else if (currentUser.hasRole("USER")) {
+ model.addAttribute("role", "USER");
+ }
+
+ if (currentUser.isPermitted("READ")) {
+ permission = permission + " READ";
+ }
+
+ if (currentUser.isPermitted("WRITE")) {
+ permission = permission + " WRITE";
+ }
+ model.addAttribute("username", currentUser.getPrincipal());
+ model.addAttribute("permission", permission);
+ }
+
+}
diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/shiro/models/UserCredentials.java b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/models/UserCredentials.java
new file mode 100644
index 0000000000..100809f6ea
--- /dev/null
+++ b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/models/UserCredentials.java
@@ -0,0 +1,28 @@
+package com.baeldung.comparison.shiro.models;
+
+public class UserCredentials {
+
+ private String username;
+ private String password;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @Override
+ public String toString() {
+ return "username = " + getUsername();
+ }
+}
diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/Application.java b/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/Application.java
new file mode 100644
index 0000000000..6878c309df
--- /dev/null
+++ b/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/Application.java
@@ -0,0 +1,19 @@
+package com.baeldung.comparison.springsecurity;
+
+import org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration;
+import org.apache.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration;
+import org.apache.shiro.spring.config.web.autoconfigure.ShiroWebAutoConfiguration;
+import org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication(exclude = {ShiroAutoConfiguration.class,
+ ShiroAnnotationProcessorAutoConfiguration.class,
+ ShiroWebAutoConfiguration.class,
+ ShiroWebFilterConfiguration.class})
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
\ No newline at end of file
diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/config/SecurityConfig.java b/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/config/SecurityConfig.java
new file mode 100644
index 0000000000..d838eef9b3
--- /dev/null
+++ b/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/config/SecurityConfig.java
@@ -0,0 +1,45 @@
+package com.baeldung.comparison.springsecurity.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+@EnableWebSecurity
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.csrf().disable().authorizeRequests(authorize -> authorize.antMatchers("/index", "/login")
+ .permitAll()
+ .antMatchers("/home", "/logout")
+ .authenticated()
+ .antMatchers("/admin/**")
+ .hasRole("ADMIN"))
+ .formLogin(formLogin -> formLogin.loginPage("/login")
+ .failureUrl("/login-error"));
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.inMemoryAuthentication()
+ .withUser("Jerry")
+ .password(passwordEncoder().encode("password"))
+ .authorities("READ", "WRITE")
+ .roles("ADMIN")
+ .and()
+ .withUser("Tom")
+ .password(passwordEncoder().encode("password"))
+ .authorities("READ")
+ .roles("USER");
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder();
+ }
+
+}
diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/web/SpringController.java b/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/web/SpringController.java
new file mode 100644
index 0000000000..34b6b0c0e3
--- /dev/null
+++ b/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/web/SpringController.java
@@ -0,0 +1,79 @@
+package com.baeldung.comparison.springsecurity.web;
+
+import java.util.Collection;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class SpringController {
+
+ @GetMapping("/")
+ public String getIndex() {
+ return "comparison/index";
+ }
+
+ @GetMapping("/login")
+ public String showLoginPage() {
+ return "comparison/login";
+ }
+
+ @RequestMapping("/login-error")
+ public String loginError(Model model) {
+ model.addAttribute("error", "Invalid Credentials");
+ return "comparison/login";
+ }
+
+ @PostMapping("/login")
+ public String doLogin(HttpServletRequest req) {
+ return "redirect:/home";
+ }
+
+ @GetMapping("/home")
+ public String showHomePage(HttpServletRequest req, Model model) {
+ addUserAttributes(model);
+ return "comparison/home";
+ }
+
+ @GetMapping("/admin")
+ public String adminOnly(HttpServletRequest req, Model model) {
+ addUserAttributes(model);
+ model.addAttribute("adminContent", "only admin can view this");
+ return "comparison/home";
+ }
+
+ private void addUserAttributes(Model model) {
+ Authentication auth = SecurityContextHolder.getContext()
+ .getAuthentication();
+ if (auth != null && !auth.getClass()
+ .equals(AnonymousAuthenticationToken.class)) {
+ User user = (User) auth.getPrincipal();
+ model.addAttribute("username", user.getUsername());
+
+ Collection authorities = user.getAuthorities();
+
+ for (GrantedAuthority authority : authorities) {
+ if (authority.getAuthority()
+ .contains("USER")) {
+ model.addAttribute("role", "USER");
+ model.addAttribute("permission", "READ");
+ } else if (authority.getAuthority()
+ .contains("ADMIN")) {
+ model.addAttribute("role", "ADMIN");
+ model.addAttribute("permission", "READ WRITE");
+ }
+ }
+ }
+ }
+
+}
diff --git a/apache-shiro/src/main/java/com/baeldung/Main.java b/apache-shiro/src/main/java/com/baeldung/intro/Main.java
similarity index 99%
rename from apache-shiro/src/main/java/com/baeldung/Main.java
rename to apache-shiro/src/main/java/com/baeldung/intro/Main.java
index 99515bb705..fbd3bc7ac7 100644
--- a/apache-shiro/src/main/java/com/baeldung/Main.java
+++ b/apache-shiro/src/main/java/com/baeldung/intro/Main.java
@@ -1,4 +1,4 @@
-package com.baeldung;
+package com.baeldung.intro;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
diff --git a/apache-shiro/src/main/java/com/baeldung/MyCustomRealm.java b/apache-shiro/src/main/java/com/baeldung/intro/MyCustomRealm.java
similarity index 99%
rename from apache-shiro/src/main/java/com/baeldung/MyCustomRealm.java
rename to apache-shiro/src/main/java/com/baeldung/intro/MyCustomRealm.java
index 6d7c01d96e..9d65e37ec4 100644
--- a/apache-shiro/src/main/java/com/baeldung/MyCustomRealm.java
+++ b/apache-shiro/src/main/java/com/baeldung/intro/MyCustomRealm.java
@@ -1,4 +1,4 @@
-package com.baeldung;
+package com.baeldung.intro;
import java.sql.Connection;
import java.sql.SQLException;
diff --git a/apache-shiro/src/main/java/com/baeldung/ShiroSpringApplication.java b/apache-shiro/src/main/java/com/baeldung/intro/ShiroSpringApplication.java
similarity index 80%
rename from apache-shiro/src/main/java/com/baeldung/ShiroSpringApplication.java
rename to apache-shiro/src/main/java/com/baeldung/intro/ShiroSpringApplication.java
index e12d3ebffa..dc288a273b 100644
--- a/apache-shiro/src/main/java/com/baeldung/ShiroSpringApplication.java
+++ b/apache-shiro/src/main/java/com/baeldung/intro/ShiroSpringApplication.java
@@ -1,4 +1,4 @@
-package com.baeldung;
+package com.baeldung.intro;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
@@ -7,12 +7,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.context.annotation.Bean;
/**
* Created by smatt on 21/08/2017.
*/
-@SpringBootApplication
+@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
public class ShiroSpringApplication {
private static final transient Logger log = LoggerFactory.getLogger(ShiroSpringApplication.class);
@@ -29,7 +30,7 @@ public class ShiroSpringApplication {
@Bean
- public ShiroFilterChainDefinition shiroFilterChainDefinition() {
+ public ShiroFilterChainDefinition filterChainDefinition() {
DefaultShiroFilterChainDefinition filter
= new DefaultShiroFilterChainDefinition();
diff --git a/apache-shiro/src/main/java/com/baeldung/controllers/ShiroSpringController.java b/apache-shiro/src/main/java/com/baeldung/intro/controllers/ShiroSpringController.java
similarity index 97%
rename from apache-shiro/src/main/java/com/baeldung/controllers/ShiroSpringController.java
rename to apache-shiro/src/main/java/com/baeldung/intro/controllers/ShiroSpringController.java
index 2713786d71..1605f390a8 100644
--- a/apache-shiro/src/main/java/com/baeldung/controllers/ShiroSpringController.java
+++ b/apache-shiro/src/main/java/com/baeldung/intro/controllers/ShiroSpringController.java
@@ -1,6 +1,5 @@
-package com.baeldung.controllers;
+package com.baeldung.intro.controllers;
-import com.baeldung.models.UserCredentials;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
@@ -13,6 +12,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+import com.baeldung.intro.models.UserCredentials;
+
import javax.servlet.http.HttpServletRequest;
@Controller
diff --git a/apache-shiro/src/main/java/com/baeldung/models/UserCredentials.java b/apache-shiro/src/main/java/com/baeldung/intro/models/UserCredentials.java
similarity index 95%
rename from apache-shiro/src/main/java/com/baeldung/models/UserCredentials.java
rename to apache-shiro/src/main/java/com/baeldung/intro/models/UserCredentials.java
index 51b429046a..6614d07257 100644
--- a/apache-shiro/src/main/java/com/baeldung/models/UserCredentials.java
+++ b/apache-shiro/src/main/java/com/baeldung/intro/models/UserCredentials.java
@@ -1,4 +1,4 @@
-package com.baeldung.models;
+package com.baeldung.intro.models;
public class UserCredentials {
diff --git a/apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/Main.java b/apache-shiro/src/main/java/com/baeldung/permissions/custom/Main.java
similarity index 98%
rename from apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/Main.java
rename to apache-shiro/src/main/java/com/baeldung/permissions/custom/Main.java
index a902a24388..c9ab2b6e37 100644
--- a/apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/Main.java
+++ b/apache-shiro/src/main/java/com/baeldung/permissions/custom/Main.java
@@ -1,4 +1,4 @@
-package com.baeldung.shiro.permissions.custom;
+package com.baeldung.permissions.custom;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
diff --git a/apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/PathPermission.java b/apache-shiro/src/main/java/com/baeldung/permissions/custom/PathPermission.java
similarity index 90%
rename from apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/PathPermission.java
rename to apache-shiro/src/main/java/com/baeldung/permissions/custom/PathPermission.java
index f7dfbda06a..828484087f 100644
--- a/apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/PathPermission.java
+++ b/apache-shiro/src/main/java/com/baeldung/permissions/custom/PathPermission.java
@@ -1,4 +1,4 @@
-package com.baeldung.shiro.permissions.custom;
+package com.baeldung.permissions.custom;
import org.apache.shiro.authz.Permission;
diff --git a/apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/PathPermissionResolver.java b/apache-shiro/src/main/java/com/baeldung/permissions/custom/PathPermissionResolver.java
similarity index 88%
rename from apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/PathPermissionResolver.java
rename to apache-shiro/src/main/java/com/baeldung/permissions/custom/PathPermissionResolver.java
index 4b60d2fbd4..30bdece65f 100644
--- a/apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/PathPermissionResolver.java
+++ b/apache-shiro/src/main/java/com/baeldung/permissions/custom/PathPermissionResolver.java
@@ -1,4 +1,4 @@
-package com.baeldung.shiro.permissions.custom;
+package com.baeldung.permissions.custom;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.permission.PermissionResolver;
diff --git a/apache-shiro/src/main/resources/templates/comparison/home.ftl b/apache-shiro/src/main/resources/templates/comparison/home.ftl
new file mode 100644
index 0000000000..37eb3d1812
--- /dev/null
+++ b/apache-shiro/src/main/resources/templates/comparison/home.ftl
@@ -0,0 +1,19 @@
+
+
+ Home Page
+
+
+Welcome ${username}!
+Role: ${role}
+Permissions
+${permission}
+Admin only
+<#if adminContent??>
+ ${adminContent}
+#if>
+
+
+
+
\ No newline at end of file
diff --git a/apache-shiro/src/main/resources/templates/comparison/index.ftl b/apache-shiro/src/main/resources/templates/comparison/index.ftl
new file mode 100644
index 0000000000..8f35c0af1b
--- /dev/null
+++ b/apache-shiro/src/main/resources/templates/comparison/index.ftl
@@ -0,0 +1,10 @@
+
+
+ Index
+
+
+ Welcome Guest!
+
+ Go to the secured page
+
+
\ No newline at end of file
diff --git a/apache-shiro/src/main/resources/templates/comparison/login.ftl b/apache-shiro/src/main/resources/templates/comparison/login.ftl
new file mode 100644
index 0000000000..7340f47204
--- /dev/null
+++ b/apache-shiro/src/main/resources/templates/comparison/login.ftl
@@ -0,0 +1,25 @@
+
+
+ Login
+
+
+Login
+
+
+
+
\ No newline at end of file
diff --git a/apache-shiro/src/test/java/com/baeldung/comparison/shiro/SpringContextTest.java b/apache-shiro/src/test/java/com/baeldung/comparison/shiro/SpringContextTest.java
new file mode 100644
index 0000000000..0d150d0fad
--- /dev/null
+++ b/apache-shiro/src/test/java/com/baeldung/comparison/shiro/SpringContextTest.java
@@ -0,0 +1,20 @@
+package com.baeldung.comparison.shiro;
+
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import com.baeldung.comparison.shiro.ShiroApplication;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(classes = { ShiroApplication.class })
+public class SpringContextTest {
+
+ @Test
+ public void whenSpringContextIsBootstrapped_thenNoExceptions() {
+
+ }
+
+}
\ No newline at end of file
diff --git a/apache-shiro/src/test/java/com/baeldung/comparison/springsecurity/SpringContextTest.java b/apache-shiro/src/test/java/com/baeldung/comparison/springsecurity/SpringContextTest.java
new file mode 100644
index 0000000000..5044b40e31
--- /dev/null
+++ b/apache-shiro/src/test/java/com/baeldung/comparison/springsecurity/SpringContextTest.java
@@ -0,0 +1,19 @@
+package com.baeldung.comparison.springsecurity;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import com.baeldung.comparison.springsecurity.Application;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(classes = { Application.class })
+public class SpringContextTest {
+
+ @Test
+ public void whenSpringContextIsBootstrapped_thenNoExceptions() {
+
+ }
+
+}
\ No newline at end of file
diff --git a/aws-app-sync/pom.xml b/aws-app-sync/pom.xml
index 700ffad735..5ef150de01 100644
--- a/aws-app-sync/pom.xml
+++ b/aws-app-sync/pom.xml
@@ -46,7 +46,4 @@
-
- 1.8
-
diff --git a/core-java-modules/core-java-collections-3/pom.xml b/core-java-modules/core-java-collections-3/pom.xml
index bd991bfefa..b206cd61d2 100644
--- a/core-java-modules/core-java-collections-3/pom.xml
+++ b/core-java-modules/core-java-collections-3/pom.xml
@@ -27,6 +27,11 @@
${assertj.version}
test
+
+ org.apache.commons
+ commons-lang3
+ 3.10
+
diff --git a/core-java-modules/core-java-collections-3/src/main/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java b/core-java-modules/core-java-collections-3/src/main/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java
new file mode 100644
index 0000000000..f7be99abdc
--- /dev/null
+++ b/core-java-modules/core-java-collections-3/src/main/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToList.java
@@ -0,0 +1,47 @@
+package com.baeldung.collections.iterators;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import com.google.common.primitives.Ints;
+import org.apache.commons.lang3.ArrayUtils;
+
+public class ConvertPrimitivesArrayToList {
+
+ public static void failConvert() {
+ int[] input = new int[]{1,2,3,4};
+ // List inputAsList = Arrays.asList(input);
+ }
+
+ public static List iterateConvert(int[] input) {
+ List output = new ArrayList();
+ for (int value : input) {
+ output.add(value);
+ }
+ return output;
+ }
+
+ public static List streamConvert(int[] input) {
+ List output = Arrays.stream(input).boxed().collect(Collectors.toList());
+ return output;
+ }
+
+ public static List streamConvertIntStream(int[] input) {
+ List output = IntStream.of(input).boxed().collect(Collectors.toList());
+ return output;
+ }
+
+ public static List guavaConvert(int[] input) {
+ List output = Ints.asList(input);
+ return output;
+ }
+
+ public static List apacheCommonConvert(int[] input) {
+ Integer[] outputBoxed = ArrayUtils.toObject(input);
+ List output = Arrays.asList(outputBoxed);
+ return output;
+ }
+
+}
diff --git a/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java b/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java
new file mode 100644
index 0000000000..b773baf7d8
--- /dev/null
+++ b/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/convertarrayprimitives/ConvertPrimitivesArrayToListUnitTest.java
@@ -0,0 +1,38 @@
+package com.baeldung.collections.iterators;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+import com.google.common.primitives.Ints;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ConvertPrimitivesArrayToListUnitTest {
+
+ @Test
+ public void givenArrayWithPrimitives_whenIterativeConvert_thenArrayGetsConverted() {
+ assertEquals(Arrays.asList(1,2,3,4), ConvertPrimitivesArrayToList.iterateConvert(new int[]{1,2,3,4}));
+ }
+
+ @Test
+ public void givenArrayWithPrimitives_whenStreamConvert_thenArrayGetsConverted() {
+ assertEquals(Arrays.asList(1,2,3,4), ConvertPrimitivesArrayToList.streamConvert(new int[]{1,2,3,4}));
+ }
+
+ @Test
+ public void givenArrayWithPrimitives_whenIntStreamConvert_thenArrayGetsConverted() {
+ assertEquals(Arrays.asList(1,2,3,4), ConvertPrimitivesArrayToList.streamConvertIntStream(new int[]{1,2,3,4}));
+ }
+
+ @Test
+ public void givenArrayWithPrimitives_whenGuavaConvert_thenArrayGetsConverted() {
+ assertEquals(Arrays.asList(1,2,3,4), ConvertPrimitivesArrayToList.guavaConvert(new int[]{1,2,3,4}));
+ }
+
+ @Test
+ public void givenArrayWithPrimitives_whenApacheCommonConvert_thenArrayGetsConverted() {
+ assertEquals(Arrays.asList(1,2,3,4), ConvertPrimitivesArrayToList.apacheCommonConvert(new int[]{1,2,3,4}));
+ }
+}
diff --git a/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/localvariables/LocalAndLambda.java b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/localvariables/LocalAndLambda.java
new file mode 100644
index 0000000000..d8e0815797
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/localvariables/LocalAndLambda.java
@@ -0,0 +1,10 @@
+package com.baeldung.concurrent.localvariables;
+
+public class LocalAndLambda {
+ public static void main(String... args) {
+ String text = "";
+ // Un-commenting the next line will break compilation, because text is no longer effectively final
+ // text = "675";
+ new Thread(() -> System.out.println(text)).start();
+ }
+}
diff --git a/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/localvariables/LocalVariables.java b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/localvariables/LocalVariables.java
new file mode 100644
index 0000000000..39cae8da81
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/localvariables/LocalVariables.java
@@ -0,0 +1,20 @@
+package com.baeldung.concurrent.localvariables;
+
+import java.security.SecureRandom;
+
+public class LocalVariables implements Runnable {
+ private int field;
+
+ public static void main(String... args) {
+ LocalVariables target = new LocalVariables();
+ new Thread(target).start();
+ new Thread(target).start();
+ }
+
+ @Override
+ public void run() {
+ field = new SecureRandom().nextInt();
+ int local = new SecureRandom().nextInt();
+ System.out.println(field + " - " + local);
+ }
+}
diff --git a/core-java-modules/core-java-exceptions-2/pom.xml b/core-java-modules/core-java-exceptions-2/pom.xml
index a53bf37b77..4497874640 100644
--- a/core-java-modules/core-java-exceptions-2/pom.xml
+++ b/core-java-modules/core-java-exceptions-2/pom.xml
@@ -33,7 +33,6 @@
http://maven.apache.org
- UTF-8
3.10
3.10.0
diff --git a/core-java-modules/core-java-io-conversions-2/README.md b/core-java-modules/core-java-io-conversions-2/README.md
index 9ce36e7437..b2153b3669 100644
--- a/core-java-modules/core-java-io-conversions-2/README.md
+++ b/core-java-modules/core-java-io-conversions-2/README.md
@@ -6,4 +6,6 @@ This module contains articles about core Java input/output(IO) conversions.
- [Java InputStream to String](https://www.baeldung.com/convert-input-stream-to-string)
- [Java – Write an InputStream to a File](https://www.baeldung.com/convert-input-stream-to-a-file)
- [Converting a BufferedReader to a JSONObject](https://www.baeldung.com/java-bufferedreader-to-jsonobject)
+- [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array)
+- [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv)
- More articles: [[<-- prev]](/core-java-modules/core-java-io-conversions)
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 e9cf3f55d1..b8b5074c7c 100644
--- a/core-java-modules/core-java-io-conversions-2/pom.xml
+++ b/core-java-modules/core-java-io-conversions-2/pom.xml
@@ -26,6 +26,12 @@
json
${json.version}
+
+ com.opencsv
+ opencsv
+ ${opencsv.version}
+ test
+
@@ -40,6 +46,7 @@
20200518
+ 4.1
\ No newline at end of file
diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/csv/WriteCsvFileExample.java b/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java
similarity index 100%
rename from core-java-modules/core-java-io/src/main/java/com/baeldung/csv/WriteCsvFileExample.java
rename to core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java
diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/csv/ReadCSVInArrayUnitTest.java b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/csv/ReadCSVInArrayUnitTest.java
similarity index 92%
rename from core-java-modules/core-java-io/src/test/java/com/baeldung/csv/ReadCSVInArrayUnitTest.java
rename to core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/csv/ReadCSVInArrayUnitTest.java
index 2593eee82b..7e4c1a127f 100644
--- a/core-java-modules/core-java-io/src/test/java/com/baeldung/csv/ReadCSVInArrayUnitTest.java
+++ b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/csv/ReadCSVInArrayUnitTest.java
@@ -1,20 +1,11 @@
package com.baeldung.csv;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Scanner;
-
+import com.opencsv.CSVReader;
import org.junit.Assert;
import org.junit.Test;
-import com.opencsv.CSVReader;
+import java.io.*;
+import java.util.*;
public class ReadCSVInArrayUnitTest {
public static final String COMMA_DELIMITER = ",";
diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/csv/WriteCsvFileExampleUnitTest.java b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/csv/WriteCsvFileExampleUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-io/src/test/java/com/baeldung/csv/WriteCsvFileExampleUnitTest.java
rename to core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/csv/WriteCsvFileExampleUnitTest.java
index 5f4827bc21..fa76472685 100644
--- a/core-java-modules/core-java-io/src/test/java/com/baeldung/csv/WriteCsvFileExampleUnitTest.java
+++ b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/csv/WriteCsvFileExampleUnitTest.java
@@ -1,7 +1,9 @@
package com.baeldung.csv;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileNotFoundException;
@@ -10,10 +12,8 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
public class WriteCsvFileExampleUnitTest {
private static final Logger LOG = LoggerFactory.getLogger(WriteCsvFileExampleUnitTest.class);
diff --git a/core-java-modules/core-java-io/src/test/resources/book.csv b/core-java-modules/core-java-io-conversions-2/src/test/resources/book.csv
similarity index 100%
rename from core-java-modules/core-java-io/src/test/resources/book.csv
rename to core-java-modules/core-java-io-conversions-2/src/test/resources/book.csv
diff --git a/core-java-modules/core-java-io/README.md b/core-java-modules/core-java-io/README.md
index 2c6c3363cb..dd0f4f58c3 100644
--- a/core-java-modules/core-java-io/README.md
+++ b/core-java-modules/core-java-io/README.md
@@ -8,10 +8,8 @@ This module contains articles about core Java input and output (IO)
- [Java – Directory Size](https://www.baeldung.com/java-folder-size)
- [File Size in Java](https://www.baeldung.com/java-file-size)
- [Zipping and Unzipping in Java](https://www.baeldung.com/java-compress-and-uncompress)
-- [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array)
- [How to Get the File Extension of a File in Java](https://www.baeldung.com/java-file-extension)
- [Getting a File’s Mime Type in Java](https://www.baeldung.com/java-file-mime-type)
-- [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv)
- [How to Avoid the Java FileNotFoundException When Loading Resources](https://www.baeldung.com/java-classpath-resource-cannot-be-opened)
- [Create a Directory in Java](https://www.baeldung.com/java-create-directory)
- [[More -->]](/core-java-modules/core-java-io-2)
diff --git a/core-java-modules/core-java-io/pom.xml b/core-java-modules/core-java-io/pom.xml
index ccfb57e909..0968536e65 100644
--- a/core-java-modules/core-java-io/pom.xml
+++ b/core-java-modules/core-java-io/pom.xml
@@ -29,12 +29,6 @@
${hsqldb.version}
runtime
-
- com.opencsv
- opencsv
- ${opencsv.version}
- test
-
org.apache.tika
@@ -142,8 +136,6 @@
-
- 4.1
3.6.1
diff --git a/core-java-modules/core-java-jvm-2/README.md b/core-java-modules/core-java-jvm-2/README.md
index 4925a268a9..1aa69e7e63 100644
--- a/core-java-modules/core-java-jvm-2/README.md
+++ b/core-java-modules/core-java-jvm-2/README.md
@@ -2,4 +2,10 @@
This module contains articles about working with the Java Virtual Machine (JVM).
-### Relevant Articles:
\ No newline at end of file
+### Relevant Articles:
+
+- [Memory Layout of Objects in Java](https://www.baeldung.com/java-memory-layout)
+- [Measuring Object Sizes in the JVM](https://www.baeldung.com/jvm-measuring-object-sizes)
+- [Adding Shutdown Hooks for JVM Applications](https://www.baeldung.com/jvm-shutdown-hooks)
+- [boolean and boolean[] Memory Layout in the JVM](https://www.baeldung.com/jvm-boolean-memory-layout)
+- More articles: [[<-- prev]](/core-java-modules/core-java-jvm)
\ No newline at end of file
diff --git a/core-java-modules/core-java-jvm/src/test/java/com/baeldung/boolsize/BooleanSizeUnitTest.java b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/boolsize/BooleanSizeUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-jvm/src/test/java/com/baeldung/boolsize/BooleanSizeUnitTest.java
rename to core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/boolsize/BooleanSizeUnitTest.java
diff --git a/core-java-modules/core-java-jvm/src/test/java/com/baeldung/boolsize/BooleanWrapper.java b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/boolsize/BooleanWrapper.java
similarity index 100%
rename from core-java-modules/core-java-jvm/src/test/java/com/baeldung/boolsize/BooleanWrapper.java
rename to core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/boolsize/BooleanWrapper.java
diff --git a/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/memaddress/MemoryAddressUnitTest.java b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/memaddress/MemoryAddressUnitTest.java
new file mode 100644
index 0000000000..5d4ba0a129
--- /dev/null
+++ b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/memaddress/MemoryAddressUnitTest.java
@@ -0,0 +1,24 @@
+package com.baeldung.memaddress;
+
+import org.junit.Test;
+import org.openjdk.jol.vm.VM;
+
+public class MemoryAddressUnitTest {
+
+ @Test
+ public void printTheMemoryAddress() {
+ String answer = "42";
+
+ System.out.println("The memory address is " + VM.current().addressOf(answer));
+ }
+
+ @Test
+ public void identityHashCodeAndMemoryAddress() {
+ Object obj = new Object();
+
+ System.out.println("Memory address: " + VM.current().addressOf(obj));
+ System.out.println("hashCode: " + obj.hashCode());
+ System.out.println("hashCode: " + System.identityHashCode(obj));
+ System.out.println("toString: " + obj);
+ }
+}
diff --git a/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/Course.java b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/Course.java
new file mode 100644
index 0000000000..cbe2eed47f
--- /dev/null
+++ b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/Course.java
@@ -0,0 +1,10 @@
+package com.baeldung.objectsize;
+
+public class Course {
+
+ private String name;
+
+ public Course(String name) {
+ this.name = name;
+ }
+}
diff --git a/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/InstrumentedSize.java b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/InstrumentedSize.java
new file mode 100644
index 0000000000..54177caf30
--- /dev/null
+++ b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/InstrumentedSize.java
@@ -0,0 +1,11 @@
+package com.baeldung.objectsize;
+
+public class InstrumentedSize {
+
+ public static void main(String[] args) {
+ String ds = "Data Structures";
+ Course course = new Course(ds);
+
+ System.out.println(ObjectSizeCalculator.sizeOf(course));
+ }
+}
diff --git a/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/MANIFEST.MF b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/MANIFEST.MF
new file mode 100644
index 0000000000..5366581b2f
--- /dev/null
+++ b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/MANIFEST.MF
@@ -0,0 +1 @@
+Premain-Class: com.baeldung.objectsize.ObjectSizeCalculator
diff --git a/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/ObjectSizeCalculator.java b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/ObjectSizeCalculator.java
new file mode 100644
index 0000000000..9c1e4c96a0
--- /dev/null
+++ b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/ObjectSizeCalculator.java
@@ -0,0 +1,16 @@
+package com.baeldung.objectsize;
+
+import java.lang.instrument.Instrumentation;
+
+public class ObjectSizeCalculator {
+
+ private static Instrumentation instrumentation;
+
+ public static void premain(String args, Instrumentation inst) {
+ instrumentation = inst;
+ }
+
+ public static long sizeOf(Object o) {
+ return instrumentation.getObjectSize(o);
+ }
+}
diff --git a/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/ObjectSizeUnitTest.java b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/ObjectSizeUnitTest.java
new file mode 100644
index 0000000000..f2ba748d84
--- /dev/null
+++ b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/ObjectSizeUnitTest.java
@@ -0,0 +1,40 @@
+package com.baeldung.objectsize;
+
+import org.junit.Test;
+import org.openjdk.jol.info.ClassLayout;
+import org.openjdk.jol.info.GraphLayout;
+import org.openjdk.jol.vm.VM;
+
+public class ObjectSizeUnitTest {
+
+ @Test
+ public void printingTheVMDetails() {
+ System.out.println(VM.current().details());
+ }
+
+ @Test
+ public void printingTheProfClassLayout() {
+ System.out.println(ClassLayout.parseClass(Professor.class).toPrintable());
+ }
+
+ @Test
+ public void printingTheCourseClassLayout() {
+ System.out.println(ClassLayout.parseClass(Course.class).toPrintable());
+ }
+
+ @Test
+ public void printingACourseInstanceLayout() {
+ String ds = "Data Structures";
+ Course course = new Course(ds);
+
+ System.out.println("The shallow size is :" + VM.current().sizeOf(course));
+
+ System.out.println(ClassLayout.parseInstance(course).toPrintable());
+ System.out.println(ClassLayout.parseInstance(ds).toPrintable());
+ System.out.println(ClassLayout.parseInstance(ds.toCharArray()).toPrintable());
+
+ System.out.println(GraphLayout.parseInstance(course).totalSize());
+ System.out.println(GraphLayout.parseInstance(course).toFootprint());
+ System.out.println(GraphLayout.parseInstance(course).toPrintable());
+ }
+}
diff --git a/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/Professor.java b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/Professor.java
new file mode 100644
index 0000000000..6cd421f273
--- /dev/null
+++ b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/objectsize/Professor.java
@@ -0,0 +1,24 @@
+package com.baeldung.objectsize;
+
+import java.time.LocalDate;
+import java.util.List;
+
+public class Professor {
+
+ private String name;
+ private boolean tenured;
+ private List courses;
+ private int level;
+ private LocalDate birthDay;
+ private double lastEvaluation;
+
+ public Professor(String name, boolean tenured, List courses,
+ int level, LocalDate birthDay, double lastEvaluation) {
+ this.name = name;
+ this.tenured = tenured;
+ this.courses = courses;
+ this.level = level;
+ this.birthDay = birthDay;
+ this.lastEvaluation = lastEvaluation;
+ }
+}
diff --git a/core-java-modules/core-java-jvm/src/test/java/com/baeldung/shutdownhook/ShutdownHookUnitTest.java b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/shutdownhook/ShutdownHookUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-jvm/src/test/java/com/baeldung/shutdownhook/ShutdownHookUnitTest.java
rename to core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/shutdownhook/ShutdownHookUnitTest.java
diff --git a/core-java-modules/core-java-jvm/README.md b/core-java-modules/core-java-jvm/README.md
index 7471d7d902..431cf021c8 100644
--- a/core-java-modules/core-java-jvm/README.md
+++ b/core-java-modules/core-java-jvm/README.md
@@ -11,8 +11,7 @@ This module contains articles about working with the Java Virtual Machine (JVM).
- [A Guide to System.exit()](https://www.baeldung.com/java-system-exit)
- [Guide to System.gc()](https://www.baeldung.com/java-system-gc)
- [Runtime.getRuntime().halt() vs System.exit() in Java](https://www.baeldung.com/java-runtime-halt-vs-system-exit)
-- [Adding Shutdown Hooks for JVM Applications](https://www.baeldung.com/jvm-shutdown-hooks)
- [How to Get the Size of an Object in Java](http://www.baeldung.com/java-size-of-object)
- [What Causes java.lang.OutOfMemoryError: unable to create new native thread](https://www.baeldung.com/java-outofmemoryerror-unable-to-create-new-native-thread)
- [View Bytecode of a Class File in Java](https://www.baeldung.com/java-class-view-bytecode)
-- [boolean and boolean[] Memory Layout in the JVM](https://www.baeldung.com/jvm-boolean-memory-layout)
+- More articles: [[next -->]](/core-java-modules/core-java-jvm-2)
diff --git a/core-java-modules/core-java-lang-2/README.md b/core-java-modules/core-java-lang-2/README.md
index 635746251f..c043d29811 100644
--- a/core-java-modules/core-java-lang-2/README.md
+++ b/core-java-modules/core-java-lang-2/README.md
@@ -13,4 +13,4 @@ This module contains articles about core features in the Java language
- [Comparing Long Values in Java](https://www.baeldung.com/java-compare-long-values)
- [Comparing Objects in Java](https://www.baeldung.com/java-comparing-objects)
- [Casting int to Enum in Java](https://www.baeldung.com/java-cast-int-to-enum)
-- [[<-- Prev]](/core-java-modules/core-java-lang)
+[[ <-- Prev]](/core-java-modules/core-java-lang)[[Next --> ]](/core-java-modules/core-java-lang-3)
diff --git a/core-java-modules/core-java-lang-3/README.md b/core-java-modules/core-java-lang-3/README.md
new file mode 100644
index 0000000000..f496b74bfb
--- /dev/null
+++ b/core-java-modules/core-java-lang-3/README.md
@@ -0,0 +1,5 @@
+## Core Java Lang (Part 3)
+
+This module contains articles about core features in the Java language
+
+- [[<-- Prev]](/core-java-modules/core-java-lang-2)
diff --git a/core-java-modules/core-java-lang-3/pom.xml b/core-java-modules/core-java-lang-3/pom.xml
new file mode 100644
index 0000000000..2a2856a80a
--- /dev/null
+++ b/core-java-modules/core-java-lang-3/pom.xml
@@ -0,0 +1,42 @@
+
+
+ 4.0.0
+ core-java-lang-3
+ 0.1.0-SNAPSHOT
+ core-java-lang-3
+ jar
+
+
+ com.baeldung.core-java-modules
+ core-java-modules
+ 0.0.1-SNAPSHOT
+ ../
+
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+
+
+ core-java-lang-3
+
+
+ src/main/resources
+ true
+
+
+
+
+
+ 3.12.2
+
+
+
diff --git a/core-java-modules/core-java-lang-2/src/main/java/com/baeldung/isinstancevsisassignablefrom/IsoscelesTriangle.java b/core-java-modules/core-java-lang-3/src/main/java/com/baeldung/isinstancevsisassignablefrom/IsoscelesTriangle.java
similarity index 100%
rename from core-java-modules/core-java-lang-2/src/main/java/com/baeldung/isinstancevsisassignablefrom/IsoscelesTriangle.java
rename to core-java-modules/core-java-lang-3/src/main/java/com/baeldung/isinstancevsisassignablefrom/IsoscelesTriangle.java
diff --git a/core-java-modules/core-java-lang-2/src/main/java/com/baeldung/isinstancevsisassignablefrom/Shape.java b/core-java-modules/core-java-lang-3/src/main/java/com/baeldung/isinstancevsisassignablefrom/Shape.java
similarity index 100%
rename from core-java-modules/core-java-lang-2/src/main/java/com/baeldung/isinstancevsisassignablefrom/Shape.java
rename to core-java-modules/core-java-lang-3/src/main/java/com/baeldung/isinstancevsisassignablefrom/Shape.java
diff --git a/core-java-modules/core-java-lang-2/src/main/java/com/baeldung/isinstancevsisassignablefrom/Triangle.java b/core-java-modules/core-java-lang-3/src/main/java/com/baeldung/isinstancevsisassignablefrom/Triangle.java
similarity index 100%
rename from core-java-modules/core-java-lang-2/src/main/java/com/baeldung/isinstancevsisassignablefrom/Triangle.java
rename to core-java-modules/core-java-lang-3/src/main/java/com/baeldung/isinstancevsisassignablefrom/Triangle.java
diff --git a/core-java-modules/core-java-lang-2/src/test/java/com/baeldung/isinstancevsisassignablefrom/IsInstanceIsAssignableFromUnitTest.java b/core-java-modules/core-java-lang-3/src/test/java/com/baeldung/isinstancevsisassignablefrom/IsInstanceIsAssignableFromUnitTest.java
similarity index 100%
rename from core-java-modules/core-java-lang-2/src/test/java/com/baeldung/isinstancevsisassignablefrom/IsInstanceIsAssignableFromUnitTest.java
rename to core-java-modules/core-java-lang-3/src/test/java/com/baeldung/isinstancevsisassignablefrom/IsInstanceIsAssignableFromUnitTest.java
diff --git a/core-java-modules/core-java-lang-3/src/test/java/com/baeldung/stringtoboolean/StringToBooleanUnitTest.java b/core-java-modules/core-java-lang-3/src/test/java/com/baeldung/stringtoboolean/StringToBooleanUnitTest.java
new file mode 100644
index 0000000000..8b10d78fe3
--- /dev/null
+++ b/core-java-modules/core-java-lang-3/src/test/java/com/baeldung/stringtoboolean/StringToBooleanUnitTest.java
@@ -0,0 +1,30 @@
+package com.baeldung.stringtoboolean;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+public class StringToBooleanUnitTest {
+
+ @Test
+ public void givenStringTrue_whenUsingParseBoolean_thenTrue() {
+ assertThat(Boolean.parseBoolean("true")).isTrue();
+ }
+
+ @Test
+ public void givenStringTrue_whenUsingValueOf_thenTrue() {
+ assertThat(Boolean.valueOf("true")).isTrue();
+ }
+
+ @Test
+ public void givenStringTrue_whenUsingGetBoolean_thenFalse() {
+ assertThat(Boolean.getBoolean("true")).isFalse();
+ }
+
+ @Test
+ public void givenSystemProperty_whenUsingGetBoolean_thenTrue() {
+ System.setProperty("CODING_IS_FUN", "true");
+
+ assertThat(Boolean.getBoolean("CODING_IS_FUN")).isTrue();
+ }
+}
diff --git a/core-java-modules/core-java-lang/README.md b/core-java-modules/core-java-lang/README.md
index 9166b93b7f..963a1e623e 100644
--- a/core-java-modules/core-java-lang/README.md
+++ b/core-java-modules/core-java-lang/README.md
@@ -13,4 +13,5 @@ This module contains articles about core features in the Java language
- [Retrieving a Class Name in Java](https://www.baeldung.com/java-class-name)
- [The Java continue and break Keywords](https://www.baeldung.com/java-continue-and-break)
- [Infinite Loops in Java](https://www.baeldung.com/infinite-loops-java)
-- [[More --> ]](/core-java-modules/core-java-lang-2)
+
+[[Next --> ]](/core-java-modules/core-java-lang-2)
diff --git a/core-java-modules/core-java-reflection-2/pom.xml b/core-java-modules/core-java-reflection-2/pom.xml
new file mode 100644
index 0000000000..ea76ee8c98
--- /dev/null
+++ b/core-java-modules/core-java-reflection-2/pom.xml
@@ -0,0 +1,44 @@
+
+
+ 4.0.0
+ core-java-reflection-2
+ 0.1.0-SNAPSHOT
+ core-java-reflection-2
+ jar
+
+ com.baeldung.core-java-modules
+ core-java-modules
+ 0.0.1-SNAPSHOT
+ ../
+
+
+
+ core-java-reflection-2
+
+
+ src/main/resources
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${source.version}
+ ${target.version}
+ -parameters
+
+
+
+
+
+
+ 3.8.0
+ 1.8
+ 1.8
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/access/privatefields/Person.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/access/privatefields/Person.java
new file mode 100755
index 0000000000..4e2f0fc0cc
--- /dev/null
+++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/access/privatefields/Person.java
@@ -0,0 +1,87 @@
+package com.baeldung.reflection.access.privatefields;
+
+public class Person {
+
+ private String name = "John";
+ private byte age = 30;
+ private short uidNumber = 5555;
+ private int pinCode = 452002;
+ private long contactNumber = 123456789L;
+ private float height = 6.1242f;
+ private double weight = 75.2564;
+ private char gender = 'M';
+ private boolean active = true;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public byte getAge() {
+ return age;
+ }
+
+ public void setAge(byte age) {
+ this.age = age;
+ }
+
+ public short getUidNumber() {
+ return uidNumber;
+ }
+
+ public void setUidNumber(short uidNumber) {
+ this.uidNumber = uidNumber;
+ }
+
+ public int getPinCode() {
+ return pinCode;
+ }
+
+ public void setPinCode(int pinCode) {
+ this.pinCode = pinCode;
+ }
+
+ public long getContactNumber() {
+ return contactNumber;
+ }
+
+ public void setContactNumber(long contactNumber) {
+ this.contactNumber = contactNumber;
+ }
+
+ public float getHeight() {
+ return height;
+ }
+
+ public void setHeight(float height) {
+ this.height = height;
+ }
+
+ public double getWeight() {
+ return weight;
+ }
+
+ public void setWeight(double weight) {
+ this.weight = weight;
+ }
+
+ public char getGender() {
+ return gender;
+ }
+
+ public void setGender(char gender) {
+ this.gender = gender;
+ }
+
+ public boolean isActive() {
+ return active;
+ }
+
+ public void setActive(boolean active) {
+ this.active = active;
+ }
+
+}
diff --git a/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/access/privatefields/AccessPrivateFieldsUnitTest.java b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/access/privatefields/AccessPrivateFieldsUnitTest.java
new file mode 100644
index 0000000000..49e1b917b1
--- /dev/null
+++ b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/access/privatefields/AccessPrivateFieldsUnitTest.java
@@ -0,0 +1,168 @@
+package com.baeldung.reflection.access.privatefields;
+
+import java.lang.reflect.Field;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class AccessPrivateFieldsUnitTest {
+
+ @Test
+ public void whenGetIntegerFields_thenSuccess() throws Exception {
+ Person person = new Person();
+
+ Field ageField = person.getClass()
+ .getDeclaredField("age");
+ ageField.setAccessible(true);
+
+ byte age = ageField.getByte(person);
+ Assertions.assertEquals(30, age);
+
+ Field uidNumberField = person.getClass()
+ .getDeclaredField("uidNumber");
+ uidNumberField.setAccessible(true);
+
+ short uidNumber = uidNumberField.getShort(person);
+ Assertions.assertEquals(5555, uidNumber);
+
+ Field pinCodeField = person.getClass()
+ .getDeclaredField("pinCode");
+ pinCodeField.setAccessible(true);
+
+ int pinCode = pinCodeField.getInt(person);
+ Assertions.assertEquals(452002, pinCode);
+
+ Field contactNumberField = person.getClass()
+ .getDeclaredField("contactNumber");
+ contactNumberField.setAccessible(true);
+
+ long contactNumber = contactNumberField.getLong(person);
+ Assertions.assertEquals(123456789L, contactNumber);
+
+ }
+
+ @Test
+ public void whenDoAutoboxing_thenSuccess() throws Exception {
+ Person person = new Person();
+
+ Field pinCodeField = person.getClass()
+ .getDeclaredField("pinCode");
+ pinCodeField.setAccessible(true);
+
+ Integer pinCode = pinCodeField.getInt(person);
+ Assertions.assertEquals(452002, pinCode);
+ }
+
+ @Test
+ public void whenDoWidening_thenSuccess() throws Exception {
+ Person person = new Person();
+
+ Field pinCodeField = person.getClass()
+ .getDeclaredField("pinCode");
+ pinCodeField.setAccessible(true);
+
+ Long pinCode = pinCodeField.getLong(person);
+ Assertions.assertEquals(452002L, pinCode);
+ }
+
+ @Test
+ public void whenGetFloatingTypeFields_thenSuccess() throws Exception {
+ Person person = new Person();
+
+ Field heightField = person.getClass()
+ .getDeclaredField("height");
+ heightField.setAccessible(true);
+
+ float height = heightField.getFloat(person);
+ Assertions.assertEquals(6.1242f, height);
+
+ Field weightField = person.getClass()
+ .getDeclaredField("weight");
+ weightField.setAccessible(true);
+
+ double weight = weightField.getDouble(person);
+ Assertions.assertEquals(75.2564, weight);
+ }
+
+ @Test
+ public void whenGetCharacterFields_thenSuccess() throws Exception {
+ Person person = new Person();
+
+ Field genderField = person.getClass()
+ .getDeclaredField("gender");
+ genderField.setAccessible(true);
+
+ char gender = genderField.getChar(person);
+ Assertions.assertEquals('M', gender);
+ }
+
+ @Test
+ public void whenGetBooleanFields_thenSuccess() throws Exception {
+ Person person = new Person();
+
+ Field activeField = person.getClass()
+ .getDeclaredField("active");
+ activeField.setAccessible(true);
+
+ boolean active = activeField.getBoolean(person);
+ Assertions.assertTrue(active);
+ }
+
+ @Test
+ public void whenGetObjectFields_thenSuccess() throws Exception {
+ Person person = new Person();
+
+ Field nameField = person.getClass()
+ .getDeclaredField("name");
+ nameField.setAccessible(true);
+
+ String name = (String) nameField.get(person);
+ Assertions.assertEquals("John", name);
+ }
+
+ @Test
+ public void givenInt_whenGetStringField_thenIllegalArgumentException() throws Exception {
+ Person person = new Person();
+ Field nameField = person.getClass()
+ .getDeclaredField("name");
+ nameField.setAccessible(true);
+
+ Assertions.assertThrows(IllegalArgumentException.class, () -> nameField.getInt(person));
+ }
+
+ @Test
+ public void givenInt_whenGetLongField_thenIllegalArgumentException() throws Exception {
+ Person person = new Person();
+ Field contactNumberField = person.getClass()
+ .getDeclaredField("contactNumber");
+ contactNumberField.setAccessible(true);
+
+ Assertions.assertThrows(IllegalArgumentException.class, () -> contactNumberField.getInt(person));
+ }
+
+ @Test
+ public void whenFieldNotSetAccessible_thenIllegalAccessException() throws Exception {
+ Person person = new Person();
+ Field nameField = person.getClass()
+ .getDeclaredField("name");
+
+ Assertions.assertThrows(IllegalAccessException.class, () -> nameField.get(person));
+ }
+
+ @Test
+ public void whenAccessingWrongProperty_thenNoSuchFieldException() throws Exception {
+ Person person = new Person();
+
+ Assertions.assertThrows(NoSuchFieldException.class, () -> person.getClass()
+ .getDeclaredField("firstName"));
+ }
+
+ @Test
+ public void whenAccessingNullProperty_thenNullPointerException() throws Exception {
+ Person person = new Person();
+
+ Assertions.assertThrows(NullPointerException.class, () -> person.getClass()
+ .getDeclaredField(null));
+ }
+
+}
diff --git a/core-java-modules/core-java-security-2/src/main/java/com/baeldung/pem/JavaSecurityPemUtils.java b/core-java-modules/core-java-security-2/src/main/java/com/baeldung/pem/JavaSecurityPemUtils.java
new file mode 100644
index 0000000000..2697072e27
--- /dev/null
+++ b/core-java-modules/core-java-security-2/src/main/java/com/baeldung/pem/JavaSecurityPemUtils.java
@@ -0,0 +1,48 @@
+package com.baeldung.pem;
+
+import org.apache.commons.codec.binary.Base64;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+public class JavaSecurityPemUtils {
+
+ public static RSAPrivateKey readPKCS8PrivateKey(File file) throws GeneralSecurityException, IOException {
+ String key = new String(Files.readAllBytes(file.toPath()), Charset.defaultCharset());
+
+ String privateKeyPEM = key
+ .replace("-----BEGIN PRIVATE KEY-----", "")
+ .replaceAll(System.lineSeparator(), "")
+ .replace("-----END PRIVATE KEY-----", "");
+
+ byte[] encoded = Base64.decodeBase64(privateKeyPEM);
+
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
+ return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
+ }
+
+ public static RSAPublicKey readX509PublicKey(File file) throws GeneralSecurityException, IOException {
+ String key = new String(Files.readAllBytes(file.toPath()), Charset.defaultCharset());
+
+ String publicKeyPEM = key
+ .replace("-----BEGIN PUBLIC KEY-----", "")
+ .replaceAll(System.lineSeparator(), "")
+ .replace("-----END PUBLIC KEY-----", "");
+
+ byte[] encoded = Base64.decodeBase64(publicKeyPEM);
+
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
+ return (RSAPublicKey) keyFactory.generatePublic(keySpec);
+ }
+
+}
diff --git a/core-java-modules/core-java-security-2/src/main/resources/pem/private-key-pkcs8.pem b/core-java-modules/core-java-security-2/src/main/resources/pem/private-key-pkcs8.pem
new file mode 100644
index 0000000000..903f903d7a
--- /dev/null
+++ b/core-java-modules/core-java-security-2/src/main/resources/pem/private-key-pkcs8.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCyO0YiTxLEP44S
+IGk/b9MlQAXS6nC4oYyTrAfxHCi/zxW/MmtWbY0K2JxOTkVSD5QbmvwkCutXi0k9
+EdDK+orAXg2KSy686O/cfIh/iho6FmNPyEOd7UF+/5wWpknrUaTQyMA2H9Pmr2/E
+RH/tN1Q0cqmhFX41WUo3lsRT81DkVCNVeJx+zDGHpjp+XY8gWpPYJ+MP4WQE9TWJ
+P2rIlgcDfwhG/A21yK0WAJ5nB0Y+jGI8+HVYdjxXGlRUG//YmxS2sH+sAhsapmjE
+Aha+KMk972jVNjdWU7OT0BJnUB5q286Kv6INUnk6kqYufNzjpCAY9SyMjKjpKN71
+3Gka2gZBAgMBAAECggEAFlPam12wiik0EQ1CYhIOL3JvyFZaPKbwR2ebrxbJ/A1j
+OgqE69TZgGxWWHDxui/9a9/kildb2CG40Q+0SllMnICrzZFRj5TWx5ZKOz//vRsk
+4c/CuLwKInC/Cw9V30bhEM61VZJzJ0j/BWVXaU4vHEro+ScKIoDHDWOzwJiQn6m9
+C+Ti5lFpax3hx8ZrgPqmBCFYNvErrWkOr7mCYl0jS+E22c68yn8+LjdlF1LWUa6N
+zutk3MPj5UwEyR0h7EZReCeGkPTMQNyOBhDcmAtlEno4fjtZzUDHRjh8/QpG1Mz/
+alavvrkjswc1DmRUOdgiYu+Waxan5noBhxEAvd/hyQKBgQDjYJD0n+m0tUrpNtX0
++mdzHstClHrpx5oNxs4sIBjCoCwEXaSpeY8+JxCdnZ6n29mLZLq/wPXxZ3EJcOSZ
+PYUvZJfV/IUvoLPFbtT3ILzDTcAAeHj2GAOpzYP8J1JSFsc78ZjKMF1XeNjXcq8T
+XNXoWfY7N/fShoycVeG42JJCFwKBgQDIqvHL0QfJ8r6yM8Efj7Zq6Wa4C9okORes
+8UVWfBoO6UOWvpK+D9IjnaEisJcnEalwNi8/eKudR9hfvmzATV+t3YJIgktto3TT
+BWLsEyniNU4vSTl7GPBrV2xabWogbChlt7TXUfw6YogaBKm43snYXBbJFc+NcpQH
+ONB5igppZwKBgGDyYHvc3wGsttb/CXTde1RLUfD+a/XXpCixlmCcAtKhBoOKBdY4
+vUmL0HrTpLz/cR8NAM8XkAWwzDJxTxbDc1EEu/SCKatoAp5wph8Ed1dyhCXvN+v9
+yzoQJXFStrfHfIVjenji7DmKjjI2dM11rMLX8LPJJkI+Gh/iQk7VEG9bAoGAH/aS
+sztleTZwR6RUw7k5fkgVM4W3xoNNkR+RQthbsjpXqMBMUXflqgSmsQbd3LxEd/o5
+hmurMk9KWN3VJsBsWB5rbS9L4nfh2OcHvcDDsCN7g66vODtduEthl/nLqMRxnton
+NRD7EzW0pihN/IOINS1d98PAnrA8gfX7xxBE3ksCgYBvoljHGjvy3bPJ++vDGKJK
+y6JuEeRVzgdPXEb60uU+BR7kdh+MMsZLmgfFTgza3R+/xeZcC/cuOPsbzeooRQi/
+9NpKwSCXjVNk9nglUWBoPRh4uYqrArWn+HoR7MI/BxeRJm5e1+ii8P19Y9joX5s0
+Q3OLn8GeH56ClJmNiWDhsA==
+-----END PRIVATE KEY-----
\ No newline at end of file
diff --git a/core-java-modules/core-java-security-2/src/main/resources/pem/public-key.pem b/core-java-modules/core-java-security-2/src/main/resources/pem/public-key.pem
new file mode 100644
index 0000000000..54262dca03
--- /dev/null
+++ b/core-java-modules/core-java-security-2/src/main/resources/pem/public-key.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjtGIk8SxD+OEiBpP2/T
+JUAF0upwuKGMk6wH8Rwov88VvzJrVm2NCticTk5FUg+UG5r8JArrV4tJPRHQyvqK
+wF4NiksuvOjv3HyIf4oaOhZjT8hDne1Bfv+cFqZJ61Gk0MjANh/T5q9vxER/7TdU
+NHKpoRV+NVlKN5bEU/NQ5FQjVXicfswxh6Y6fl2PIFqT2CfjD+FkBPU1iT9qyJYH
+A38IRvwNtcitFgCeZwdGPoxiPPh1WHY8VxpUVBv/2JsUtrB/rAIbGqZoxAIWvijJ
+Pe9o1TY3VlOzk9ASZ1AeatvOir+iDVJ5OpKmLnzc46QgGPUsjIyo6Sje9dxpGtoG
+QQIDAQAB
+-----END PUBLIC KEY-----
\ No newline at end of file
diff --git a/core-java-modules/core-java-security-2/src/test/java/com/baeldung/pem/JavaSecurityPemUtilsUnitTest.java b/core-java-modules/core-java-security-2/src/test/java/com/baeldung/pem/JavaSecurityPemUtilsUnitTest.java
new file mode 100644
index 0000000000..9c6db9c122
--- /dev/null
+++ b/core-java-modules/core-java-security-2/src/test/java/com/baeldung/pem/JavaSecurityPemUtilsUnitTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.pem;
+
+
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class JavaSecurityPemUtilsUnitTest {
+
+ @Test
+ public void whenReadPublicKeyFromPEMFile_thenSuccess() throws Exception {
+ File pemFile = new File(JavaSecurityPemUtilsUnitTest.class.getResource("/pem/public-key.pem").getFile());
+
+ RSAPublicKey publicKey = JavaSecurityPemUtils.readX509PublicKey(pemFile);
+
+ assertEquals("X.509", publicKey.getFormat());
+ assertEquals("RSA", publicKey.getAlgorithm());
+ }
+
+ @Test
+ public void whenReadPrivateKeyFromPEMFile_thenSuccess() throws Exception {
+ File pemFile = new File(JavaSecurityPemUtilsUnitTest.class.getResource("/pem/private-key-pkcs8.pem").getFile());
+
+ RSAPrivateKey privateKey = JavaSecurityPemUtils.readPKCS8PrivateKey(pemFile);
+
+ assertEquals("PKCS#8", privateKey.getFormat());
+ assertEquals("RSA", privateKey.getAlgorithm());
+ }
+}
diff --git a/core-java-modules/core-java-streams/README.md b/core-java-modules/core-java-streams/README.md
index 135e136fee..b950325e40 100644
--- a/core-java-modules/core-java-streams/README.md
+++ b/core-java-modules/core-java-streams/README.md
@@ -9,7 +9,6 @@ This module contains articles about the Stream API in Java.
- [Iterable to Stream in Java](https://www.baeldung.com/java-iterable-to-stream)
- [How to Iterate Over a Stream With Indices](https://www.baeldung.com/java-stream-indices)
- [Stream Ordering in Java](https://www.baeldung.com/java-stream-ordering)
-- [Introduction to Protonpack](https://www.baeldung.com/java-protonpack)
- [Java Stream Filter with Lambda Expression](https://www.baeldung.com/java-stream-filter-lambda)
- [Counting Matches on a Stream Filter](https://www.baeldung.com/java-stream-filter-count)
- [Summing Numbers with Java Streams](https://www.baeldung.com/java-stream-sum)
diff --git a/core-java-modules/core-java-string-operations-2/README.md b/core-java-modules/core-java-string-operations-2/README.md
index cafb3b9017..d66515d372 100644
--- a/core-java-modules/core-java-string-operations-2/README.md
+++ b/core-java-modules/core-java-string-operations-2/README.md
@@ -10,7 +10,6 @@ This module contains articles about string operations.
- [Java String equalsIgnoreCase()](https://www.baeldung.com/java-string-equalsignorecase)
- [Case-Insensitive String Matching in Java](https://www.baeldung.com/java-case-insensitive-string-matching)
- [L-Trim and R-Trim Alternatives in Java](https://www.baeldung.com/java-trim-alternatives)
-- [Java Convert PDF to Base64](https://www.baeldung.com/java-convert-pdf-to-base64)
- [Encode a String to UTF-8 in Java](https://www.baeldung.com/java-string-encode-utf-8)
- [Guide to Character Encoding](https://www.baeldung.com/java-char-encoding)
- [Convert Hex to ASCII in Java](https://www.baeldung.com/java-convert-hex-to-ascii) #remove additional readme file
diff --git a/core-java-modules/core-java-string-operations-3/pom.xml b/core-java-modules/core-java-string-operations-3/pom.xml
new file mode 100644
index 0000000000..5edff0e090
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-3/pom.xml
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+ core-java-string-operations-3
+ 0.1.0-SNAPSHOT
+ core-java-string-operations-3
+ jar
+
+ com.baeldung.core-java-modules
+ core-java-modules
+ 0.0.1-SNAPSHOT
+ ../
+
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+ org.apache.maven
+ maven-artifact
+ ${maven-artifact.version}
+
+
+ org.gradle
+ gradle-core
+ ${gradle-core.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ ${jackson-core.version}
+
+
+ com.vdurmont
+ semver4j
+ ${semver4j.version}
+
+
+
+
+ 3.6.1
+ 3.6.3
+ 6.1.1
+ 2.11.1
+ 3.1.0
+
+
+
+
+ gradle-repo
+ https://repo.gradle.org/gradle/libs-releases-local/
+
+
+
diff --git a/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/versioncomparison/VersionCompare.java b/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/versioncomparison/VersionCompare.java
new file mode 100644
index 0000000000..5a1663e50d
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/versioncomparison/VersionCompare.java
@@ -0,0 +1,25 @@
+package com.baeldung.versioncomparison;
+
+public class VersionCompare {
+
+ public static int compareVersions(String version1, String version2) {
+ int comparisonResult = 0;
+
+ String[] version1Splits = version1.split("\\.");
+ String[] version2Splits = version2.split("\\.");
+
+ int maxLengthOfVersionSplits = Math.max(version1Splits.length, version2Splits.length);
+ for (int i = 0; i < maxLengthOfVersionSplits; i++){
+ Integer v1 = i < version1Splits.length ? Integer.parseInt(version1Splits[i]) : 0;
+ Integer v2 = i < version2Splits.length ? Integer.parseInt(version2Splits[i]) : 0;
+ int compare = v1.compareTo(v2);
+ if (compare != 0) {
+ comparisonResult = compare;
+ break;
+ }
+ }
+
+ return comparisonResult;
+ }
+
+}
diff --git a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/versioncomparison/VersionComparisonUnitTest.java b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/versioncomparison/VersionComparisonUnitTest.java
new file mode 100644
index 0000000000..145e9788e4
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/versioncomparison/VersionComparisonUnitTest.java
@@ -0,0 +1,136 @@
+package com.baeldung.versioncomparison;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.Version;
+import com.vdurmont.semver4j.Semver;
+import com.vdurmont.semver4j.Semver.VersionDiff;
+
+import org.apache.maven.artifact.versioning.ComparableVersion;
+import org.gradle.util.VersionNumber;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class VersionComparisonUnitTest {
+
+ @Test
+ public void givenVersionStrings_whenUsingMavenArtifact_thenCompareVersions() {
+ ComparableVersion version1_1 = new ComparableVersion("1.1");
+ ComparableVersion version1_2 = new ComparableVersion("1.2");
+ ComparableVersion version1_3 = new ComparableVersion("1.3");
+
+ assertTrue(version1_1.compareTo(version1_2) < 0);
+ assertTrue(version1_3.compareTo(version1_2) > 0);
+
+ ComparableVersion version1_1_0 = new ComparableVersion("1.1.0");
+ assertEquals(0, version1_1.compareTo(version1_1_0));
+
+ ComparableVersion version1_1_alpha = new ComparableVersion("1.1-alpha");
+ assertTrue(version1_1.compareTo(version1_1_alpha) > 0);
+
+ ComparableVersion version1_1_beta = new ComparableVersion("1.1-beta");
+ ComparableVersion version1_1_milestone = new ComparableVersion("1.1-milestone");
+ ComparableVersion version1_1_rc = new ComparableVersion("1.1-rc");
+ ComparableVersion version1_1_snapshot = new ComparableVersion("1.1-snapshot");
+
+ assertTrue(version1_1_alpha.compareTo(version1_1_beta) < 0);
+ assertTrue(version1_1_beta.compareTo(version1_1_milestone) < 0);
+ assertTrue(version1_1_rc.compareTo(version1_1_snapshot) < 0);
+ assertTrue(version1_1_snapshot.compareTo(version1_1) < 0);
+
+ ComparableVersion version1_1_c = new ComparableVersion("1.1-c");
+ ComparableVersion version1_1_z = new ComparableVersion("1.1-z");
+ ComparableVersion version1_1_1 = new ComparableVersion("1.1.1");
+
+ assertTrue(version1_1_c.compareTo(version1_1_z) < 0);
+ assertTrue(version1_1_z.compareTo(version1_1_1) < 0);
+ }
+
+ @Test
+ public void givenVersionStrings_whenUsingGradle_thenCompareVersions() {
+ VersionNumber version1_1 = VersionNumber.parse("1.1");
+ VersionNumber version1_2 = VersionNumber.parse("1.2");
+ VersionNumber version1_3 = VersionNumber.parse("1.3");
+
+ assertTrue(version1_1.compareTo(version1_2) < 0);
+ assertTrue(version1_3.compareTo(version1_2) > 0);
+
+ VersionNumber version1_1_0 = VersionNumber.parse("1.1.0");
+ assertEquals(0, version1_1.compareTo(version1_1_0));
+
+ VersionNumber version1_1_1_1_alpha = VersionNumber.parse("1.1.1.1-alpha");
+ assertTrue(version1_1.compareTo(version1_1_1_1_alpha) < 0);
+
+ VersionNumber version1_1_beta = VersionNumber.parse("1.1.0.0-beta");
+ assertTrue(version1_1_beta.compareTo(version1_1_1_1_alpha) < 0);
+
+ VersionNumber version1_1_1_snapshot = VersionNumber.parse("1.1.1-snapshot");
+ assertTrue(version1_1_1_1_alpha.compareTo(version1_1_1_snapshot) < 0);
+ }
+
+ @Test
+ public void givenVersionStrings_whenUsingJackson_thenCompareVersions() {
+ Version version1_1 = new Version(1, 1, 0, null, null, null);
+ Version version1_2 = new Version(1, 2, 0, null, null, null);
+ Version version1_3 = new Version(1, 3, 0, null, null, null);
+
+ assertTrue(version1_1.compareTo(version1_2) < 0);
+ assertTrue(version1_3.compareTo(version1_2) > 0);
+
+ Version version1_1_1 = new Version(1, 1, 1, null, null, null);
+ assertTrue(version1_1.compareTo(version1_1_1) < 0);
+
+ Version version1_1_maven = new Version(1, 1, 0, null, "org.apache.maven", null);
+ Version version1_1_gradle = new Version(1, 1, 0, null, "org.gradle", null);
+ assertTrue(version1_1_maven.compareTo(version1_1_gradle) < 0);
+
+ Version version1_1_snapshot = new Version(1, 1, 0, "snapshot", null, null);
+ assertEquals(0, version1_1.compareTo(version1_1_snapshot));
+
+ assertTrue(version1_1_snapshot.isSnapshot());
+ }
+
+ @Test
+ public void givenVersionStrings_whenUsingSemver_thenCompareVersions() {
+ Semver version1_1 = new Semver("1.1.0");
+ Semver version1_2 = new Semver("1.2.0");
+ Semver version1_3 = new Semver("1.3.0");
+
+ assertTrue(version1_1.compareTo(version1_2) < 0);
+ assertTrue(version1_3.compareTo(version1_2) > 0);
+
+ Semver version1_1_alpha = new Semver("1.1.0-alpha");
+ assertTrue(version1_1.isGreaterThan(version1_1_alpha));
+
+ Semver version1_1_beta = new Semver("1.1.0-beta");
+ Semver version1_1_milestone = new Semver("1.1.0-milestone");
+ Semver version1_1_rc = new Semver("1.1.0-rc");
+ Semver version1_1_snapshot = new Semver("1.1.0-snapshot");
+
+ assertTrue(version1_1_alpha.isLowerThan(version1_1_beta));
+ assertTrue(version1_1_beta.compareTo(version1_1_milestone) < 0);
+ assertTrue(version1_1_rc.compareTo(version1_1_snapshot) < 0);
+ assertTrue(version1_1_snapshot.compareTo(version1_1) < 0);
+
+ assertTrue(version1_1.isEqualTo("1.1.0"));
+
+ assertEquals(VersionDiff.MAJOR, version1_1.diff("2.1.0"));
+ assertEquals(VersionDiff.MINOR, version1_1.diff("1.2.3"));
+ assertEquals(VersionDiff.PATCH, version1_1.diff("1.1.1"));
+
+ assertTrue(version1_1.isStable());
+ assertFalse(version1_1_alpha.isStable());
+ }
+
+ @Test
+ public void givenVersionStrings_whenUsingCustomVersionCompare_thenCompareVersions() {
+ assertTrue(VersionCompare.compareVersions("1.0.1", "1.1.2") < 0);
+ assertTrue(VersionCompare.compareVersions("1.0.1", "1.10") < 0);
+ assertTrue(VersionCompare.compareVersions("1.1.2", "1.0.1") > 0);
+ assertTrue(VersionCompare.compareVersions("1.1.2", "1.2") < 0);
+ assertEquals(0, VersionCompare.compareVersions("1.3.0", "1.3"));
+ }
+
+}
diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml
index d01a7cc792..03b15f60d6 100644
--- a/core-java-modules/pom.xml
+++ b/core-java-modules/pom.xml
@@ -85,6 +85,7 @@
core-java-lambdas
core-java-lang
core-java-lang-2
+ core-java-lang-3
core-java-lang-math
core-java-lang-math-2
core-java-lang-oop-constructors
@@ -110,6 +111,7 @@
core-java-perf
core-java-reflection
+ core-java-reflection-2
core-java-security
core-java-security-2
@@ -124,6 +126,7 @@
core-java-string-conversions-2
core-java-string-operations
core-java-string-operations-2
+ core-java-string-operations-3
core-java-strings
core-java-sun
diff --git a/core-kotlin-modules/core-kotlin-lang-2/README.md b/core-kotlin-modules/core-kotlin-lang-2/README.md
index e2b282258b..e7f232856b 100644
--- a/core-kotlin-modules/core-kotlin-lang-2/README.md
+++ b/core-kotlin-modules/core-kotlin-lang-2/README.md
@@ -7,7 +7,6 @@ This module contains articles about core features in the Kotlin language.
- [Infix Functions in Kotlin](https://www.baeldung.com/kotlin-infix-functions)
- [Lambda Expressions in Kotlin](https://www.baeldung.com/kotlin-lambda-expressions)
- [Creating Java static final Equivalents in Kotlin](https://www.baeldung.com/kotlin-java-static-final)
-- [Initializing Arrays in Kotlin](https://www.baeldung.com/kotlin-initialize-array)
- [Lazy Initialization in Kotlin](https://www.baeldung.com/kotlin-lazy-initialization)
- [Comprehensive Guide to Null Safety in Kotlin](https://www.baeldung.com/kotlin-null-safety)
- [Kotlin Scope Functions](https://www.baeldung.com/kotlin-scope-functions)
diff --git a/core-kotlin-modules/core-kotlin-lang-2/src/test/kotlin/com/baeldung/arrayinitialization/ArrayInitializationTest.kt b/core-kotlin-modules/core-kotlin-lang-2/src/test/kotlin/com/baeldung/arrayinitialization/ArrayInitializationTest.kt
deleted file mode 100644
index d4b9d607fb..0000000000
--- a/core-kotlin-modules/core-kotlin-lang-2/src/test/kotlin/com/baeldung/arrayinitialization/ArrayInitializationTest.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.baeldung.arrayinitialization
-
-import org.junit.Test
-import kotlin.test.assertEquals
-
-class ArrayInitializationTest {
-
- @Test
- fun givenArrayOfStrings_thenValuesPopulated() {
- val strings = arrayOf("January", "February", "March")
-
- assertEquals(3, strings.size)
- assertEquals("March", strings[2])
- }
-
- @Test
- fun givenArrayOfIntegers_thenValuesPopulated() {
- val integers = intArrayOf(1, 2, 3, 4)
-
- assertEquals(4, integers.size)
- assertEquals(1, integers[0])
- }
-
- @Test
- fun givenArrayOfNulls_whenPopulated_thenValuesPresent() {
- val array = arrayOfNulls(5)
-
- for (i in array.indices) {
- array[i] = i * i
- }
-
- assertEquals(16, array[4])
- }
-
- @Test
- fun whenGeneratorUsed_thenValuesPresent() {
- val generatedArray = IntArray(10) { i -> i * i }
-
- assertEquals(81, generatedArray[9])
- }
-
- @Test
- fun whenStringGenerated_thenValuesPresent() {
- val generatedStringArray = Array(10) { i -> "Number of index: $i" }
-
- assertEquals("Number of index: 0", generatedStringArray[0])
- }
-
-}
\ No newline at end of file
diff --git a/guava-2/README.md b/guava-2/README.md
index c20fc3e7bd..634c17f0eb 100644
--- a/guava-2/README.md
+++ b/guava-2/README.md
@@ -4,3 +4,4 @@ This module contains articles a Google Guava
### Relevant Articles:
- [Introduction to Guava Throwables](https://www.baeldung.com/guava-throwables)
+- [Guava CharMatcher](https://www.baeldung.com/guava-string-charmatcher)
diff --git a/guava-2/src/test/java/com/baeldung/guava/charmatcher/GuavaCharMatcherUnitTest.java b/guava-2/src/test/java/com/baeldung/guava/charmatcher/GuavaCharMatcherUnitTest.java
new file mode 100644
index 0000000000..e60777595e
--- /dev/null
+++ b/guava-2/src/test/java/com/baeldung/guava/charmatcher/GuavaCharMatcherUnitTest.java
@@ -0,0 +1,113 @@
+package com.baeldung.guava.charmatcher;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+
+import org.junit.Test;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Predicate;
+
+public class GuavaCharMatcherUnitTest {
+
+ @Test
+ public void whenRemoveSpecialCharacters_thenRemoved() {
+ final String input = "H*el.lo,}12";
+ final CharMatcher matcher = CharMatcher.javaLetterOrDigit();
+ final String result = matcher.retainFrom(input);
+
+ assertEquals("Hello12", result);
+ }
+
+ @Test
+ public void whenRemoveNonASCIIChars_thenRemoved() {
+ final String input = "あhello₤";
+
+ String result = CharMatcher.ascii().retainFrom(input);
+ assertEquals("hello", result);
+
+ result = CharMatcher.inRange('0', 'z').retainFrom(input);
+ assertEquals("hello", result);
+ }
+
+ @Test
+ public void whenValidateString_thenValid() {
+ final String input = "hello";
+
+ boolean result = CharMatcher.javaLowerCase().matchesAllOf(input);
+ assertTrue(result);
+
+ result = CharMatcher.is('e').matchesAnyOf(input);
+ assertTrue(result);
+
+ result = CharMatcher.javaDigit().matchesNoneOf(input);
+ assertTrue(result);
+ }
+
+ @Test
+ public void whenTrimString_thenTrimmed() {
+ final String input = "---hello,,,";
+
+ String result = CharMatcher.is('-').trimLeadingFrom(input);
+ assertEquals("hello,,,", result);
+
+ result = CharMatcher.is(',').trimTrailingFrom(input);
+ assertEquals("---hello", result);
+
+ result = CharMatcher.anyOf("-,").trimFrom(input);
+ assertEquals("hello", result);
+ }
+
+ @Test
+ public void whenCollapseFromString_thenCollapsed() {
+ final String input = " hel lo ";
+
+ String result = CharMatcher.is(' ').collapseFrom(input, '-');
+ assertEquals("-hel-lo-", result);
+
+ result = CharMatcher.is(' ').trimAndCollapseFrom(input, '-');
+ assertEquals("hel-lo", result);
+ }
+
+ @Test
+ public void whenReplaceFromString_thenReplaced() {
+ final String input = "apple-banana.";
+
+ String result = CharMatcher.anyOf("-.").replaceFrom(input, '!');
+ assertEquals("apple!banana!", result);
+
+ result = CharMatcher.is('-').replaceFrom(input, " and ");
+ assertEquals("apple and banana.", result);
+ }
+
+ @Test
+ public void whenCountCharInString_thenCorrect() {
+ final String input = "a, c, z, 1, 2";
+
+ int result = CharMatcher.is(',').countIn(input);
+ assertEquals(4, result);
+
+ result = CharMatcher.inRange('a', 'h').countIn(input);
+ assertEquals(2, result);
+ }
+
+ @Test
+ public void whenRemoveCharsNotInCharset_thenRemoved() {
+ final Charset charset = Charset.forName("cp437");
+ final CharsetEncoder encoder = charset.newEncoder();
+
+ final Predicate inRange = new Predicate() {
+ @Override
+ public boolean apply(final Character c) {
+ return encoder.canEncode(c);
+ }
+ };
+
+ final String result = CharMatcher.forPredicate(inRange).retainFrom("helloは");
+ assertEquals("hello", result);
+ }
+
+}
diff --git a/guava-collections/README.md b/guava-collections/README.md
index 17cdb91ef5..51731d7db7 100644
--- a/guava-collections/README.md
+++ b/guava-collections/README.md
@@ -14,4 +14,3 @@ This module contains articles about Google Guava collections
- [Guava – Lists](https://www.baeldung.com/guava-lists)
- [Guide to Guava MinMaxPriorityQueue and EvictingQueue](https://www.baeldung.com/guava-minmax-priority-queue-and-evicting-queue)
- [Guide to Guava Table](https://www.baeldung.com/guava-table)
-- [Guava CharMatcher](https://www.baeldung.com/guava-string-charmatcher)
diff --git a/guava-collections/src/test/java/com/baeldung/guava/joinsplit/GuavaStringUnitTest.java b/guava-collections/src/test/java/com/baeldung/guava/joinsplit/GuavaStringUnitTest.java
index 0c480d02a0..d1dd4af3bb 100644
--- a/guava-collections/src/test/java/com/baeldung/guava/joinsplit/GuavaStringUnitTest.java
+++ b/guava-collections/src/test/java/com/baeldung/guava/joinsplit/GuavaStringUnitTest.java
@@ -4,20 +4,19 @@ import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
-import com.google.common.collect.*;
import org.junit.Test;
-import com.google.common.base.CharMatcher;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
-import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
public class GuavaStringUnitTest {
@@ -113,102 +112,4 @@ public class GuavaStringUnitTest {
assertEquals(4, result.size());
assertThat(result, contains("a", "b", "c", "d,e"));
}
-
- @Test
- public void whenRemoveSpecialCharacters_thenRemoved() {
- final String input = "H*el.lo,}12";
- final CharMatcher matcher = CharMatcher.javaLetterOrDigit();
- final String result = matcher.retainFrom(input);
-
- assertEquals("Hello12", result);
- }
-
- @Test
- public void whenRemoveNonASCIIChars_thenRemoved() {
- final String input = "あhello₤";
-
- String result = CharMatcher.ascii().retainFrom(input);
- assertEquals("hello", result);
-
- result = CharMatcher.inRange('0', 'z').retainFrom(input);
- assertEquals("hello", result);
- }
-
- @Test
- public void whenValidateString_thenValid() {
- final String input = "hello";
-
- boolean result = CharMatcher.javaLowerCase().matchesAllOf(input);
- assertTrue(result);
-
- result = CharMatcher.is('e').matchesAnyOf(input);
- assertTrue(result);
-
- result = CharMatcher.javaDigit().matchesNoneOf(input);
- assertTrue(result);
- }
-
- @Test
- public void whenTrimString_thenTrimmed() {
- final String input = "---hello,,,";
-
- String result = CharMatcher.is('-').trimLeadingFrom(input);
- assertEquals("hello,,,", result);
-
- result = CharMatcher.is(',').trimTrailingFrom(input);
- assertEquals("---hello", result);
-
- result = CharMatcher.anyOf("-,").trimFrom(input);
- assertEquals("hello", result);
- }
-
- @Test
- public void whenCollapseFromString_thenCollapsed() {
- final String input = " hel lo ";
-
- String result = CharMatcher.is(' ').collapseFrom(input, '-');
- assertEquals("-hel-lo-", result);
-
- result = CharMatcher.is(' ').trimAndCollapseFrom(input, '-');
- assertEquals("hel-lo", result);
- }
-
- @Test
- public void whenReplaceFromString_thenReplaced() {
- final String input = "apple-banana.";
-
- String result = CharMatcher.anyOf("-.").replaceFrom(input, '!');
- assertEquals("apple!banana!", result);
-
- result = CharMatcher.is('-').replaceFrom(input, " and ");
- assertEquals("apple and banana.", result);
- }
-
- @Test
- public void whenCountCharInString_thenCorrect() {
- final String input = "a, c, z, 1, 2";
-
- int result = CharMatcher.is(',').countIn(input);
- assertEquals(4, result);
-
- result = CharMatcher.inRange('a', 'h').countIn(input);
- assertEquals(2, result);
- }
-
- @Test
- public void whenRemoveCharsNotInCharset_thenRemoved() {
- final Charset charset = Charset.forName("cp437");
- final CharsetEncoder encoder = charset.newEncoder();
-
- final Predicate inRange = new Predicate() {
- @Override
- public boolean apply(final Character c) {
- return encoder.canEncode(c);
- }
- };
-
- final String result = CharMatcher.forPredicate(inRange).retainFrom("helloは");
- assertEquals("hello", result);
- }
-
}
diff --git a/image-processing/pom.xml b/image-processing/pom.xml
index 8fe161337c..f2551598d5 100644
--- a/image-processing/pom.xml
+++ b/image-processing/pom.xml
@@ -60,6 +60,27 @@
tesseract-platform
${tesseract-platform.version}
+
+ org.imgscalr
+ imgscalr-lib
+ ${imgscalr-version}
+
+
+ net.coobird
+ thumbnailator
+ ${thumbnailator-version}
+
+
+ com.github.downgoon
+ marvin
+ ${marvin-version}
+ pom
+
+
+ com.github.downgoon
+ MarvinPlugins
+ ${marvin-version}
+
@@ -69,6 +90,9 @@
4.5.1
4.1.0-1.5.2
3.4.2-0
+ 4.2
+ 0.4.11
+ 1.5.5
\ No newline at end of file
diff --git a/image-processing/src/main/java/com/baeldung/image/resize/core/Graphics2DExample.java b/image-processing/src/main/java/com/baeldung/image/resize/core/Graphics2DExample.java
new file mode 100644
index 0000000000..d52a2dac1b
--- /dev/null
+++ b/image-processing/src/main/java/com/baeldung/image/resize/core/Graphics2DExample.java
@@ -0,0 +1,25 @@
+package com.baeldung.image.resize.core;
+
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+public class Graphics2DExample {
+
+ static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
+ BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
+ Graphics2D graphics2D = resizedImage.createGraphics();
+ graphics2D.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
+ graphics2D.dispose();
+ return resizedImage;
+ }
+
+ public static void main(String[] args) throws IOException {
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = resizeImage(originalImage, 200, 200);
+ ImageIO.write(outputImage, "jpg", new File("src/main/resources/images/sampleImage-resized-graphics2d.jpg"));
+ }
+}
diff --git a/image-processing/src/main/java/com/baeldung/image/resize/core/ImageScaledInstanceExample.java b/image-processing/src/main/java/com/baeldung/image/resize/core/ImageScaledInstanceExample.java
new file mode 100644
index 0000000000..a6e252f3eb
--- /dev/null
+++ b/image-processing/src/main/java/com/baeldung/image/resize/core/ImageScaledInstanceExample.java
@@ -0,0 +1,24 @@
+package com.baeldung.image.resize.core;
+
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+public class ImageScaledInstanceExample {
+ static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
+ Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_DEFAULT);
+ BufferedImage bufferedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
+ bufferedImage.getGraphics()
+ .drawImage(resultingImage, 0, 0, null);
+ return bufferedImage;
+ }
+
+ public static void main(String[] args) throws IOException {
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = resizeImage(originalImage, 200, 200);
+ ImageIO.write(outputImage, "jpg", new File("src/main/resources/images/sampleImage-resized-scaledinstance.jpg"));
+ }
+}
diff --git a/image-processing/src/main/java/com/baeldung/image/resize/imgscalr/ImgscalrExample.java b/image-processing/src/main/java/com/baeldung/image/resize/imgscalr/ImgscalrExample.java
new file mode 100644
index 0000000000..10d4217de6
--- /dev/null
+++ b/image-processing/src/main/java/com/baeldung/image/resize/imgscalr/ImgscalrExample.java
@@ -0,0 +1,24 @@
+package com.baeldung.image.resize.imgscalr;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+
+import javax.imageio.ImageIO;
+
+import org.imgscalr.Scalr;
+
+public class ImgscalrExample {
+ public static BufferedImage simpleResizeImage(BufferedImage originalImage, int targetWidth) {
+ return Scalr.resize(originalImage, targetWidth);
+ }
+
+ public static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
+ return Scalr.resize(originalImage, Scalr.Method.AUTOMATIC, Scalr.Mode.AUTOMATIC, targetWidth, targetHeight, Scalr.OP_ANTIALIAS);
+ }
+
+ public static void main(String[] args) throws Exception {
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = resizeImage(originalImage, 200, 200);
+ ImageIO.write(outputImage, "jpg", new File("src/main/resources/images/sampleImage-resized-imgscalr.jpg"));
+ }
+}
diff --git a/image-processing/src/main/java/com/baeldung/image/resize/marvin/MarvinExample.java b/image-processing/src/main/java/com/baeldung/image/resize/marvin/MarvinExample.java
new file mode 100644
index 0000000000..9a7233c4f4
--- /dev/null
+++ b/image-processing/src/main/java/com/baeldung/image/resize/marvin/MarvinExample.java
@@ -0,0 +1,29 @@
+package com.baeldung.image.resize.marvin;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import org.marvinproject.image.transform.scale.Scale;
+
+import marvin.image.MarvinImage;
+
+public class MarvinExample {
+ static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
+ MarvinImage image = new MarvinImage(originalImage);
+ Scale scale = new Scale();
+ scale.load();
+ scale.setAttribute("newWidth", targetWidth);
+ scale.setAttribute("newHeight", targetHeight);
+ scale.process(image.clone(), image, null, null, false);
+ return image.getBufferedImageNoAlpha();
+ }
+
+ public static void main(String args[]) throws IOException {
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = resizeImage(originalImage, 200, 200);
+ ImageIO.write(outputImage, "jpg", new File("src/main/resources/images/sampleImage-resized-marvin.jpg"));
+ }
+}
diff --git a/image-processing/src/main/java/com/baeldung/image/resize/thumbnailator/ThumbnailatorExample.java b/image-processing/src/main/java/com/baeldung/image/resize/thumbnailator/ThumbnailatorExample.java
new file mode 100644
index 0000000000..2296c1649d
--- /dev/null
+++ b/image-processing/src/main/java/com/baeldung/image/resize/thumbnailator/ThumbnailatorExample.java
@@ -0,0 +1,31 @@
+package com.baeldung.image.resize.thumbnailator;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import net.coobird.thumbnailator.Thumbnails;
+
+public class ThumbnailatorExample {
+ static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ Thumbnails.of(originalImage)
+ .size(targetWidth, targetHeight)
+ .outputFormat("JPEG")
+ .outputQuality(0.90)
+ .toOutputStream(outputStream);
+ byte[] data = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
+ return ImageIO.read(inputStream);
+ }
+
+ public static void main(String[] args) throws Exception {
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = resizeImage(originalImage, 200, 200);
+ ImageIO.write(outputImage, "jpg", new File("src/main/resources/images/sampleImage-resized-thumbnailator.jpg"));
+ }
+}
diff --git a/image-processing/src/main/java/com/baeldung/imageprocessing/addingtext/AddText.java b/image-processing/src/main/java/com/baeldung/imageprocessing/addingtext/AddText.java
new file mode 100644
index 0000000000..a19dd95af1
--- /dev/null
+++ b/image-processing/src/main/java/com/baeldung/imageprocessing/addingtext/AddText.java
@@ -0,0 +1,220 @@
+package com.baeldung.imageprocessing.addingtext;
+
+import ij.IJ;
+import ij.ImagePlus;
+import ij.process.ImageProcessor;
+
+import java.awt.*;
+import java.awt.font.GlyphVector;
+import java.awt.font.TextAttribute;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.text.AttributedString;
+
+import javax.imageio.ImageIO;
+
+public class AddText {
+ public static void main(String[] args) throws IOException {
+ String imagePath = AddText.class.getClassLoader().getResource("lena.jpg").getPath();
+
+ ImagePlus resultPlus= signImageImageProcessor("www.baeldung.com", imagePath);
+ resultPlus.show();
+
+ ImagePlus resultGraphics = new ImagePlus("", signImageGraphics("www.baeldung.com", imagePath));
+ resultGraphics.show();
+
+ ImagePlus resultGraphicsWithIterator = new ImagePlus("", signImageGraphicsWithIterator("www.baeldung.com", imagePath));
+ resultGraphicsWithIterator.show();
+
+ ImagePlus resultGraphicsCentered = new ImagePlus("", signImageCenter("www.baeldung.com", imagePath));
+ resultGraphicsCentered.show();
+
+ ImagePlus resultGraphicsBottomRight = new ImagePlus("", signImageBottomRight("www.baeldung.com", imagePath));
+ resultGraphicsBottomRight.show();
+
+ ImagePlus resultGraphicsTopLeft= new ImagePlus("", signImageTopLeft("www.baeldung.com", imagePath));
+ resultGraphicsTopLeft.show();
+
+ ImagePlus resultGraphicsAdaptBasedOnImage= new ImagePlus("", signImageAdaptBasedOnImage("www.baeldung.com", imagePath));
+ resultGraphicsAdaptBasedOnImage.show();
+ }
+
+ private static ImagePlus signImageImageProcessor(String text, String path) {
+ ImagePlus image = IJ.openImage(path);
+ Font font = new Font("Arial", Font.BOLD, 18);
+
+ ImageProcessor ip = image.getProcessor();
+ ip.setColor(Color.GREEN);
+ ip.setFont(font);
+ ip.drawString(text, 0, 20);
+
+ return image;
+ }
+
+ private static BufferedImage signImageGraphics(String text, String path) throws IOException {
+ BufferedImage image = ImageIO.read(new File(path));
+ Font font = new Font("Arial", Font.BOLD, 18);
+
+ Graphics g = image.getGraphics();
+ g.setFont(font);
+ g.setColor(Color.GREEN);
+ g.drawString(text, 0, 20);
+
+ return image;
+ }
+
+
+ private static BufferedImage signImageGraphicsWithIterator(String text, String path) throws IOException {
+ BufferedImage image = ImageIO.read(new File(path));
+ Font font = new Font("Arial", Font.BOLD, 18);
+
+ AttributedString attributedText = new AttributedString(text);
+ attributedText.addAttribute(TextAttribute.FONT, font);
+ attributedText.addAttribute(TextAttribute.FOREGROUND, Color.GREEN);
+
+ Graphics g = image.getGraphics();
+ g.drawString(attributedText.getIterator(), 0, 20);
+
+ return image;
+ }
+
+ /**
+ * Draw a String centered in the middle of a Rectangle.
+ *
+ * @param g The Graphics instance.
+ * @param text The String to draw.
+ * @param rect The Rectangle to center the text in.
+ * @throws IOException
+ */
+ public static BufferedImage signImageCenter(String text, String path) throws IOException {
+
+ BufferedImage image = ImageIO.read(new File(path));
+ Font font = new Font("Arial", Font.BOLD, 18);
+
+ AttributedString attributedText = new AttributedString(text);
+ attributedText.addAttribute(TextAttribute.FONT, font);
+ attributedText.addAttribute(TextAttribute.FOREGROUND, Color.GREEN);
+
+ Graphics g = image.getGraphics();
+
+ FontMetrics metrics = g.getFontMetrics(font);
+ int positionX = (image.getWidth() - metrics.stringWidth(text)) / 2;
+ int positionY = (image.getHeight() - metrics.getHeight()) / 2 + metrics.getAscent();
+
+ g.drawString(attributedText.getIterator(), positionX, positionY);
+
+ return image;
+ }
+
+ /**
+ * Draw a String centered in the middle of a Rectangle.
+ *
+ * @param g The Graphics instance.
+ * @param text The String to draw.
+ * @param rect The Rectangle to center the text in.
+ * @throws IOException
+ */
+ public static BufferedImage signImageBottomRight(String text, String path) throws IOException {
+
+ BufferedImage image = ImageIO.read(new File(path));
+
+ Font font = new Font("Arial", Font.BOLD, 18);
+
+ AttributedString attributedText = new AttributedString(text);
+ attributedText.addAttribute(TextAttribute.FONT, font);
+ attributedText.addAttribute(TextAttribute.FOREGROUND, Color.GREEN);
+
+ Graphics g = image.getGraphics();
+
+ FontMetrics metrics = g.getFontMetrics(font);
+ int positionX = (image.getWidth() - metrics.stringWidth(text));
+ int positionY = (image.getHeight() - metrics.getHeight()) + metrics.getAscent();
+
+ g.drawString(attributedText.getIterator(), positionX, positionY);
+
+ return image;
+ }
+
+ /**
+ * Draw a String centered in the middle of a Rectangle.
+ *
+ * @param g The Graphics instance.
+ * @param text The String to draw.
+ * @param rect The Rectangle to center the text in.
+ * @throws IOException
+ */
+ public static BufferedImage signImageTopLeft(String text, String path) throws IOException {
+
+ BufferedImage image = ImageIO.read(new File(path));
+
+ Font font = new Font("Arial", Font.BOLD, 18);
+
+ AttributedString attributedText = new AttributedString(text);
+ attributedText.addAttribute(TextAttribute.FONT, font);
+ attributedText.addAttribute(TextAttribute.FOREGROUND, Color.GREEN);
+
+ Graphics g = image.getGraphics();
+
+ FontMetrics metrics = g.getFontMetrics(font);
+ int positionX = 0;
+ int positionY = metrics.getAscent();
+
+ g.drawString(attributedText.getIterator(), positionX, positionY);
+
+ return image;
+ }
+
+ /**
+ * Draw a String centered in the middle of a Rectangle.
+ *
+ * @param g The Graphics instance.
+ * @param text The String to draw.
+ * @param rect The Rectangle to center the text in.
+ * @throws IOException
+ */
+ public static BufferedImage signImageAdaptBasedOnImage(String text, String path) throws IOException {
+
+ BufferedImage image = ImageIO.read(new File(path));
+
+ Font font = createFontToFit(new Font("Arial", Font.BOLD, 80), text, image);
+
+ AttributedString attributedText = new AttributedString(text);
+ attributedText.addAttribute(TextAttribute.FONT, font);
+ attributedText.addAttribute(TextAttribute.FOREGROUND, Color.GREEN);
+
+ Graphics g = image.getGraphics();
+
+ FontMetrics metrics = g.getFontMetrics(font);
+ int positionX = (image.getWidth() - metrics.stringWidth(text));
+ int positionY = (image.getHeight() - metrics.getHeight()) + metrics.getAscent();
+
+ g.drawString(attributedText.getIterator(), positionX, positionY);
+
+ return image;
+ }
+
+ public static Font createFontToFit(Font baseFont, String text, BufferedImage image) throws IOException
+ {
+ Font newFont = baseFont;
+
+ FontMetrics ruler = image.getGraphics().getFontMetrics(baseFont);
+ GlyphVector vector = baseFont.createGlyphVector(ruler.getFontRenderContext(), text);
+
+ Shape outline = vector.getOutline(0, 0);
+
+ double expectedWidth = outline.getBounds().getWidth();
+ double expectedHeight = outline.getBounds().getHeight();
+
+ boolean textFits = image.getWidth() >= expectedWidth && image.getHeight() >= expectedHeight;
+
+ if(!textFits) {
+ double widthBasedFontSize = (baseFont.getSize2D()*image.getWidth())/expectedWidth;
+ double heightBasedFontSize = (baseFont.getSize2D()*image.getHeight())/expectedHeight;
+
+ double newFontSize = widthBasedFontSize < heightBasedFontSize ? widthBasedFontSize : heightBasedFontSize;
+ newFont = baseFont.deriveFont(baseFont.getStyle(), (float)newFontSize);
+ }
+ return newFont;
+ }
+}
diff --git a/image-processing/src/test/java/com/baeldung/image/resize/core/Graphics2DExampleUnitTest.java b/image-processing/src/test/java/com/baeldung/image/resize/core/Graphics2DExampleUnitTest.java
new file mode 100644
index 0000000000..675a17366d
--- /dev/null
+++ b/image-processing/src/test/java/com/baeldung/image/resize/core/Graphics2DExampleUnitTest.java
@@ -0,0 +1,71 @@
+package com.baeldung.image.resize.core;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import org.junit.Test;
+
+public class Graphics2DExampleUnitTest {
+
+ @Test(expected = Test.None.class)
+ public void whenOriginalImageExistsAndTargetSizesAreNotZero_thenImageGeneratedWithoutError() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = Graphics2DExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNotNull(outputImage);
+ }
+
+ @Test(expected = Test.None.class)
+ public void whenOriginalImageExistsAndTargetSizesAreNotZero_thenOutputImageSizeIsValid() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ assertNotEquals(originalImage.getWidth(), targetWidth);
+ assertNotEquals(originalImage.getHeight(), targetHeight);
+ BufferedImage outputImage = Graphics2DExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertEquals(outputImage.getWidth(), targetWidth);
+ assertEquals(outputImage.getHeight(), targetHeight);
+ }
+
+ @Test(expected = Exception.class)
+ public void whenTargetWidthIsZero_thenErrorIsThrown() throws IOException {
+ int targetWidth = 0;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = Graphics2DExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNull(outputImage);
+ }
+
+ @Test(expected = Exception.class)
+ public void whenTargetHeightIsZero_thenErrorIsThrown() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 0;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = Graphics2DExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNull(outputImage);
+ }
+
+ @Test(expected = Test.None.class)
+ public void whenOriginalImageDoesNotExist_thenErrorIsNotThrownAndImageIsGenerated() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage outputImage = Graphics2DExample.resizeImage(null, targetWidth, targetHeight);
+
+ assertNotNull(outputImage);
+ assertEquals(outputImage.getWidth(), targetWidth);
+ assertEquals(outputImage.getHeight(), targetHeight);
+ }
+}
diff --git a/image-processing/src/test/java/com/baeldung/image/resize/core/ImageScaledInstanceExampleUnitTest.java b/image-processing/src/test/java/com/baeldung/image/resize/core/ImageScaledInstanceExampleUnitTest.java
new file mode 100644
index 0000000000..b0ac5a7787
--- /dev/null
+++ b/image-processing/src/test/java/com/baeldung/image/resize/core/ImageScaledInstanceExampleUnitTest.java
@@ -0,0 +1,69 @@
+package com.baeldung.image.resize.core;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import org.junit.Test;
+
+public class ImageScaledInstanceExampleUnitTest {
+
+ @Test(expected = Test.None.class)
+ public void whenOriginalImageExistsAndTargetSizesAreNotZero_thenImageGeneratedWithoutError() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = ImageScaledInstanceExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNotNull(outputImage);
+ }
+
+ @Test(expected = Test.None.class)
+ public void whenOriginalImageExistsAndTargetSizesAreNotZero_thenOutputImageSizeIsValid() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ assertNotEquals(originalImage.getWidth(), targetWidth);
+ assertNotEquals(originalImage.getHeight(), targetHeight);
+ BufferedImage outputImage = ImageScaledInstanceExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertEquals(outputImage.getWidth(), targetWidth);
+ assertEquals(outputImage.getHeight(), targetHeight);
+ }
+
+ @Test(expected = Exception.class)
+ public void whenTargetWidthIsZero_thenErrorIsThrown() throws IOException {
+ int targetWidth = 0;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = ImageScaledInstanceExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNull(outputImage);
+ }
+
+ @Test(expected = Exception.class)
+ public void whenTargetHeightIsZero_thenErrorIsThrown() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 0;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = ImageScaledInstanceExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNull(outputImage);
+ }
+
+ @Test(expected = Exception.class)
+ public void whenOriginalImageDoesNotExist_thenErrorIsThrown() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage outputImage = ImageScaledInstanceExample.resizeImage(null, targetWidth, targetHeight);
+
+ assertNull(outputImage);
+ }
+}
diff --git a/image-processing/src/test/java/com/baeldung/image/resize/imgscalr/ImgscalrExampleUnitTest.java b/image-processing/src/test/java/com/baeldung/image/resize/imgscalr/ImgscalrExampleUnitTest.java
new file mode 100644
index 0000000000..e38850da21
--- /dev/null
+++ b/image-processing/src/test/java/com/baeldung/image/resize/imgscalr/ImgscalrExampleUnitTest.java
@@ -0,0 +1,69 @@
+package com.baeldung.image.resize.imgscalr;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import org.junit.Test;
+
+public class ImgscalrExampleUnitTest {
+
+ @Test(expected = Test.None.class)
+ public void whenOriginalImageExistsAndTargetSizesAreNotZero_thenImageGeneratedWithoutError() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = ImgscalrExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNotNull(outputImage);
+ }
+
+ @Test(expected = Test.None.class)
+ public void whenOriginalImageExistsAndTargetSizesAreNotZero_thenOutputImageSizeIsValid() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ assertNotEquals(originalImage.getWidth(), targetWidth);
+ assertNotEquals(originalImage.getHeight(), targetHeight);
+ BufferedImage outputImage = ImgscalrExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertEquals(outputImage.getWidth(), targetWidth);
+ assertEquals(outputImage.getHeight(), targetHeight);
+ }
+
+ @Test(expected = Test.None.class)
+ public void whenTargetWidthIsZero_thenImageIsCreated() throws IOException {
+ int targetWidth = 0;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = ImgscalrExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNotNull(outputImage);
+ }
+
+ @Test(expected = Test.None.class)
+ public void whenTargetHeightIsZero_thenImageIsCreated() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 0;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = ImgscalrExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNotNull(outputImage);
+ }
+
+ @Test(expected = Exception.class)
+ public void whenOriginalImageDoesNotExist_thenErrorIsThrown() {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage outputImage = ImgscalrExample.resizeImage(null, targetWidth, targetHeight);
+
+ assertNull(outputImage);
+ }
+}
diff --git a/image-processing/src/test/java/com/baeldung/image/resize/marvin/MarvinExampleUnitTest.java b/image-processing/src/test/java/com/baeldung/image/resize/marvin/MarvinExampleUnitTest.java
new file mode 100644
index 0000000000..3133a71035
--- /dev/null
+++ b/image-processing/src/test/java/com/baeldung/image/resize/marvin/MarvinExampleUnitTest.java
@@ -0,0 +1,68 @@
+package com.baeldung.image.resize.marvin;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import org.junit.Test;
+
+public class MarvinExampleUnitTest {
+ @Test(expected = Test.None.class)
+ public void whenOriginalImageExistsAndTargetSizesAreNotZero_thenImageGeneratedWithoutError() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = MarvinExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNotNull(outputImage);
+ }
+
+ @Test(expected = Test.None.class)
+ public void whenOriginalImageExistsAndTargetSizesAreNotZero_thenOutputImageSizeIsValid() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ assertNotEquals(originalImage.getWidth(), targetWidth);
+ assertNotEquals(originalImage.getHeight(), targetHeight);
+ BufferedImage outputImage = MarvinExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertEquals(outputImage.getWidth(), targetWidth);
+ assertEquals(outputImage.getHeight(), targetHeight);
+ }
+
+ @Test(expected = Exception.class)
+ public void whenTargetWidthIsZero_thenErrorIsThrown() throws IOException {
+ int targetWidth = 0;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = MarvinExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNull(outputImage);
+ }
+
+ @Test(expected = Exception.class)
+ public void whenTargetHeightIsZero_thenErrorIsThrown() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 0;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = MarvinExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNull(outputImage);
+ }
+
+ @Test(expected = Exception.class)
+ public void whenOriginalImageDoesNotExist_thenErrorIsThrown() {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage outputImage = MarvinExample.resizeImage(null, targetWidth, targetHeight);
+
+ assertNull(outputImage);
+ }
+}
diff --git a/image-processing/src/test/java/com/baeldung/image/resize/thumbnailator/ThumbnailatorExampleUnitTest.java b/image-processing/src/test/java/com/baeldung/image/resize/thumbnailator/ThumbnailatorExampleUnitTest.java
new file mode 100644
index 0000000000..383ac1c7af
--- /dev/null
+++ b/image-processing/src/test/java/com/baeldung/image/resize/thumbnailator/ThumbnailatorExampleUnitTest.java
@@ -0,0 +1,68 @@
+package com.baeldung.image.resize.thumbnailator;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import org.junit.Test;
+
+public class ThumbnailatorExampleUnitTest {
+ @Test(expected = Test.None.class)
+ public void whenOriginalImageExistsAndTargetSizesAreNotZero_thenImageGeneratedWithoutError() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = ThumbnailatorExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNotNull(outputImage);
+ }
+
+ @Test(expected = Test.None.class)
+ public void whenOriginalImageExistsAndTargetSizesAreNotZero_thenOutputImageSizeIsValid() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ assertNotEquals(originalImage.getWidth(), targetWidth);
+ assertNotEquals(originalImage.getHeight(), targetHeight);
+ BufferedImage outputImage = ThumbnailatorExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertEquals(outputImage.getWidth(), targetWidth);
+ assertEquals(outputImage.getHeight(), targetHeight);
+ }
+
+ @Test(expected = Exception.class)
+ public void whenTargetWidthIsZero_thenErrorIsThrown() throws IOException {
+ int targetWidth = 0;
+ int targetHeight = 200;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = ThumbnailatorExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNull(outputImage);
+ }
+
+ @Test(expected = Exception.class)
+ public void whenTargetHeightIsZero_thenErrorIsThrown() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 0;
+ BufferedImage originalImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
+ BufferedImage outputImage = ThumbnailatorExample.resizeImage(originalImage, targetWidth, targetHeight);
+
+ assertNull(outputImage);
+ }
+
+ @Test(expected = Exception.class)
+ public void whenOriginalImageDoesNotExist_thenErrorIsThrown() throws IOException {
+ int targetWidth = 200;
+ int targetHeight = 200;
+ BufferedImage outputImage = ThumbnailatorExample.resizeImage(null, targetWidth, targetHeight);
+
+ assertNull(outputImage);
+ }
+}
diff --git a/libraries-6/README.md b/libraries-6/README.md
index 79bb83113e..5f74517ab5 100644
--- a/libraries-6/README.md
+++ b/libraries-6/README.md
@@ -14,4 +14,5 @@ Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-m
- [Introduction to Functional Java](https://www.baeldung.com/java-functional-library)
- [A Guide to the Reflections Library](https://www.baeldung.com/reflections-library)
- [Exactly Once Processing in Kafka](https://www.baeldung.com/kafka-exactly-once)
+- [Introduction to Protonpack](https://www.baeldung.com/java-protonpack)
- More articles [[<-- prev]](/libraries-5)
diff --git a/core-java-modules/core-java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java b/libraries-6/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java
similarity index 99%
rename from core-java-modules/core-java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java
rename to libraries-6/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java
index 371ac3a9bb..c28248e52c 100644
--- a/core-java-modules/core-java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java
+++ b/libraries-6/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java
@@ -10,8 +10,6 @@ import org.junit.Test;
import java.util.List;
import java.util.Optional;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
diff --git a/libraries-security/src/main/java/com/baeldung/pem/BouncyCastlePemUtils.java b/libraries-security/src/main/java/com/baeldung/pem/BouncyCastlePemUtils.java
new file mode 100644
index 0000000000..03140666f7
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/pem/BouncyCastlePemUtils.java
@@ -0,0 +1,71 @@
+package com.baeldung.pem;
+
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.openssl.PEMParser;
+import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.bouncycastle.util.io.pem.PemObject;
+import org.bouncycastle.util.io.pem.PemReader;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+public class BouncyCastlePemUtils {
+
+ public static RSAPublicKey readX509PublicKey(File file) throws InvalidKeySpecException, IOException, NoSuchAlgorithmException {
+ KeyFactory factory = KeyFactory.getInstance("RSA");
+
+ try (FileReader keyReader = new FileReader(file);
+ PemReader pemReader = new PemReader(keyReader)) {
+
+ PemObject pemObject = pemReader.readPemObject();
+ byte[] content = pemObject.getContent();
+ X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
+ return (RSAPublicKey) factory.generatePublic(pubKeySpec);
+ }
+ }
+
+ public static RSAPublicKey readX509PublicKeySecondApproach(File file) throws IOException {
+ try (FileReader keyReader = new FileReader(file)) {
+
+ PEMParser pemParser = new PEMParser(keyReader);
+ JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
+ SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(pemParser.readObject());
+
+ return (RSAPublicKey) converter.getPublicKey(publicKeyInfo);
+ }
+ }
+
+ public static RSAPrivateKey readPKCS8PrivateKey(File file) throws InvalidKeySpecException, IOException, NoSuchAlgorithmException {
+ KeyFactory factory = KeyFactory.getInstance("RSA");
+
+ try (FileReader keyReader = new FileReader(file);
+ PemReader pemReader = new PemReader(keyReader)) {
+
+ PemObject pemObject = pemReader.readPemObject();
+ byte[] content = pemObject.getContent();
+ PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);
+ return (RSAPrivateKey) factory.generatePrivate(privKeySpec);
+ }
+ }
+
+ public static RSAPrivateKey readPKCS8PrivateKeySecondApproach(File file) throws IOException {
+ try (FileReader keyReader = new FileReader(file)) {
+
+ PEMParser pemParser = new PEMParser(keyReader);
+ JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
+ PrivateKeyInfo privateKeyInfo = PrivateKeyInfo.getInstance(pemParser.readObject());
+
+ return (RSAPrivateKey) converter.getPrivateKey(privateKeyInfo);
+ }
+ }
+
+}
diff --git a/libraries-security/src/main/resources/pem/private-key-pkcs8.pem b/libraries-security/src/main/resources/pem/private-key-pkcs8.pem
new file mode 100644
index 0000000000..903f903d7a
--- /dev/null
+++ b/libraries-security/src/main/resources/pem/private-key-pkcs8.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCyO0YiTxLEP44S
+IGk/b9MlQAXS6nC4oYyTrAfxHCi/zxW/MmtWbY0K2JxOTkVSD5QbmvwkCutXi0k9
+EdDK+orAXg2KSy686O/cfIh/iho6FmNPyEOd7UF+/5wWpknrUaTQyMA2H9Pmr2/E
+RH/tN1Q0cqmhFX41WUo3lsRT81DkVCNVeJx+zDGHpjp+XY8gWpPYJ+MP4WQE9TWJ
+P2rIlgcDfwhG/A21yK0WAJ5nB0Y+jGI8+HVYdjxXGlRUG//YmxS2sH+sAhsapmjE
+Aha+KMk972jVNjdWU7OT0BJnUB5q286Kv6INUnk6kqYufNzjpCAY9SyMjKjpKN71
+3Gka2gZBAgMBAAECggEAFlPam12wiik0EQ1CYhIOL3JvyFZaPKbwR2ebrxbJ/A1j
+OgqE69TZgGxWWHDxui/9a9/kildb2CG40Q+0SllMnICrzZFRj5TWx5ZKOz//vRsk
+4c/CuLwKInC/Cw9V30bhEM61VZJzJ0j/BWVXaU4vHEro+ScKIoDHDWOzwJiQn6m9
+C+Ti5lFpax3hx8ZrgPqmBCFYNvErrWkOr7mCYl0jS+E22c68yn8+LjdlF1LWUa6N
+zutk3MPj5UwEyR0h7EZReCeGkPTMQNyOBhDcmAtlEno4fjtZzUDHRjh8/QpG1Mz/
+alavvrkjswc1DmRUOdgiYu+Waxan5noBhxEAvd/hyQKBgQDjYJD0n+m0tUrpNtX0
++mdzHstClHrpx5oNxs4sIBjCoCwEXaSpeY8+JxCdnZ6n29mLZLq/wPXxZ3EJcOSZ
+PYUvZJfV/IUvoLPFbtT3ILzDTcAAeHj2GAOpzYP8J1JSFsc78ZjKMF1XeNjXcq8T
+XNXoWfY7N/fShoycVeG42JJCFwKBgQDIqvHL0QfJ8r6yM8Efj7Zq6Wa4C9okORes
+8UVWfBoO6UOWvpK+D9IjnaEisJcnEalwNi8/eKudR9hfvmzATV+t3YJIgktto3TT
+BWLsEyniNU4vSTl7GPBrV2xabWogbChlt7TXUfw6YogaBKm43snYXBbJFc+NcpQH
+ONB5igppZwKBgGDyYHvc3wGsttb/CXTde1RLUfD+a/XXpCixlmCcAtKhBoOKBdY4
+vUmL0HrTpLz/cR8NAM8XkAWwzDJxTxbDc1EEu/SCKatoAp5wph8Ed1dyhCXvN+v9
+yzoQJXFStrfHfIVjenji7DmKjjI2dM11rMLX8LPJJkI+Gh/iQk7VEG9bAoGAH/aS
+sztleTZwR6RUw7k5fkgVM4W3xoNNkR+RQthbsjpXqMBMUXflqgSmsQbd3LxEd/o5
+hmurMk9KWN3VJsBsWB5rbS9L4nfh2OcHvcDDsCN7g66vODtduEthl/nLqMRxnton
+NRD7EzW0pihN/IOINS1d98PAnrA8gfX7xxBE3ksCgYBvoljHGjvy3bPJ++vDGKJK
+y6JuEeRVzgdPXEb60uU+BR7kdh+MMsZLmgfFTgza3R+/xeZcC/cuOPsbzeooRQi/
+9NpKwSCXjVNk9nglUWBoPRh4uYqrArWn+HoR7MI/BxeRJm5e1+ii8P19Y9joX5s0
+Q3OLn8GeH56ClJmNiWDhsA==
+-----END PRIVATE KEY-----
\ No newline at end of file
diff --git a/libraries-security/src/main/resources/pem/public-key.pem b/libraries-security/src/main/resources/pem/public-key.pem
new file mode 100644
index 0000000000..54262dca03
--- /dev/null
+++ b/libraries-security/src/main/resources/pem/public-key.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjtGIk8SxD+OEiBpP2/T
+JUAF0upwuKGMk6wH8Rwov88VvzJrVm2NCticTk5FUg+UG5r8JArrV4tJPRHQyvqK
+wF4NiksuvOjv3HyIf4oaOhZjT8hDne1Bfv+cFqZJ61Gk0MjANh/T5q9vxER/7TdU
+NHKpoRV+NVlKN5bEU/NQ5FQjVXicfswxh6Y6fl2PIFqT2CfjD+FkBPU1iT9qyJYH
+A38IRvwNtcitFgCeZwdGPoxiPPh1WHY8VxpUVBv/2JsUtrB/rAIbGqZoxAIWvijJ
+Pe9o1TY3VlOzk9ASZ1AeatvOir+iDVJ5OpKmLnzc46QgGPUsjIyo6Sje9dxpGtoG
+QQIDAQAB
+-----END PUBLIC KEY-----
\ No newline at end of file
diff --git a/libraries-security/src/test/java/com/baeldung/pem/BouncyCastlePemUtilsUnitTest.java b/libraries-security/src/test/java/com/baeldung/pem/BouncyCastlePemUtilsUnitTest.java
new file mode 100644
index 0000000000..1297568d0e
--- /dev/null
+++ b/libraries-security/src/test/java/com/baeldung/pem/BouncyCastlePemUtilsUnitTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.pem;
+
+
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class BouncyCastlePemUtilsUnitTest {
+
+ @Test
+ public void whenReadPublicKeyFromPEMFile_thenSuccess() throws Exception {
+ File pemFile = new File(BouncyCastlePemUtilsUnitTest.class.getResource("/pem/public-key.pem").getFile());
+
+ RSAPublicKey publicKey1 = BouncyCastlePemUtils.readX509PublicKey(pemFile);
+ RSAPublicKey publicKey2 = BouncyCastlePemUtils.readX509PublicKeySecondApproach(pemFile);
+
+ assertEquals("X.509", publicKey1.getFormat());
+ assertEquals("RSA", publicKey1.getAlgorithm());
+
+ assertEquals("X.509", publicKey2.getFormat());
+ assertEquals("RSA", publicKey2.getAlgorithm());
+ }
+
+ @Test
+ public void whenReadPrivateKeyFromPEMFile_thenSuccess() throws Exception {
+ File pemFile = new File(BouncyCastlePemUtilsUnitTest.class.getResource("/pem/private-key-pkcs8.pem").getFile());
+
+ RSAPrivateKey privateKey1 = BouncyCastlePemUtils.readPKCS8PrivateKey(pemFile);
+ RSAPrivateKey privateKey2 = BouncyCastlePemUtils.readPKCS8PrivateKeySecondApproach(pemFile);
+
+ assertEquals("PKCS#8", privateKey1.getFormat());
+ assertEquals("RSA", privateKey1.getAlgorithm());
+
+ assertEquals("PKCS#8", privateKey2.getFormat());
+ assertEquals("RSA", privateKey2.getAlgorithm());
+ }
+}
diff --git a/maven-all/version-collision/pom.xml b/maven-all/version-collision/pom.xml
new file mode 100644
index 0000000000..7bbd17a789
--- /dev/null
+++ b/maven-all/version-collision/pom.xml
@@ -0,0 +1,54 @@
+
+
+
+ maven-all
+ com.baeldung
+ 0.0.1-SNAPSHOT
+
+ 4.0.0
+
+ version-collision
+ pom
+
+ project-a
+ project-b
+ project-collision
+
+
+
+
+
+
+ com.google.guava
+ guava
+ 29.0-jre
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/maven-all/version-collision/project-a/pom.xml b/maven-all/version-collision/project-a/pom.xml
new file mode 100644
index 0000000000..1b7af7e963
--- /dev/null
+++ b/maven-all/version-collision/project-a/pom.xml
@@ -0,0 +1,21 @@
+
+
+
+ version-collision
+ com.baeldung
+ 0.0.1-SNAPSHOT
+
+ 4.0.0
+
+ project-a
+
+
+
+ com.google.guava
+ guava
+ 22.0
+
+
+
\ No newline at end of file
diff --git a/maven-all/version-collision/project-b/pom.xml b/maven-all/version-collision/project-b/pom.xml
new file mode 100644
index 0000000000..0b0f50aeb8
--- /dev/null
+++ b/maven-all/version-collision/project-b/pom.xml
@@ -0,0 +1,21 @@
+
+
+
+ version-collision
+ com.baeldung
+ 0.0.1-SNAPSHOT
+
+ 4.0.0
+
+ project-b
+
+
+
+ com.google.guava
+ guava
+ 29.0-jre
+
+
+
\ No newline at end of file
diff --git a/maven-all/version-collision/project-collision/pom.xml b/maven-all/version-collision/project-collision/pom.xml
new file mode 100644
index 0000000000..3bec0ed54a
--- /dev/null
+++ b/maven-all/version-collision/project-collision/pom.xml
@@ -0,0 +1,34 @@
+
+
+
+ version-collision
+ com.baeldung
+ 0.0.1-SNAPSHOT
+
+ 4.0.0
+
+ project-collision
+
+
+
+
+ com.baeldung
+ project-a
+ 0.0.1-SNAPSHOT
+
+
+
+
+
+
+
+
+
+ com.baeldung
+ project-b
+ 0.0.1-SNAPSHOT
+
+
+
\ No newline at end of file
diff --git a/maven-all/version-collision/project-collision/src/test/java/com/baeldung/version/collision/VersionCollisionUnitTest.java b/maven-all/version-collision/project-collision/src/test/java/com/baeldung/version/collision/VersionCollisionUnitTest.java
new file mode 100644
index 0000000000..de0b3a7776
--- /dev/null
+++ b/maven-all/version-collision/project-collision/src/test/java/com/baeldung/version/collision/VersionCollisionUnitTest.java
@@ -0,0 +1,14 @@
+package com.baeldung.version.collision;
+
+import com.google.common.util.concurrent.Futures;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+public class VersionCollisionUnitTest {
+ @Test
+ public void whenVersionCollisionDoesNotExist_thenShouldCompile() {
+ assertThat(Futures.immediateVoidFuture(), notNullValue());
+ }
+}
\ No newline at end of file
diff --git a/maven-modules/maven-exec-plugin/README.md b/maven-modules/maven-exec-plugin/README.md
new file mode 100644
index 0000000000..411639aae1
--- /dev/null
+++ b/maven-modules/maven-exec-plugin/README.md
@@ -0,0 +1,5 @@
+## Maven WAR Plugin
+
+This module contains articles about the Maven Exec Plugin.
+
+### Relevant Articles
diff --git a/maven-modules/maven-exec-plugin/pom.xml b/maven-modules/maven-exec-plugin/pom.xml
new file mode 100644
index 0000000000..6c12971e29
--- /dev/null
+++ b/maven-modules/maven-exec-plugin/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+ com.baeldung
+ maven-exec-plugin
+ 0.0.1-SNAPSHOT
+ maven-exec-plugin
+
+
+ 3.8.1
+ 1.8
+ 1.2.3
+
+
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback-classic.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${java.version}
+ ${java.version}
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.0.0
+
+ com.baeldung.main.Exec
+
+ First
+ Second
+ Third
+
+
+
+
+
+
+
diff --git a/maven-modules/maven-exec-plugin/src/main/java/com/baeldung/main/Exec.java b/maven-modules/maven-exec-plugin/src/main/java/com/baeldung/main/Exec.java
new file mode 100644
index 0000000000..5a1494cf4a
--- /dev/null
+++ b/maven-modules/maven-exec-plugin/src/main/java/com/baeldung/main/Exec.java
@@ -0,0 +1,18 @@
+package com.baeldung.main;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+
+public class Exec {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(Exec.class);
+
+ public static void main(String[] args) {
+ LOGGER.info("Running the main method");
+ if (args.length > 0) {
+ LOGGER.info("List of arguments: {}", Arrays.toString(args));
+ }
+ }
+}
diff --git a/maven-modules/pom.xml b/maven-modules/pom.xml
index 56e0bd2bdc..b00da22519 100644
--- a/maven-modules/pom.xml
+++ b/maven-modules/pom.xml
@@ -16,6 +16,7 @@
maven-custom-plugin
+ maven-exec-plugin
maven-integration-test
maven-multi-source
maven-plugins
@@ -23,6 +24,7 @@
maven-war-plugin
maven-profiles
versions-maven-plugin
+ version-collision
diff --git a/maven-modules/version-collision/child-module/pom.xml b/maven-modules/version-collision/child-module/pom.xml
new file mode 100644
index 0000000000..7784bc5953
--- /dev/null
+++ b/maven-modules/version-collision/child-module/pom.xml
@@ -0,0 +1,21 @@
+
+
+
+ version-collision
+ com.baeldung
+ 0.0.1-SNAPSHOT
+
+ 4.0.0
+
+ child-module
+
+
+
+ org.apache.maven
+ maven-core
+ 3.3.9
+
+
+
\ No newline at end of file
diff --git a/maven-modules/version-collision/pom.xml b/maven-modules/version-collision/pom.xml
new file mode 100644
index 0000000000..9a38fd0edb
--- /dev/null
+++ b/maven-modules/version-collision/pom.xml
@@ -0,0 +1,44 @@
+
+
+
+ maven-all
+ com.baeldung
+ 0.0.1-SNAPSHOT
+
+ 4.0.0
+
+ version-collision
+ pom
+
+
+ child-module
+
+
+
+
+ org.apache.commons
+ commons-configuration2
+ 2.7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pdf/README.md b/pdf/README.md
index b904b101fb..bed468ad24 100644
--- a/pdf/README.md
+++ b/pdf/README.md
@@ -6,3 +6,4 @@ This module contains articles about PDF files.
- [PDF Conversions in Java](https://www.baeldung.com/pdf-conversions-java)
- [Creating PDF Files in Java](https://www.baeldung.com/java-pdf-creation)
- [Generating PDF Files Using Thymeleaf](https://www.baeldung.com/thymeleaf-generate-pdf)
+- [Java Convert PDF to Base64](https://www.baeldung.com/java-convert-pdf-to-base64)
diff --git a/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/pdf/base64/EncodeDecodeUnitTest.java b/pdf/src/test/java/com/baeldung/pdf/base64/EncodeDecodeUnitTest.java
similarity index 94%
rename from core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/pdf/base64/EncodeDecodeUnitTest.java
rename to pdf/src/test/java/com/baeldung/pdf/base64/EncodeDecodeUnitTest.java
index 0df6f58136..db76f9a0c8 100644
--- a/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/pdf/base64/EncodeDecodeUnitTest.java
+++ b/pdf/src/test/java/com/baeldung/pdf/base64/EncodeDecodeUnitTest.java
@@ -1,8 +1,7 @@
package com.baeldung.pdf.base64;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
+import org.junit.BeforeClass;
+import org.junit.Test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -11,8 +10,7 @@ import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import static org.junit.Assert.*;
public class EncodeDecodeUnitTest {
diff --git a/core-java-modules/core-java-string-operations-2/src/test/resources/input.pdf b/pdf/src/test/resources/input.pdf
similarity index 100%
rename from core-java-modules/core-java-string-operations-2/src/test/resources/input.pdf
rename to pdf/src/test/resources/input.pdf
diff --git a/core-java-modules/core-java-string-operations-2/src/test/resources/output.pdf b/pdf/src/test/resources/output.pdf
similarity index 100%
rename from core-java-modules/core-java-string-operations-2/src/test/resources/output.pdf
rename to pdf/src/test/resources/output.pdf
diff --git a/performance-tests/pom.xml b/performance-tests/pom.xml
index 8c66794cfc..0dc38e56a4 100644
--- a/performance-tests/pom.xml
+++ b/performance-tests/pom.xml
@@ -164,8 +164,6 @@
- UTF-8
-
@@ -176,7 +174,6 @@
1.2.0.Final
1.1.0
1.6.0.1
- 1.8
1.2.0.Final
1.21
1.21
diff --git a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/JdbcDriverLoadingUnitTest.java b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/JdbcDriverLoadingUnitTest.java
new file mode 100644
index 0000000000..387c050285
--- /dev/null
+++ b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/JdbcDriverLoadingUnitTest.java
@@ -0,0 +1,72 @@
+package com.baeldung.jdbc;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+public class JdbcDriverLoadingUnitTest {
+
+ @Before
+ public void setup() throws SQLException {
+ if (!org.postgresql.Driver.isRegistered()) {
+ org.postgresql.Driver.register();
+ }
+ }
+ /**
+ * Driver is registered automatically with the service provider mechanism.
+ */
+ @Test
+ public void givenJdbcDriverWithSP_whenGettingDriver_thenDriverIsReturned() throws SQLException {
+ Driver driver = getDriver();
+ assertNotNull("Expected initialized postgres driver", driver);
+ }
+
+ /**
+ * Driver is registered automatically, then deregistered.
+ * @throws SQLException
+ */
+ @Test(expected = SQLException.class)
+ public void givenRegisteredJdbcDriver_whenDeregister_thenNoDriverIsReturned() throws SQLException {
+ Driver driver = getDriver();
+ DriverManager.deregisterDriver(driver);
+ driver = getDriver();
+ assertNull(driver);
+ }
+
+ /**
+ * Driver is automatically by the JVM, then deregistered, then registered again.
+ * @throws SQLException
+ * @throws ClassNotFoundException
+ */
+ @Test
+ public void givenNoRegisteredDriver_whenClassForName_thenDriverIsReturned() throws SQLException, ClassNotFoundException {
+ deregisterDriver();
+
+ Driver driver = null;
+ try {
+ driver = getDriver();
+ }
+ catch (SQLException e) {
+ // expected
+ }
+ assertNull("Must fail on attempt to get a deregistered driver", driver);
+
+ org.postgresql.Driver.register(); // This is invoked as part of Class.forName() logic
+
+ driver = getDriver();
+ assertNotNull("Driver must register as part of class loading", driver);
+ }
+
+ private void deregisterDriver() throws SQLException {
+ org.postgresql.Driver.deregister();
+ }
+
+ private Driver getDriver() throws SQLException {
+ return DriverManager.getDriver("jdbc:postgresql:");
+ }
+}
diff --git a/persistence-modules/hibernate-exceptions/pom.xml b/persistence-modules/hibernate-exceptions/pom.xml
index e5217e83bd..f7eee22960 100644
--- a/persistence-modules/hibernate-exceptions/pom.xml
+++ b/persistence-modules/hibernate-exceptions/pom.xml
@@ -33,7 +33,6 @@
2.4.0
2.3.0
- 5.3.7.Final
diff --git a/persistence-modules/hibernate-libraries/pom.xml b/persistence-modules/hibernate-libraries/pom.xml
index ea2dda7e88..808c47133c 100644
--- a/persistence-modules/hibernate-libraries/pom.xml
+++ b/persistence-modules/hibernate-libraries/pom.xml
@@ -171,7 +171,6 @@
2.9.7
5.4.14.Final
2.10.3
- 1.8
3.27.0-GA
2.3.1
2.0.0
diff --git a/persistence-modules/hibernate-queries/pom.xml b/persistence-modules/hibernate-queries/pom.xml
index a439ded9df..06f7f42088 100644
--- a/persistence-modules/hibernate-queries/pom.xml
+++ b/persistence-modules/hibernate-queries/pom.xml
@@ -71,7 +71,6 @@
- 5.3.7.Final
6.0.6
2.2.3
3.8.0
diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml
index efef4f2015..f1154f203b 100644
--- a/persistence-modules/pom.xml
+++ b/persistence-modules/pom.xml
@@ -78,4 +78,8 @@
spring-persistence-simple-2
+
+
+ 5.2.17.Final
+
diff --git a/persistence-modules/r2dbc/pom.xml b/persistence-modules/r2dbc/pom.xml
index d0f53ba37c..2da81cba06 100644
--- a/persistence-modules/r2dbc/pom.xml
+++ b/persistence-modules/r2dbc/pom.xml
@@ -62,7 +62,6 @@
- 1.8
0.8.1.RELEASE
1.4.200
diff --git a/persistence-modules/spring-boot-persistence/pom.xml b/persistence-modules/spring-boot-persistence/pom.xml
index cc26ff58d5..9e44a7b9c1 100644
--- a/persistence-modules/spring-boot-persistence/pom.xml
+++ b/persistence-modules/spring-boot-persistence/pom.xml
@@ -74,7 +74,6 @@
- UTF-8
2.23.0
2.0.1.Final
diff --git a/persistence-modules/spring-data-geode/pom.xml b/persistence-modules/spring-data-geode/pom.xml
index 557d09376a..07aa65463c 100644
--- a/persistence-modules/spring-data-geode/pom.xml
+++ b/persistence-modules/spring-data-geode/pom.xml
@@ -85,7 +85,6 @@
2.1.9.RELEASE
- UTF-8
com.baeldung.springdatageode.app.ClientCacheApp
1.1.1.RELEASE
2.1.9.RELEASE
diff --git a/persistence-modules/spring-data-jpa-5/pom.xml b/persistence-modules/spring-data-jpa-5/pom.xml
index f09c83ab11..db58a16062 100644
--- a/persistence-modules/spring-data-jpa-5/pom.xml
+++ b/persistence-modules/spring-data-jpa-5/pom.xml
@@ -71,7 +71,6 @@
2.1.9.RELEASE
- UTF-8
com.baeldung.springdatageode.app.ClientCacheApp
1.1.1.RELEASE
2.1.9.RELEASE
diff --git a/persistence-modules/spring-jpa/pom.xml b/persistence-modules/spring-jpa/pom.xml
index ef05269c92..410ed592b0 100644
--- a/persistence-modules/spring-jpa/pom.xml
+++ b/persistence-modules/spring-jpa/pom.xml
@@ -133,8 +133,6 @@
5.1.5.RELEASE
3.21.0-GA
-
- 5.2.17.Final
6.0.6
2.1.5.RELEASE
diff --git a/spf4j/spf4j-aspects-app/pom.xml b/spf4j/spf4j-aspects-app/pom.xml
index db6a18f26a..24a419233e 100644
--- a/spf4j/spf4j-aspects-app/pom.xml
+++ b/spf4j/spf4j-aspects-app/pom.xml
@@ -81,7 +81,6 @@
- UTF-8
8.6.10
1.7.21
3.8.0
diff --git a/spf4j/spf4j-core-app/pom.xml b/spf4j/spf4j-core-app/pom.xml
index 48cbf4a1c9..280a59e0d9 100644
--- a/spf4j/spf4j-core-app/pom.xml
+++ b/spf4j/spf4j-core-app/pom.xml
@@ -81,7 +81,6 @@
- UTF-8
8.6.10
1.7.21
3.8.0
diff --git a/spring-5-reactive-oauth/pom.xml b/spring-5-reactive-oauth/pom.xml
index e286e821b2..e9882a6d32 100644
--- a/spring-5-reactive-oauth/pom.xml
+++ b/spring-5-reactive-oauth/pom.xml
@@ -65,8 +65,6 @@
- UTF-8
- UTF-8
2.1.0.RELEASE
diff --git a/spring-5-webflux/pom.xml b/spring-5-webflux/pom.xml
index 22f429da2a..292e4d7ad9 100644
--- a/spring-5-webflux/pom.xml
+++ b/spring-5-webflux/pom.xml
@@ -64,7 +64,4 @@
-
- 2.2.0.RELEASE
-
diff --git a/spring-activiti/pom.xml b/spring-activiti/pom.xml
index eef4d37ff8..4803827b45 100644
--- a/spring-activiti/pom.xml
+++ b/spring-activiti/pom.xml
@@ -56,8 +56,6 @@
- UTF-8
- UTF-8
6.0.0
diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml
index e1198dec98..84f1f0e86c 100644
--- a/spring-boot-modules/pom.xml
+++ b/spring-boot-modules/pom.xml
@@ -49,6 +49,7 @@
spring-boot-kotlin
spring-boot-mvc
spring-boot-mvc-2
+ spring-boot-mvc-3
spring-boot-mvc-birt
spring-boot-nashorn
spring-boot-parent
@@ -65,16 +66,33 @@
+
+
+
+ org.junit
+ junit-bom
+ ${junit-jupiter.version}
+ pom
+ import
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
org.junit.jupiter
junit-jupiter
- test
org.junit.vintage
junit-vintage-engine
- test
@@ -90,5 +108,6 @@
5.6.2
+ 2.6
diff --git a/spring-boot-modules/spring-boot-crud/pom.xml b/spring-boot-modules/spring-boot-crud/pom.xml
index c27afe3926..8ba7bab171 100644
--- a/spring-boot-modules/spring-boot-crud/pom.xml
+++ b/spring-boot-modules/spring-boot-crud/pom.xml
@@ -81,8 +81,4 @@
-
- UTF-8
-
-
diff --git a/spring-boot-modules/spring-boot-libraries/pom.xml b/spring-boot-modules/spring-boot-libraries/pom.xml
index 189eb4cf1a..05ab59aab7 100644
--- a/spring-boot-modules/spring-boot-libraries/pom.xml
+++ b/spring-boot-modules/spring-boot-libraries/pom.xml
@@ -9,10 +9,10 @@
This is simple boot application for Spring boot actuator test
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+ ../
diff --git a/spring-boot-modules/spring-boot-mvc-2/pom.xml b/spring-boot-modules/spring-boot-mvc-2/pom.xml
index 45202d1e4c..73a75f020c 100644
--- a/spring-boot-modules/spring-boot-mvc-2/pom.xml
+++ b/spring-boot-modules/spring-boot-mvc-2/pom.xml
@@ -3,18 +3,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-mvc-2
- spring-boot-mvc-2
- jar
- Module For Spring Boot MVC Web Fn
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+ ../
+ spring-boot-mvc-2
+ jar
+
+ spring-boot-mvc-2
+ Module For Spring Boot MVC Web Fn
+
org.springframework.boot
@@ -99,8 +101,7 @@
3.0.0-SNAPSHOT
com.baeldung.swagger2boot.SpringBootSwaggerApplication
- 2.2.6.RELEASE
- 1.4.11.1
+ 1.4.11.1
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-mvc-3/pom.xml b/spring-boot-modules/spring-boot-mvc-3/pom.xml
index 64e8a99c6c..71b7383ef4 100644
--- a/spring-boot-modules/spring-boot-mvc-3/pom.xml
+++ b/spring-boot-modules/spring-boot-mvc-3/pom.xml
@@ -3,18 +3,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-mvc-3
- spring-boot-mvc-3
- jar
- Module For Spring Boot MVC Web
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+ ../
+ spring-boot-mvc-3
+ jar
+
+ spring-boot-mvc-3
+ Module For Spring Boot MVC Web
+
org.springframework.boot
diff --git a/spring-boot-modules/spring-boot-mvc-birt/pom.xml b/spring-boot-modules/spring-boot-mvc-birt/pom.xml
index 0e8e231a84..0ab744bb26 100644
--- a/spring-boot-modules/spring-boot-mvc-birt/pom.xml
+++ b/spring-boot-modules/spring-boot-mvc-birt/pom.xml
@@ -3,19 +3,21 @@
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-mvc-birt
- 0.0.1-SNAPSHOT
- spring-boot-mvc-birt
- jar
- Module For Spring Boot Integration with BIRT
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+ ../
+ spring-boot-mvc-birt
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-boot-mvc-birt
+ Module For Spring Boot Integration with BIRT
+
org.springframework.boot
diff --git a/spring-boot-modules/spring-boot-mvc/pom.xml b/spring-boot-modules/spring-boot-mvc/pom.xml
index 019d29285c..fd6f1b0a8a 100644
--- a/spring-boot-modules/spring-boot-mvc/pom.xml
+++ b/spring-boot-modules/spring-boot-mvc/pom.xml
@@ -3,18 +3,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-mvc
- spring-boot-mvc
- jar
- Module For Spring Boot MVC
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+ ../
-
+
+ spring-boot-mvc
+ jar
+
+ spring-boot-mvc
+ Module For Spring Boot MVC
+
diff --git a/spring-boot-modules/spring-boot-nashorn/pom.xml b/spring-boot-modules/spring-boot-nashorn/pom.xml
index c60997005d..ca0b726a47 100644
--- a/spring-boot-modules/spring-boot-nashorn/pom.xml
+++ b/spring-boot-modules/spring-boot-nashorn/pom.xml
@@ -3,18 +3,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
+
+
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+ ../
+
+
com.baeldung.nashorn
spring-boot-nashorn
1.0
- spring-boot-nashorn
jar
-
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
-
+ spring-boot-nashorn
diff --git a/spring-boot-modules/spring-boot-parent/pom.xml b/spring-boot-modules/spring-boot-parent/pom.xml
index cf0a6702ea..ebd3cd5d36 100644
--- a/spring-boot-modules/spring-boot-parent/pom.xml
+++ b/spring-boot-modules/spring-boot-parent/pom.xml
@@ -3,21 +3,23 @@
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-parent
- 1.0.0-SNAPSHOT
- spring-boot-parent
- pom
- spring-boot-parent
com.baeldung.spring-boot-modules
spring-boot-modules
1.0.0-SNAPSHOT
+ ../
+ spring-boot-parent
+ 1.0.0-SNAPSHOT
+ pom
+
+ spring-boot-parent
+ spring-boot-parent
+
spring-boot-with-starter-parent
spring-boot-with-custom-parent
-
diff --git a/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml b/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml
index d08384e34c..5f5d3a9f6a 100644
--- a/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml
+++ b/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml
@@ -3,17 +3,19 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- spring-boot-with-custom-parent
- 1.0.0-SNAPSHOT
- spring-boot-with-custom-parent
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../../parent-boot-2
+ com.baeldung.spring-boot-modules
+ spring-boot-parent
+ 1.0.0-SNAPSHOT
+ ../
+ spring-boot-with-custom-parent
+ 1.0.0-SNAPSHOT
+
+ spring-boot-with-custom-parent
+
org.springframework.boot
diff --git a/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml b/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml
index 331a85ec5b..7413492d7f 100644
--- a/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml
+++ b/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml
@@ -3,17 +3,19 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
+
+
+ com.baeldung.spring-boot-modules
+ spring-boot-parent
+ 1.0.0-SNAPSHOT
+ ../
+
+
com.baeldung
spring-boot-with-starter-parent
1.0.0-SNAPSHOT
- spring-boot-with-starter-parent
-
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../../parent-boot-2
-
+ spring-boot-with-starter-parent
diff --git a/spring-boot-modules/spring-boot-performance/pom.xml b/spring-boot-modules/spring-boot-performance/pom.xml
index 1f3eafd96c..053f68eea3 100644
--- a/spring-boot-modules/spring-boot-performance/pom.xml
+++ b/spring-boot-modules/spring-boot-performance/pom.xml
@@ -2,18 +2,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-performance
- spring-boot-performance
- war
- This is a simple Spring Boot application taking advantage of the latest Spring Boot improvements/features. Current version: 2.2
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+ ../
+ spring-boot-performance
+ war
+
+ spring-boot-performance
+ This is a simple Spring Boot application taking advantage of the latest Spring Boot improvements/features. Current version: 2.2
+
org.springframework.boot
diff --git a/spring-boot-modules/spring-boot-properties-2/pom.xml b/spring-boot-modules/spring-boot-properties-2/pom.xml
index bd2a35b19d..e777b8f318 100644
--- a/spring-boot-modules/spring-boot-properties-2/pom.xml
+++ b/spring-boot-modules/spring-boot-properties-2/pom.xml
@@ -2,19 +2,21 @@
4.0.0
- spring-boot-properties-2
- spring-boot-properties-2
- jar
- Spring Boot Properties Module
- 0.0.1-SNAPSHOT
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+ ../
+ spring-boot-properties-2
+ jar
+ 0.0.1-SNAPSHOT
+
+ spring-boot-properties-2
+ Spring Boot Properties Module
+
org.springframework.boot
diff --git a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/yamllist/YamlListApplication.java b/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/yamllist/YamlListApplication.java
new file mode 100644
index 0000000000..c8fa1af22e
--- /dev/null
+++ b/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/yamllist/YamlListApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.properties.yamllist;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class YamlListApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(YamlListApplication.class, args);
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/yamllist/pojo/ApplicationProps.java b/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/yamllist/pojo/ApplicationProps.java
new file mode 100644
index 0000000000..f05e3cbbff
--- /dev/null
+++ b/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/yamllist/pojo/ApplicationProps.java
@@ -0,0 +1,72 @@
+package com.baeldung.properties.yamllist.pojo;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "application")
+public class ApplicationProps {
+
+ private List
diff --git a/spring-boot-modules/spring-boot-security/pom.xml b/spring-boot-modules/spring-boot-security/pom.xml
index b9f28b68c4..33b7cbfd74 100644
--- a/spring-boot-modules/spring-boot-security/pom.xml
+++ b/spring-boot-modules/spring-boot-security/pom.xml
@@ -2,18 +2,20 @@
4.0.0
- spring-boot-security
- spring-boot-security
- Spring Boot Security Auto-Configuration
- jar
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+ ../
+ spring-boot-security
+ jar
+
+ spring-boot-security
+ Spring Boot Security Auto-Configuration
+
org.springframework.boot
@@ -84,9 +86,7 @@
com.baeldung.springbootsecurity.basic_auth.SpringBootSecurityApplication
- 2.6
2.4.0.RELEASE
- 2.6
2.2.2.RELEASE
diff --git a/spring-boot-modules/spring-boot-springdoc/pom.xml b/spring-boot-modules/spring-boot-springdoc/pom.xml
index 4bede8c796..3e8d5175f7 100644
--- a/spring-boot-modules/spring-boot-springdoc/pom.xml
+++ b/spring-boot-modules/spring-boot-springdoc/pom.xml
@@ -4,19 +4,21 @@
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-springdoc
- 0.0.1-SNAPSHOT
- spring-boot-springdoc
- jar
- Project for Springdoc integration
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+ ../
+ spring-boot-springdoc
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-boot-springdoc
+ Project for Springdoc integration
+
org.springframework.boot
diff --git a/spring-boot-modules/spring-boot-testing/pom.xml b/spring-boot-modules/spring-boot-testing/pom.xml
index 8353f9de61..a3b176af88 100644
--- a/spring-boot-modules/spring-boot-testing/pom.xml
+++ b/spring-boot-modules/spring-boot-testing/pom.xml
@@ -3,18 +3,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-testing
- spring-boot-testing
- war
- This is simple boot application for demonstrating testing features.
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+ ../
+ spring-boot-testing
+ war
+
+ spring-boot-testing
+ This is simple boot application for demonstrating testing features.
+
org.springframework.boot
diff --git a/spring-boot-modules/spring-boot-vue/pom.xml b/spring-boot-modules/spring-boot-vue/pom.xml
index 0a6307e46b..9973246115 100644
--- a/spring-boot-modules/spring-boot-vue/pom.xml
+++ b/spring-boot-modules/spring-boot-vue/pom.xml
@@ -2,19 +2,21 @@
4.0.0
- spring-boot-vue
- 0.0.1-SNAPSHOT
- spring-boot-vue
- jar
- Demo project for Spring Boot Vue project
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+ ../
+ spring-boot-vue
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-boot-vue
+ Demo project for Spring Boot Vue project
+
org.springframework.boot
@@ -43,9 +45,4 @@
-
- UTF-8
- UTF-8
-
-
diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/pom.xml b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/pom.xml
index 43772505a4..f4557335d6 100644
--- a/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/pom.xml
+++ b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/pom.xml
@@ -60,8 +60,6 @@
- UTF-8
- UTF-8
Hoxton.SR4
diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/pom.xml b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/pom.xml
index f0d18a1c4f..81f194c772 100644
--- a/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/pom.xml
+++ b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/pom.xml
@@ -52,8 +52,6 @@
- UTF-8
- UTF-8
Hoxton.SR4
diff --git a/spring-cloud/spring-cloud-bootstrap/README.md b/spring-cloud/spring-cloud-bootstrap/README.md
index 01998ccf51..223c21b762 100644
--- a/spring-cloud/spring-cloud-bootstrap/README.md
+++ b/spring-cloud/spring-cloud-bootstrap/README.md
@@ -11,6 +11,7 @@ This module contains articles about bootstrapping Spring Cloud applications
### Running the Project
+- First, you need a redis server running on the default port
- To run the project:
- copy the appliction-config folder to c:\Users\{username}\ on Windows or /home/{username}/ on *nix. Then open a git bash terminal in application-config and run:
- git init
diff --git a/spring-cloud/spring-cloud-bootstrap/customer-service/pom.xml b/spring-cloud/spring-cloud-bootstrap/customer-service/pom.xml
index 35f8aceb8d..8fcf4adadb 100644
--- a/spring-cloud/spring-cloud-bootstrap/customer-service/pom.xml
+++ b/spring-cloud/spring-cloud-bootstrap/customer-service/pom.xml
@@ -76,9 +76,7 @@
- 1.8
1.8
1.8
- UTF-8
diff --git a/spring-cloud/spring-cloud-bootstrap/order-service/pom.xml b/spring-cloud/spring-cloud-bootstrap/order-service/pom.xml
index b626c3b81b..a1c6c1c39f 100644
--- a/spring-cloud/spring-cloud-bootstrap/order-service/pom.xml
+++ b/spring-cloud/spring-cloud-bootstrap/order-service/pom.xml
@@ -117,7 +117,6 @@
0.0.2
1.8
1.8
- UTF-8
com.baeldung.orderservice.OrderApplication
diff --git a/spring-cloud/spring-cloud-contract/pom.xml b/spring-cloud/spring-cloud-contract/pom.xml
index 2f868980db..f26f1d7e3b 100644
--- a/spring-cloud/spring-cloud-contract/pom.xml
+++ b/spring-cloud/spring-cloud-contract/pom.xml
@@ -53,8 +53,6 @@
- UTF-8
- UTF-8
2.1.1.RELEASE
2.1.4.RELEASE
diff --git a/spring-cloud/spring-cloud-functions/pom.xml b/spring-cloud/spring-cloud-functions/pom.xml
index 03510d0504..4654d70dd7 100644
--- a/spring-cloud/spring-cloud-functions/pom.xml
+++ b/spring-cloud/spring-cloud-functions/pom.xml
@@ -82,8 +82,6 @@
- UTF-8
- UTF-8
1.0.1.RELEASE
2.0.2
1.1.0
diff --git a/spring-cloud/spring-cloud-ribbon-retry/ribbon-client-service/src/main/resources/application.yml b/spring-cloud/spring-cloud-ribbon-retry/ribbon-client-service/src/main/resources/application.yml
index 3199f38dce..29d2360793 100644
--- a/spring-cloud/spring-cloud-ribbon-retry/ribbon-client-service/src/main/resources/application.yml
+++ b/spring-cloud/spring-cloud-ribbon-retry/ribbon-client-service/src/main/resources/application.yml
@@ -9,7 +9,7 @@ weather-service:
ribbon:
eureka:
enabled: false
- listOfServers: http://localhost:8081, http://localhost:8082
+ listOfServers: http://localhost:8021, http://localhost:8022
ServerListRefreshInterval: 5000
MaxAutoRetries: 3
MaxAutoRetriesNextServer: 1
diff --git a/spring-cloud/spring-cloud-ribbon-retry/ribbon-client-service/src/test/java/com/baeldung/spring/cloud/ribbon/retry/RibbonRetryFailureIntegrationTest.java b/spring-cloud/spring-cloud-ribbon-retry/ribbon-client-service/src/test/java/com/baeldung/spring/cloud/ribbon/retry/RibbonRetryFailureIntegrationTest.java
index 0e72bdbb86..0f0a1c4255 100644
--- a/spring-cloud/spring-cloud-ribbon-retry/ribbon-client-service/src/test/java/com/baeldung/spring/cloud/ribbon/retry/RibbonRetryFailureIntegrationTest.java
+++ b/spring-cloud/spring-cloud-ribbon-retry/ribbon-client-service/src/test/java/com/baeldung/spring/cloud/ribbon/retry/RibbonRetryFailureIntegrationTest.java
@@ -24,8 +24,8 @@ public class RibbonRetryFailureIntegrationTest {
@BeforeAll
public static void setup() {
- weatherServiceInstance1 = startApp(8081);
- weatherServiceInstance2 = startApp(8082);
+ weatherServiceInstance1 = startApp(8021);
+ weatherServiceInstance2 = startApp(8022);
}
@AfterAll
diff --git a/spring-cloud/spring-cloud-ribbon-retry/ribbon-client-service/src/test/java/com/baeldung/spring/cloud/ribbon/retry/RibbonRetrySuccessIntegrationTest.java b/spring-cloud/spring-cloud-ribbon-retry/ribbon-client-service/src/test/java/com/baeldung/spring/cloud/ribbon/retry/RibbonRetrySuccessIntegrationTest.java
index 2055159117..6fdad0f2a9 100644
--- a/spring-cloud/spring-cloud-ribbon-retry/ribbon-client-service/src/test/java/com/baeldung/spring/cloud/ribbon/retry/RibbonRetrySuccessIntegrationTest.java
+++ b/spring-cloud/spring-cloud-ribbon-retry/ribbon-client-service/src/test/java/com/baeldung/spring/cloud/ribbon/retry/RibbonRetrySuccessIntegrationTest.java
@@ -25,8 +25,8 @@ public class RibbonRetrySuccessIntegrationTest {
@BeforeAll
public static void setup() {
- weatherServiceInstance1 = startApp(8081);
- weatherServiceInstance2 = startApp(8082);
+ weatherServiceInstance1 = startApp(8021);
+ weatherServiceInstance2 = startApp(8022);
}
private static ConfigurableApplicationContext startApp(int port) {
diff --git a/spring-cloud/spring-cloud-vault/pom.xml b/spring-cloud/spring-cloud-vault/pom.xml
index dbdbcb2c50..a5a29d9024 100644
--- a/spring-cloud/spring-cloud-vault/pom.xml
+++ b/spring-cloud/spring-cloud-vault/pom.xml
@@ -78,8 +78,6 @@
- UTF-8
- UTF-8
Greenwich.RELEASE
diff --git a/spring-cloud/spring-cloud-zuul/pom.xml b/spring-cloud/spring-cloud-zuul/pom.xml
index e0a63ae00b..140a1337b3 100644
--- a/spring-cloud/spring-cloud-zuul/pom.xml
+++ b/spring-cloud/spring-cloud-zuul/pom.xml
@@ -72,8 +72,6 @@
- UTF-8
- UTF-8
Hoxton.RELEASE
2.2.2.RELEASE
diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml
index 34f0e6b7ae..fd6d18fc09 100644
--- a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml
+++ b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml
@@ -48,8 +48,6 @@
- UTF-8
- UTF-8
Finchley.SR1
2.0.6.RELEASE
2.2.0.RELEASE
diff --git a/spring-data-rest/pom.xml b/spring-data-rest/pom.xml
index bb592c08d5..741d146fbf 100644
--- a/spring-data-rest/pom.xml
+++ b/spring-data-rest/pom.xml
@@ -88,7 +88,6 @@
- UTF-8
com.baeldung.books.SpringDataRestApplication
1.0
diff --git a/spring-ejb/ejb-beans/pom.xml b/spring-ejb/ejb-beans/pom.xml
index feb212b5a6..299de584ef 100644
--- a/spring-ejb/ejb-beans/pom.xml
+++ b/spring-ejb/ejb-beans/pom.xml
@@ -31,7 +31,6 @@
javaee-api
provided
-
org.apache.openejb
tomee-embedded
@@ -81,6 +80,62 @@
+
+ wildfly-managed-arquillian
+
+ true
+
+
+
+ org.wildfly
+ wildfly-arquillian-container-managed
+ ${wildfly.version}
+ test
+
+
+
+
+
+
+ maven-dependency-plugin
+ ${maven-dependency-plugin.version}
+
+ ${maven.test.skip}
+
+
+
+ unpack
+ process-test-classes
+
+ unpack
+
+
+
+
+ org.wildfly
+ wildfly-dist
+ ${wildfly.version}
+ zip
+ false
+ ${project.build.directory}
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+ always
+
+
+
+
+
arquillian-glassfish-embedded
@@ -117,12 +172,15 @@
1.7.5
3.1.2
1.0.0.CR4
+ 8.2.1.Final
3.2
5.2.3.RELEASE
5.10.2
5.13.1
2.21.0
1.8.5
+ 2.8
+ 8.2.1.Final
diff --git a/spring-ejb/ejb-beans/src/test/java/com/baeldung/ejb/stateless/StatelessEJBIntegrationTest.java b/spring-ejb/ejb-beans/src/test/java/com/baeldung/ejb/stateless/StatelessEJBIntegrationTest.java
index a970ef90ae..f74d62c36a 100644
--- a/spring-ejb/ejb-beans/src/test/java/com/baeldung/ejb/stateless/StatelessEJBIntegrationTest.java
+++ b/spring-ejb/ejb-beans/src/test/java/com/baeldung/ejb/stateless/StatelessEJBIntegrationTest.java
@@ -6,6 +6,7 @@ import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Assert;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -17,6 +18,7 @@ import javax.inject.Inject;
@RunWith(Arquillian.class)
+@Ignore("Will be fixed in BAEL-4422")
public class StatelessEJBIntegrationTest {
@Inject
diff --git a/spring-ejb/ejb-beans/src/test/resources/arquillian.xml b/spring-ejb/ejb-beans/src/test/resources/arquillian.xml
new file mode 100644
index 0000000000..3316f41f7c
--- /dev/null
+++ b/spring-ejb/ejb-beans/src/test/resources/arquillian.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ target/wildfly-8.2.1.Final
+ standalone.xml
+ true
+ 9990
+ -Djboss.http.port=8734
+
+
+
+
+
+ 127.0.0.1
+ 9990
+ admin
+ pass
+ true
+
+
+
+
\ No newline at end of file
diff --git a/spring-integration/pom.xml b/spring-integration/pom.xml
index a985f55d89..11b2803095 100644
--- a/spring-integration/pom.xml
+++ b/spring-integration/pom.xml
@@ -117,7 +117,6 @@
- UTF-8
5.0.13.RELEASE
1.1.4.RELEASE
1.4.7
diff --git a/spring-remoting/remoting-jms/remoting-jms-client/pom.xml b/spring-remoting/remoting-jms/remoting-jms-client/pom.xml
index d8b9701600..2f3f993b2e 100644
--- a/spring-remoting/remoting-jms/remoting-jms-client/pom.xml
+++ b/spring-remoting/remoting-jms/remoting-jms-client/pom.xml
@@ -30,8 +30,4 @@
-
- UTF-8
-
-
\ No newline at end of file
diff --git a/spring-remoting/remoting-jms/remoting-jms-server/pom.xml b/spring-remoting/remoting-jms/remoting-jms-server/pom.xml
index 5d6d63219d..53d95edcd7 100644
--- a/spring-remoting/remoting-jms/remoting-jms-server/pom.xml
+++ b/spring-remoting/remoting-jms/remoting-jms-server/pom.xml
@@ -30,8 +30,4 @@
-
- UTF-8
-
-
\ No newline at end of file
diff --git a/spring-remoting/remoting-rmi/remoting-rmi-server/pom.xml b/spring-remoting/remoting-rmi/remoting-rmi-server/pom.xml
index 94bdccd093..cb5eaa1031 100644
--- a/spring-remoting/remoting-rmi/remoting-rmi-server/pom.xml
+++ b/spring-remoting/remoting-rmi/remoting-rmi-server/pom.xml
@@ -30,8 +30,4 @@
-
- UTF-8
-
-
\ No newline at end of file
diff --git a/spring-rest-testing/pom.xml b/spring-rest-testing/pom.xml
index d807459cad..9bfe9d83a4 100644
--- a/spring-rest-testing/pom.xml
+++ b/spring-rest-testing/pom.xml
@@ -141,6 +141,10 @@
com.h2database
h2
+
+ net.bytebuddy
+ byte-buddy
+
diff --git a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/ExceptionTestingApplication.java b/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/ExceptionTestingApplication.java
new file mode 100644
index 0000000000..facc300dfa
--- /dev/null
+++ b/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/ExceptionTestingApplication.java
@@ -0,0 +1,25 @@
+package com.baeldung.exceptiontesting;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+/**
+ * Main Application Class - uses Spring Boot. Just run this as a normal Java
+ * class to run up a Jetty Server (on http://localhost:8082/spring-rest-full)
+ *
+ */
+@EnableScheduling
+@EnableAutoConfiguration
+@ComponentScan("com.baeldung.exceptiontesting")
+@SpringBootApplication
+public class ExceptionTestingApplication extends SpringBootServletInitializer {
+
+ public static void main(final String[] args) {
+ SpringApplication.run(ExceptionTestingApplication.class, args);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/controller/ExceptionController.java b/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/controller/ExceptionController.java
new file mode 100644
index 0000000000..0f458b5f10
--- /dev/null
+++ b/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/controller/ExceptionController.java
@@ -0,0 +1,31 @@
+package com.baeldung.exceptiontesting.controller;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.exceptiontesting.exception.BadArgumentsException;
+import com.baeldung.exceptiontesting.exception.InternalException;
+import com.baeldung.exceptiontesting.exception.ResourceNotFoundException;
+
+@RestController
+public class ExceptionController {
+
+ @GetMapping("/exception/{exception_id}")
+ public void getSpecificException(@PathVariable("exception_id") String pException) {
+ if("not_found".equals(pException)) {
+ throw new ResourceNotFoundException("resource not found");
+ }
+ else if("bad_arguments".equals(pException)) {
+ throw new BadArgumentsException("bad arguments");
+ }
+ else {
+ throw new InternalException("internal error");
+ }
+ }
+
+ @GetMapping("/exception/throw")
+ public void getException() throws Exception {
+ throw new Exception("error");
+ }
+}
diff --git a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/BadArgumentsException.java b/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/BadArgumentsException.java
new file mode 100644
index 0000000000..1eb1e6a3c9
--- /dev/null
+++ b/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/BadArgumentsException.java
@@ -0,0 +1,13 @@
+package com.baeldung.exceptiontesting.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@SuppressWarnings("serial")
+@ResponseStatus(HttpStatus.BAD_REQUEST)
+public class BadArgumentsException extends RuntimeException {
+
+ public BadArgumentsException(String message) {
+ super(message);
+ }
+}
diff --git a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/InternalException.java b/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/InternalException.java
new file mode 100644
index 0000000000..8e9f0f60f3
--- /dev/null
+++ b/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/InternalException.java
@@ -0,0 +1,13 @@
+package com.baeldung.exceptiontesting.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@SuppressWarnings("serial")
+@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+public class InternalException extends RuntimeException {
+
+ public InternalException(String message) {
+ super(message);
+ }
+}
diff --git a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/ResourceNotFoundException.java b/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/ResourceNotFoundException.java
new file mode 100644
index 0000000000..469d5af96f
--- /dev/null
+++ b/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/ResourceNotFoundException.java
@@ -0,0 +1,13 @@
+package com.baeldung.exceptiontesting.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@SuppressWarnings("serial")
+@ResponseStatus(HttpStatus.NOT_FOUND)
+public class ResourceNotFoundException extends RuntimeException {
+
+ public ResourceNotFoundException(String message) {
+ super(message);
+ }
+}
diff --git a/spring-rest-testing/src/test/java/com/baeldung/exceptiontesting/controller/ExceptionControllerUnitTest.java b/spring-rest-testing/src/test/java/com/baeldung/exceptiontesting/controller/ExceptionControllerUnitTest.java
new file mode 100644
index 0000000000..d624efcdd0
--- /dev/null
+++ b/spring-rest-testing/src/test/java/com/baeldung/exceptiontesting/controller/ExceptionControllerUnitTest.java
@@ -0,0 +1,65 @@
+package com.baeldung.exceptiontesting.controller;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+
+import com.baeldung.exceptiontesting.controller.ExceptionController;
+import com.baeldung.exceptiontesting.exception.BadArgumentsException;
+import com.baeldung.exceptiontesting.exception.InternalException;
+import com.baeldung.exceptiontesting.exception.ResourceNotFoundException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+@RunWith(SpringRunner.class)
+@WebMvcTest(ExceptionController.class)
+public class ExceptionControllerUnitTest{
+
+ @Autowired
+ private MockMvc mvc;
+
+ @Test
+ public void givenNotFound_whenGetSpecificException_thenNotFoundCode() throws Exception {
+ String exceptionParam = "not_found";
+
+ mvc.perform(get("/exception/{exception_id}", exceptionParam)
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isNotFound())
+ .andExpect(result -> assertTrue(result.getResolvedException() instanceof ResourceNotFoundException))
+ .andExpect(result -> assertEquals("resource not found", result.getResolvedException().getMessage()));
+ }
+
+ @Test
+ public void givenBadArguments_whenGetSpecificException_thenBadRequest() throws Exception {
+ String exceptionParam = "bad_arguments";
+
+ mvc.perform(get("/exception/{exception_id}", exceptionParam)
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isBadRequest())
+ .andExpect(result -> assertTrue(result.getResolvedException() instanceof BadArgumentsException))
+ .andExpect(result -> assertEquals("bad arguments", result.getResolvedException().getMessage()));
+ }
+
+ @Test
+ public void givenOther_whenGetSpecificException_thenInternalServerError() throws Exception {
+ String exceptionParam = "dummy";
+
+ mvc.perform(get("/exception/{exception_id}", exceptionParam)
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isInternalServerError())
+ .andExpect(result -> assertTrue(result.getResolvedException() instanceof InternalException))
+ .andExpect(result -> assertEquals("internal error", result.getResolvedException().getMessage()));
+ }
+
+ @Test(expected = Exception.class)
+ public void whenGetException_thenInternalServerError() throws Exception {
+ mvc.perform(get("/exception/throw")
+ .contentType(MediaType.APPLICATION_JSON));
+ }
+}
diff --git a/spring-roo/pom.xml b/spring-roo/pom.xml
index 448574ed19..a3680ade70 100644
--- a/spring-roo/pom.xml
+++ b/spring-roo/pom.xml
@@ -605,11 +605,9 @@
2.0.0.RELEASE
8
- UTF-8
1.8
1.5.4
2.1.7.RELEASE
- 1.8
1.2.0.RELEASE
1.1.2
3.0.0.RELEASE
diff --git a/spring-security-modules/pom.xml b/spring-security-modules/pom.xml
index e78b7fe80c..472c6b6e0d 100644
--- a/spring-security-modules/pom.xml
+++ b/spring-security-modules/pom.xml
@@ -17,9 +17,8 @@
spring-security-acl
spring-security-auth0
spring-security-angular/server
- spring-security-cache-control
+ spring-security-config
spring-security-core
- spring-security-cors
spring-security-mvc
spring-security-mvc-boot-1
spring-security-mvc-boot-2
diff --git a/spring-security-modules/spring-security-cache-control/README.md b/spring-security-modules/spring-security-config/cache-control/README.md
similarity index 100%
rename from spring-security-modules/spring-security-cache-control/README.md
rename to spring-security-modules/spring-security-config/cache-control/README.md
diff --git a/spring-security-modules/spring-security-cache-control/pom.xml b/spring-security-modules/spring-security-config/cache-control/pom.xml
similarity index 87%
rename from spring-security-modules/spring-security-cache-control/pom.xml
rename to spring-security-modules/spring-security-config/cache-control/pom.xml
index 743b3c291d..753307493d 100644
--- a/spring-security-modules/spring-security-cache-control/pom.xml
+++ b/spring-security-modules/spring-security-config/cache-control/pom.xml
@@ -2,15 +2,15 @@
4.0.0
- spring-security-cache-control
+ cache-control
1.0-SNAPSHOT
- spring-security-cache-control
+ cache-control
com.baeldung
parent-boot-2
0.0.1-SNAPSHOT
- ../../parent-boot-2
+ ../../../parent-boot-2
diff --git a/spring-security-modules/spring-security-cache-control/src/main/java/com/baeldung/cachecontrol/AppRunner.java b/spring-security-modules/spring-security-config/cache-control/src/main/java/com/baeldung/cachecontrol/AppRunner.java
similarity index 100%
rename from spring-security-modules/spring-security-cache-control/src/main/java/com/baeldung/cachecontrol/AppRunner.java
rename to spring-security-modules/spring-security-config/cache-control/src/main/java/com/baeldung/cachecontrol/AppRunner.java
diff --git a/spring-security-modules/spring-security-cache-control/src/main/java/com/baeldung/cachecontrol/ResourceEndpoint.java b/spring-security-modules/spring-security-config/cache-control/src/main/java/com/baeldung/cachecontrol/ResourceEndpoint.java
similarity index 100%
rename from spring-security-modules/spring-security-cache-control/src/main/java/com/baeldung/cachecontrol/ResourceEndpoint.java
rename to spring-security-modules/spring-security-config/cache-control/src/main/java/com/baeldung/cachecontrol/ResourceEndpoint.java
diff --git a/spring-security-modules/spring-security-cache-control/src/main/java/com/baeldung/cachecontrol/config/SpringSecurityConfig.java b/spring-security-modules/spring-security-config/cache-control/src/main/java/com/baeldung/cachecontrol/config/SpringSecurityConfig.java
similarity index 100%
rename from spring-security-modules/spring-security-cache-control/src/main/java/com/baeldung/cachecontrol/config/SpringSecurityConfig.java
rename to spring-security-modules/spring-security-config/cache-control/src/main/java/com/baeldung/cachecontrol/config/SpringSecurityConfig.java
diff --git a/spring-security-modules/spring-security-cache-control/src/main/java/com/baeldung/cachecontrol/model/TimestampDto.java b/spring-security-modules/spring-security-config/cache-control/src/main/java/com/baeldung/cachecontrol/model/TimestampDto.java
similarity index 100%
rename from spring-security-modules/spring-security-cache-control/src/main/java/com/baeldung/cachecontrol/model/TimestampDto.java
rename to spring-security-modules/spring-security-config/cache-control/src/main/java/com/baeldung/cachecontrol/model/TimestampDto.java
diff --git a/spring-security-modules/spring-security-cache-control/src/main/java/com/baeldung/cachecontrol/model/UserDto.java b/spring-security-modules/spring-security-config/cache-control/src/main/java/com/baeldung/cachecontrol/model/UserDto.java
similarity index 100%
rename from spring-security-modules/spring-security-cache-control/src/main/java/com/baeldung/cachecontrol/model/UserDto.java
rename to spring-security-modules/spring-security-config/cache-control/src/main/java/com/baeldung/cachecontrol/model/UserDto.java
diff --git a/spring-security-modules/spring-security-cache-control/src/main/resources/logback.xml b/spring-security-modules/spring-security-config/cache-control/src/main/resources/logback.xml
similarity index 100%
rename from spring-security-modules/spring-security-cache-control/src/main/resources/logback.xml
rename to spring-security-modules/spring-security-config/cache-control/src/main/resources/logback.xml
diff --git a/spring-security-modules/spring-security-cache-control/src/test/java/com/baeldung/SpringContextTest.java b/spring-security-modules/spring-security-config/cache-control/src/test/java/com/baeldung/SpringContextTest.java
similarity index 100%
rename from spring-security-modules/spring-security-cache-control/src/test/java/com/baeldung/SpringContextTest.java
rename to spring-security-modules/spring-security-config/cache-control/src/test/java/com/baeldung/SpringContextTest.java
diff --git a/spring-security-modules/spring-security-cache-control/src/test/java/com/baeldung/cachecontrol/ResourceEndpointIntegrationTest.java b/spring-security-modules/spring-security-config/cache-control/src/test/java/com/baeldung/cachecontrol/ResourceEndpointIntegrationTest.java
similarity index 100%
rename from spring-security-modules/spring-security-cache-control/src/test/java/com/baeldung/cachecontrol/ResourceEndpointIntegrationTest.java
rename to spring-security-modules/spring-security-config/cache-control/src/test/java/com/baeldung/cachecontrol/ResourceEndpointIntegrationTest.java
diff --git a/spring-security-modules/spring-security-cors/README.md b/spring-security-modules/spring-security-config/cors/README.md
similarity index 100%
rename from spring-security-modules/spring-security-cors/README.md
rename to spring-security-modules/spring-security-config/cors/README.md
diff --git a/spring-security-modules/spring-security-cors/pom.xml b/spring-security-modules/spring-security-config/cors/pom.xml
similarity index 87%
rename from spring-security-modules/spring-security-cors/pom.xml
rename to spring-security-modules/spring-security-config/cors/pom.xml
index 2acb99368f..19ca7f5ccc 100644
--- a/spring-security-modules/spring-security-cors/pom.xml
+++ b/spring-security-modules/spring-security-config/cors/pom.xml
@@ -2,8 +2,8 @@
4.0.0
- spring-security-cors
- spring-security-cors
+ cors
+ cors
jar
Spring Security CORS
@@ -56,9 +56,4 @@
-
- UTF-8
- UTF-8
-
-
diff --git a/spring-security-modules/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/SpringBootSecurityApplication.java b/spring-security-modules/spring-security-config/cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/SpringBootSecurityApplication.java
similarity index 100%
rename from spring-security-modules/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/SpringBootSecurityApplication.java
rename to spring-security-modules/spring-security-config/cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/SpringBootSecurityApplication.java
diff --git a/spring-security-modules/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/config/WebSecurityConfig.java b/spring-security-modules/spring-security-config/cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/config/WebSecurityConfig.java
similarity index 100%
rename from spring-security-modules/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/config/WebSecurityConfig.java
rename to spring-security-modules/spring-security-config/cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/config/WebSecurityConfig.java
diff --git a/spring-security-modules/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/controller/ResourceController.java b/spring-security-modules/spring-security-config/cors/src/main/java/com/baeldung/springbootsecuritycors/controller/ResourceController.java
similarity index 100%
rename from spring-security-modules/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/controller/ResourceController.java
rename to spring-security-modules/spring-security-config/cors/src/main/java/com/baeldung/springbootsecuritycors/controller/ResourceController.java
diff --git a/spring-security-modules/spring-security-cors/src/test/java/com/baeldung/springbootsecuritycors/ResourceControllerUnitTest.java b/spring-security-modules/spring-security-config/cors/src/test/java/com/baeldung/springbootsecuritycors/ResourceControllerUnitTest.java
similarity index 100%
rename from spring-security-modules/spring-security-cors/src/test/java/com/baeldung/springbootsecuritycors/ResourceControllerUnitTest.java
rename to spring-security-modules/spring-security-config/cors/src/test/java/com/baeldung/springbootsecuritycors/ResourceControllerUnitTest.java
diff --git a/spring-security-modules/spring-security-config/pom.xml b/spring-security-modules/spring-security-config/pom.xml
new file mode 100644
index 0000000000..b3796d1cc6
--- /dev/null
+++ b/spring-security-modules/spring-security-config/pom.xml
@@ -0,0 +1,21 @@
+
+
+ 4.0.0
+ spring-security-config
+ 0.0.1-SNAPSHOT
+ spring-security-conf
+ pom
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+ cache-control
+ cors
+
+
+
diff --git a/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml b/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml
index 7f4a02eb0d..7c6de543ae 100644
--- a/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml
+++ b/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml
@@ -262,7 +262,6 @@
- UTF-8
1.5.22
4.3.9.RELEASE
2.10.1
diff --git a/spring-vault/pom.xml b/spring-vault/pom.xml
index 40967e2894..a39c5575a9 100644
--- a/spring-vault/pom.xml
+++ b/spring-vault/pom.xml
@@ -38,7 +38,6 @@
- UTF-8
2.1.1.RELEASE
diff --git a/testing-modules/easymock/pom.xml b/testing-modules/easymock/pom.xml
index 4146ae6df4..98458b724d 100644
--- a/testing-modules/easymock/pom.xml
+++ b/testing-modules/easymock/pom.xml
@@ -23,7 +23,6 @@
- UTF-8
4.0.2
diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml
index 33fd0bbce8..831fa97e12 100644
--- a/testing-modules/junit-5/pom.xml
+++ b/testing-modules/junit-5/pom.xml
@@ -138,7 +138,7 @@
1.4.2
5.4.2
2.8.2
- 2.0.0-RC.1
+ 2.0.0
2.22.0
1.6.0
5.0.1.RELEASE
diff --git a/testing-modules/parallel-tests-junit/math-test-functions/pom.xml b/testing-modules/parallel-tests-junit/math-test-functions/pom.xml
index ba645d00ff..fb12803333 100644
--- a/testing-modules/parallel-tests-junit/math-test-functions/pom.xml
+++ b/testing-modules/parallel-tests-junit/math-test-functions/pom.xml
@@ -45,8 +45,4 @@
-
- UTF-8
-
-
diff --git a/testing-modules/parallel-tests-junit/string-test-functions/pom.xml b/testing-modules/parallel-tests-junit/string-test-functions/pom.xml
index 984dd64ce4..313d82c23f 100644
--- a/testing-modules/parallel-tests-junit/string-test-functions/pom.xml
+++ b/testing-modules/parallel-tests-junit/string-test-functions/pom.xml
@@ -37,8 +37,4 @@
-
- UTF-8
-
-
diff --git a/testing-modules/testing-libraries/pom.xml b/testing-modules/testing-libraries/pom.xml
index 53b58cee17..aa22a5253e 100644
--- a/testing-modules/testing-libraries/pom.xml
+++ b/testing-modules/testing-libraries/pom.xml
@@ -42,7 +42,18 @@
spring-boot-starter-web
2.2.0.RELEASE
-
+
+ com.github.stefanbirkner
+ system-rules
+ ${system-rules.version}
+ test
+
+
+ com.github.stefanbirkner
+ system-lambda
+ ${system-lambda.version}
+ test
+
@@ -90,6 +101,8 @@
0.4
4.8.0
3.0.0
+ 1.19.0
+ 1.0.0
diff --git a/testing-modules/testing-libraries/src/test/java/com/baeldung/systemout/SystemOutPrintlnUnitTest.java b/testing-modules/testing-libraries/src/test/java/com/baeldung/systemout/SystemOutPrintlnUnitTest.java
new file mode 100644
index 0000000000..3ffc508fa5
--- /dev/null
+++ b/testing-modules/testing-libraries/src/test/java/com/baeldung/systemout/SystemOutPrintlnUnitTest.java
@@ -0,0 +1,49 @@
+package com.baeldung.systemout;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import org.junit.Assert;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemOut;
+
+class SystemOutPrintlnUnitTest {
+
+ private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
+ private final PrintStream standardOut = System.out;
+
+ @BeforeEach
+ public void setUp() {
+ System.setOut(new PrintStream(outputStreamCaptor));
+ }
+
+ @BeforeEach
+ public void tearDown() {
+ System.setOut(standardOut);
+ }
+
+ @Test
+ void givenSystemOutRedirection_whenInvokePrintln_thenOutputCaptorSuccess() {
+ print("Hello Baeldung Readers!!");
+
+ Assert.assertEquals("Hello Baeldung Readers!!", outputStreamCaptor.toString()
+ .trim());
+ }
+
+ @Test
+ void givenTapSystemOut_whenInvokePrintln_thenOutputIsReturnedSuccessfully() throws Exception {
+
+ String text = tapSystemOut(() -> {
+ print("Hello Baeldung Readers!!");
+ });
+
+ Assert.assertEquals("Hello Baeldung Readers!!", text.trim());
+ }
+
+ private void print(String output) {
+ System.out.println(output);
+ }
+
+}
diff --git a/testing-modules/testing-libraries/src/test/java/com/baeldung/systemout/SystemOutPrintlnWithRuleUnitTest.java b/testing-modules/testing-libraries/src/test/java/com/baeldung/systemout/SystemOutPrintlnWithRuleUnitTest.java
new file mode 100644
index 0000000000..f15b71999e
--- /dev/null
+++ b/testing-modules/testing-libraries/src/test/java/com/baeldung/systemout/SystemOutPrintlnWithRuleUnitTest.java
@@ -0,0 +1,27 @@
+package com.baeldung.systemout;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.SystemOutRule;
+
+public class SystemOutPrintlnWithRuleUnitTest {
+
+ @Rule
+ public final SystemOutRule systemOutRule = new SystemOutRule().enableLog();
+
+ @Test
+ public void givenSystemOutRule_whenInvokePrintln_thenLogSuccess() {
+ print("Hello Baeldung Readers!!");
+
+ Assert.assertEquals("Hello Baeldung Readers!!", systemOutRule.getLog()
+ .trim());
+
+ Assert.assertEquals("Hello Baeldung Readers!!\n", systemOutRule.getLogWithNormalizedLineSeparator());
+ }
+
+ private void print(String output) {
+ System.out.println(output);
+ }
+
+}
diff --git a/vaadin/pom.xml b/vaadin/pom.xml
index f8f709cef7..4814e70ae3 100644
--- a/vaadin/pom.xml
+++ b/vaadin/pom.xml
@@ -182,7 +182,6 @@
8.8.5
8.8.5
9.3.9.v20160517
- UTF-8
1.8
1.8
local