form = new ArrayList<>();
+ form.add(new BasicNameValuePair("name", "admin"));
+ form.add(new BasicNameValuePair("password", "invalid"));
+
+ post.setEntity(new UrlEncodedFormEntity(form));
+ try (CloseableHttpResponse response = client.execute(post)) {
+ String body = EntityUtils.toString(response.getEntity());
+
+ assertTrue(response.getStatusLine()
+ .getStatusCode() == 401);
+
+ assertTrue(body.contains("invalid login"));
+ }
+ }
+ }
+
+ @Test
+ public void whenNotLoggedIn_thenRedirectedToLoginPage() throws Exception {
+ try (CloseableHttpClient client = buildClient()) {
+ HttpGet get = new HttpGet(BASE_URL + "/home");
+
+ try (CloseableHttpResponse response = client.execute(get)) {
+ String body = EntityUtils.toString(response.getEntity());
+
+ assertTrue(response.getStatusLine()
+ .getStatusCode() == 401);
+
+ assertTrue(body.contains("redirected to login"));
+ }
+ }
+ }
+}
diff --git a/web-modules/javax-servlets/README.md b/web-modules/javax-servlets/README.md
new file mode 100644
index 0000000000..bda7cd19e3
--- /dev/null
+++ b/web-modules/javax-servlets/README.md
@@ -0,0 +1,15 @@
+## Servlets
+
+This module contains articles about Servlets.
+
+### Relevant Articles:
+- [Introduction to Java Servlets](https://www.baeldung.com/intro-to-servlets)
+- [An MVC Example with Servlets and JSP](https://www.baeldung.com/mvc-servlet-jsp)
+- [Handling Cookies and a Session in a Java Servlet](https://www.baeldung.com/java-servlet-cookies-session)
+- [Uploading Files with Servlets and JSP](https://www.baeldung.com/upload-file-servlet)
+- [Example of Downloading File in a Servlet](https://www.baeldung.com/servlet-download-file)
+- [Returning a JSON Response from a Servlet](https://www.baeldung.com/servlet-json-response)
+- [Jakarta EE Servlet Exception Handling](https://www.baeldung.com/servlet-exceptions)
+- [Context and Servlet Initialization Parameters](https://www.baeldung.com/context-servlet-initialization-param)
+- [The Difference between getRequestURI and getPathInfo in HttpServletRequest](https://www.baeldung.com/http-servlet-request-requesturi-pathinfo)
+- [Difference Between request.getSession() and request.getSession(true)](https://www.baeldung.com/java-request-getsession)
diff --git a/web-modules/javax-servlets/pom.xml b/web-modules/javax-servlets/pom.xml
new file mode 100644
index 0000000000..80a1e3af9f
--- /dev/null
+++ b/web-modules/javax-servlets/pom.xml
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+ com.baeldung.javax-servlets
+ javax-servlets
+ 1.0-SNAPSHOT
+ javax-servlets
+ war
+
+
+ com.baeldung
+ web-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+
+ commons-fileupload
+ commons-fileupload
+ ${commons-fileupload.version}
+
+
+
+ javax.servlet
+ javax.servlet-api
+ ${javax.servlet-api.version}
+
+
+ org.apache.httpcomponents
+ httpclient
+ ${org.apache.httpcomponents.version}
+ test
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+ com.google.code.gson
+ gson
+ ${gson.version}
+
+
+
+
+ 4.5.3
+ 2.8.2
+
+
+
\ No newline at end of file
diff --git a/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java b/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java
new file mode 100644
index 0000000000..72a2b39a67
--- /dev/null
+++ b/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java
@@ -0,0 +1,39 @@
+package com.baeldung.servlets;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@WebServlet(name = "FormServlet", urlPatterns = "/calculateServlet")
+public class FormServlet extends HttpServlet {
+
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+
+ String height = request.getParameter("height");
+ String weight = request.getParameter("weight");
+ try {
+ double bmi = calculateBMI(Double.parseDouble(weight), Double.parseDouble(height));
+ request.setAttribute("bmi", bmi);
+ response.setHeader("Test", "Success");
+ response.setHeader("BMI", String.valueOf(bmi));
+ request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request, response);
+ } catch (Exception e) {
+ request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request, response);
+ }
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/index.jsp");
+ dispatcher.forward(request, response);
+ }
+
+ private Double calculateBMI(Double weight, Double height) {
+ return weight / (height * height);
+ }
+}
\ No newline at end of file
diff --git a/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/MainServlet.java b/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/MainServlet.java
new file mode 100644
index 0000000000..198920cb23
--- /dev/null
+++ b/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/MainServlet.java
@@ -0,0 +1,21 @@
+package com.baeldung.servlets;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@WebServlet("/main")
+public class MainServlet extends HttpServlet {
+
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ request.getRequestDispatcher("/WEB-INF/jsp/main.jsp").forward(request, response);
+ }
+
+
+
+
+}
diff --git a/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/UpdateServlet.java b/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/UpdateServlet.java
new file mode 100644
index 0000000000..8582a1ccef
--- /dev/null
+++ b/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/UpdateServlet.java
@@ -0,0 +1,31 @@
+package com.baeldung.servlets;
+
+import java.io.IOException;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+@WebServlet("/update")
+public class UpdateServlet extends HttpServlet {
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+
+ HttpSession session = request.getSession(false);
+
+ if (session != null) {
+
+ session.setAttribute("userName", request.getParameter("userName"));
+ session.setAttribute("age", request.getParameter("age"));
+
+ request.setAttribute("sessionData", session);
+ }
+
+ request.getRequestDispatcher("/WEB-INF/jsp/update.jsp").forward(request, response);
+ }
+
+}
diff --git a/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/UserLoginServlet.java b/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/UserLoginServlet.java
new file mode 100644
index 0000000000..25ec6a8f59
--- /dev/null
+++ b/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/UserLoginServlet.java
@@ -0,0 +1,28 @@
+package com.baeldung.servlets;
+
+
+import java.io.IOException;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+@WebServlet("/u_login")
+public class UserLoginServlet extends HttpServlet {
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ HttpSession session = request.getSession();
+
+ session.setAttribute("userId", request.getParameter("userId"));
+
+ request.setAttribute("id", session.getAttribute("userId"));
+
+ request.getRequestDispatcher("/WEB-INF/jsp/userlogin.jsp").forward(request, response);
+
+ }
+
+}
diff --git a/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/UserServlet.java b/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/UserServlet.java
new file mode 100644
index 0000000000..75977b0660
--- /dev/null
+++ b/web-modules/javax-servlets/src/main/java/com/baeldung/servlets/UserServlet.java
@@ -0,0 +1,49 @@
+package com.baeldung.servlets;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebInitParam;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@WebServlet(name = "UserServlet", urlPatterns = "/userServlet", initParams={
+ @WebInitParam(name="name", value="Not provided"),
+ @WebInitParam(name="email", value="Not provided")})
+public class UserServlet extends HttpServlet {
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ processRequest(request, response);
+ forwardRequest(request, response, "/WEB-INF/jsp/result.jsp");
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ }
+
+ protected void processRequest(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ request.setAttribute("name", getRequestParameter(request, "name"));
+ request.setAttribute("email", getRequestParameter(request, "email"));
+ request.setAttribute("province", getContextParameter("province"));
+ request.setAttribute("country", getContextParameter("country"));
+ }
+
+ protected String getRequestParameter(HttpServletRequest request, String name) {
+ String param = request.getParameter(name);
+ return !param.isEmpty() ? param : getInitParameter(name);
+ }
+
+ protected String getContextParameter(String name) {
+ return getServletContext().getInitParameter(name);
+ }
+
+ protected void forwardRequest(HttpServletRequest request, HttpServletResponse response, String path)
+ throws ServletException, IOException {
+ request.getRequestDispatcher(path).forward(request, response);
+ }
+}
\ No newline at end of file
diff --git a/web-modules/javax-servlets/src/main/resources/logback.xml b/web-modules/javax-servlets/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/web-modules/javax-servlets/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web-modules/javax-servlets/src/main/webapp/WEB-INF/jsp/main.jsp b/web-modules/javax-servlets/src/main/webapp/WEB-INF/jsp/main.jsp
new file mode 100644
index 0000000000..313310a2a9
--- /dev/null
+++ b/web-modules/javax-servlets/src/main/webapp/WEB-INF/jsp/main.jsp
@@ -0,0 +1,15 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web-modules/javax-servlets/src/main/webapp/WEB-INF/jsp/result.jsp b/web-modules/javax-servlets/src/main/webapp/WEB-INF/jsp/result.jsp
new file mode 100644
index 0000000000..7259b96ed0
--- /dev/null
+++ b/web-modules/javax-servlets/src/main/webapp/WEB-INF/jsp/result.jsp
@@ -0,0 +1,15 @@
+<%@ page contentType="text/html" pageEncoding="UTF-8"%>
+
+
+
+
+ User Data
+
+
+ User Information
+ Name: ${name}
+ Email: ${email}
+ Province: ${province}
+ Country: ${country}
+
+
diff --git a/web-modules/javax-servlets/src/main/webapp/WEB-INF/jsp/update.jsp b/web-modules/javax-servlets/src/main/webapp/WEB-INF/jsp/update.jsp
new file mode 100644
index 0000000000..fae5ea2ac2
--- /dev/null
+++ b/web-modules/javax-servlets/src/main/webapp/WEB-INF/jsp/update.jsp
@@ -0,0 +1,17 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+
+
+
+ Hi, User : ${sessionData.getAttribute("userId")}
+
+ Your User Data has been updated as below :
+ User Name: ${sessionData.getAttribute("userName")}
+ Age : ${sessionData.getAttribute("age")}
+
+
+
\ No newline at end of file
diff --git a/web-modules/javax-servlets/src/main/webapp/WEB-INF/jsp/userlogin.jsp b/web-modules/javax-servlets/src/main/webapp/WEB-INF/jsp/userlogin.jsp
new file mode 100644
index 0000000000..b2a550b811
--- /dev/null
+++ b/web-modules/javax-servlets/src/main/webapp/WEB-INF/jsp/userlogin.jsp
@@ -0,0 +1,18 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+
+
+ Update your User Details:
+
+
+
+
\ No newline at end of file
diff --git a/web-modules/javax-servlets/src/main/webapp/user.jsp b/web-modules/javax-servlets/src/main/webapp/user.jsp
new file mode 100644
index 0000000000..2139052a3a
--- /dev/null
+++ b/web-modules/javax-servlets/src/main/webapp/user.jsp
@@ -0,0 +1,18 @@
+<%@ page contentType="text/html" pageEncoding="UTF-8"%>
+
+
+
+ Context and Servlet Initialization Parameters
+
+
+
+ Please fill the form below:
+
+
+
diff --git a/web-modules/javax-servlets/src/test/java/com/baeldung/test/UserServletUnitTest.java b/web-modules/javax-servlets/src/test/java/com/baeldung/test/UserServletUnitTest.java
new file mode 100644
index 0000000000..ef3d877dd7
--- /dev/null
+++ b/web-modules/javax-servlets/src/test/java/com/baeldung/test/UserServletUnitTest.java
@@ -0,0 +1,52 @@
+package com.baeldung.test;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class UserServletUnitTest {
+
+ private static HttpServletRequest request;
+ private static HttpServletResponse response;
+
+
+ @BeforeClass
+ public static void setUpHttpServletRequestMockInstance() {
+ request = mock(HttpServletRequest.class);
+ }
+
+ @BeforeClass
+ public static void setUpHttpServletResponsetMockInstance() {
+ response = mock(HttpServletResponse.class);
+ }
+
+ @Test
+ public void givenHttpServletRequestMockInstance_whenCalledgetParameter_thenCalledAtLeastOnce() {
+ request.getParameter("name");
+ verify(request, atLeast(1)).getParameter("name");
+ }
+
+ @Test
+ public void givenHttpServletRequestMockInstance_whenCalledgetParameter_thenOneAssertion() {
+ when(request.getParameter("name")).thenReturn("username");
+ assertThat(request.getParameter("name")).isEqualTo("username");
+ }
+
+ @Test
+ public void givenHttpServletResponseMockInstance_whenCalledgetContentType_thenCalledAtLeastOnce() {
+ response.getContentType();
+ verify(response, atLeast(1)).getContentType();
+ }
+
+ @Test
+ public void givenHttpServletResponseMockInstance_whenCalledgetContentType_thenOneAssertion() {
+ when(response.getContentType()).thenReturn("text/html");
+ assertThat(response.getContentType()).isEqualTo("text/html");
+ }
+}
\ No newline at end of file
diff --git a/web-modules/jee-7/README.md b/web-modules/jee-7/README.md
new file mode 100644
index 0000000000..88359a81ec
--- /dev/null
+++ b/web-modules/jee-7/README.md
@@ -0,0 +1,14 @@
+## JEE 7
+
+This module contains articles about JEE 7.
+
+### Relevant Articles:
+- [Scheduling in Jakarta EE](https://www.baeldung.com/scheduling-in-java-enterprise-edition)
+- [JSON Processing in Java EE 7](https://www.baeldung.com/jee7-json)
+- [Converters, Listeners and Validators in Java EE 7](https://www.baeldung.com/java-ee7-converter-listener-validator)
+- [Introduction to JAX-WS](https://www.baeldung.com/jax-ws)
+- [A Guide to Java EE Web-Related Annotations](https://www.baeldung.com/javaee-web-annotations)
+- [Introduction to Testing with Arquillian](https://www.baeldung.com/arquillian)
+- [Java EE 7 Batch Processing](https://www.baeldung.com/java-ee-7-batch-processing)
+- [The Difference Between CDI and EJB Singleton](https://www.baeldung.com/jee-cdi-vs-ejb-singleton)
+- [Invoking a SOAP Web Service in Java](https://www.baeldung.com/java-soap-web-service)
diff --git a/web-modules/jee-7/pom.xml b/web-modules/jee-7/pom.xml
new file mode 100644
index 0000000000..b26027d9bf
--- /dev/null
+++ b/web-modules/jee-7/pom.xml
@@ -0,0 +1,542 @@
+
+
+ 4.0.0
+ com.baeldung.jee-7
+ jee-7
+ 1.0-SNAPSHOT
+ jee-7
+ war
+ JavaEE 7 Arquillian Archetype Sample
+
+
+ com.baeldung
+ web-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+
+ org.jboss.arquillian
+ arquillian-bom
+ ${arquillian_core.version}
+ import
+ pom
+
+
+ org.jboss.arquillian.extension
+ arquillian-drone-bom
+ ${arquillian-drone-bom.version}
+ pom
+ import
+
+
+
+
+
+
+ javax
+ javaee-api
+ ${javaee_api.version}
+ provided
+
+
+ org.jboss.arquillian.junit
+ arquillian-junit-container
+ test
+
+
+ org.jboss.arquillian.graphene
+ graphene-webdriver
+ ${graphene-webdriver.version}
+ pom
+ test
+
+
+ com.jayway.awaitility
+ awaitility
+ ${awaitility.version}
+ test
+
+
+ org.jboss.shrinkwrap.resolver
+ shrinkwrap-resolver-impl-maven
+ test
+ jar
+
+
+ org.jboss.shrinkwrap.resolver
+ shrinkwrap-resolver-impl-maven-archive
+ test
+
+
+ org.apache.httpcomponents
+ httpclient
+ ${httpclient.version}
+
+
+ commons-io
+ commons-io
+ ${commons-io.version}
+
+
+ com.sun.faces
+ jsf-api
+ ${com.sun.faces.jsf.version}
+
+
+ com.sun.faces
+ jsf-impl
+ ${com.sun.faces.jsf.version}
+
+
+ javax.servlet
+ jstl
+ ${jstl.version}
+
+
+ javax.servlet
+ javax.servlet-api
+ ${javax.servlet-api.version}
+
+
+ javax.servlet.jsp
+ jsp-api
+ ${jsp-api.version}
+ provided
+
+
+ taglibs
+ standard
+ ${taglibs.standard.version}
+
+
+ javax.mvc
+ javax.mvc-api
+ ${mvc.api.version}
+
+
+ org.glassfish.ozark
+ ozark
+ ${ozark.version}
+
+
+ org.springframework.security
+ spring-security-web
+ ${org.springframework.security.version}
+
+
+ org.springframework.security
+ spring-security-config
+ ${org.springframework.security.version}
+
+
+ org.springframework.security
+ spring-security-taglibs
+ ${org.springframework.security.version}
+
+
+
+ org.jboss.spec.javax.batch
+ jboss-batch-api_1.0_spec
+ ${jboss-batch-api.version}
+
+
+ org.jberet
+ jberet-core
+ ${jberet.version}
+
+
+ org.jberet
+ jberet-support
+ ${jberet.version}
+
+
+ org.jboss.spec.javax.transaction
+ jboss-transaction-api_1.2_spec
+ ${jboss-transaction-api.version}
+
+
+ org.jboss.marshalling
+ jboss-marshalling
+ ${jboss-marshalling.version}
+
+
+ org.jboss.weld
+ weld-core
+ ${weld.version}
+
+
+ org.jboss.weld.se
+ weld-se
+ ${weld.version}
+
+
+ org.jberet
+ jberet-se
+ ${jberet.version}
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+ org.glassfish.jersey.containers
+ jersey-container-jetty-servlet
+ ${jersey-container-jetty-servlet.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ ${maven-war-plugin.version}
+
+ src/main/webapp
+ false
+
+
+
+
+
+
+
+
+ org.eclipse.m2e
+ lifecycle-mapping
+ ${lifecycle.mapping.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+
+
+ maven-pmd-plugin
+
+
+ [3.8,)
+
+
+ check
+
+
+
+
+
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ jaxws-maven-plugin
+ 2.6
+
+
+ wsimport-from-jdk
+
+ wsimport
+
+
+
+
+
+ http://localhost:8888/ws/country?wsdl
+
+ true
+ com.baeldung.soap.ws.client.generated
+ src/main/java
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ --add-opens java.base/java.lang=ALL-UNNAMED
+ --add-opens=java.base/java.lang.reflect=ALL-UNNAMED
+ --add-opens java.base/java.io=ALL-UNNAMED
+
+
+
+
+
+
+
+
+
+ wildfly-managed-arquillian
+
+ true
+
+
+
+ io.undertow
+ undertow-websockets-jsr
+ ${undertow-websockets-jsr.version}
+ test
+
+
+ org.jboss.resteasy
+ resteasy-client
+ ${resteasy.version}
+ test
+
+
+ org.jboss.resteasy
+ resteasy-jaxb-provider
+ ${resteasy.version}
+ test
+
+
+ org.jboss.resteasy
+ resteasy-json-p-provider
+ ${resteasy.version}
+ test
+
+
+ org.wildfly
+ wildfly-arquillian-container-managed
+ ${wildfly.version}
+ test
+
+
+ sun.jdk
+ jconsole
+
+
+
+
+
+
+
+
+ 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
+
+
+ --add-opens java.base/java.lang=ALL-UNNAMED
+
+
+
+
+
+
+
+ wildfly-remote-arquillian
+
+
+ io.undertow
+ undertow-websockets-jsr
+ ${undertow-websockets-jsr.version}
+ test
+
+
+ org.jboss.resteasy
+ resteasy-client
+ ${resteasy.version}
+ test
+
+
+ org.jboss.resteasy
+ resteasy-jaxb-provider
+ ${resteasy.version}
+ test
+
+
+ org.jboss.resteasy
+ resteasy-json-p-provider
+ ${resteasy.version}
+ test
+
+
+ org.wildfly
+ wildfly-arquillian-container-remote
+ ${wildfly.version}
+ test
+
+
+ sun.jdk
+ jconsole
+
+
+
+
+
+
+ glassfish-embedded-arquillian
+
+
+ org.glassfish.main.extras
+ glassfish-embedded-all
+ ${glassfish-embedded-all.version}
+ test
+
+
+ org.glassfish
+ javax.json
+ ${javax.json.version}
+ test
+
+
+ org.glassfish.tyrus
+ tyrus-client
+ ${tyrus.version}
+ test
+
+
+ org.glassfish.tyrus
+ tyrus-container-grizzly-client
+ ${tyrus.version}
+ test
+
+
+ org.glassfish.jersey.core
+ jersey-client
+ ${jersey.version}
+ test
+
+
+ org.jboss.arquillian.container
+ arquillian-glassfish-embedded-3.1
+ ${arquillian-glassfish.version}
+ test
+
+
+
+
+ glassfish-remote-arquillian
+
+
+ org.glassfish
+ javax.json
+ ${javax.json.version}
+ test
+
+
+ org.glassfish.tyrus
+ tyrus-client
+ ${tyrus.version}
+ test
+
+
+ org.glassfish.tyrus
+ tyrus-container-grizzly-client
+ ${tyrus.version}
+ test
+
+
+ org.glassfish.jersey.core
+ jersey-client
+ ${jersey.version}
+ test
+
+
+ org.glassfish.jersey.media
+ jersey-media-json-jackson
+ ${jersey.version}
+ test
+
+
+ org.glassfish.jersey.media
+ jersey-media-json-processing
+ ${jersey.version}
+ test
+
+
+ org.jboss.arquillian.container
+ arquillian-glassfish-remote-3.1
+ ${arquillian-glassfish.version}
+ test
+
+
+
+
+ webdriver-chrome
+
+ true
+
+
+ chrome
+
+
+
+ webdriver-firefox
+
+ firefox
+
+
+
+
+
+ 1.0.0
+ 1.0-edr2
+ 1.8
+ 3.0.0
+ 7.0
+ 1.1.11.Final
+ 8.2.1.Final
+ 1.7.0
+ 1.4.6.Final
+ 3.0.19.Final
+ 4.1.1
+ 1.0.4
+ 1.13
+ 2.25
+ 1.0.0.Final
+ 4.2.3.RELEASE
+ 1.1.2
+ 2.2.14
+ 4.5
+ 2.0.1.Final
+ 2.1.0.Final
+ 2.8
+ 2.2
+ 1.0.0-m02
+ 1.0.0.Final
+ 1.0.2.Final
+ 1.0.0.Final
+ 2.1.1.Final
+ 2.1.1.Final
+ 2.22.1
+
+
+
\ No newline at end of file
diff --git a/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/Country.java b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/Country.java
new file mode 100644
index 0000000000..6a810b9afa
--- /dev/null
+++ b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/Country.java
@@ -0,0 +1,129 @@
+
+package com.baeldung.soap.ws.client.generated;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Java class for country complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="country">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="capital" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ * <element name="currency" type="{http://server.ws.soap.baeldung.com/}currency" minOccurs="0"/>
+ * <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ * <element name="population" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ * </sequence>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "country", propOrder = { "capital", "currency", "name", "population" })
+public class Country {
+
+ protected String capital;
+ @XmlSchemaType(name = "string")
+ protected Currency currency;
+ protected String name;
+ protected int population;
+
+ /**
+ * Gets the value of the capital property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getCapital() {
+ return capital;
+ }
+
+ /**
+ * Sets the value of the capital property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setCapital(String value) {
+ this.capital = value;
+ }
+
+ /**
+ * Gets the value of the currency property.
+ *
+ * @return
+ * possible object is
+ * {@link Currency }
+ *
+ */
+ public Currency getCurrency() {
+ return currency;
+ }
+
+ /**
+ * Sets the value of the currency property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Currency }
+ *
+ */
+ public void setCurrency(Currency value) {
+ this.currency = value;
+ }
+
+ /**
+ * Gets the value of the name property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the value of the name property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setName(String value) {
+ this.name = value;
+ }
+
+ /**
+ * Gets the value of the population property.
+ *
+ */
+ public int getPopulation() {
+ return population;
+ }
+
+ /**
+ * Sets the value of the population property.
+ *
+ */
+ public void setPopulation(int value) {
+ this.population = value;
+ }
+
+}
diff --git a/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/CountryService.java b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/CountryService.java
new file mode 100644
index 0000000000..bda4a305a5
--- /dev/null
+++ b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/CountryService.java
@@ -0,0 +1,34 @@
+
+package com.baeldung.soap.ws.client.generated;
+
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebResult;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.ws.Action;
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.3.2
+ * Generated source version: 2.2
+ *
+ */
+@WebService(name = "CountryService", targetNamespace = "http://server.ws.soap.baeldung.com/")
+@SOAPBinding(style = SOAPBinding.Style.RPC)
+@XmlSeeAlso({ ObjectFactory.class })
+public interface CountryService {
+
+ /**
+ *
+ * @param arg0
+ * @return
+ * returns com.baeldung.soap.ws.client.generated.Country
+ */
+ @WebMethod
+ @WebResult(partName = "return")
+ @Action(input = "http://server.ws.soap.baeldung.com/CountryService/findByNameRequest", output = "http://server.ws.soap.baeldung.com/CountryService/findByNameResponse")
+ public Country findByName(@WebParam(name = "arg0", partName = "arg0") String arg0);
+
+}
diff --git a/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java
new file mode 100644
index 0000000000..a6983938f5
--- /dev/null
+++ b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/CountryServiceImplService.java
@@ -0,0 +1,91 @@
+
+package com.baeldung.soap.ws.client.generated;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.xml.namespace.QName;
+import javax.xml.ws.Service;
+import javax.xml.ws.WebEndpoint;
+import javax.xml.ws.WebServiceClient;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.WebServiceFeature;
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.2.9-b130926.1035
+ * Generated source version: 2.2
+ *
+ */
+@WebServiceClient(name = "CountryServiceImplService", targetNamespace = "http://server.ws.soap.baeldung.com/", wsdlLocation = "http://localhost:8888/ws/country?wsdl")
+public class CountryServiceImplService extends Service {
+
+ private final static URL COUNTRYSERVICEIMPLSERVICE_WSDL_LOCATION;
+ private final static WebServiceException COUNTRYSERVICEIMPLSERVICE_EXCEPTION;
+ private final static QName COUNTRYSERVICEIMPLSERVICE_QNAME = new QName("http://server.ws.soap.baeldung.com/", "CountryServiceImplService");
+
+ static {
+ URL url = null;
+ WebServiceException e = null;
+ try {
+ url = new URL("http://localhost:8888/ws/country?wsdl");
+ } catch (MalformedURLException ex) {
+ e = new WebServiceException(ex);
+ }
+ COUNTRYSERVICEIMPLSERVICE_WSDL_LOCATION = url;
+ COUNTRYSERVICEIMPLSERVICE_EXCEPTION = e;
+ }
+
+ public CountryServiceImplService() {
+ super(__getWsdlLocation(), COUNTRYSERVICEIMPLSERVICE_QNAME);
+ }
+
+ public CountryServiceImplService(WebServiceFeature... features) {
+ super(__getWsdlLocation(), COUNTRYSERVICEIMPLSERVICE_QNAME, features);
+ }
+
+ public CountryServiceImplService(URL wsdlLocation) {
+ super(wsdlLocation, COUNTRYSERVICEIMPLSERVICE_QNAME);
+ }
+
+ public CountryServiceImplService(URL wsdlLocation, WebServiceFeature... features) {
+ super(wsdlLocation, COUNTRYSERVICEIMPLSERVICE_QNAME, features);
+ }
+
+ public CountryServiceImplService(URL wsdlLocation, QName serviceName) {
+ super(wsdlLocation, serviceName);
+ }
+
+ public CountryServiceImplService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
+ super(wsdlLocation, serviceName, features);
+ }
+
+ /**
+ *
+ * @return
+ * returns CountryService
+ */
+ @WebEndpoint(name = "CountryServiceImplPort")
+ public CountryService getCountryServiceImplPort() {
+ return super.getPort(new QName("http://server.ws.soap.baeldung.com/", "CountryServiceImplPort"), CountryService.class);
+ }
+
+ /**
+ *
+ * @param features
+ * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features
parameter will have their default values.
+ * @return
+ * returns CountryService
+ */
+ @WebEndpoint(name = "CountryServiceImplPort")
+ public CountryService getCountryServiceImplPort(WebServiceFeature... features) {
+ return super.getPort(new QName("http://server.ws.soap.baeldung.com/", "CountryServiceImplPort"), CountryService.class, features);
+ }
+
+ private static URL __getWsdlLocation() {
+ if (COUNTRYSERVICEIMPLSERVICE_EXCEPTION != null) {
+ throw COUNTRYSERVICEIMPLSERVICE_EXCEPTION;
+ }
+ return COUNTRYSERVICEIMPLSERVICE_WSDL_LOCATION;
+ }
+
+}
diff --git a/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/Currency.java b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/Currency.java
new file mode 100644
index 0000000000..8b9355edc5
--- /dev/null
+++ b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/Currency.java
@@ -0,0 +1,37 @@
+
+package com.baeldung.soap.ws.client.generated;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Java class for currency.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <simpleType name="currency">
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ * <enumeration value="EUR"/>
+ * <enumeration value="INR"/>
+ * <enumeration value="USD"/>
+ * </restriction>
+ * </simpleType>
+ *
+ *
+ */
+@XmlType(name = "currency")
+@XmlEnum
+public enum Currency {
+
+ EUR, INR, USD;
+
+ public String value() {
+ return name();
+ }
+
+ public static Currency fromValue(String v) {
+ return valueOf(v);
+ }
+
+}
diff --git a/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/ObjectFactory.java b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/ObjectFactory.java
new file mode 100644
index 0000000000..241debe758
--- /dev/null
+++ b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/ObjectFactory.java
@@ -0,0 +1,38 @@
+
+package com.baeldung.soap.ws.client.generated;
+
+import javax.xml.bind.annotation.XmlRegistry;
+
+/**
+ * This object contains factory methods for each
+ * Java content interface and Java element interface
+ * generated in the com.baeldung.soap.ws.client.generated package.
+ * An ObjectFactory allows you to programatically
+ * construct new instances of the Java representation
+ * for XML content. The Java representation of XML
+ * content can consist of schema derived interfaces
+ * and classes representing the binding of schema
+ * type definitions, element declarations and model
+ * groups. Factory methods for each of these are
+ * provided in this class.
+ *
+ */
+@XmlRegistry
+public class ObjectFactory {
+
+ /**
+ * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.baeldung.soap.ws.client.generated
+ *
+ */
+ public ObjectFactory() {
+ }
+
+ /**
+ * Create an instance of {@link Country }
+ *
+ */
+ public Country createCountry() {
+ return new Country();
+ }
+
+}
diff --git a/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/package-info.java b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/package-info.java
new file mode 100644
index 0000000000..6df70b70f1
--- /dev/null
+++ b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/client/generated/package-info.java
@@ -0,0 +1,2 @@
+@javax.xml.bind.annotation.XmlSchema(namespace = "http://server.ws.soap.baeldung.com/", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+package com.baeldung.soap.ws.client.generated;
diff --git a/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/Country.java b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/Country.java
new file mode 100644
index 0000000000..62ea4a22ed
--- /dev/null
+++ b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/Country.java
@@ -0,0 +1,41 @@
+package com.baeldung.soap.ws.server;
+
+public class Country {
+ protected String name;
+ protected int population;
+ protected String capital;
+ protected Currency currency;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getPopulation() {
+ return population;
+ }
+
+ public void setPopulation(int population) {
+ this.population = population;
+ }
+
+ public String getCapital() {
+ return capital;
+ }
+
+ public void setCapital(String capital) {
+ this.capital = capital;
+ }
+
+ public Currency getCurrency() {
+ return currency;
+ }
+
+ public void setCurrency(Currency currency) {
+ this.currency = currency;
+ }
+
+}
\ No newline at end of file
diff --git a/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/CountryRepository.java b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/CountryRepository.java
new file mode 100644
index 0000000000..558f7c1293
--- /dev/null
+++ b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/CountryRepository.java
@@ -0,0 +1,43 @@
+package com.baeldung.soap.ws.server;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class CountryRepository {
+
+ private static final Map countries = new HashMap<>();
+
+ {
+ initData();
+ }
+
+ private final static void initData() {
+ Country usa = new Country();
+ usa.setName("USA");
+ usa.setCapital("Washington D.C.");
+ usa.setCurrency(Currency.USD);
+ usa.setPopulation(323947000);
+
+ countries.put(usa.getName(), usa);
+
+ Country india = new Country();
+ india.setName("India");
+ india.setCapital("New Delhi");
+ india.setCurrency(Currency.INR);
+ india.setPopulation(1295210000);
+
+ countries.put(india.getName(), india);
+
+ Country france = new Country();
+ france.setName("France");
+ france.setCapital("Paris");
+ france.setCurrency(Currency.EUR);
+ france.setPopulation(66710000);
+
+ countries.put(france.getName(), france);
+ }
+
+ public Country findCountry(String name) {
+ return countries.get(name);
+ }
+}
diff --git a/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/CountryService.java b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/CountryService.java
new file mode 100644
index 0000000000..e3f68a4e59
--- /dev/null
+++ b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/CountryService.java
@@ -0,0 +1,15 @@
+package com.baeldung.soap.ws.server;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.jws.soap.SOAPBinding.Style;
+
+@WebService
+@SOAPBinding(style=Style.RPC)
+public interface CountryService {
+
+ @WebMethod
+ Country findByName(String name);
+
+}
diff --git a/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/CountryServiceImpl.java b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/CountryServiceImpl.java
new file mode 100644
index 0000000000..a8c6250354
--- /dev/null
+++ b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/CountryServiceImpl.java
@@ -0,0 +1,15 @@
+package com.baeldung.soap.ws.server;
+
+import javax.jws.WebService;
+
+@WebService(endpointInterface = "com.baeldung.soap.ws.server.CountryService")
+public class CountryServiceImpl implements CountryService {
+
+ private CountryRepository countryRepository = new CountryRepository();
+
+ @Override
+ public Country findByName(String name) {
+ return countryRepository.findCountry(name);
+ }
+
+}
diff --git a/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/CountryServicePublisher.java b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/CountryServicePublisher.java
new file mode 100644
index 0000000000..e7c1c480f4
--- /dev/null
+++ b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/CountryServicePublisher.java
@@ -0,0 +1,19 @@
+package com.baeldung.soap.ws.server;
+
+import javax.xml.ws.Endpoint;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class CountryServicePublisher {
+
+ private static final Logger logger = LoggerFactory.getLogger(CountryServicePublisher.class);
+
+ public static void main(String[] args) {
+ Endpoint endpoint = Endpoint.create(new CountryServiceImpl());
+ endpoint.publish("http://localhost:8888/ws/country");
+
+ logger.info("Country web service ready to consume requests!");
+ }
+}
\ No newline at end of file
diff --git a/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/Currency.java b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/Currency.java
new file mode 100644
index 0000000000..d1b25a26c6
--- /dev/null
+++ b/web-modules/jee-7/src/main/java/com/baeldung/soap/ws/server/Currency.java
@@ -0,0 +1,15 @@
+package com.baeldung.soap.ws.server;
+
+public enum Currency {
+
+ EUR, INR, USD;
+
+ public String value() {
+ return name();
+ }
+
+ public static Currency fromValue(String v) {
+ return valueOf(v);
+ }
+
+}
diff --git a/web-modules/jee-7/src/main/resources/country.xsd b/web-modules/jee-7/src/main/resources/country.xsd
new file mode 100644
index 0000000000..c94b6047f9
--- /dev/null
+++ b/web-modules/jee-7/src/main/resources/country.xsd
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web-modules/jee-7/src/main/resources/logback.xml b/web-modules/jee-7/src/main/resources/logback.xml
new file mode 100644
index 0000000000..5c1b7ec771
--- /dev/null
+++ b/web-modules/jee-7/src/main/resources/logback.xml
@@ -0,0 +1,15 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web-modules/jee-7/src/main/webapp/WEB-INF/beans.xml b/web-modules/jee-7/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointIntegrationTest.java b/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointIntegrationTest.java
new file mode 100644
index 0000000000..8190ae5afb
--- /dev/null
+++ b/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointIntegrationTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.batch.understanding;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Properties;
+
+import javax.batch.operations.JobOperator;
+import javax.batch.runtime.BatchRuntime;
+import javax.batch.runtime.BatchStatus;
+import javax.batch.runtime.JobExecution;
+import javax.batch.runtime.StepExecution;
+
+import org.junit.jupiter.api.Test;
+
+class CustomCheckPointIntegrationTest {
+ @Test
+ public void givenChunk_whenCustomCheckPoint_thenCommitCountIsThree() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("customCheckPoint", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
+ for (StepExecution stepExecution : jobOperator.getStepExecutions(executionId)) {
+ if (stepExecution.getStepName()
+ .equals("firstChunkStep")) {
+ jobOperator.getStepExecutions(executionId)
+ .stream()
+ .map(BatchTestHelper::getCommitCount)
+ .forEach(count -> assertEquals(3L, count.longValue()));
+ }
+ }
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
+ }
+}
diff --git a/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceIntegrationTest.java b/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceIntegrationTest.java
new file mode 100644
index 0000000000..7dda13a752
--- /dev/null
+++ b/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceIntegrationTest.java
@@ -0,0 +1,76 @@
+package com.baeldung.batch.understanding;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import javax.batch.operations.JobOperator;
+import javax.batch.runtime.BatchRuntime;
+import javax.batch.runtime.BatchStatus;
+import javax.batch.runtime.JobExecution;
+import javax.batch.runtime.StepExecution;
+
+import org.junit.jupiter.api.Test;
+
+class JobSequenceIntegrationTest {
+ @Test
+ public void givenTwoSteps_thenBatch_CompleteWithSuccess() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("simpleJobSequence", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
+ assertEquals(2 , jobOperator.getStepExecutions(executionId).size());
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
+ }
+
+ @Test
+ public void givenFlow_thenBatch_CompleteWithSuccess() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("flowJobSequence", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
+ assertEquals(3 , jobOperator.getStepExecutions(executionId).size());
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
+ }
+
+ @Test
+ public void givenDecider_thenBatch_CompleteWithSuccess() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("decideJobSequence", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
+ List stepExecutions = jobOperator.getStepExecutions(executionId);
+ List executedSteps = new ArrayList<>();
+ for (StepExecution stepExecution : stepExecutions) {
+ executedSteps.add(stepExecution.getStepName());
+ }
+ assertEquals(2, jobOperator.getStepExecutions(executionId).size());
+ assertArrayEquals(new String[] { "firstBatchStepStep1", "firstBatchStepStep3" }, executedSteps.toArray());
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
+ }
+
+ @Test
+ public void givenSplit_thenBatch_CompletesWithSuccess() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("splitJobSequence", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
+ List stepExecutions = jobOperator.getStepExecutions(executionId);
+ List executedSteps = new ArrayList<>();
+ for (StepExecution stepExecution : stepExecutions) {
+ executedSteps.add(stepExecution.getStepName());
+ }
+ assertEquals(3, stepExecutions.size());
+ assertTrue(executedSteps.contains("splitJobSequenceStep1"));
+ assertTrue(executedSteps.contains("splitJobSequenceStep2"));
+ assertTrue(executedSteps.contains("splitJobSequenceStep3"));
+ assertTrue(executedSteps.get(0).equals("splitJobSequenceStep1") || executedSteps.get(0).equals("splitJobSequenceStep2"));
+ assertTrue(executedSteps.get(1).equals("splitJobSequenceStep1") || executedSteps.get(1).equals("splitJobSequenceStep2"));
+ assertTrue(executedSteps.get(2).equals("splitJobSequenceStep3"));
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
+ }
+}
diff --git a/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetIntegrationTest.java b/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetIntegrationTest.java
new file mode 100644
index 0000000000..dc91f747d3
--- /dev/null
+++ b/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetIntegrationTest.java
@@ -0,0 +1,64 @@
+package com.baeldung.batch.understanding;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Properties;
+
+import javax.batch.operations.JobOperator;
+import javax.batch.runtime.BatchRuntime;
+import javax.batch.runtime.BatchStatus;
+import javax.batch.runtime.JobExecution;
+
+import org.junit.jupiter.api.Test;
+
+class SimpleBatchLetIntegrationTest {
+ @Test
+ public void givenBatchLet_thenBatch_CompleteWithSuccess() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("simpleBatchLet", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
+ }
+
+ @Test
+ public void givenBatchLetProperty_thenBatch_CompleteWithSuccess() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("injectionSimpleBatchLet", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
+ }
+
+ @Test
+ public void givenBatchLetPartition_thenBatch_CompleteWithSuccess() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("partitionSimpleBatchLet", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
+ }
+
+ @Test
+ public void givenBatchLetStarted_whenStopped_thenBatchStopped() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("simpleBatchLet", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobOperator.stop(executionId);
+ jobExecution = BatchTestHelper.keepTestStopped(jobExecution);
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.STOPPED);
+ }
+
+ @Test
+ public void givenBatchLetStopped_whenRestarted_thenBatchCompletesSuccess() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("simpleBatchLet", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobOperator.stop(executionId);
+ jobExecution = BatchTestHelper.keepTestStopped(jobExecution);
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.STOPPED);
+ executionId = jobOperator.restart(jobExecution.getExecutionId(), new Properties());
+ jobExecution = BatchTestHelper.keepTestAlive(jobOperator.getJobExecution(executionId));
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
+ }
+}
diff --git a/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkIntegrationTest.java b/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkIntegrationTest.java
new file mode 100644
index 0000000000..a7884dbb32
--- /dev/null
+++ b/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkIntegrationTest.java
@@ -0,0 +1,68 @@
+package com.baeldung.batch.understanding;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.batch.operations.JobOperator;
+import javax.batch.runtime.BatchRuntime;
+import javax.batch.runtime.BatchStatus;
+import javax.batch.runtime.JobExecution;
+import javax.batch.runtime.Metric;
+import javax.batch.runtime.StepExecution;
+
+import org.junit.jupiter.api.Test;
+
+class SimpleChunkIntegrationTest {
+ @Test
+ public void givenChunk_thenBatch_CompletesWithSucess() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("simpleChunk", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
+ List stepExecutions = jobOperator.getStepExecutions(executionId);
+ for (StepExecution stepExecution : stepExecutions) {
+ if (stepExecution.getStepName()
+ .equals("firstChunkStep")) {
+ Map metricsMap = BatchTestHelper.getMetricsMap(stepExecution.getMetrics());
+ assertEquals(10L, metricsMap.get(Metric.MetricType.READ_COUNT)
+ .longValue());
+ assertEquals(10L / 2L, metricsMap.get(Metric.MetricType.WRITE_COUNT)
+ .longValue());
+ assertEquals(10L / 3 + (10L % 3 > 0 ? 1 : 0), metricsMap.get(Metric.MetricType.COMMIT_COUNT)
+ .longValue());
+ }
+ }
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
+ }
+
+ @Test
+ public void givenChunk__thenBatch_fetchInformation() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("simpleChunk", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
+ // job name contains simpleBatchLet which is the name of the file
+ assertTrue(jobOperator.getJobNames().contains("simpleChunk"));
+ // job parameters are empty
+ assertTrue(jobOperator.getParameters(executionId).isEmpty());
+ // step execution information
+ List stepExecutions = jobOperator.getStepExecutions(executionId);
+ assertEquals("firstChunkStep", stepExecutions.get(0).getStepName());
+ // finding out batch status
+ assertEquals(BatchStatus.COMPLETED, stepExecutions.get(0).getBatchStatus());
+ Map metricTest = BatchTestHelper.getMetricsMap(stepExecutions.get(0).getMetrics());
+ assertEquals(10L, metricTest.get(Metric.MetricType.READ_COUNT).longValue());
+ assertEquals(5L, metricTest.get(Metric.MetricType.FILTER_COUNT).longValue());
+ assertEquals(4L, metricTest.get(Metric.MetricType.COMMIT_COUNT).longValue());
+ assertEquals(5L, metricTest.get(Metric.MetricType.WRITE_COUNT).longValue());
+ assertEquals(0L, metricTest.get(Metric.MetricType.READ_SKIP_COUNT).longValue());
+ assertEquals(0L, metricTest.get(Metric.MetricType.WRITE_SKIP_COUNT).longValue());
+ assertEquals(0L, metricTest.get(Metric.MetricType.PROCESS_SKIP_COUNT).longValue());
+ assertEquals(0L, metricTest.get(Metric.MetricType.ROLLBACK_COUNT).longValue());
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
+ }
+}
diff --git a/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkIntegrationTest.java b/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkIntegrationTest.java
new file mode 100644
index 0000000000..8c3beeb2f3
--- /dev/null
+++ b/web-modules/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkIntegrationTest.java
@@ -0,0 +1,45 @@
+package com.baeldung.batch.understanding;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import java.util.Properties;
+
+import javax.batch.operations.JobOperator;
+import javax.batch.runtime.BatchRuntime;
+import javax.batch.runtime.BatchStatus;
+import javax.batch.runtime.JobExecution;
+import javax.batch.runtime.StepExecution;
+
+import org.junit.jupiter.api.Test;
+
+class SimpleErrorChunkIntegrationTest {
+
+ @Test
+ public void givenChunkError_thenBatch_CompletesWithFailed() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("simpleErrorChunk", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobExecution = BatchTestHelper.keepTestFailed(jobExecution);
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.FAILED);
+ }
+
+ @Test
+ public void givenChunkError_thenErrorSkipped_CompletesWithSuccess() throws Exception {
+ JobOperator jobOperator = BatchRuntime.getJobOperator();
+ Long executionId = jobOperator.start("simpleErrorSkipChunk", new Properties());
+ JobExecution jobExecution = jobOperator.getJobExecution(executionId);
+ jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
+ List stepExecutions = jobOperator.getStepExecutions(executionId);
+ for (StepExecution stepExecution : stepExecutions) {
+ if (stepExecution.getStepName()
+ .equals("errorStep")) {
+ jobOperator.getStepExecutions(executionId)
+ .stream()
+ .map(BatchTestHelper::getProcessSkipCount)
+ .forEach(skipCount -> assertEquals(1L, skipCount.longValue()));
+ }
+ }
+ assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
+ }
+}
diff --git a/web-modules/jee-7/src/test/java/com/baeldung/singleton/CarServiceLiveTest.java b/web-modules/jee-7/src/test/java/com/baeldung/singleton/CarServiceLiveTest.java
new file mode 100644
index 0000000000..c054f9c2db
--- /dev/null
+++ b/web-modules/jee-7/src/test/java/com/baeldung/singleton/CarServiceLiveTest.java
@@ -0,0 +1,109 @@
+package com.baeldung.singleton;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ejb.EJB;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.CDI;
+import javax.inject.Inject;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RunWith(Arquillian.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class CarServiceLiveTest {
+
+ public static final Logger LOG = LoggerFactory.getLogger(CarServiceLiveTest.class);
+
+ @Deployment
+ public static JavaArchive createDeployment() {
+ return ShrinkWrap.create(JavaArchive.class)
+ .addClasses(CarServiceBean.class, CarServiceSingleton.class, CarServiceEjbSingleton.class, Car.class)
+ .addAsResource("META-INF/persistence.xml")
+ .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
+ }
+
+ @Inject
+ private CarServiceBean carServiceBean;
+
+ @Inject
+ private CarServiceSingleton carServiceSingleton;
+
+ @EJB
+ private CarServiceEjbSingleton carServiceEjbSingleton;
+
+ @Test
+ public void givenASingleton_whenGetBeanIsCalledTwice_thenTheSameInstanceIsReturned() {
+ CarServiceSingleton one = getBean(CarServiceSingleton.class);
+ CarServiceSingleton two = getBean(CarServiceSingleton.class);
+ assertTrue(one == two);
+ }
+
+ @Test
+ public void givenAPojo_whenGetBeanIsCalledTwice_thenDifferentInstancesAreReturned() {
+ CarServiceBean one = getBean(CarServiceBean.class);
+ CarServiceBean two = getBean(CarServiceBean.class);
+ assertTrue(one != two);
+ }
+
+ @SuppressWarnings("unchecked")
+ private T getBean(Class beanClass) {
+ BeanManager bm = CDI.current().getBeanManager();
+ Bean bean = (Bean) bm.getBeans(beanClass).iterator().next();
+ CreationalContext ctx = bm.createCreationalContext(bean);
+ return (T) bm.getReference(bean, beanClass, ctx);
+ }
+
+ @Test
+ public void givenCDI_whenConcurrentAccess_thenLockingIsNotProvided() {
+ for (int i = 0; i < 10; i++) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ String model = Double.toString(Math.round(Math.random() * 100));
+ Car car = new Car("Speedster", model);
+ int serviceQueue = carServiceSingleton.service(car);
+ assertTrue(serviceQueue < 10);
+ }
+ }).start();
+ }
+ return;
+ }
+
+ @Test
+ public void givenEJB_whenConcurrentAccess_thenLockingIsProvided() {
+ for (int i = 0; i < 10; i++) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ String model = Double.toString(Math.round(Math.random() * 100));
+ Car car = new Car("Speedster", model);
+ int serviceQueue = carServiceEjbSingleton.service(car);
+ assertEquals(0, serviceQueue);
+ }
+ }).start();
+ }
+ return;
+ }
+
+}
\ No newline at end of file
diff --git a/web-modules/jee-7/src/test/java/com/baeldung/soap/ws/client/CountryClientLiveTest.java b/web-modules/jee-7/src/test/java/com/baeldung/soap/ws/client/CountryClientLiveTest.java
new file mode 100644
index 0000000000..ae423f9bdd
--- /dev/null
+++ b/web-modules/jee-7/src/test/java/com/baeldung/soap/ws/client/CountryClientLiveTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.soap.ws.client;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.baeldung.soap.ws.client.generated.CountryService;
+import com.baeldung.soap.ws.client.generated.CountryServiceImplService;
+import com.baeldung.soap.ws.client.generated.Currency;
+
+//Ensure that com.baeldung.soap.ws.server.CountryServicePublisher is running before executing this test
+public class CountryClientLiveTest {
+
+ private static CountryService countryService;
+
+ @BeforeClass
+ public static void setup() {
+ CountryServiceImplService service = new CountryServiceImplService();
+ countryService = service.getCountryServiceImplPort();
+ }
+
+ @Test
+ public void givenCountryService_whenCountryIndia_thenCapitalIsNewDelhi() {
+ assertEquals("New Delhi", countryService.findByName("India").getCapital());
+ }
+
+ @Test
+ public void givenCountryService_whenCountryFrance_thenPopulationCorrect() {
+ assertEquals(66710000, countryService.findByName("France").getPopulation());
+ }
+
+ @Test
+ public void givenCountryService_whenCountryUSA_thenCurrencyUSD() {
+ assertEquals(Currency.USD, countryService.findByName("USA").getCurrency());
+ }
+
+
+}
diff --git a/web-modules/jee-7/src/test/resources/arquillian.xml b/web-modules/jee-7/src/test/resources/arquillian.xml
new file mode 100644
index 0000000000..f4274877fd
--- /dev/null
+++ b/web-modules/jee-7/src/test/resources/arquillian.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ target/wildfly-8.2.1.Final
+ standalone.xml
+ true
+ 9990
+ -Djboss.http.port=8639
+
+
+
+
+
+ 127.0.0.1
+ 9990
+ admin
+ pass
+ true
+
+
+
+
\ No newline at end of file
diff --git a/web-modules/jee-7/src/test/resources/jberet.properties b/web-modules/jee-7/src/test/resources/jberet.properties
new file mode 100644
index 0000000000..e8b9907de5
--- /dev/null
+++ b/web-modules/jee-7/src/test/resources/jberet.properties
@@ -0,0 +1 @@
+db-url=jdbc:h2:mem:jberet-repo;DB_CLOSE_DELAY=-1
\ No newline at end of file
diff --git a/web-modules/jooby/conf/application.conf b/web-modules/jooby/conf/application.conf
new file mode 100644
index 0000000000..7da56eef6b
--- /dev/null
+++ b/web-modules/jooby/conf/application.conf
@@ -0,0 +1,4 @@
+#application.secret = 2o128940921eo298e21
+#db = /url/to/the/datastore
+
+#redis = "redis://localhost:6379"
\ No newline at end of file
diff --git a/web-modules/jooby/pom.xml b/web-modules/jooby/pom.xml
new file mode 100644
index 0000000000..238f17571f
--- /dev/null
+++ b/web-modules/jooby/pom.xml
@@ -0,0 +1,83 @@
+
+
+ 4.0.0
+ com.baeldung.jooby
+ jooby
+ 1.0
+ jooby
+
+
+ com.baeldung
+ web-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ io.jooby
+ jooby
+ ${jooby.version}
+
+
+ io.jooby
+ jooby-test
+ ${jooby.version}
+
+
+ io.jooby
+ jooby-jetty
+ ${jooby.version}
+
+
+ io.jooby
+ jooby-redis
+ ${jooby.version}
+
+
+ io.rest-assured
+ rest-assured
+ test
+ ${rest-assured.version}
+
+
+ com.squareup.okhttp3
+ okhttp
+ ${squareup.okhttp.version}
+
+
+
+
+
+
+ maven-shade-plugin
+ ${maven-shade-plugin.version}
+
+
+ io.jooby
+ jooby-maven-plugin
+ ${jooby.version}
+
+
+ maven-compiler-plugin
+ ${maven-compiler.version}
+
+
+ -parameters
+
+
+
+
+
+
+
+ 2.16.1
+ 3.1.1
+ com.baeldung.jooby.App
+ 3.2.4
+ 3.8.1
+ 4.9.1
+
+
+
\ No newline at end of file
diff --git a/web-modules/jooby/public/form.html b/web-modules/jooby/public/form.html
new file mode 100644
index 0000000000..bb9a705b9a
--- /dev/null
+++ b/web-modules/jooby/public/form.html
@@ -0,0 +1,18 @@
+
+
+
+
+ Insert title here
+
+
+
+
+
\ No newline at end of file
diff --git a/web-modules/jooby/src/main/java/com/baeldung/jooby/App.java b/web-modules/jooby/src/main/java/com/baeldung/jooby/App.java
new file mode 100644
index 0000000000..1bfaf6de5d
--- /dev/null
+++ b/web-modules/jooby/src/main/java/com/baeldung/jooby/App.java
@@ -0,0 +1,123 @@
+package com.baeldung.jooby;
+
+import com.baeldung.jooby.bean.Employee;
+
+import io.jooby.Jooby;
+import io.jooby.ServerOptions;
+import io.jooby.Session;
+import io.jooby.SessionStore;
+
+public class App extends Jooby {
+ {
+ setServerOptions(new ServerOptions().setPort(8080)
+ .setSecurePort(8433));
+ }
+
+ {
+ get("/", ctx -> "Hello World!");
+ }
+
+ {
+ get("/user/{id}", ctx -> "Hello user : " + ctx.path("id")
+ .value());
+ get("/user/:id", ctx -> "Hello user: " + ctx.path("id")
+ .value());
+ get("/uid:{id}", ctx -> "Hello User with id : uid = " + ctx.path("id")
+ .value());
+ }
+
+ {
+ onStarting(() -> System.out.println("starting app"));
+
+ onStop(() -> System.out.println("stopping app"));
+
+ onStarted(() -> System.out.println("app started"));
+ }
+
+ {
+ get("/login", ctx -> "Hello from Baeldung");
+ }
+
+ {
+ post("/save", ctx -> {
+ String userId = ctx.query("id")
+ .value();
+ return userId;
+ });
+ }
+
+ {
+ {
+ assets("/employee", "public/form.html");
+ }
+
+ post("/submitForm", ctx -> {
+ Employee employee = ctx.path(Employee.class);
+ // ...
+ return "employee data saved successfully";
+ });
+
+ }
+
+ {
+ decorator(next -> ctx -> {
+ System.out.println("first");
+ // Moves execution to next handler: second
+ return next.apply(ctx);
+ });
+ decorator(next -> ctx -> {
+ System.out.println("second");
+ // Moves execution to next handler: third
+ return next.apply(ctx);
+ });
+
+ get("/handler", ctx -> "third");
+ }
+
+ {
+ get("/sessionInMemory", ctx -> {
+ Session session = ctx.session();
+ session.put("token", "value");
+ return session.get("token")
+ .value();
+ });
+ }
+
+ {
+ String secret = "super secret token";
+
+ setSessionStore(SessionStore.signed(secret));
+
+ get("/signedSession", ctx -> {
+ Session session = ctx.session();
+ session.put("token", "value");
+ return session.get("token")
+ .value();
+ });
+ }
+
+ {
+ get("/sessionInMemoryRedis", ctx -> {
+ Session session = ctx.session();
+ session.put("token", "value");
+ return session.get("token")
+ .value();
+ });
+ }
+
+ /* This will work once redis is installed locally
+ {
+ install(new RedisModule("redis"));
+ setSessionStore(new RedisSessionStore(require(RedisClient.class)));
+ get("/redisSession", ctx -> {
+ Session session = ctx.session();
+ session.put("token", "value");
+ return session.get("token");
+ });
+ }*/
+
+ public static void main(final String[] args) {
+ runApp(args, App::new);
+ }
+
+}
diff --git a/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/GetController.java b/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/GetController.java
new file mode 100644
index 0000000000..bd43fb1717
--- /dev/null
+++ b/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/GetController.java
@@ -0,0 +1,23 @@
+package com.baeldung.jooby.mvc;
+
+import java.util.HashMap;
+
+import io.jooby.ModelAndView;
+import io.jooby.annotations.GET;
+import io.jooby.annotations.Path;
+
+@Path("/hello")
+public class GetController {
+
+ @GET
+ public String hello() {
+ return "Hello Baeldung";
+ }
+
+ @GET
+ @Path("/home")
+ public ModelAndView home() {
+ return new ModelAndView("welcome.html", new HashMap<>());
+ }
+
+}
diff --git a/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/PostController.java b/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/PostController.java
new file mode 100644
index 0000000000..0f014580f9
--- /dev/null
+++ b/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/PostController.java
@@ -0,0 +1,13 @@
+package com.baeldung.jooby.mvc;
+
+import io.jooby.annotations.POST;
+import io.jooby.annotations.Path;
+
+@Path("/submit")
+public class PostController {
+
+ @POST
+ public String hello() {
+ return "Submit Baeldung";
+ }
+}
diff --git a/web-modules/jooby/src/main/resources/logback.xml b/web-modules/jooby/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/web-modules/jooby/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web-modules/jooby/src/test/java/com/baeldung/jooby/AppLiveTest.java b/web-modules/jooby/src/test/java/com/baeldung/jooby/AppLiveTest.java
new file mode 100644
index 0000000000..e55e0e04a4
--- /dev/null
+++ b/web-modules/jooby/src/test/java/com/baeldung/jooby/AppLiveTest.java
@@ -0,0 +1,32 @@
+package com.baeldung.jooby;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+
+import org.junit.jupiter.api.Test;
+
+import io.jooby.JoobyTest;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+@JoobyTest(value = App.class, port = 8080)
+class AppLiveTest {
+
+ static OkHttpClient client = new OkHttpClient();
+
+ @Test
+ void given_defaultUrl_expect_fixedString() {
+ Request request = new Request.Builder().url("http://localhost:8080")
+ .build();
+ try (Response response = client.newCall(request)
+ .execute()) {
+ assertEquals("Hello World!", response.body()
+ .string());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/web-modules/jooby/src/test/java/com/baeldung/jooby/AppUnitTest.java b/web-modules/jooby/src/test/java/com/baeldung/jooby/AppUnitTest.java
new file mode 100644
index 0000000000..98184e11f3
--- /dev/null
+++ b/web-modules/jooby/src/test/java/com/baeldung/jooby/AppUnitTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.jooby;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import io.jooby.MockRouter;
+
+public class AppUnitTest {
+
+ @Test
+ public void given_defaultUrl_with_mockrouter_expect_fixedString() {
+ MockRouter router = new MockRouter(new App());
+ assertEquals("Hello World!", router.get("/")
+ .value());
+ }
+}
diff --git a/web-modules/linkrest/pom.xml b/web-modules/linkrest/pom.xml
new file mode 100644
index 0000000000..f43add6910
--- /dev/null
+++ b/web-modules/linkrest/pom.xml
@@ -0,0 +1,70 @@
+
+
+ 4.0.0
+ linkrest
+ 0.0.1-SNAPSHOT
+ linkrest
+ war
+
+
+ com.baeldung
+ web-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ com.nhl.link.rest
+ link-rest
+ ${linkrest.version}
+
+
+ org.glassfish.jersey.containers
+ jersey-container-servlet
+ ${jersey.version}
+
+
+
+
+
+
+ maven-war-plugin
+ ${maven-war-plugin.version}
+
+ WebContent
+ false
+
+
+
+ org.apache.cayenne.plugins
+ cayenne-maven-plugin
+ ${cayenne.version}
+
+
+ ${project.basedir}/src/main/resources/linkrest.map.xml
+
+
+
+
+ cgen
+
+
+
+
+
+ org.apache.cayenne.plugins
+ cayenne-modeler-maven-plugin
+ ${cayenne.version}
+
+
+
+
+
+ 2.9
+ 4.0.B1
+ 2.25.1
+
+
+
\ No newline at end of file
diff --git a/web-modules/linkrest/src/main/resources/logback.xml b/web-modules/linkrest/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/web-modules/linkrest/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web-modules/ninja/README.md b/web-modules/ninja/README.md
new file mode 100644
index 0000000000..554d088c1b
--- /dev/null
+++ b/web-modules/ninja/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles
+
+- [Introduction to Ninja Framework](https://www.baeldung.com/ninja-framework-intro)
diff --git a/web-modules/ninja/pom.xml b/web-modules/ninja/pom.xml
new file mode 100644
index 0000000000..cb3e234172
--- /dev/null
+++ b/web-modules/ninja/pom.xml
@@ -0,0 +1,226 @@
+
+
+ 4.0.0
+ ninja
+ 1.0.0
+ jar
+ http://www.ninjaframework.org
+
+
+ com.baeldung
+ web-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ org.webjars
+ bootstrap
+ ${bootstrap.version}
+
+
+ org.webjars
+ jquery
+ ${jquery.version}
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+ org.ninjaframework
+ ninja-standalone
+ ${ninja.version}
+
+
+ org.ninjaframework
+ ninja-test-utilities
+ ${ninja.version}
+ test
+
+
+
+ junit
+ junit
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ ${junit-jupiter.version}
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ ${junit-jupiter.version}
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${compiler.plugin.version}
+
+ ${source.version}
+ ${target.version}
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ ${enforcer.plugin.version}
+
+
+ enforce-banned-dependencies
+
+ enforce
+
+
+
+
+
+ commons-logging
+
+
+
+ true
+
+
+
+
+
+ org.eclipse.jetty
+ jetty-maven-plugin
+ ${jetty.version}
+
+
+ /
+
+ stop
+ 8889
+ 1
+ automatic
+
+
+ target/classes
+
+ **/*
+
+
+ **/*.ftl.html
+ assets/**
+
+
+
+
+
+ ninja.mode
+ dev
+
+
+
+
+
+
+
+
+ org.ninjaframework
+ ninja-maven-plugin
+ ${ninja.version}
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ ${deploy.plugin.version}
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ ${shade.plugin.version}
+
+ true
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+
+
+
+
+
+
+ package
+
+ shade
+
+
+
+
+
+ ninja.standalone.NinjaJetty
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ --add-opens java.base/java.lang=ALL-UNNAMED
+
+
+
+
+
+
+ src/main/java
+
+ **/*
+
+
+ **/*.java
+
+
+
+ src/main/resources
+
+ **/*
+
+
+
+
+
+
+ 6.5.0
+ 9.4.18.v20190429
+ 3.3.4
+ 2.1.3
+ 3.2
+ 17
+ 17
+ 1.3.1
+ 2.8.2
+ 2.2
+ 5.8.1
+
+
+
\ No newline at end of file
diff --git a/web-modules/ninja/src/main/java/META-INF/persistence.xml b/web-modules/ninja/src/main/java/META-INF/persistence.xml
new file mode 100644
index 0000000000..e57cd5ecc0
--- /dev/null
+++ b/web-modules/ninja/src/main/java/META-INF/persistence.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+ org.hibernate.jpa.HibernatePersistenceProvider
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web-modules/ninja/src/main/java/assets/css/custom.css b/web-modules/ninja/src/main/java/assets/css/custom.css
new file mode 100644
index 0000000000..41d249d3cb
--- /dev/null
+++ b/web-modules/ninja/src/main/java/assets/css/custom.css
@@ -0,0 +1,3 @@
+/* Add additional stylesheets below
+-------------------------------------------------- */
+
diff --git a/web-modules/ninja/src/main/java/conf/Filters.java b/web-modules/ninja/src/main/java/conf/Filters.java
new file mode 100644
index 0000000000..b201780fa1
--- /dev/null
+++ b/web-modules/ninja/src/main/java/conf/Filters.java
@@ -0,0 +1,13 @@
+package conf;
+
+import java.util.List;
+import ninja.Filter;
+
+public class Filters implements ninja.application.ApplicationFilters {
+
+ @Override
+ public void addFilters(List> filters) {
+ // Add your application - wide filters here
+ // filters.add(MyFilter.class);
+ }
+}
diff --git a/web-modules/ninja/src/main/java/conf/Module.java b/web-modules/ninja/src/main/java/conf/Module.java
new file mode 100644
index 0000000000..f7c03a4b26
--- /dev/null
+++ b/web-modules/ninja/src/main/java/conf/Module.java
@@ -0,0 +1,18 @@
+package conf;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Singleton;
+
+import services.UserService;
+import services.UserServiceImpl;
+
+@Singleton
+public class Module extends AbstractModule {
+
+ protected void configure() {
+
+ bind(UserService.class).to(UserServiceImpl.class);
+
+ }
+
+}
diff --git a/web-modules/ninja/src/main/java/conf/Routes.java b/web-modules/ninja/src/main/java/conf/Routes.java
new file mode 100644
index 0000000000..a1727d55b0
--- /dev/null
+++ b/web-modules/ninja/src/main/java/conf/Routes.java
@@ -0,0 +1,32 @@
+package conf;
+
+import ninja.AssetsController;
+import ninja.Router;
+import ninja.application.ApplicationRoutes;
+import controllers.ApplicationController;
+
+public class Routes implements ApplicationRoutes {
+
+ @Override
+ public void init(Router router) {
+
+ router.GET().route("/index").with(ApplicationController::index);
+ router.GET().route("/home").with(ApplicationController::home);
+ router.GET().route("/hello").with(ApplicationController::helloWorld);
+ router.GET().route("/userJson").with(ApplicationController::userJson);
+ router.GET().route("/createUser").with(ApplicationController::createUser);
+ router.GET().route("/flash").with(ApplicationController::showFlashMsg);
+
+ router.GET().route("/users").with(ApplicationController::fetchUsers);
+ router.POST().route("/users").with(ApplicationController::insertUser);
+
+ //Assets
+ router.GET().route("/assets/webjars/{fileName: .*}").with(AssetsController::serveWebJars);
+ router.GET().route("/assets/{fileName: .*}").with(AssetsController::serveStatic);
+
+ //Index
+ router.GET().route("/.*").with(ApplicationController::index);
+
+ }
+
+}
diff --git a/web-modules/ninja/src/main/java/conf/application.conf b/web-modules/ninja/src/main/java/conf/application.conf
new file mode 100644
index 0000000000..0ae4c7ec40
--- /dev/null
+++ b/web-modules/ninja/src/main/java/conf/application.conf
@@ -0,0 +1,21 @@
+application.name=baeldung ninja dev application
+%test.application.name=baeldung ninja test application
+%prod.application.name=baeldung ninja application
+
+application.cookie.prefix=NINJA
+
+application.languages=fr,en
+
+application.session.expire_time_in_seconds=3600
+application.session.send_only_if_changed=true
+application.session.transferred_over_https_only=false
+
+ninja.port=8000
+ninja.ssl.port=8001
+application.secret = fxSjSL9Q017BSL7gBnkyo2Prln7uXaXIT35gotXRIED8c46OSa8s4QdoIQdTsEtj
+
+# h2 jpa configuration
+ninja.jpa.persistence_unit_name=dev_unit
+db.connection.url=jdbc:h2:./devDb
+db.connection.username=sa
+db.connection.password=
diff --git a/web-modules/ninja/src/main/java/conf/messages.properties b/web-modules/ninja/src/main/java/conf/messages.properties
new file mode 100644
index 0000000000..3bddfcd8c7
--- /dev/null
+++ b/web-modules/ninja/src/main/java/conf/messages.properties
@@ -0,0 +1,2 @@
+header.home=Home!
+helloMsg=Hello, welcome to Ninja Framework!
\ No newline at end of file
diff --git a/web-modules/ninja/src/main/java/conf/messages_fr.properties b/web-modules/ninja/src/main/java/conf/messages_fr.properties
new file mode 100644
index 0000000000..89264e0cb9
--- /dev/null
+++ b/web-modules/ninja/src/main/java/conf/messages_fr.properties
@@ -0,0 +1,2 @@
+header.home=Accueil!
+helloMsg=Bonjour, bienvenue dans Ninja Framework!
\ No newline at end of file
diff --git a/web-modules/ninja/src/main/java/controllers/ApplicationController.java b/web-modules/ninja/src/main/java/controllers/ApplicationController.java
new file mode 100644
index 0000000000..38dd598694
--- /dev/null
+++ b/web-modules/ninja/src/main/java/controllers/ApplicationController.java
@@ -0,0 +1,102 @@
+package controllers;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
+
+import models.User;
+import ninja.Context;
+import ninja.Result;
+import ninja.Results;
+import ninja.i18n.Lang;
+import ninja.i18n.Messages;
+import ninja.jpa.UnitOfWork;
+import ninja.session.FlashScope;
+import ninja.validation.JSR303Validation;
+import ninja.validation.Validation;
+import services.UserService;
+
+@Singleton
+public class ApplicationController {
+
+ @Inject
+ Lang lang;
+
+ @Inject
+ Messages msg;
+
+ private static Log logger = LogFactory.getLog(ApplicationController.class);
+
+ @Inject
+ Provider entityManagerProvider;
+
+ @Inject
+ UserService userService;
+
+ public Result index() {
+ return Results.html();
+ }
+
+ public Result userJson() {
+ HashMap userMap = userService.getUserMap();
+ logger.info(userMap);
+ return Results.json().render(userMap);
+ }
+
+ public Result helloWorld(Context context) {
+ Optional language = Optional.of("fr");
+ String helloMsg = msg.get("helloMsg", language).get();
+ return Results.text().render(helloMsg);
+ }
+
+ public Result showFlashMsg(FlashScope flashScope) {
+ flashScope.success("Success message");
+ flashScope.error("Error message");
+ return Results.redirect("/home");
+ }
+
+ public Result home() {
+ return Results.html();
+ }
+
+ public Result createUser() {
+ return Results.html();
+ }
+
+ @UnitOfWork
+ public Result fetchUsers() {
+ EntityManager entityManager = entityManagerProvider.get();
+ Query q = entityManager.createQuery("SELECT x FROM User x");
+ List users = (List) q.getResultList();
+ return Results.json().render(users);
+ }
+
+ @Transactional
+ public Result insertUser(FlashScope flashScope, @JSR303Validation User user, Validation validation) {
+ logger.info("Inserting User : " +user);
+
+ if (validation.getViolations().size() > 0) {
+ flashScope.error("Validation Error: User can't be created");
+ } else {
+ EntityManager entityManager = entityManagerProvider.get();
+ entityManager.persist(user);
+ entityManager.flush();
+ flashScope.success("User '" + user + "' is created successfully");
+ }
+
+ return Results.redirect("/home");
+ }
+
+}
diff --git a/web-modules/ninja/src/main/java/ehcache.xml b/web-modules/ninja/src/main/java/ehcache.xml
new file mode 100644
index 0000000000..b401b61a36
--- /dev/null
+++ b/web-modules/ninja/src/main/java/ehcache.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/web-modules/ninja/src/main/java/logback.xml b/web-modules/ninja/src/main/java/logback.xml
new file mode 100644
index 0000000000..ebdcf56f76
--- /dev/null
+++ b/web-modules/ninja/src/main/java/logback.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
diff --git a/web-modules/ninja/src/main/java/models/User.java b/web-modules/ninja/src/main/java/models/User.java
new file mode 100644
index 0000000000..e021567bca
--- /dev/null
+++ b/web-modules/ninja/src/main/java/models/User.java
@@ -0,0 +1,25 @@
+package models;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.validation.constraints.NotNull;
+
+@Entity
+public class User {
+
+ @Id
+ @GeneratedValue(strategy=GenerationType.AUTO)
+ Long id;
+
+ @NotNull
+ public String firstName;
+
+ public String email;
+
+ public String toString() {
+ return firstName + " : " + email;
+ }
+
+}
diff --git a/web-modules/ninja/src/main/java/services/UserService.java b/web-modules/ninja/src/main/java/services/UserService.java
new file mode 100644
index 0000000000..10d625c66f
--- /dev/null
+++ b/web-modules/ninja/src/main/java/services/UserService.java
@@ -0,0 +1,9 @@
+package services;
+
+import java.util.HashMap;
+
+public interface UserService {
+
+ HashMap getUserMap();
+
+}
diff --git a/web-modules/ninja/src/main/java/services/UserServiceImpl.java b/web-modules/ninja/src/main/java/services/UserServiceImpl.java
new file mode 100644
index 0000000000..0f8c2214cf
--- /dev/null
+++ b/web-modules/ninja/src/main/java/services/UserServiceImpl.java
@@ -0,0 +1,15 @@
+package services;
+
+import java.util.HashMap;
+
+public class UserServiceImpl implements UserService {
+
+ @Override
+ public HashMap getUserMap() {
+ HashMap userMap = new HashMap<>();
+ userMap.put("name", "Norman Lewis");
+ userMap.put("email", "norman@email.com");
+ return userMap;
+ }
+
+}
diff --git a/web-modules/ninja/src/main/java/views/ApplicationController/createUser.ftl.html b/web-modules/ninja/src/main/java/views/ApplicationController/createUser.ftl.html
new file mode 100644
index 0000000000..9156f7dbf2
--- /dev/null
+++ b/web-modules/ninja/src/main/java/views/ApplicationController/createUser.ftl.html
@@ -0,0 +1,12 @@
+<#import "../layout/defaultLayout.ftl.html" as layout>
+<@layout.myLayout "Create User">
+
+